/* Avergona: clean and quiet (D15). No decoration competing with content.
   Mobile-first single column; tablet and desktop center the same column. */

:root {
  --bg: #fafaf9;
  --surface: #ffffff;
  --text: #1c1c1a;
  --muted: #6b6b66;
  --border: #e4e2dd;
  --accent: #2f6f4f;
  --accent-contrast: #ffffff;
  --gold: #b8860b;
  --level1: #cfe3d6;
  --level2: #8fc4a4;
  --group-0: #3d7ea6;
  --group-1: #8a5fa0;
  --group-2: #b3591f;
  --group-3: #56658c;
  --group-4: #a84868;
  --group-5: #8c7a1f;
  --tabbar-h: 64px;
  --fab-size: 56px;
  --radius: 14px;
  /* light dark (not a fixed "light") lets native widgets -- checkbox/radio
     chrome, the date/time picker popovers -- follow the same
     prefers-color-scheme signal the --bg/--surface/etc. overrides below key
     off, instead of always rendering their stock light appearance. */
  color-scheme: light dark;
  accent-color: var(--accent);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 16px;
  line-height: 1.4;
}

.view {
  max-width: 640px;
  margin: 0 auto;
  padding: 14px 16px calc(var(--tabbar-h) + 24px);
  min-height: 100vh;
}

.tap-target {
  min-height: 44px;
  min-width: 44px;
}

/* Tab bar: fixed to the bottom, thumb-reachable. */
.tabbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--tabbar-h);
  display: flex;
  background: var(--surface);
  border-top: 1px solid var(--border);
  max-width: 640px;
  margin: 0 auto;
}

.tab {
  flex: 1;
  border: none;
  background: none;
  color: var(--muted);
  font-size: 13px;
  cursor: pointer;
}

.tab.is-active {
  color: var(--accent);
  font-weight: 600;
}

/* Quick-add fab, present on every screen except Settings (app.js hides it
   there). Same equal-specificity [hidden] pattern already fixed for
   .overlay and .field-destination -- explicit here too so a later rule
   giving .fab a `display` can't silently break `hidden` again.
   .fab-anchor reuses .tabbar's centering triple (left/right 0, max-width,
   margin auto) so the button's containing block is the same centered
   column as everything else, instead of the raw viewport edge -- on a
   wide screen the column no longer leaves the fab stranded near the
   window's true right edge. */
.fab[hidden] { display: none; }

.fab-anchor {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  max-width: 640px;
  margin: 0 auto;
  pointer-events: none;
}

.fab {
  position: absolute;
  right: 20px;
  bottom: calc(var(--tabbar-h) + 16px);
  pointer-events: auto;
  width: var(--fab-size);
  height: var(--fab-size);
  border-radius: 50%;
  border: none;
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

/* Cards */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  margin-bottom: 16px;
}

.card-title {
  margin: 0 0 6px;
  font-size: 18px;
  font-weight: 600;
}

.card-body {
  margin: 0 0 16px;
  color: var(--muted);
}

.card-celebrate { border-color: var(--accent); }
.card-closed .card-body { margin-bottom: 0; }
.card-note {
  margin: 8px 0 0;
  color: var(--muted);
  font-style: italic;
}
.card-golden { border-color: var(--gold); }
.card-golden .card-title { color: var(--gold); }

.review-trigger { width: 100%; }

/* Buttons */
.btn {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  border-radius: 10px;
  padding: 10px 18px;
  font-size: 15px;
  cursor: pointer;
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}

/* Today: focus list */
.focus-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}

.focus-count {
  color: var(--muted);
  margin: 0;
}

.focus-list {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
}

.focus-item + .focus-item {
  margin-top: 8px;
}

/* The whole row is the drag surface once reordering (no separate handle) --
   stop iOS Safari starting a page-scroll gesture before Pointer Events fire,
   same reasoning the old .drag-handle carried alone; also stops the row
   reading as selectable text under a long-press. */
.is-reorder-list .focus-item {
  touch-action: none;
  user-select: none;
  cursor: grab;
}

/* The priority control overlays the check surface instead of sitting beside
   it -- a sibling flex item's own width (even at 44px min tap-target width)
   always ate into one edge of the check button, leaving it short of the
   row's actual left or right edge depending on which side the control sat.
   Overlaying keeps the check surface spanning the full row (edge to edge)
   while the control still gets its own full 44x44 tap target on top of it. */
.focus-row {
  position: relative;
}

.focus-row .item-controls {
  position: absolute;
  left: 4px;
  top: 50%;
  transform: translateY(-50%);
}

/* Only reserve the gutter when a control is actually rendered -- with
   SHOW_PRIORITY off (itemcontrols.js) no .item-controls exists, and the
   check should use the row's full width instead of a blank left strip. */
.focus-row:has(.item-controls) .check {
  padding-left: 52px;
}

.check {
  width: 100%;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  font-size: 16px;
  color: var(--text);
  cursor: pointer;
}

/* One line, ellipsized -- scoped to Today's own browsing row, so every Today
   row is the same height. The plan and review sheets share the .check class
   but wrap their titles instead: a candidate you are about to pick is worth
   two lines. */
.focus-row .check {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.focus-item.is-done .check {
  color: var(--muted);
  text-decoration: line-through;
  background: var(--bg);
}

/* The reorder-mode row's inert lookalike -- same .check surface, but it's a
   plain div (see today.js), so it must give up .check's own cursor:pointer
   to let the row's grab/grabbing cursor (below) show through instead. */
.check-static {
  cursor: inherit;
}

/* Priority + reorder controls (Today, Inbox, plan sheet). Quiet markers
   (D3/D15): accent for high, muted for low, nothing for normal -- no red,
   no badges. The dot/button is transparent by default so a normal-priority
   item shows no marker at all. */
.priority-dot,
.priority-btn {
  color: transparent;
  flex-shrink: 0;
}

.priority-dot.priority-high,
.priority-btn.priority-high { color: var(--accent); }

.priority-dot.priority-low,
.priority-btn.priority-low { color: var(--muted); }

.priority-btn {
  background: none;
  border: none;
  font-size: 16px;
  padding: 4px;
  cursor: pointer;
}

.item-controls {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

/* Group (bucket) dot: which group a task is in, as a small colored marker
   instead of a sub-heading -- direct feedback wanted items to sort freely
   across groups rather than being partitioned into separate lists. Same
   inherited font-size as surrounding text (no explicit font-size rule), so
   it never adds vertical space to a row. Six quiet, muted hues -- kept
   distinct from --accent/--gold and from each other, per D15's no-badges
   identity -- assigned per-group by groupColorIndex (src/core/buckets.js),
   a hash of the group's own name resolved against every other group
   currently configured so no two look the same (up to six groups; a color
   only ever shifts to un-collide, never a random reshuffle). */
.group-dot { flex-shrink: 0; }

.group-dot-0 { color: var(--group-0); }
.group-dot-1 { color: var(--group-1); }
.group-dot-2 { color: var(--group-2); }
.group-dot-3 { color: var(--group-3); }
.group-dot-4 { color: var(--group-4); }
.group-dot-5 { color: var(--group-5); }

/* Reorder: hamburger menu (Today's focus header, each Inbox group header)
   and the per-row drag handle it gates behind "Reorder". Same
   quiet/bordered/muted language the removed .order-btn arrows used. */
.list-menu {
  position: relative;
  flex-shrink: 0;
}

.list-menu-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--muted);
  cursor: pointer;
}

.list-menu-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

.hamburger-icon {
  position: relative;
  display: inline-block;
  width: 16px;
  height: 2px;
  background: currentColor;
}

.hamburger-icon::before,
.hamburger-icon::after {
  content: "";
  position: absolute;
  left: 0;
  width: 16px;
  height: 2px;
  background: currentColor;
}

.hamburger-icon::before { top: -5px; }
.hamburger-icon::after { top: 5px; }

.list-menu-popover {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 10;
  min-width: 140px;
  padding: 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.list-menu-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 15px;
  color: var(--text);
  cursor: pointer;
}

.list-menu-item:disabled {
  opacity: 0.4;
  cursor: default;
}

/* SortableJS's own state classes (ghostClass/chosenClass/dragClass), same
   names the POC uses. The ghost is the real dragged element playing
   placeholder while a separate floating clone (.sortable-drag, fallback
   mode) follows the pointer. */
.sortable-ghost {
  opacity: 0.4;
}

/* Grab while hovering a sortable row, grabbing once it's actually picked up
   (chosenClass) or while its floating clone (dragClass) follows the pointer
   -- never the default arrow or a text-select I-beam. The chosen/drag
   compounds need to out-specify the plain grab rules below them (both
   target the same row), not just come later in the stylesheet. */
.is-reorder-list .focus-item.sortable-chosen,
.drag-row.sortable-chosen {
  cursor: grabbing;
}

.sortable-drag {
  background: var(--surface);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  border-radius: 10px;
  cursor: grabbing;
  /* The floating clone is reparented onto document.body (fallbackOnBody) --
     outside the list's `list-style: none`, so it inherits nothing and falls
     back to the UA default (disc), showing a bullet next to the dragged
     row for the drag's whole duration without this. */
  list-style: none;
}

.screen-title { margin: 0 0 6px; font-size: 21px; }
.screen-body { color: var(--muted); }

/* Inbox's title row: "Inbox" plus the one consolidated sort menu, at the
   top right -- same convention as Today's .focus-header. */
.screen-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}

.screen-header .screen-title { margin: 0; }

/* The active section's name sits right of "Inbox" instead of its own
   subheading row -- Someday/Archived/Repeating used to each render as a
   full group (with its own heading) stacked on the same screen; now only
   one shows at a time (src/ui/inbox.js), reached via the hamburger's
   "View X" items, and this is the only label left naming it. */
.screen-title-group {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.screen-subtitle {
  color: var(--muted);
  font-size: 14px;
}

/* A browsing-mode group's pager with no heading beside it (renderPagerRow)
   -- right-align it instead of inheriting .inbox-group-header's
   space-between, which would otherwise push a lone child to the left. */
.inbox-pager-row {
  justify-content: flex-end;
}

/* B6: the one shared pager control (Inbox groups, plan sheet). Prev/next
   at 44px (D16) with a plain "N of M" between them; quiet (D15), same
   border/muted language as .list-menu-btn. Hidden entirely at one page --
   src/ui/pager.js returns null rather than rendering this, so nothing
   below applies when a list already fits. */
.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 8px 0 4px;
}

.pager-btn {
  background: none;
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--muted);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.pager-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

.pager-label {
  color: var(--muted);
  font-size: 13px;
}

/* Capture overlay */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.overlay[hidden] {
  display: none;
}

.sheet {
  width: 100%;
  max-width: 640px;
  background: var(--surface);
  border-radius: var(--radius) var(--radius) 0 0;
  padding: 20px 16px calc(env(safe-area-inset-bottom, 0px) + 20px);
}

.sheet-title { margin: 0 0 16px; }

/* Capture's title row: "New task" plus the bucket menu button, top right --
   same convention as .screen-header. */
.sheet-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 16px;
}

.sheet-header .sheet-title { margin: 0; }

/* Groups "Add many" + the group-menu button on the header's right side, so
   .sheet-header's space-between still splits just two things: the title and
   this wrapper. */
.sheet-header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Green-outline variant of .btn (border/text in --accent, same --surface
   background as plain .btn) -- visually distinct from both .btn and the
   filled .btn-primary. */
.btn-accent-outline {
  border-color: var(--accent);
  color: var(--accent);
}

/* Text-content variant of .list-menu-btn (that one's a fixed-size hamburger
   icon) -- shows "Group" or the chosen name (plus its colored dot), so
   auto-width with its own padding instead of a square icon tap target. */
.bucket-menu-btn {
  padding: 8px 12px;
  font-size: 14px;
  color: var(--text);
}

.bucket-menu-new {
  display: flex;
  gap: 8px;
  padding: 4px;
}

.bucket-menu-new input { flex: 1; }

/* Native inputs: color-scheme + accent-color above fix a field's own chrome
   (checkbox fill, date/time picker popover); these still stay UA-default
   white/black regardless, since color-scheme only changes which default
   palette a browser draws them in, not whether they read our custom
   surface/text/border variables at all. Color-only (no padding/radius) so
   this can't fight the sizing each field's own class below sets. */
input[type="text"],
input[type="date"],
input[type="time"],
input[type="number"],
input[type="file"],
select,
textarea {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border);
}

.field-title {
  width: 100%;
  font-size: 16px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 12px;
}

/* Add many's textarea: same box treatment as .field-title, taller and
   resizable for pasting several lines at once. */
.field-bulk {
  width: 100%;
  font-size: 16px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 12px;
  min-height: 200px;
  resize: vertical;
  font-family: inherit;
}

.field-due {
  display: block;
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 12px;
}

.field-due input { display: block; margin-top: 4px; }

.field-destination {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 14px;
  color: var(--muted);
  margin-bottom: 16px;
}

/* Same class of bug as .overlay[hidden] above: an author rule with equal
   specificity to the UA [hidden] default wins the cascade regardless of
   source order, so a plain `hidden` attribute silently loses without this
   explicit override (found in A2/A5 hand-walks, fixed here in A6). */
.field-destination[hidden] { display: none; }

/* B5: recurrence editor (capture + Inbox edit) and the "Repeating" group.
   The due row is hidden while a repeat is active; add the same
   [hidden]-specificity override .field-destination/.field-bucket already
   carry, since .field-due sets an explicit display: block. */
.field-due[hidden] { display: none; }

.capture-repeat { margin-bottom: 12px; }

.field-repeat {
  display: block;
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 8px;
}

.field-repeat select,
.field-repeat input { display: inline-block; margin-left: 6px; }

.repeat-kind { padding: 6px; border: 1px solid var(--border); border-radius: 8px; }

.repeat-weekdays {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 13px;
  color: var(--muted);
}

.repeat-weekdays[hidden] { display: none; }

.repeat-weekday {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

.repeat-custom[hidden] { display: none; }

.repeat-every {
  width: 64px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
}

/* Shares the title's row (top right of the item) rather than its own line
   below it -- see the Repeating item's .inbox-row in inbox.js. */
.repeat-summary {
  flex-shrink: 0;
  font-size: 13px;
  color: var(--muted);
}

/* The template edit form stacks (title, rule editor, save) rather than the
   single-row layout .inbox-edit uses for a plain title rewrite. */
.repeat-edit {
  flex-direction: column;
  align-items: stretch;
}

.sheet-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

/* Plan sheet.

   The sheet takes as much of the window as it needs and stops at the window's
   own height, so the candidate list is short on a phone and long on a desktop.
   The column's fixed parts -- title, suggested line, notice, pager row, Commit
   row -- keep their height; .plan-groups is the only part that shrinks, and
   plan.js measures the height it ends up with to decide how many candidates go
   on a page. overflow-y is a safety net: it catches the row the over-suggested
   notice pushes down when it appears after the measurement. */
.plan-sheet {
  display: flex;
  flex-direction: column;
  max-height: 100%;
}

.plan-sheet .plan-groups {
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.plan-suggested {
  color: var(--muted);
  margin: 0 0 8px;
}

.plan-notice {
  color: var(--accent);
  font-size: 13px;
  margin: 0 0 12px;
}

.plan-notice[hidden] { display: none; }

.plan-empty {
  color: var(--muted);
  margin: 0 0 16px;
}

.plan-groups {
  margin-bottom: 4px;
}

.plan-group + .plan-group { margin-top: 16px; }

.plan-group-title {
  margin: 0 0 8px;
  font-size: 12px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.plan-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.plan-item + .plan-item { margin-top: 8px; }

.plan-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.plan-item .check { flex: 1; }

.plan-item .check[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-contrast);
}

.plan-shrink {
  flex-shrink: 0;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 12px;
  text-decoration: underline;
  cursor: pointer;
  padding: 4px;
}

/* B4: a quiet, non-interactive bucket tag on candidate rows. */
.bucket-tag {
  flex-shrink: 0;
  color: var(--muted);
  font-size: 12px;
  padding: 2px 6px;
  border: 1px solid var(--border);
  border-radius: 6px;
}

.plan-edit {
  display: flex;
  gap: 8px;
  flex: 1;
}

.plan-edit-input {
  flex: 1;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 15px;
}

/* Review sheet */
.review-oneaway {
  color: var(--accent);
  font-size: 13px;
  margin: 0 0 12px;
}

.review-oneaway[hidden] { display: none; }

.review-freeze {
  color: var(--muted);
  font-size: 14px;
  margin: 0 0 12px;
}

.review-freeze[hidden] { display: none; }

/* Inbox screen */
.inbox-group + .inbox-group { margin-top: 8px; }

.inbox-group-title {
  margin: 0 0 8px;
  font-size: 12px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* B6: a group's heading and its pager share one row instead of the pager
   sitting in its own row below the list -- four independently-paginated
   groups (Inbox, Someday, Archived, Repeating) share the Inbox screen, and a
   separate pager row per group is chrome the 390x844 budget doesn't have. */
.inbox-group-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}

.inbox-group-header .inbox-group-title { margin: 0; }
.inbox-group-header .pager { margin: 0; }

.inbox-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.inbox-item + .inbox-item { margin-top: 8px; }

.inbox-item {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 10px;
}

/* One line, ellipsized, everywhere -- every browsing-mode row (Inbox,
   Someday, Archived, Repeating) is then the same height, which is also what
   a fixed-per-section page size can measure reliably against. */
.inbox-item-title {
  display: block;
  margin-bottom: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The priority control + title share one row (normal browsing) so a
   normal-priority item's invisible-but-44px-tall control doesn't sit in a
   row of its own -- that lone band was the "blank space" under every item.
   Leads with the control, same position the reorder-mode marker uses. */
.inbox-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}

.inbox-row .inbox-item-title { margin-bottom: 0; flex: 1 1 auto; min-width: 0; }

/* Reorder mode: .drag-row is a modifier on the <li> itself (see
   src/ui/inbox.js), not scoped through the ancestor .drag-list <ul> --
   SortableJS's forceFallback clone is reparented straight onto
   document.body mid-drag, outside that <ul>, so an ancestor-scoped rule
   would stop applying to the clone and it would render as broken stacked
   text for the whole drag. The whole row is the drag surface (no handle),
   laid out the same way .inbox-row is, and clipped to one line (normal
   browsing keeps full wrapped titles, including the "(due ...)" suffix --
   only the dense reorder rows need the ellipsis). Same touch-action
   reasoning as .is-reorder-list .focus-item above. */
.drag-row {
  display: flex;
  align-items: center;
  gap: 8px;
  touch-action: none;
  user-select: none;
  cursor: grab;
}

.drag-row .inbox-item-title {
  flex: 1 1 auto;
  min-width: 0;
  margin-bottom: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.inbox-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

.inbox-actions button {
  border: none;
  background: none;
  color: var(--accent);
  font-size: 13px;
  padding: 2px 0;
  cursor: pointer;
}

.inbox-edit { display: flex; gap: 8px; }

.inbox-edit-input {
  flex: 1;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 15px;
}

/* The inline group-picker opened by a task's "Group" action. */
.inbox-bucket-edit { margin-bottom: 8px; }

.inbox-bucket-edit select { width: 100%; }

/* History screen */
.history-streak { font-size: 16px; margin: 0 0 16px; }

.heatmap {
  display: grid;
  grid-template-columns: repeat(14, 1fr);
  gap: 3px;
  margin-bottom: 20px;
}

.heatmap-cell {
  aspect-ratio: 1;
  border-radius: 3px;
  background: var(--border);
}

.heatmap-cell.level-1 { background: var(--level1); }
.heatmap-cell.level-2 { background: var(--level2); }
.heatmap-cell.level-3 { background: var(--accent); }
.heatmap-cell.is-golden { background: var(--gold); }
.heatmap-cell.is-freeze { background: var(--bg); border: 2px solid var(--accent); }

.history-weekly { margin-bottom: 16px; }

.weekly-list {
  list-style: none;
  margin: 0;
  padding: 0;
  color: var(--muted);
  font-size: 14px;
}

.weekly-list li + li { margin-top: 4px; }

.history-milestone { color: var(--muted); margin: 0 0 8px; }

/* Settings screen. B6: five collapsible groups (Nudges, Notifications,
   Buckets, Data, About), one open at a time, all collapsed by default --
   with a bucket or two configured the flat list of groups overflowed
   390x844 (measured 950px of 844), and the B6 prompt calls for collapsible
   groups over paginating prose once that happens. */
.settings-group { margin-bottom: 4px; }

.settings-group-header {
  display: flex;
  width: 100%;
  justify-content: space-between;
  align-items: center;
  background: none;
  border: none;
  border-bottom: 1px solid var(--border);
  padding: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: pointer;
}

.settings-group-body { padding: 12px 0 4px; }

.settings-subgroup + .settings-subgroup { margin-top: 16px; }

.settings-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.settings-times {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: 14px;
}

.settings-line { color: var(--muted); margin: 0 0 8px; }

.settings-import {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 12px;
  font-size: 14px;
  color: var(--muted);
}

.settings-about { color: var(--muted); font-size: 13px; margin: 0; }

.settings-version { color: var(--muted); font-size: 11px; opacity: 0.7; margin: 4px 0 0; }

/* B4: buckets list -- same item-row language as .inbox-item/.inbox-actions. */
.bucket-list {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
}

.bucket-item + .bucket-item { margin-top: 8px; }

.bucket-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 14px;
}

/* min-width: 0 overrides the flex default (auto, i.e. the text's own
   min-content width) -- without it a long, unbroken bucket name pushes the
   row wider than the screen instead of wrapping, forcing a horizontal
   scroll on mobile. overflow-wrap covers a single word too long to wrap
   at all (a pasted URL, no spaces). */
.bucket-item-title {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}

.bucket-actions {
  display: flex;
  gap: 14px;
}

.bucket-actions button {
  border: none;
  background: none;
  color: var(--accent);
  font-size: 13px;
  padding: 4px 0;
  cursor: pointer;
}

.bucket-edit { display: flex; gap: 8px; flex: 1; min-width: 0; }

.bucket-edit-input,
.bucket-add-input {
  flex: 1;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 15px;
}

.bucket-add { display: flex; gap: 8px; }

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #161614;
    --surface: #201f1c;
    --text: #ececea;
    --muted: #9a9a94;
    --border: #34332e;
    --accent: #4f9c72;
    --accent-contrast: #06140d;
    --level1: #234a34;
    --level2: #3a7856;
    --group-0: #6bb8e0;
    --group-1: #b98fd1;
    --group-2: #e0894f;
    --group-3: #8a9bc4;
    --group-4: #d17e9c;
    --group-5: #c4b358;
    color-scheme: dark;
  }
}

@media (min-width: 720px) {
  .view { padding-top: 32px; }
}
