* { box-sizing: border-box; }
:root { --slowmo: 1; } /* dev slow motion, set from ?slowmo= in app.js */
[hidden] { display: none !important; }

/* pace. fonts, self-hosted (variable files). */
@font-face { font-family: "Inter"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("fonts/inter-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Inter Tight"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("fonts/inter-tight-latin.woff2") format("woff2"); }

/* pace. tokens (docs/brand-identity/build-checklist.md). Dark swaps
   each one for its dark value; nothing is inverted or filtered. */
:root {
  --font-ui: "Inter", system-ui, sans-serif;
  --font-head: "Inter Tight", "Inter", system-ui, sans-serif;
  --page: #f4f3ef;
  --surface: #ffffff;
  --track: #ebeae5;
  --sunk: #ecebe6;
  --block: #ecebe6; /* pending block fill */
  --block-on-sunk: #ffffff; /* the same on a past day's shaded cell */
  --line: #d9d8d2;
  --faint: #e6e5e0;
  --divider: #efeeea;
  --done-fill: #c2c1ba;
  --ink: #1c1d21;
  --text-2: #3a3c42;
  --muted: #62646b;
  --faint-text: #686a71; /* AA (4.5:1) as text on page, surface and sunk; Chunk 99 */
  --field-line: #85878e; /* text-field borders: 3:1 on every surface (1.4.11); Chunk 99 */
  --badge-fill: #c2410c; /* orange count badges: white on it 5.2:1; Chunk 99 */
  --on-badge: #ffffff;
  --missed-accent: #e8590c;
  --missed-ink: #8f3507;
  --missed-ink-2: #b4430a;
  --missed-a: #f9d7c4;
  --missed-b: #f4c6ab;
  --missed-stripes: repeating-linear-gradient(148deg, var(--missed-a) 0 6px, var(--missed-b) 6px 9px);
  --brand-accent: #e8590c; /* logo only */
  /* Primary buttons: Ink in light, paper-on-light in dark. */
  --primary-fill: #1c1d21;
  --on-primary: #f4f3ef;
  /* Ink feature cards (Next up, today column, year card): raised in dark. */
  --feature: #1c1d21;
  --feature-2: #2c2d32;
  --feature-3: #45464c;
  --feature-line: #33363b;
  --on-feature: #f4f3ef;
  --on-feature-2: #c9c8c2;
  --on-feature-3: #9a9ca3;
  /* Blocks on the Ink feature column/cell (today in Week and Month). */
  --on-feature-block: #2a2c31;
  --on-feature-done: #4a4d54;
  --shadow-line: 0 1px 0 var(--line);

  /* Type scale (Chunk 80). Snapshot steps: Display 96/88, Title 40/40,
     Heading 20/24, Body 15/22, Meta 11/14; one-offs snapped to the nearest
     step, ties going down (the type is tighter). */
  --fs-2xs: 10px;     /* micro labels, Month pills */
  --fs-xs: 11px;      /* meta, section labels */
  --fs-sm: 12px;
  --fs-md: 13px;      /* kicker over a title */
  --fs-base: 14px;    /* buttons, controls */
  --fs-body: 15px;    /* body */
  --fs-lg: 17px;
  --fs-heading: 20px; /* card titles */
  --fs-input: 16px;   /* quick-add sheet, inputs that must not zoom */
  --fs-lead: 18px;
  --fs-h-lg: 24px;
  --fs-section: 22px; /* History section heads */
  --fs-xl: 26px;
  --fs-dialog-title: 28px; /* Event dialog title */
  --fs-2xl: 32px;     /* big stats */
  --fs-title: 40px;   /* page title */
  --fs-3xl: 44px;
  --fs-display: 64px;
  --lh-meta: 14px;
  --lh-heading: 24px;
  --lh-body: 22px;
  --lh-title: 44px;
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semi: 600;
  --fw-bold: 700;
  --fw-heavy: 800;

  /* Spacing: one 4px base step, with half steps below 12px. One-offs
     snapped to the nearest step, ties going down. */
  --sp-px: 1px;
  --sp-0-5: 2px;
  --sp-1: 4px;
  --sp-1-5: 6px;
  --sp-2: 8px;
  --sp-2-5: 10px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-7: 28px;
  --sp-8: 32px;
  --sp-10: 40px;
  --sp-12: 48px;

  /* Corners (Ed, 2 Nov: pills for buttons, 12-14px on cards and popovers;
     the 28 Oct 0.35x pass is undone). */
  --r-pill: 999px;   /* tabs, buttons, dropdowns, segmented, icon buttons, badges */
  --r-dialog: 16px;  /* dialogs */
  --r-popover: 14px; /* main cards, panels, popovers */
  --r-card: 12px;    /* side and tray cards, Waiting block, menus */
  --r-small: 10px;   /* small cards, day cells, chips */
  --r-input: 8px;    /* text inputs, notes */
  --r-block: 6px;    /* task blocks */
  --r-sheet: 22px;   /* quick-add bottom sheet top corners */
  --r-band: 20px;    /* move-dialog range band ends */
  --r-key: 5px;      /* keyboard key caps */
  --r-mini: 3px;     /* Month mini blocks */
  --r-dash: 2px;     /* goal dash, progress bars */

  /* Shadows */
  --shadow-soft: 0 1px 3px rgb(0 0 0 / 0.08);
  --shadow-menu: 0 12px 32px rgb(0 0 0 / 0.14);  /* menus and popovers */
  --shadow-dialog: 0 16px 48px rgb(0 0 0 / 0.22);
  --shadow-bubble: 0 4px 14px rgb(31 39 51 / 0.28); /* round floating buttons */
  --shadow-panel: -12px 0 32px rgb(0 0 0 / 0.10);

  /* Motion: values only, every one --slowmo-aware. Named by value so
     Chunk 89 can merge them; curves named as in interaction-inventory.md. */
  --dur-60: calc(60ms * var(--slowmo));
  --dur-80: calc(80ms * var(--slowmo));
  --dur-90: calc(90ms * var(--slowmo));
  --dur-120: calc(120ms * var(--slowmo));
  --dur-140: calc(140ms * var(--slowmo));
  --dur-150: calc(150ms * var(--slowmo));
  --dur-160: calc(160ms * var(--slowmo));
  --dur-180: calc(180ms * var(--slowmo));
  --dur-200: calc(200ms * var(--slowmo));
  --dur-220: calc(220ms * var(--slowmo));
  --dur-240: calc(240ms * var(--slowmo));
  --dur-260: calc(260ms * var(--slowmo));
  --dur-280: calc(280ms * var(--slowmo));
  --dur-300: calc(300ms * var(--slowmo));
  --dur-320: calc(320ms * var(--slowmo));
  --stagger: calc(14ms * var(--slowmo));
  --ease-glide: cubic-bezier(0.22, 0.9, 0.25, 1);
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-panel: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-snappy: cubic-bezier(0.25, 0.8, 0.3, 1);
  --ease-pop: cubic-bezier(0.34, 1.3, 0.5, 1);
  --ease-soft: cubic-bezier(0.3, 0.7, 0.4, 1);
  /* Motion rules (Chunk 89): the names to use, per
     docs/brand-identity/motion.md. Built from the --dur-* values above,
     which go once chunks 90-91 move every rule onto these. */
  --motion-press: var(--dur-90);    /* a press: scale to 0.96 */
  --motion-out: var(--dur-120);     /* small things leaving */
  --motion-fast: var(--dur-160);    /* fades, colour, small things arriving */
  --motion-move: var(--dur-240);    /* things moving on screen; panels leaving */
  --motion-panel: var(--dur-320);   /* panels and drawers arriving */
  --motion-max: var(--dur-320);     /* nothing but a spring runs longer */
  --motion-delay: var(--dur-80);    /* contents following their container */
  --motion-settle: var(--dur-160);  /* labels shown once their container is open */
  --ease-enter: var(--ease-glide);  /* arriving and settling */
  --ease-move: var(--ease-standard); /* moving or resizing in place */
  --ease-exit: cubic-bezier(0.4, 0, 1, 1); /* leaving: gathers speed, no settle */
  --ease-fade: ease;                /* colour and opacity only */
  /* The switch's springs, copied from springCurve() in app.js (no change):
     SWITCH_SPRING (0.6, 0.85) and PILL_SPRING (0.48, 0.86). */
  --spring-switch-ms: calc(788ms * var(--slowmo));
  --spring-switch: linear(0, 0.0087, 0.0324, 0.0674, 0.1108, 0.1601, 0.2133, 0.2686,
    0.3247, 0.3805, 0.4351, 0.4879, 0.5382, 0.5858, 0.6305, 0.6721,
    0.7105, 0.7458, 0.7781, 0.8073, 0.8337, 0.8574, 0.8785, 0.8973,
    0.9139, 0.9285, 0.9413, 0.9523, 0.9619, 0.9701, 0.9771, 0.9831,
    0.9881, 0.9922, 0.9956, 0.9984, 1.0006, 1.0024, 1.0037, 1.0047,
    1.0054, 1.0059, 1.0062, 1.0063, 1.0063, 1.0061, 1.006, 1.0057,
    1.0054, 1.0051, 1.0047, 1.0044, 1.004, 1.0037, 1.0033, 1.003,
    1.0027, 1.0024, 1.0022, 1.0019, 1);
  --spring-pill-ms: calc(628ms * var(--slowmo));
  --spring-pill: linear(0, 0.0087, 0.0321, 0.0667, 0.1097, 0.1585, 0.2111, 0.2659,
    0.3214, 0.3765, 0.4306, 0.4827, 0.5326, 0.5798, 0.6241, 0.6654,
    0.7036, 0.7387, 0.7708, 0.8, 0.8264, 0.8502, 0.8715, 0.8904,
    0.9072, 0.9221, 0.9351, 0.9464, 0.9563, 0.9648, 0.9722, 0.9784,
    0.9837, 0.9882, 0.9919, 0.995, 0.9975, 0.9995, 1.0011, 1.0024,
    1.0033, 1.004, 1.0045, 1.0048, 1.005, 1.005, 1.005, 1.0048,
    1.0047, 1.0045, 1.0042, 1.0039, 1.0037, 1.0034, 1.0031, 1.0028,
    1.0026, 1.0023, 1.0021, 1.0019, 1);

  --danger: #b3261e;
  --danger-bg: #fbeceb;
  --link: #2a5db0;
  --warn-bg: #fff3cd;
  --warn-line: #e0c97a;
  --warn-ink: #7a5b00;
  --today: var(--feature);
  --missed: var(--missed-accent);
  color-scheme: light;
}
:root[data-theme="dark"] {
  --page: #141517;
  --surface: #1d1f22;
  --track: #18191c;
  --sunk: #1a1b1e;
  --block: #2a2c31;
  --block-on-sunk: #2a2c31;
  --line: #33363b;
  --faint: #2a2c31;
  --divider: #26282c;
  --done-fill: #4a4d54;
  --ink: #ecebe6;
  --text-2: #c9c8c2;
  --muted: #9a9ca3;
  --faint-text: #92949b; /* AA as text on page, surface, sunk and blocks; Chunk 99 */
  --field-line: #787b82; /* text-field borders: 3:1 on every surface (1.4.11) */
  --badge-fill: #f07a3a; /* dark text on it 6.6:1 (white would be 2.8:1) */
  --on-badge: #141517;
  --missed-accent: #f07a3a;
  --missed-ink: #ffb48a;
  --missed-ink-2: #ffb48a;
  --missed-a: #4d2a1a;
  --missed-b: #5e3420;
  --brand-accent: #f07a3a;
  --primary-fill: #ecebe6;
  --on-primary: #141517;
  --feature: #26282c;
  --feature-2: #303237;
  --feature-3: #45484e;
  --feature-line: #3a3d42;
  --on-feature: #ecebe6;
  --on-feature-2: #c9c8c2;
  --on-feature-3: #9a9ca3;
  --on-feature-block: #313338;
  --on-feature-done: #4a4d54;
  --danger: #ff8a80;
  --danger-bg: #3a1f1e;
  --link: #8fb3ff;
  --warn-bg: #3a3220;
  --warn-line: #6b5a2a;
  --warn-ink: #f0d68a;
  color-scheme: dark;
}

body {
  --sidebar-width: 200px;
  --cal-panel: var(--track); /* the calendar's own panel, and what its gutters show */
  margin: 0;
  font: var(--fs-base)/1.4 var(--font-ui);
  color: var(--ink);
  background: var(--page);
}

/* The sidebar stays put while the main area scrolls under the page, and
   follows the same auto-fit rule as Day view and Month's grid: it fills the
   window's height exactly and never scrolls as a whole - only the Goals list
   inside it does, and only once that list overflows. */
.sidebar {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  width: var(--sidebar-width);
  display: flex;
  flex-direction: column;
  gap: var(--sp-0-5);
  padding: var(--sp-3) var(--sp-2);
  background: var(--surface);
  border-right: 1px solid var(--line);
  min-height: 0;
  overflow: hidden;
}
.sidebar h1 { padding: 0 var(--sp-2) var(--sp-3); }
.content { margin-left: var(--sidebar-width); padding: 0 var(--sp-8) var(--sp-7); }
.content > .error { margin: var(--sp-3) 0 0; }
#goal-view > .panel, #routine-view > .panel, #completed-view > .panel, #checkin-view > .panel, #history-view > .panel, #collection-view > .panel { margin-top: var(--sp-3); }

.nav-entry, .nav-goal {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-radius: var(--r-mini);
  padding: var(--sp-1-5) var(--sp-2);
  cursor: pointer;
  color: var(--text-2);
}
.nav-entry:hover, .nav-goal:hover { background: var(--divider); }
.nav-entry.active { background: var(--track); font-weight: var(--fw-semi); }

/* Once there are more open Goals than fit, the Goals section scrolls on its
   own and Completed/List stay pinned below it. */
.nav-goals {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 0 1 auto;
  margin: var(--sp-2) 0;
}
.nav-goals h2 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 0 var(--sp-1);
  padding: 0 var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}
#sidebar-goals, #sidebar-routines, #sidebar-collections { overflow-y: auto; overscroll-behavior: contain; min-height: 0; }
#sidebar-goals > .muted, #sidebar-routines > .muted, #sidebar-collections > .muted { display: block; padding: var(--sp-1) var(--sp-2); }
.nav-goal {
  --goal: #8a8f98;
  margin-top: var(--sp-0-5);
  border-left: 4px solid var(--goal);
  border-radius: 0 var(--r-mini) var(--r-mini) 0;
  background: color-mix(in srgb, var(--goal) 12%, var(--surface));
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.nav-goal:hover { background: color-mix(in srgb, var(--goal) 24%, var(--surface)); }
.nav-row { position: relative; }
.nav-goal.active {
  background: color-mix(in srgb, var(--goal) 32%, var(--surface));
  font-weight: var(--fw-semi);
}

h1 { font-size: var(--fs-lg); margin: 0; }
h2 { font-size: var(--fs-body); margin: 0 0 var(--sp-2); }

button, input, select { font: inherit; }

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
}

.error {
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  padding: var(--sp-2);
}

.layout {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  gap: var(--sp-3);
  align-items: start;
}

.week {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--sp-2-5);
}

/* Week and Day rest as a sandwich (Chunk 19): the focused week or day in full
   between its two neighbours, blurred and faded - context only, inert in JS
   and unclickable here. Week stacks them top to bottom, Day side by side. */
.week-stack { display: flex; flex-direction: column; gap: var(--sp-2); }
/* Week auto-fits (Chunk 22): JS sets the stack's height and each neighbour's
   share of it, and the focused week takes the rest - a day with more than
   fits scrolls inside itself. */
.week-stack > .week { min-height: 0; }
.week.neighbour { flex: none; overflow: hidden; }
.week.focused { flex: 1 1 0; }
/* A flex row rather than a 1fr 2fr 1fr grid (Chunk 26) so a paging step can
   ease each column's own width, the way Week eases each row's height. */
.day-stack {
  display: flex;
  gap: var(--sp-2);
  align-items: flex-start;
}
.day-stack > .day-view { flex: 1 1 0; min-width: 0; }
.day-stack > .day-view.focused { flex-grow: 2; }
/* The focused slot sits above its neighbours. Paging is an instant cut (Chunk 109, #40). */
.week-stack > .focused, .day-stack > .focused { position: relative; z-index: 1; }
.neighbour { user-select: none; cursor: pointer; }
/* Day's neighbours are blurred (Chunk 19); Week's are bar rows instead
   (Chunk 36), already legible, so hovering one only shows the pointer. */
.day-view.neighbour {
  filter: blur(1.7px);
  opacity: 0.55;
  transition: filter var(--motion-move) var(--ease-move), opacity var(--motion-move) var(--ease-move);
}
@media (prefers-reduced-motion: reduce) { .day-view.neighbour { transition: none; } }
/* Hovering a Day neighbour says it's clickable (a click pages to it) without
   selecting anything: partly un-blurred and brightened, never fully - it's
   still context, not the working view. */
body:not(.dragging) .day-view.neighbour:hover { filter: blur(0.8px); opacity: 0.7; }
/* Dragged over, it's refused outright - it never takes a drop. */
.neighbour.drop-refused-here { outline: 2px dashed var(--danger); outline-offset: -2px; }
/* Clicking drills in: a Month week row to Week, a Week day to Day. */
.month .month-week, .week.focused .day { cursor: pointer; }

.day {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-input);
  padding: var(--sp-2-5);
  min-height: 120px;
}

.day h3 {
  font-size: var(--fs-md);
  margin: 0 0 var(--sp-2);
  font-weight: normal;
  color: var(--muted);
}

/* Past days are shaded a step darker than today and the future. Today is
   marked in a neutral ink, since any hue could belong to a Goal. */
.day.past, .month-day.past, .day-view.past { background-color: var(--sunk); }
.day.past h3, .month-day.past .month-h { color: var(--muted); }
/* One Today marker per zoom (Chunk 38): a bar across the column top plus a
   "Today" tag in Week and Day; the date number in a filled circle in Month
   and Year (below), with no bar. */
.day.today, .day-view.today { box-shadow: inset 0 3px 0 var(--today); }
.day.today h3 { font-weight: bold; color: var(--ink); }
.today-tag {
  display: inline-block;
  margin-left: var(--sp-1-5);
  padding: 0 var(--sp-1);
  border-radius: var(--r-mini);
  background: var(--today);
  color: var(--on-feature);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  line-height: 16px;
  vertical-align: 1px;
}

/* The Unscheduled / Loose ends column. Same auto-fit rule as the left sidebar,
   Day view and Month's grid: JS gives it whatever height is left in the window
   (see fitAside) and it never grows with its content - only the lists inside
   it scroll, and only once they actually overflow. Loose ends stays pinned
   below Unscheduled rather than scrolling out of reach, the way Completed and
   List do in the left sidebar. */
#calendar-aside {
  padding-top: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  min-height: 0;
  overflow: hidden;
}
.side-panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  padding: var(--sp-2);
}
.side-panel h2 { flex: 0 0 auto; margin: 0 0 var(--sp-1); font-size: var(--fs-body); }
.side-panel > .muted { flex: 0 0 auto; margin: 0 0 var(--sp-1-5); font-size: var(--fs-sm); }
/* Only as tall as its own content (Chunk 36); over-full, it scrolls inside.
   Loose ends sit at the end of the same list (Chunk 47). */
#unscheduled { flex: 0 1 auto; }
#unscheduled-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Unscheduled's headings: one fixed set at every zoom (Chunk 39). */
.unsched-heading {
  margin: var(--sp-2-5) 0 var(--sp-0-5);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.unsched-heading:first-child { margin-top: 0; }

/* An Unscheduled or Loose ends row (Chunk 39): a colour stripe in its class's
   colour, then one line - title, owner label, icons, the same anatomy as a
   Chip. The title never shortens: the owner gives way first (it shrinks a
   hundred times faster), and only once it's gone does the title wrap. An
   Unscheduled row's second line (due-by, "N of N left") only shows expanded -
   hovered, or selected from the keyboard; a Loose ends row's reason always
   shows. */
.entry.event.tab {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin-top: var(--sp-0-5);
  padding: var(--sp-0-5) var(--sp-1-5);
  border-left: 4px solid var(--goal);
  border-radius: 0 var(--r-mini) var(--r-mini) 0;
  font-size: var(--fs-sm);
  line-height: 16px;
  white-space: normal;
}
.tab-line { display: flex; align-items: baseline; gap: var(--sp-1-5); min-width: 0; }
.entry.event.tab .entry-title {
  flex: 0 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}
.entry.event.tab .entry-owner {
  flex: 0 100 auto;
  min-width: 0;
  margin-left: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.entry.event.tab .entry-icons { flex: 0 0 auto; margin-left: auto; align-self: center; }
.entry.event.tab .entry-owner::before, .entry.event.tab .entry-icons::before { content: none; }
.tab-due { flex: 0 0 auto; font-size: var(--fs-2xs); color: var(--muted); white-space: nowrap; }
.entry.event.tab .entry-sub { margin-left: 0; font-size: var(--fs-xs); color: var(--muted); }

/* A calendar or Loose ends entry: a title box and nothing else. Everything you can
   do to it is behind a click, on the event detail screen. */
.entry {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--done-fill);
  border-radius: var(--r-mini);
  padding: var(--sp-1) var(--sp-1-5);
  margin-top: var(--sp-1);
  cursor: pointer;
}
.entry:hover { background: var(--page); }
.entry.completed { color: var(--faint-text); text-decoration: line-through; }

/* A calendar Event: one border and fill in its Goal's colour, whatever its
   state. --goal is set inline per Event; a standalone Task has no Goal and
   falls back to grey. The state shows as an icon instead (Chunk 33, below). */
.entry.event {
  --goal: #8a8f98;
  --tint: color-mix(in srgb, var(--goal) 18%, var(--surface));
  background: var(--tint);
  border: 1px solid var(--goal);
  color: var(--ink);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.entry.event:hover { background: var(--tint); filter: brightness(0.94); }
.entry-sub {
  margin-left: var(--sp-1-5);
  font-size: var(--fs-xs);
  color: var(--muted);
}
/* Owner label and icon row (Chunk 33). Single-line by default - Day boxes,
   Repeating history rows, Unscheduled rows - running inline after the title,
   dot-separated. The owner tints toward its Goal's or Routine's colour; the
   icons stay a neutral grey, whatever tint they sit on. */
.entry-owner {
  margin-left: var(--sp-1-5);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semi);
  color: color-mix(in srgb, var(--goal, #8a8f98) 70%, var(--ink));
}
.entry-icons {
  display: inline-flex;
  gap: var(--sp-0-5);
  margin-left: var(--sp-1-5);
  vertical-align: -1px;
  color: var(--faint-text);
}
.entry-owner::before, .entry-icons::before { content: "·"; margin-right: var(--sp-1-5); color: var(--faint-text); font-weight: var(--fw-regular); }
.entry-icons:empty { display: none; }
.entry-icon { display: inline-flex; }
.entry-icon svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.entry-icon svg .fill { fill: currentColor; stroke: none; }
.entry.event.state-done .entry-owner, .entry.event.state-done .entry-icons { text-decoration: none; }

.entry-icon.icon-missed { color: var(--missed); }
.entry-time { display: none; }


/* Calendar toolbar and paging */
.zoom button.active { font-weight: bold; }
#range-label { font-size: var(--fs-body); font-weight: var(--fw-semi); }
.calendar-main { min-width: 0; }
/* The calendar section is one slightly darker panel, standing forward of the
   sidebar: its date across the top, then the calendar (and its footer) and
   the Unscheduled / Loose ends column side by side under it. app.js's
   auto-fit leaves room for the panel's bottom padding and border (see
   frameRoom). */
.calendar-panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 34px;
  column-gap: var(--sp-2-5);
  position: relative;
  align-items: start;
  padding: 0 var(--sp-2-5) var(--sp-2-5);
  background: var(--cal-panel);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-soft);
}
.calendar-panel > .toolbar { grid-column: 1 / -1; padding: var(--sp-2-5) var(--sp-0-5) var(--sp-2); }
.calendar-frame { display: flex; flex-direction: column; }
.calendar-frame > #calendar-grid { min-width: 0; }
.range-title { display: inline-flex; align-items: center; gap: var(--sp-2); }
/* Prev/Next at every zoom, pinned beside the toggle (Chunk 38). */
.range-paging { display: inline-flex; gap: var(--sp-0-5); }
.page-arrow {
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-mini);
  background: var(--surface);
  color: var(--muted);
  font-size: var(--fs-lg);
  line-height: 1;
  cursor: pointer;
}
.page-arrow:hover { background: var(--divider); color: var(--ink); }
/* Today sits apart from the toggle and looks unlike it - an outlined button
   rather than a segment - and dims once the view already includes today. */
.today-btn {
  height: 32px;
  padding: 0 var(--sp-3);
  border: 1px solid var(--faint-text);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-2);
  cursor: pointer;
}
.today-btn:hover { background: var(--divider); border-color: var(--faint-text); }

/* Footer bar under the grid, in every view (Chunk 31): +New bottom left,
   Check-in bottom right. The + is a circle at rest and grows into a
   "+ New" pill on hover - the same button widening, its label easing in. */
.calendar-footer {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-2);
  height: 36px;
}
.calendar-footer .spacer { flex: 1; }
.footer-new {
  display: inline-flex;
  align-items: center;
  height: 32px;
  min-width: 32px;
  padding: 0 var(--sp-2);
  border: 1px solid var(--faint-text);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-2);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
}
.footer-new-plus { font-size: var(--fs-lg); line-height: 1; width: 12px; text-align: center; }
.footer-new-label {
  display: inline-block;
  max-width: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-width var(--motion-fast) var(--ease-move), margin-left var(--motion-fast) var(--ease-move),
              opacity var(--motion-fast) var(--ease-fade);
}
.footer-new:hover, .footer-new:focus-visible { background: var(--divider); border-color: var(--faint-text); }
.footer-new:hover .footer-new-label, .footer-new:focus-visible .footer-new-label {
  max-width: 6em;
  margin-left: var(--sp-1);
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) { .footer-new-label { transition: none; } }

/* Something's waiting on the check-in (Chunk 38). */
.checkin-badge {
  display: inline-block;
  min-width: 18px;
  margin-left: var(--sp-1-5);
  padding: 0 var(--sp-1);
  border-radius: var(--r-input);
  background: var(--today);
  color: var(--on-feature);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  line-height: 18px;
  text-align: center;
}
#checkin-overlay { width: min(720px, calc(100vw - 32px)); max-height: 85vh; overflow-y: auto; }
#checkin-overlay::backdrop { background: rgb(0 0 0 / 0.3); }
#checkin-overlay .overlay-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
#checkin-overlay .overlay-head h2 { margin: 0; }

/* Month follows the same auto-fit rule as Day view: JS gives the grid whatever
   height is left in the window and the weeks share it between them, so the
   month never grows with its content and never scrolls as a whole. Rows are a
   flex column of 7-column grids (not one flat 42-cell grid) because the week
   row is the thing that resizes on hover. */
.month {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1-5);
  min-height: 0;
  overflow: hidden;
}
.month-head-row, .month-week {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--sp-1-5);
}
.month-week {
  flex: 0 0 auto; /* JS sets the height in px; don't let flex shrink past it */
  min-height: 0;
  /* The row's part of the shared resize (Chunk 37): same length as its
     boxes', starting when theirs does - after any collapse's fade. */
  transition: height var(--row-resize, var(--motion-move)) var(--row-ease, var(--ease-move)) var(--row-delay, 0s);
}
/* .no-anim is on while a render or a resize sets the heights from scratch,
   so those land in place rather than animating from the last month's. */
.month.no-anim .month-week { transition: none; }
@media (prefers-reduced-motion: reduce) {
  .month-week { transition: none; }
}
.month-head { font-size: var(--fs-sm); color: var(--muted); padding: 0 var(--sp-1); }
.month-day {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-block);
  padding: var(--sp-1) var(--sp-1-5);
  min-height: 0;
  overflow: hidden;
}
.month-day .month-h { font-size: var(--fs-sm); margin: 0 0 var(--sp-0-5); font-weight: normal; color: var(--muted); flex: 0 0 auto; }
/* The one scrollable region: clipped (with a "+N more") while the row is at
   bar density, scrollable once it's grown and its content is past the row's
   capped height. */
.month-day-events { flex: 1; min-height: 0; overflow: hidden; }
/* A day with more than fits shows the bars that fit whole, then "+N more"
   on its own line under them (Chunk 85, look audit M1: it used to sit over a
   faded fourth bar and cover its title). Bars past the fold keep their
   place, unseen, so the count never moves the ones above it. */
.month-day-events > .month-hidden { visibility: hidden; }
.month-day-events.class-lane > .month-hidden { visibility: visible; }
.month-more {
  position: absolute;
  left: var(--sp-2);
  right: var(--sp-1-5);
  bottom: var(--sp-1);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semi);
  line-height: var(--lh-meta);
  color: var(--muted);
  white-space: nowrap;
  pointer-events: none;
}
.month-day.outside { background: var(--surface); }
.month-day.outside .month-h { color: var(--faint-text); }
.month-day.past.outside { background: var(--page); }
.month-date { display: inline-block; min-width: 18px; text-align: center; border-radius: var(--r-input); }
.month-day.today .month-date { background: var(--today); color: var(--on-feature); font-weight: var(--fw-semi); }

/* A Goal's or Milestone's target date. Deliberately *not* an Event box: no
   fill, no full border, just a flag glyph and a colour edge, so it can't be
   mistaken for something with an occurrence behind it. It inherits its Goal's
   colour like everything else under that Goal. */
.flag {
  --goal: #8a8f98;
  --flag-ink: color-mix(in srgb, var(--goal) 60%, var(--ink));
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  width: 100%;
  margin-top: var(--sp-0-5);
  padding: var(--sp-px) var(--sp-1);
  background: none;
  border: 0;
  border-left: 3px solid var(--goal);
  border-radius: 0 var(--r-mini) var(--r-mini) 0;
  color: var(--flag-ink);
  font: inherit;
  font-size: var(--fs-sm);
  text-align: left;
  cursor: pointer;
  overflow: hidden;
  white-space: nowrap;
}
.flag:hover { background: color-mix(in srgb, var(--goal) 14%, var(--surface)); }
.flag-icon { flex: 0 0 auto; color: var(--goal); line-height: 1; }
.flag-title { overflow: hidden; text-overflow: ellipsis; }
/* "Target" / "Milestone due" - Week's chip only (Chunk 36). */
.flag-kind { display: none; }
.week .flag[data-density="chip"] { flex-wrap: wrap; column-gap: var(--sp-1); row-gap: 0; }
.week .flag[data-density="chip"] .flag-title { white-space: normal; }
.week .flag[data-density="chip"] .flag-kind {
  display: inline;
  flex: 0 0 auto;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semi);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
/* At bar density a flag has no room for its title, the same as an Event bar
   doesn't - the glyph alone still says "a target lands here". */
.flag[data-density="bar"] {
  margin-top: var(--sp-0-5);
  width: auto; /* shrink to the glyph - the rest of the row isn't the flag */
  padding: 0;
  border-left: 0;
  font-size: var(--fs-xs);
  line-height: 11px;
}
.flag[data-density="bar"] > :not(.flag-icon) { display: none; }
/* Day view: a target date has no time, so it sits in a strip above the axis
   rather than anywhere on it. */
.day-flags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2-5);
  padding: var(--sp-1) var(--sp-2);
  border-bottom: 1px solid var(--faint);
}
.day-flags .flag { width: auto; margin-top: 0; }

/* Class highlight (Chunk 38 - Month alone before): every match swaps to
   strip density in app.js and everything else on the grid dims. Nothing moves
   for it - a Month bar row keeps its height, so a day whose strips don't fit
   scrolls inside itself instead, and its "+N more" (counted for bars) goes. */
.flag.year-flag.class-hit { background: color-mix(in srgb, var(--goal) 25%, var(--surface)); font-weight: var(--fw-bold); }
.month-week .class-lane.scrolls { overflow-y: auto; overscroll-behavior: contain; }
.month-week .class-lane ~ .month-more { display: none; }
/* Day's boxes are placed on the hour axis; a strip keeps its place there,
   one line tall. */
/* A target flag at strip: glyph and title, one line. */
.flag[data-density="strip"] .flag-kind { display: none; }

.day-view {
  --pane-bg: var(--surface);
  background: var(--pane-bg);
  border: 1px solid var(--line);
  border-radius: var(--r-input);
  overflow: hidden;
}
.day-view.past { --pane-bg: var(--sunk); }
.day-view-head {
  font-size: var(--fs-md);
  font-weight: normal;
  color: var(--muted);
  margin: 0;
  padding: var(--sp-1-5) var(--sp-2);
  border-bottom: 1px solid var(--faint);
}
.day-view.today .day-view-head { font-weight: bold; color: var(--ink); }
.day-pane { position: relative; }
.day-pane .hour {
  position: absolute;
  left: 0;
  right: 0;
  border-top: 1px solid var(--faint);
}
.day-pane .hour.minor { left: 56px; border-top-color: var(--divider); }
.day-pane .hour span {
  position: absolute;
  top: -8px;
  left: 6px;
  font-size: var(--fs-xs);
  color: var(--faint-text);
  background: var(--pane-bg);
  padding: 0 var(--sp-0-5);
}
.day-pane .hour:first-child span { top: 0; }
.day-events {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 62px;
  right: 34px;
}
/* The hour axis scrolls (Chunk 36), opening on 06:00-22:00. The three
   columns scroll as one (app.js); only the focused one shows a scrollbar. A
   busy hour's lanes past their minimum width scroll sideways instead. */
.day-scroll { overflow: auto; overscroll-behavior: contain; }
.day-view.neighbour .day-scroll { overflow: hidden; }

/* Selection: an Event is ringed in its own Goal colour; a Loose ends box
   (no Goal colour) and a selected empty day in neutral grey. */
.entry.selected { outline: 2px solid var(--muted); outline-offset: 1px; }
#calendar-grid [data-day].selected { outline: 2px dashed var(--faint-text); outline-offset: -2px; }

/* Dragging */
#calendar-grid .entry.event:not(.state-done):not(.state-closed),
#unscheduled-list .unsched-row { cursor: grab; }
/* Clicking a day drills in; it shouldn't select the day's text too. */
#calendar-grid [data-day] { user-select: none; }
.drag-source { opacity: 0.4; }
.drag-ghost {
  position: fixed;
  z-index: 1000;
  margin: 0;
  pointer-events: none;
  opacity: 0.9;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
body.dragging { user-select: none; }
body.dragging, body.dragging * { cursor: grabbing !important; }
body.drop-refused, body.drop-refused * { cursor: not-allowed !important; }
/* A day that won't take the drop is greyed out for the whole drag, and
   crossed through when you're actually over it. */
#calendar-grid [data-day].drop-invalid {
  background-image: repeating-linear-gradient(45deg, rgba(0, 0, 0, 0.05) 0 6px, transparent 6px 12px);
}
#calendar-grid [data-day].drop-invalid > * { opacity: 0.55; }
#calendar-grid [data-day].drop-over { outline: 2px solid var(--muted); outline-offset: -2px; }
#calendar-grid [data-day].drop-over.drop-invalid { outline: 2px dashed var(--danger); }
/* Dragging a Task onto a new parent (Chunk 32): the same outline language,
   on a Goal or Routine in the sidebar or a Milestone row in the Goal. */
.task-item { cursor: grab; }
.task-item .item-buttons button { cursor: pointer; }
.drop-target.drop-invalid { opacity: 0.55; }
.drop-target.drop-over { outline: 2px solid var(--muted); outline-offset: -2px; }
.drop-target.drop-over.drop-invalid { outline: 2px dashed var(--danger); }


.item {
  border-top: 1px solid var(--divider);
  padding: var(--sp-1-5) 0;
}

.item .title { display: block; margin-bottom: var(--sp-1); }
.item.completed .title { text-decoration: line-through; color: var(--faint-text); }

.item form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  margin-top: var(--sp-1);
}

.item input[type=text], .item input[type=number], .item input[type=date] {
  width: 100%;
  min-width: 0;
  padding: var(--sp-0-5) var(--sp-1);
}

.muted { color: var(--faint-text); font-size: var(--fs-sm); }

.toolbar .spacer { flex: 1; }

.panel h2 button { font-size: var(--fs-md); font-weight: normal; margin-left: var(--sp-1); }

/* Check-in: each item carries its Goal's colour down its left edge, the way
   the goal view does. */
.checkin-item { border-left: 3px solid var(--goal, var(--line)); padding-left: var(--sp-2); }
.checkin-item.goal-row { border: 0; border-left: 3px solid var(--goal, var(--line)); padding-left: var(--sp-2); margin-top: var(--sp-1); }


.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  padding: var(--sp-2);
  min-height: 120px;
}

.goal-row {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-top: 1px solid var(--divider);
  padding: var(--sp-1-5) var(--sp-1);
  cursor: pointer;
}
.goal-row .title { display: block; }
.goal-row:hover .title { text-decoration: underline; }

/* The goal view carries its Goal's colour down its left edge. */
#goal-detail, #routine-detail, #collection-detail { border-left: 4px solid var(--goal, var(--line)); }

/* -- Goal and Routine focus views (Chunk 42) -- */
/* The header: larger, washed in its own colour, title on the left. */
.focus-head {
  margin: calc(-1 * var(--sp-2)) calc(-1 * var(--sp-2)) var(--sp-1);
  padding: var(--sp-3) var(--sp-4) var(--sp-3);
  background: color-mix(in srgb, var(--goal, #999) 11%, var(--surface));
  border-bottom: 1px solid color-mix(in srgb, var(--goal, #999) 22%, var(--surface));
}
.focus-title-row { display: flex; align-items: flex-start; gap: var(--sp-3); }
.focus-titles { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-1) var(--sp-2-5); min-width: 0; }
.focus-kicker {
  flex-basis: 100%;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--goal, #999) 70%, var(--ink));
}
.focus-head h2 { margin: 0; font-size: var(--fs-heading); line-height: 1.2; color: color-mix(in srgb, var(--goal, #999) 45%, var(--ink)); }
.focus-title-row > .item-buttons { margin-left: auto; padding-top: var(--sp-3); }
.focus-description { margin: var(--sp-1-5) 0 0; font-size: var(--fs-base); color: var(--text-2); }
.focus-meta { margin: var(--sp-1) 0 0; font-size: var(--fs-sm); color: var(--muted); }
/* Edit and Remove: tucked until the row's hovered, focused into, or opened
   from its "..." - the innermost row only, so hovering a Task doesn't open
   up its Milestone too. */
.row-tucked { display: none; gap: var(--sp-1); }
:is([data-row]:hover:not(:has([data-row]:hover)),
    [data-row]:focus-within:not(:has([data-row]:focus-within)),
    [data-row].actions-open) > :is(.item-head, .focus-title-row) > .item-buttons > .row-tucked { display: inline-flex; }
.btn.row-more { padding: 0 var(--sp-1-5); color: var(--faint-text); font-size: var(--fs-body); line-height: 18px; letter-spacing: 1px; }
[data-row].actions-open > :is(.item-head, .focus-title-row) > .item-buttons > .row-more { background: var(--sunk); color: var(--ink); }
/* Pending review: says it's waiting on you, never looks finished. */
.review-badge {
  align-self: center;
  padding: var(--sp-px) var(--sp-2-5);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  line-height: 16px;
  white-space: nowrap;
}
/* A Milestone's progress: its "x / y" on the bar itself. */
.progress-bar {
  position: relative;
  max-width: 420px;
  height: 16px;
  margin: var(--sp-1-5) 0 var(--sp-1);
  border-radius: var(--r-input);
  background: color-mix(in srgb, var(--goal, #999) 10%, var(--divider));
  overflow: hidden;
}
.progress-fill { position: absolute; top: 0; bottom: 0; left: 0; background: color-mix(in srgb, var(--goal, #999) 50%, var(--surface)); }
.progress-label {
  position: relative;
  display: block;
  padding: 0 var(--sp-2);
  color: var(--ink);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  line-height: 16px;
  font-variant-numeric: tabular-nums;
}
.progress-none { margin: var(--sp-1) 0; }
/* Task row: the calendar's icon row after its tags; under a Routine, a quiet
   line on how this period's going. */
.task-icons { align-self: center; margin-left: var(--sp-2-5); gap: var(--sp-1); color: var(--muted); }
.task-icons::before { content: none; }
.task-icons .entry-icon svg { width: 14px; height: 14px; }
.task-progress { margin: var(--sp-0-5) 0 0; font-size: var(--fs-sm); color: var(--muted); }
.notes-block .notes-body {
  display: block;
  width: 100%;
  padding: var(--sp-2) var(--sp-2-5);
  border: 1px solid var(--faint);
  border-radius: var(--r-block);
  background: var(--surface);
  color: var(--text-2);
  font: inherit;
  font-size: var(--fs-md);
  text-align: left;
  white-space: pre-wrap;
  cursor: text;
}
.notes-block .notes-body:hover { border-color: var(--done-fill); }
.notes-block .notes-body.empty { color: var(--faint-text); font-style: italic; }
.done-group { margin-top: var(--sp-2); }
.done-group > summary { padding: var(--sp-1) 0; color: var(--muted); font-size: var(--fs-md); cursor: pointer; }
/* Dragging a Task to a new parent: a small pill in its colour, off to the
   side of the pointer so the target's own label stays readable. */
.drag-ghost.reparent-ghost {
  max-width: 220px;
  padding: var(--sp-0-5) var(--sp-2-5);
  border-radius: var(--r-pill);
  background: var(--goal);
  color: var(--on-feature);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  line-height: 16px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* An editable title: reads as text, behaves as the button it is. */
.link-title {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.link-title:hover { text-decoration: underline; }

/* Goal header, Milestone row, Task row: title, then its buttons beside it. */
.item-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-1) var(--sp-3);
  margin-bottom: var(--sp-1);
}
.item-head h2 { margin: 0; }
.item .item-head .title { display: inline; margin-bottom: 0; }
/* Task row (Chunk 29): title and dot-separated tags run together, Edit on
   the row's right edge (Chunk 35). */
.task-item .item-head { column-gap: 0; margin-bottom: 0; }
.item-buttons { display: flex; flex-wrap: wrap; gap: var(--sp-1); }
.item-buttons button { font-size: var(--fs-sm); }

#goal-detail .section, #routine-detail .section, #collection-detail .section { margin-top: var(--sp-4); }
#goal-detail h3, #routine-detail h3, #collection-detail h3 { font-size: var(--fs-base); margin: 0 0 var(--sp-1-5); }
#goal-detail .subtasks { margin: var(--sp-1-5) 0 0 var(--sp-4); }
#goal-detail .item.completed .item:not(.completed) .title {
  text-decoration: none;
  color: inherit;
}

/* Recorded occurrences (Chunk 41): one row per stored Event, in fixed
   columns - date, state, note, time. Done is muted, never struck through. */
/* The History page (review gate 1, D2): divider rows in one white card,
   like a Goal's task rows; done rows stay readable in Text 2. */
#history-detail .history-card h3 { margin: 0 0 var(--sp-2); font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--muted); }
.history-list { display: flex; flex-direction: column; }
.history-row {
  display: grid;
  grid-template-columns: minmax(9em, 1.4fr) minmax(7em, 1fr) minmax(0, 2fr) 5em;
  gap: var(--sp-3);
  align-items: center;
  width: 100%;
  min-height: 44px;
  padding: var(--sp-2) var(--sp-2-5);
  border: 0;
  border-bottom: 1px solid var(--line);
  background: none;
  color: inherit;
  font: inherit;
  font-size: var(--fs-md);
  text-align: left;
  cursor: pointer;
}
.history-row:last-child { border-bottom: 0; }
.history-row:hover { background: var(--track); }
.history-row > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.history-state, .history-time { color: var(--muted); }
.history-time { text-align: right; font-variant-numeric: tabular-nums; }
.history-row.state-done { color: var(--text-2); }
.history-row.state-done > span { color: inherit; }
.history-row.state-removed, .history-row.state-closed, .history-row.state-confirmed_missed { color: var(--faint-text); }
@media (max-width: 600px) {
  .history-row { grid-template-columns: 1fr 1fr; row-gap: var(--sp-0-5); }
}

dialog textarea { display: block; width: 100%; margin-top: var(--sp-1); font: inherit; }
#notes-form [data-notes-fields] label { display: block; margin: var(--sp-2) 0; }
#pattern-form [data-pattern] > label { display: block; margin: var(--sp-1-5) 0; }

dialog {
  width: min(480px, calc(100vw - 32px));
  border: 1px solid var(--faint-text);
  padding: var(--sp-4);
}

dialog form > label, dialog fieldset label, dialog fieldset > div { display: block; margin: var(--sp-1-5) 0; }
dialog .weekdays label { display: inline-block; margin-right: var(--sp-2); }
dialog input[type=text] { width: 100%; }
dialog fieldset { border: 1px solid var(--line); margin: var(--sp-2-5) 0; }
dialog .actions { display: flex; gap: var(--sp-2); margin-top: var(--sp-3); }
dialog .actions .spacer { flex: 1; }
#confirm-dialog { width: min(420px, calc(100vw - 32px)); }
#confirm-dialog p { margin: 0; white-space: pre-line; }
#confirm-dialog .actions { justify-content: flex-end; }
.date-clear { font-size: var(--fs-sm); padding: var(--sp-px) var(--sp-1-5); }

/* +New's icon pickers (Chunk 17): real radios, hidden, with the label as the tile. */
.icon-choice { display: flex; gap: var(--sp-2); margin: var(--sp-2-5) 0; }
.icon-choice label {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-0-5);
  padding: var(--sp-2) var(--sp-1) var(--sp-1-5);
  border: 1px solid var(--line);
  border-radius: var(--r-block);
  background: var(--surface);
  color: var(--muted);
  font-size: var(--fs-sm);
  cursor: pointer;
}
.icon-choice input { position: absolute; opacity: 0; pointer-events: none; }
.icon-choice svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.icon-choice svg .fill { fill: currentColor; stroke: none; }
.icon-choice label:hover { border-color: var(--faint-text); color: var(--text-2); }
.icon-choice label:has(input:checked) { border-color: var(--ink); background: var(--divider); color: var(--ink); font-weight: var(--fw-semi); }
.icon-choice label:has(input:focus-visible) { outline: var(--focus-width) solid var(--focus-color); outline-offset: var(--focus-offset); }

.disclosure { margin: var(--sp-1-5) 0; }
.disclosure summary { cursor: pointer; color: var(--muted); width: fit-content; }
.disclosure > label { display: block; margin: var(--sp-1-5) 0 0; }

.lane { border: 1px solid var(--line); padding: var(--sp-1) var(--sp-2-5); margin: 0 0 var(--sp-2-5); }
.lane > label, .lane > div { display: block; margin: var(--sp-1-5) 0; }
.lane .weekdays label { display: inline-block; margin-right: var(--sp-2); }

@media (max-width: 1100px) {
  .calendar-panel { grid-template-columns: 1fr; }
  .week { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
}

/* A touched fixed date Task's date (Chunk 11 follow-up): shown, not editable. */
label.locked input[readonly] { background: var(--divider); color: var(--muted); border-style: dashed; cursor: not-allowed; }
label.locked input[readonly]::-webkit-calendar-picker-indicator { display: none; }

/* Year (Chunk 34): twelve small month grids, 4 by 3, sharing whatever height
   the calendar has to give (auto-fit, same as Month). A day is its date and a
   row of dots, one per Goal or Routine on it; a target date keeps its flag,
   shrunk to fit. Clicking anywhere in a month drills into Month. */
.year {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-template-rows: repeat(3, minmax(0, 1fr));
  gap: var(--sp-2-5);
}
.year-month {
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: var(--sp-1) var(--sp-1-5) var(--sp-1-5);
  background: var(--surface);
  border: 1px solid var(--line);
  cursor: pointer;
  overflow: hidden;
}
.year-month:hover { border-color: var(--faint-text); }
.year-month h3 { flex: 0 0 auto; margin: 0 0 var(--sp-0-5); font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--text-2); }
.year-days {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  grid-template-rows: auto;
  grid-auto-rows: minmax(0, 1fr);
  gap: var(--sp-0-5);
}
.year-head { font-size: var(--fs-2xs); color: var(--muted); font-weight: var(--fw-semi); text-align: center; }
.year-day {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-height: 0;
  padding: var(--sp-px) 0 0 var(--sp-0-5);
  border-radius: var(--r-block);
  overflow: hidden;
}
.year-day.past { background-color: var(--sunk); }
.year-day.past .year-date { color: var(--faint-text); }
/* Today: the date in a filled circle, the same as Month's (Chunk 37 -
   Chunk 34's ring round the cell). */
.year-date {
  display: inline-block;
  min-width: 15px;
  font-size: var(--fs-2xs);
  line-height: 13px;
  text-align: center;
  border-radius: var(--r-block);
  color: var(--text-2);
}
.year-day.today .year-date { background: var(--today); color: var(--on-feature); font-weight: var(--fw-bold); }
.flag.year-flag {
  width: auto;
  margin: 0;
  padding: 0 var(--sp-px);
  border: 0;
  font-size: var(--fs-2xs);
  line-height: 10px;
  background: none;
}
.flag.year-flag .flag-title { display: none; }

/* -- Buttons (Chunk 35) --
   Three kinds, the same everywhere: primary (filled - the one action a screen
   most wants taken), quiet (a text button - everything secondary), danger
   (Remove/Delete - icon only, never a same-weight peer of primary). --primary
   is the fill, tinted to the chosen colour in the Goal/Routine form. */
.btn {
  --primary: var(--primary-fill);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-1);
  padding: var(--sp-1) var(--sp-3);
  border: 1px solid transparent;
  border-radius: var(--r-block);
  background: none;
  color: var(--text-2);
  font: inherit;
  line-height: 1.3;
  cursor: pointer;
  white-space: nowrap;
}
.btn:disabled:not([aria-busy="true"]) { opacity: var(--state-disabled); cursor: default; }
.btn.primary { background: var(--primary); border-color: var(--primary); color: var(--on-primary); font-weight: var(--fw-semi); }
.btn.primary:hover:not(:disabled) { filter: brightness(1.15); }
.btn.quiet { padding: var(--sp-1) var(--sp-2); }
.btn.quiet:hover:not(:disabled) { background: var(--sunk); color: var(--ink); }
.btn.danger { padding: var(--sp-1) var(--sp-1-5); color: var(--faint-text); }
.btn.danger:hover { background: var(--danger-bg); color: var(--danger); }
.btn.danger svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.btn.icon-btn { padding: 0 var(--sp-1-5); line-height: 18px; font-size: var(--fs-body); }
.item-buttons .btn { padding-top: var(--sp-0-5); padding-bottom: var(--sp-0-5); }
.item-buttons .btn.danger svg { width: 14px; height: 14px; }
.zoom { display: inline-flex; gap: var(--sp-0-5); }
.zoom .btn.active { background: var(--faint); color: var(--ink); }
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
/* A row's own buttons sit on its right edge. */
.item-head .item-buttons { margin-left: auto; align-self: center; }
.task-item .item-head .item-buttons { margin-left: auto; }
/* In a dialog, Save/Cancel sit together on the right; a destructive action,
   when there is one, far left with the spacer between. */
dialog .actions { align-items: center; }

/* -- Text conventions (Chunk 35) -- */
/* Beside an optional field's label, and stays there once it's filled in. */
.optional-tag {
  display: inline-block;
  margin: 0 var(--sp-0-5);
  padding: 0 var(--sp-1);
  border-radius: var(--r-mini);
  background: var(--divider);
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-regular);
  line-height: 16px;
  vertical-align: 1px;
}
/* Dot-separated tags after a title in a flex row: the space before the dot. */
.dot-lead { margin-left: 0.3em; }

/* -- Swatch-palette colour picker (Chunk 35) -- */
.colour-field { margin: var(--sp-2) 0; }
.colour-field .field-label { display: block; margin-bottom: var(--sp-1); }
.swatches { display: flex; flex-wrap: wrap; gap: var(--sp-1-5); min-height: 26px; }
.swatch {
  position: relative;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 2px solid var(--surface);
  border-radius: 50%;
  background: var(--swatch);
  box-shadow: 0 0 0 1px var(--done-fill);
  cursor: pointer;
}
.swatch:hover { box-shadow: 0 0 0 1px var(--faint-text); }
.swatch.selected { box-shadow: 0 0 0 2px var(--ink); }
/* In use nearby: a small white dot in the middle. Still pickable - marked,
   not refused. */
.swatch.used::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.25);
}
.colour-tools { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-top: var(--sp-1-5); }
dialog .colour-tools label.colour-custom { display: inline-flex; align-items: center; gap: var(--sp-1-5); margin: 0; }
.colour-custom input[type=color] { width: 32px; height: 24px; padding: 0; border: 1px solid var(--done-fill); background: none; }
/* The rest of the form tints live to whatever's picked. */
#goal-dialog.tinted {
  border-top: 6px solid var(--goal);
  background: color-mix(in srgb, var(--goal) 6%, var(--surface));
}
#goal-dialog.tinted h2 { color: color-mix(in srgb, var(--goal) 65%, var(--ink)); }
#goal-dialog.tinted .btn { --primary: color-mix(in srgb, var(--goal) 85%, var(--ink)); }
/* tinted inputs: the one focus ring (Chunk 81) */
dialog input.time-input { width: 6em; }

/* Dark mode: the tokens swap (top of file); nothing is filtered or inverted. */
html[data-theme="dark"] dialog::backdrop { background: rgb(0 0 0 / 0.6); }
.theme-toggle { margin-top: var(--sp-1); color: var(--muted); font-size: var(--fs-md); }

/* -- Calendar area chrome (off-brief, Ed's direct ask) --
   The calendar's own buttons - paging, Today, the zoom toggle, the footer's
   + New task and Check-in - share one darker slate treatment so they read as
   the calendar's controls rather than the app's quiet text buttons. The
   toggle is one segmented control: the active zoom is the light, high-
   contrast segment. The calendar's text runs a shade cooler and darker than
   the rest of the app, with even-width figures so dates line up. */
.calendar-main, .calendar-controls {
  --cal-btn: var(--feature-2);
  --cal-btn-hover: var(--feature-3);
  --cal-btn-ink: var(--on-feature);
  --cal-ink: var(--ink);
  --cal-soft-ink: var(--text-2);
  color: var(--cal-ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.005em;
}
.calendar-panel #range-label { font-weight: 650; letter-spacing: -0.01em; color: var(--ink); }
.calendar-main :is(.day h3, .month-day .month-h, .day-view-head, .month-head, .year-month h3) { color: var(--cal-soft-ink); }
.calendar-main :is(.day.past h3, .month-day.past .month-h) { color: var(--muted); }

.calendar-controls .page-arrow,
.calendar-controls .today-btn,
.calendar-main .footer-new {
  background: var(--cal-btn);
  border-color: var(--cal-btn);
  color: var(--cal-btn-ink);
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.18);
}
.calendar-controls .page-arrow:hover,
.calendar-controls .today-btn:hover,
.calendar-main .footer-new:hover, .calendar-main .footer-new:focus-visible {
  background: var(--cal-btn-hover);
  border-color: var(--cal-btn-hover);
  color: var(--on-feature);
}


.calendar-controls .zoom-unused {
  gap: var(--sp-0-5);
  padding: var(--sp-0-5);
  border-radius: var(--r-input);
  background: var(--cal-btn);
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.18);
}
.calendar-controls .zoom .btn { height: 28px; padding: 0 var(--sp-2-5); border-radius: var(--r-block); color: var(--on-feature-2); font-weight: var(--fw-medium); }
.calendar-controls .zoom .btn:hover:not(.active) { background: var(--cal-btn-hover); color: var(--on-feature); }
.calendar-controls .zoom .btn.active { background: var(--cal-btn-ink); color: var(--cal-btn); font-weight: var(--fw-medium); }

/* The range title and its controls are the calendar panel's own header -
   the same panel, its top half - rather than floating above it. */
/* Today, Prev/Next and the zoom toggle sit a level up, above the panel - the
   app's controls over the calendar, not part of it (Ed's call, off-brief). */
.calendar-controls {
  grid-column: 1 / -1;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) 0 0;
}

/* -- Collapsing sidebar (off-brief, Ed's direct ask) --
   The sidebar rests as a narrow rail - an icon per entry, a colour dot per
   Goal and Routine - and opens over the page on hover (or keyboard focus).
   It's always its full width underneath and only clipped to the rail, so
   opening is a clip-path easing out rather than a width changing: nothing
   inside reflows and the page beside it never moves. Labels fade in as it
   opens and out as it closes. A short delay before opening means sweeping
   the pointer past it on the way somewhere doesn't set it off. */
body { --sidebar-width: 56px; --sidebar-open: 220px; }
.sidebar {
  width: var(--sidebar-open);
  z-index: 40;
  clip-path: inset(0 calc(var(--sidebar-open) - var(--sidebar-width)) 0 0);
  transition: clip-path var(--motion-panel) var(--ease-enter) var(--motion-delay),
              box-shadow var(--motion-panel) var(--ease-fade) var(--motion-delay);
  border-right: 0;
}
.sidebar::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--sidebar-width) - 1px);
  width: 1px;
  background: var(--line);
  transition: opacity var(--motion-fast) var(--ease-fade) var(--motion-delay);
}
.sidebar.expanded{
  clip-path: inset(0 -24px 0 0);
  box-shadow: 4px 0 18px rgb(0 0 0 / 0.1), 1px 0 0 var(--line);
  transition-delay: var(--motion-delay);
}
/* It opens over the page rather than pushing it, so the calendar never
   resizes for it. */

.sidebar.expanded::after{ opacity: 0; transition-delay: var(--motion-delay); }
.nav-label {
  opacity: 0;
  transition: opacity var(--motion-fast) var(--ease-fade);
  white-space: nowrap;
}
.sidebar.expanded .nav-label{
  opacity: 1;
  transition: opacity var(--motion-fast) var(--ease-fade) var(--motion-settle);
}
.nav-icon {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.sidebar h1 { display: flex; align-items: center; gap: var(--sp-3); padding: 0 var(--sp-2-5) var(--sp-3); overflow: hidden; }
.sidebar h1 .nav-icon { width: 22px; height: 22px; margin-left: calc(-1 * var(--sp-px)); color: var(--today); }
.nav-entry { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-1-5) var(--sp-2-5); overflow: hidden; }
.theme-toggle { color: var(--muted); }
/* Goals and Routines: collapsed, each row is its colour dot on a tinted tab. */
.nav-goal { display: flex; align-items: center; gap: var(--sp-3); padding-left: var(--sp-2); }
.nav-goal .nav-label { overflow: hidden; text-overflow: ellipsis; }
.nav-dot {
  flex: 0 0 auto;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--goal);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--goal) 25%, var(--surface));
}
.nav-goal.active .nav-dot { box-shadow: 0 0 0 2px var(--surface), 0 0 0 3.5px var(--goal); }
/* The section headings shrink to a hairline in the rail. */
.nav-goals h2 { position: relative; min-height: 18px; }
.nav-goals h2::before {
  content: "";
  position: absolute;
  left: 10px;
  width: 20px;
  top: 50%;
  border-top: 1px solid var(--line);
  transition: opacity var(--motion-fast) var(--ease-fade);
}
.sidebar.expanded .nav-goals h2::before{ opacity: 0; }
.nav-goals h2 .icon-btn { opacity: 0; transition: opacity var(--motion-fast) var(--ease-fade); }
.sidebar.expanded .nav-goals h2 .icon-btn{ opacity: 1; transition-delay: var(--motion-settle); }
@media (prefers-reduced-motion: reduce) {
  .sidebar, .sidebar::after, .nav-label, .nav-goals h2::before, .nav-goals h2 .icon-btn { transition: none; }
}

/* Footer (Ed's call, off-brief): Check-in bottom left, quiet; + New task
   bottom right beside the column it opens over - the one obvious action,
   filled and always labelled. */
.calendar-main #footer-checkin {
  height: 32px;
  padding: 0 var(--sp-3);
  border: 1px solid var(--done-fill);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--cal-soft-ink);
}
.calendar-main #footer-checkin:hover { background: rgb(0 0 0 / 0.05); color: var(--cal-ink); }
.calendar-main .footer-new {
  height: 36px;
  padding: 0 var(--sp-4) 0 var(--sp-3);
  border-radius: var(--r-pill);
  background: var(--today);
  border-color: var(--today);
  font-weight: var(--fw-semi);
  box-shadow: 0 2px 6px rgb(31 39 51 / 0.3);
}
.calendar-main .footer-new-label { max-width: none; margin-left: var(--sp-1-5); opacity: 1; }
.calendar-main .footer-new:hover, .calendar-main .footer-new:focus-visible { background: var(--feature-2); border-color: var(--ink); }

/* New task slides in over the right-hand column rather than blocking the page
   (Ed's call, off-brief): pinned to the window's right edge, the calendar
   left free beside it. */
dialog.slide-panel:is([open], :not([open])) {
  position: fixed;
  inset: 12px 16px 16px auto;
  width: 320px;
  max-height: calc(100vh - 28px);
  margin: 0;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-panel);
  z-index: 30;
}

/* New task in the right-hand column (Ed's call, off-brief): the column widens
   to hold it, the calendar giving way beside it, and the form sits at its top
   as a card of its own above Unscheduled, which shrinks and scrolls under it. */

.aside-drawer > dialog.slide-panel:is([open], :not([open])) {
  position: static;
  inset: auto;
  flex: 0 0 auto;
  width: auto;
  max-height: 72%;
  margin: 0;
  padding: var(--sp-3);
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-soft);
}
.aside-drawer > dialog.slide-panel h2 { font-size: var(--fs-body); }


/* Sidebar markers (Ed's call): no dots - a Goal's or Routine's colour edge
   widens into a small filled rounded tab in the rail, and slims back to the
   row's edge stripe as the sidebar opens, the row's tint coming in behind. */
.nav-dot { display: none; }
.nav-goal {
  position: relative;
  border-left: 0;
  border-radius: var(--r-block);
  padding-left: var(--sp-4);
  background: transparent;
  transition: background-color var(--motion-fast) var(--ease-fade);
}
.nav-goal::before {
  content: "";
  position: absolute;
  top: 5px;
  bottom: 5px;
  left: 13px;
  width: 14px;
  border-radius: var(--r-block);
  background: var(--goal);
  transition: left var(--motion-move) var(--ease-move),
              width var(--motion-move) var(--ease-move),
              top var(--motion-move) var(--ease-move),
              bottom var(--motion-move) var(--ease-move);
}
.nav-goal.active::before { box-shadow: 0 0 0 2px var(--surface), 0 0 0 3.5px var(--goal); }
.sidebar.expanded .nav-goal{ background: color-mix(in srgb, var(--goal) 12%, var(--surface)); }
.sidebar.expanded .nav-goal:hover { background: color-mix(in srgb, var(--goal) 24%, var(--surface)); }
.sidebar.expanded .nav-goal.active{ background: color-mix(in srgb, var(--goal) 32%, var(--surface)); }
.sidebar.expanded .nav-goal::before{
  top: 0;
  bottom: 0;
  left: 0;
  width: 4px;
  border-radius: var(--r-block) 0 0 var(--r-block);
  box-shadow: none;
}
@media (prefers-reduced-motion: reduce) { .nav-goal, .nav-goal::before { transition: none; } }

/* The Unscheduled drawer (app.js, setAsideOpen). The column is only the tab's
   width; the drawer sits over the calendar's right-hand side from there,
   always its full width underneath and clipped down to nothing at rest, so
   opening is a clip easing out - nothing inside it reflows, and the calendar
   beside it never moves. New task opens it wider. Tucked away for any drag. */
#calendar-aside { position: relative; overflow: visible; gap: 0; }
.aside-tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  width: 34px;
  padding: var(--sp-2-5) 0;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surface);
  color: var(--cal-soft-ink, var(--text-2));
  cursor: pointer;
  box-shadow: var(--shadow-soft);
  transition: opacity var(--motion-fast) var(--ease-fade);
}
.aside-tab:hover { background: var(--page); }
.aside-tab-label { writing-mode: vertical-rl; font-size: var(--fs-sm); font-weight: var(--fw-semi); letter-spacing: 0.04em; }
.aside-tab-count {
  min-width: 20px;
  padding: 0 var(--sp-1);
  border-radius: var(--r-input);
  background: var(--today);
  color: var(--on-feature);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  line-height: 18px;
  text-align: center;
}
.aside-drawer {
  --drawer: 280px;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  width: var(--drawer);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  min-height: 0;
  clip-path: inset(0 0 0 100% round 10px);
  pointer-events: none;
  transition: clip-path var(--motion-panel) var(--ease-enter),
              width var(--motion-panel) var(--ease-enter);
}
.aside-drawer > .side-panel { border-radius: var(--r-small); box-shadow: var(--shadow-panel); }
.calendar-panel.aside-open .aside-drawer, .calendar-panel.composing .aside-drawer {
  clip-path: inset(-24px -24px -24px -24px round 10px);
  pointer-events: auto;
}
.calendar-panel.aside-open .aside-tab, .calendar-panel.composing .aside-tab { opacity: 0; pointer-events: none; }
.calendar-panel.composing .aside-drawer { --drawer: 340px; }
.side-panel h2 { display: flex; align-items: center; justify-content: space-between; }
.aside-close { font-size: var(--fs-lg); }
@media (prefers-reduced-motion: reduce) { .aside-drawer, .aside-tab { transition: none; } }

/* The zoom switch (Ed's call, off-brief): Day/Week/Month/Year stacked down
   the calendar panel's left side, an icon and a small label each, the dark
   slate of the calendar's other controls. The active segment is a light
   highlight that slides along the switch like a dial turning, rather than
   jumping from one button to the next. */
.layout > .zoom {
  --seg: 54px;
  --pad: 4px;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0;
  align-self: start;
  padding: var(--pad);
  border-radius: var(--r-popover);
  background: var(--feature-3);
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.2);
}
.layout > .zoom::before {
  content: "";
  position: absolute;
  left: var(--pad);
  right: var(--pad);
  top: var(--pad);
  height: var(--seg);
  border-radius: var(--r-card);
  background: var(--divider);
  transform: translateY(calc(var(--zoom-i, 1) * var(--seg)));
  transition: transform var(--spring-switch-ms) var(--spring-switch);
}
.layout > .zoom .btn {
  position: relative;
  flex-direction: column;
  gap: var(--sp-0-5);
  height: var(--seg);
  width: 44px;
  padding: 0;
  border-radius: var(--r-card);
  background: none;
  color: var(--on-feature-2);
  font-weight: var(--fw-medium);
  transition: color var(--motion-fast) var(--ease-fade);
}
.layout > .zoom .btn:hover:not(.active) { background: color-mix(in srgb, var(--surface) 8%, transparent); color: var(--on-feature); }
.layout > .zoom .btn.active { background: none; color: var(--text-2); font-weight: var(--fw-medium); }
.zoom-icon {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linejoin: round;
  transition: transform var(--spring-switch-ms) var(--spring-switch);
}
.layout > .zoom .btn.active .zoom-icon { transform: rotate(-8deg) scale(1.08); }
.zoom-label { font-size: var(--fs-2xs); line-height: 1; letter-spacing: 0.02em; }
@media (prefers-reduced-motion: reduce) {
  .layout > .zoom::before, .zoom-icon { transition: none; }
}
/* The zoom indicators ride the switch's spring (motion.md M8, Chunk 91);
   where linear() isn't supported they glide on the spring's fallback curve. */
@supports not (transition-timing-function: linear(0, 1)) {
  .layout > .zoom::before, .zoom-icon, .calendar-footer .zoom::before { transition-duration: var(--motion-panel); transition-timing-function: var(--ease-panel); }
}

/* -- Page balance (Ed's call, off-brief) --
   The calendar section sits centred at a comfortable maximum width with room
   all round rather than running edge to edge: more margin, more padding in
   the panel, a larger date. The Unscheduled drawer is a column of the panel
   and pushes the calendar over as it opens - but the section's maximum width
   grows by the same move, into the margin either side, so on a wide window
   the calendar gives up far less than the drawer takes. The calendar re-fits
   once it's settled (app.js). */
.layout {
  grid-template-columns: 56px minmax(0, 1fr);
  column-gap: var(--sp-4);
  row-gap: var(--sp-3);
  max-width: 1320px;
  margin: 0 auto;
  transition: max-width var(--motion-panel) var(--ease-enter);
}
.layout.s-cal.cal-aside-open, .layout.s-cal.cal-composing { max-width: 1520px; }
.calendar-controls { padding: var(--sp-5) 0 var(--sp-1); }
.calendar-panel {
  grid-template-columns: minmax(0, 1fr) 34px;
  column-gap: var(--sp-4);
  padding: 0 var(--sp-5) var(--sp-5);
  transition: grid-template-columns var(--motion-panel) var(--ease-enter);
}
.calendar-panel.aside-open { grid-template-columns: minmax(0, 1fr) 280px; }
.calendar-panel.composing { grid-template-columns: minmax(0, 1fr) 340px; }
.calendar-panel > .toolbar { padding: var(--sp-4) var(--sp-0-5) var(--sp-3); }
.calendar-panel #range-label { font-size: var(--fs-heading); }
.calendar-footer { margin-top: var(--sp-3); }
.week-stack { gap: var(--sp-3); }

/* The drawer in its column: vertically centred against the calendar, its tab
   too. The drawer keeps its own width while the column opens around it, so
   it's revealed rather than reflowed; tucked, it's hidden behind the tab. */
#calendar-aside { overflow: hidden; }
.aside-tab { position: absolute; top: 50%; right: 0; transform: translateY(-50%); }
.aside-drawer {
  top: 50%;
  bottom: auto;
  max-height: 100%;
  transform: translateY(-50%);
  clip-path: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--motion-fast) var(--ease-fade), visibility 0s linear var(--motion-fast);
}
.aside-drawer > .side-panel { box-shadow: none; }
.calendar-panel.aside-open .aside-drawer, .calendar-panel.composing .aside-drawer {
  clip-path: none;
  opacity: 1;
  visibility: visible;
  transition: opacity var(--motion-fast) var(--ease-fade) var(--motion-delay), visibility 0s;
}

/* The sidebar pushes the page right as it opens (Ed's call - overlaying it
   read as a pop). The reveal and the push share one smooth curve and one
   length, so they move as one; no shadow, since nothing's lying over the page.
   On a wide window the push only eats into the margin round the centred
   calendar; on a narrow one the calendar re-fits once it's settled (app.js,
   on .content's transitionend). */
body { --sidebar-ease: var(--ease-move); --sidebar-ms: var(--motion-panel); }
.sidebar { transition: clip-path var(--sidebar-ms) var(--sidebar-ease) var(--motion-delay); }
.sidebar.expanded{ box-shadow: 1px 0 0 var(--line); transition-delay: var(--motion-delay); }
.content { transition: margin-left var(--sidebar-ms) var(--sidebar-ease) var(--motion-delay); }
body.s-cal.s-sidebar .content { margin-left: var(--sidebar-open); }
.sidebar.expanded .nav-label{
  transition: opacity var(--motion-fast) var(--ease-fade) var(--motion-settle);
}
@media (prefers-reduced-motion: reduce) { .sidebar, .content { transition: none; } }

/* Selected in the rail: a rounded pill that fits the rail rather than a row's
   background cut off square at its edge; it stretches to the full row as the
   sidebar opens. */
.nav-entry { position: relative; background: none; }
.nav-entry > * { position: relative; }
.nav-entry::before {
  content: "";
  position: absolute;
  top: 1px;
  bottom: 1px;
  left: 4px;
  width: 32px;
  border-radius: var(--r-input);
  background: transparent;
  transition: width var(--sidebar-ms) var(--sidebar-ease) var(--motion-delay), background-color var(--motion-fast) var(--ease-fade);
}
.nav-entry:hover, .nav-entry.active { background: none; }
.nav-entry:hover::before { background: var(--divider); }
.nav-entry.active::before { background: var(--faint); }
.sidebar.expanded .nav-entry::before{ width: calc(100% - 8px); }

/* The zoom switch's active segment: just the highlight, nothing tilting. */
.layout > .zoom .btn.active .zoom-icon { transform: none; }

/* The zoom switch on the calendar's right-hand side (Ed's call). */
.layout { grid-template-columns: minmax(0, 1fr) 56px; }
.layout > .calendar-panel { grid-column: 1; grid-row: 2; }
.layout > .zoom { grid-column: 2; grid-row: 2; }

/* Pinned (Chunk 38f): understated, and unlike hover - a hairline ring in the
   row's own colour and a slightly deeper tint; in the rail, the colour tab
   goes hollow. */
.sidebar.expanded .nav-row.pinned .nav-goal{
  background: color-mix(in srgb, var(--goal) 20%, var(--surface));
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--goal) 60%, transparent);
}
.nav-row.pinned .nav-goal::before { box-shadow: inset 0 0 0 3px color-mix(in srgb, var(--goal) 35%, var(--surface)); }

/* Chunk 46: a Lane's top and bottom edges resize it. Lane density only - a
   box swapped to strip in place (class highlight) has none. */
.lane-edge { position: absolute; left: 0; right: 0; height: 6px; cursor: ns-resize; z-index: 2; }
.lane-edge[data-edge="top"] { top: -1px; }
.lane-edge[data-edge="bottom"] { bottom: -1px; }
.entry.event:not([data-density="lane"]) .lane-edge { display: none; }

/* -- The completion control (shared: Event dialog, Week review) -- */
.ev-complete { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-2-5); width: 100%; }
.ev-complete .btn.primary { min-width: 120px; }
.ev-field { display: flex; flex-direction: column; gap: var(--sp-1); flex: 1 1 180px; font-size: var(--fs-sm); }
.ev-field-label { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--text-2); margin: 0; }
.ev-required { margin-left: var(--sp-1); font-weight: var(--fw-medium); color: var(--muted); }
.ev-amount { display: flex; align-items: center; border: 1px solid var(--done-fill); border-radius: var(--r-block); background: var(--surface); }
.ev-amount input { flex: 1; min-width: 0; border: 0; padding: var(--sp-1-5) var(--sp-2); background: none; font-variant-numeric: tabular-nums; }
.ev-unit { padding: 0 var(--sp-2-5); color: var(--text-2); font-size: var(--fs-md); }
.ev-field textarea { width: 100%; padding: var(--sp-1-5) var(--sp-2); border: 1px solid var(--done-fill); border-radius: var(--r-block); resize: vertical; font: inherit; }
.ev-daterow { display: flex; align-items: center; gap: var(--sp-2); width: 100%; padding: var(--sp-2) var(--sp-2-5); border-radius: var(--r-input); background: var(--page); }
.ev-row-label { font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--text-2); min-width: 88px; }
.ev-daterow input { flex: 1; min-width: 0; }
.ev-confirm { display: flex; flex-direction: column; gap: var(--sp-2); }
.ev-confirm p { margin: 0; }
.btn.danger-text { color: var(--danger); }
.btn.danger-text:hover { background: var(--divider); }

/* -- Unscheduled rail (Ed's call) --
   The left sidebar's mirror on the window's right edge: a 56px rail at rest,
   full height, with the count and "Unscheduled" down its middle; clicked
   open, it slides out to its full width and pushes the page left, on the
   same curve and timing as the left bar. Always full width underneath and
   clipped down to the rail, so nothing inside reflows as it opens. */
body { --rail: 56px; --aside-open: 300px; }
#calendar-aside {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  width: var(--aside-open);
  height: auto;
  padding: 0;
  display: block;
  background: var(--surface);
  overflow: hidden;
  clip-path: inset(0 0 0 calc(100% - var(--rail)));
  transition: clip-path var(--sidebar-ms) var(--sidebar-ease), width var(--sidebar-ms) var(--sidebar-ease);
}
#calendar-aside::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(100% - var(--rail));
  width: 1px;
  background: var(--line);
  transition: left var(--sidebar-ms) var(--sidebar-ease);
}
body:not([data-view="calendar"]) #calendar-aside { display: none; }
body.s-cal.cal-aside-open #calendar-aside,
body.s-cal.cal-composing #calendar-aside { clip-path: inset(0); }
body.s-cal.cal-aside-open #calendar-aside::before,
body.s-cal.cal-composing #calendar-aside::before { left: 0; }
body.s-cal.cal-composing { --aside-open: 360px; }
.aside-tab { right: calc((var(--rail) - 34px) / 2); }
.aside-drawer {
  position: absolute;
  inset: 16px;
  top: 16px;
  bottom: 16px;
  width: auto;
  max-height: none;
  transform: none;
}
.aside-drawer > .side-panel { border-radius: var(--r-small); }
/* No longer a column of the panel: the calendar takes the panel's width. */
.calendar-panel, .calendar-panel.aside-open, .calendar-panel.composing { grid-template-columns: minmax(0, 1fr); }
.layout.s-cal.cal-aside-open, .layout.s-cal.cal-composing { max-width: 1320px; }
/* The page leaves the rail its room and moves over as it opens. */
.content { transition: margin-left var(--sidebar-ms) var(--sidebar-ease) var(--motion-delay), margin-right var(--sidebar-ms) var(--sidebar-ease); }
body[data-view="calendar"] .content { margin-right: var(--rail); }
body[data-view="calendar"].s-cal.cal-aside-open .content,
body[data-view="calendar"].s-cal.cal-composing .content { margin-right: var(--aside-open); }
@media (prefers-reduced-motion: reduce) { #calendar-aside, #calendar-aside::before { transition: none; } }
/* The rail lives in <body> now, so "open" is read off the panel from there. */
body.s-cal.cal-aside-open .aside-drawer,
body.s-cal.cal-composing .aside-drawer {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity var(--motion-fast) var(--ease-fade) var(--motion-delay), visibility 0s;
}
body.s-cal.cal-aside-open .aside-tab,
body.s-cal.cal-composing .aside-tab { opacity: 0; pointer-events: none; }
body.s-cal.cal-composing .aside-drawer { --drawer: auto; }

/* -- Edge tabs (Ed's call) --
   Unscheduled and + New task as two horizontal tabs on the window's right
   edge, one above the other, overhanging the page; opening the drawer slides
   them out with it, so they stay on its edge (Unscheduled then closes it). */
.edge-tabs {
  position: fixed;
  right: 0;
  top: 50%;
  z-index: 45;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--sp-2-5);
  transform: translate(0, -50%);
  transition: transform var(--sidebar-ms) var(--sidebar-ease);
}
body:not([data-view="calendar"]) .edge-tabs { display: none; }
body.s-cal.cal-aside-open .edge-tabs,
body.s-cal.cal-composing .edge-tabs { transform: translate(calc(-1 * var(--aside-open)), -50%); }
.edge-tabs .aside-tab,
body.s-cal.cal-aside-open .edge-tabs .aside-tab,
body.s-cal.cal-composing .edge-tabs .aside-tab {
  position: static;
  transform: none;
  opacity: 1;
  pointer-events: auto;
  flex-direction: row;
  width: auto;
  height: 40px;
  padding: 0 var(--sp-3) 0 var(--sp-3);
  gap: var(--sp-2);
  border: 1px solid var(--line);
  border-right: 0;
  border-radius: var(--r-small) 0 0 var(--r-small);
  background: var(--surface);
  box-shadow: -3px 2px 10px rgb(0 0 0 / 0.08);
}
.edge-tabs .aside-tab-label { writing-mode: horizontal-tb; font-size: var(--fs-md); letter-spacing: 0.01em; }
.edge-tabs .footer-new {
  height: 40px;
  padding: 0 var(--sp-4) 0 var(--sp-3);
  border: 0;
  border-radius: var(--r-small) 0 0 var(--r-small);
  background: var(--today);
  color: var(--on-feature);
  font-weight: var(--fw-semi);
  box-shadow: -3px 2px 10px rgb(31 39 51 / 0.25);
}
.edge-tabs .footer-new:hover, .edge-tabs .footer-new:focus-visible { background: var(--feature-2); }
.edge-tabs .footer-new-label { max-width: none; margin-left: var(--sp-1-5); opacity: 1; }
@media (prefers-reduced-motion: reduce) { .edge-tabs { transition: none; } }

/* Check-in (Ed's call): a round button at rest - its icon, and the count of
   what's waiting on its corner - that widens into a "Check-in" pill on hover
   or keyboard focus, the label easing in. */
.calendar-main #footer-checkin.footer-checkin {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 38px;
  min-width: 38px;
  padding: 0 var(--sp-2);
  border: 1px solid var(--done-fill);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--cal-soft-ink);
  cursor: pointer;
  box-shadow: var(--shadow-soft);
  transition: background-color var(--motion-fast) var(--ease-fade), border-color var(--motion-fast) var(--ease-fade);
}
.calendar-main #footer-checkin.footer-checkin:hover,
.calendar-main #footer-checkin.footer-checkin:focus-visible { background: var(--page); border-color: var(--faint-text); color: var(--cal-ink); }
.footer-checkin-icon { flex: 0 0 auto; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linejoin: round; }
.footer-checkin-label {
  display: inline-block;
  max-width: 0;
  opacity: 0;
  overflow: hidden;
  white-space: nowrap;
  font-weight: var(--fw-medium);
  transition: max-width var(--motion-move) var(--ease-move),
              margin-left var(--motion-move) var(--ease-move),
              opacity var(--motion-fast) var(--ease-fade);
}
.footer-checkin:hover .footer-checkin-label, .footer-checkin:focus-visible .footer-checkin-label {
  max-width: 6em;
  margin-left: var(--sp-1-5);
  opacity: 1;
}
.footer-checkin .checkin-badge {
  position: absolute;
  top: -6px;
  right: -8px;
  margin: 0;
  min-width: 18px;
  box-shadow: 0 0 0 2px var(--cal-panel);
}
@media (prefers-reduced-motion: reduce) { .footer-checkin-label { transition: none; } }

/* Today and Prev/Next sit in the panel's own header, right-aligned against
   its right wall, level with the date (Ed's call) - no row above the panel. */
.calendar-panel > .toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-3); }
.calendar-panel > .toolbar .calendar-controls { margin-left: auto; padding: 0; grid-column: auto; }
.layout { padding-top: var(--sp-5); }
.layout > .calendar-panel, .layout > .zoom { grid-row: 1; }

/* -- Task forms (Chunk 43) -- */
.task-form { display: flex; flex-direction: column; gap: var(--sp-3); }
.task-form > h2 { margin: 0; }
.tf-section { display: flex; flex-direction: column; gap: var(--sp-2-5); }
.tf-divider {
  margin: var(--sp-1) 0 0;
  padding-top: var(--sp-3);
  border-top: 1px solid var(--faint);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
}
.tf-help { margin: calc(-1 * var(--sp-1-5)) 0 0; color: var(--muted); font-size: var(--fs-sm); }
.tf-field { display: flex; flex-direction: column; gap: var(--sp-1); font-size: var(--fs-md); }
.tf-field input[type=text], .tf-field input[type=date] { width: 100%; }
.tf-inline { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.tf-inline input[type=date], .tf-inline .time-input { width: auto; }
/* The reserved line: always there, one line tall, so the form doesn't move as the tile changes. */
.tf-desc { margin: calc(-1 * var(--sp-1)) 0 0; min-height: 1.4em; color: var(--text-2); font-size: var(--fs-sm); }
/* One height for every lane (the tallest), so switching doesn't resize the dialog. */
.tf-lanes { min-height: 212px; }
.tf-lane { display: flex; flex-direction: column; gap: var(--sp-2-5); }
.tf-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); }
.tf-tile {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-2-5); border: 1px solid var(--line); border-radius: var(--r-input);
  font-size: var(--fs-md); line-height: 1.25; cursor: pointer; background: var(--surface);
}
.tf-tile:has(input:checked) { border-color: var(--ink); background: var(--divider); font-weight: var(--fw-semi); }
.tf-tile input { accent-color: var(--ink); }
.tf-chips { display: flex; gap: var(--sp-1-5); }
.tf-chip { position: relative; cursor: pointer; }
.tf-chip input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.tf-chip span {
  display: grid; place-items: center; width: 34px; height: 34px;
  border: 1px solid var(--line); border-radius: 50%; font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--text-2); background: var(--surface);
}
.tf-chip input:checked + span { background: var(--primary-fill); border-color: var(--primary-fill); color: var(--on-primary); }
.tf-chip input:focus-visible + span, .tf-chip.is-focus span { outline: var(--focus-width) solid var(--focus-color); outline-offset: var(--focus-offset); }
.tf-presets { display: flex; gap: var(--sp-1); margin-top: calc(-1 * var(--sp-1)); }
.tf-presets .btn { padding: var(--sp-0-5) var(--sp-2); font-size: var(--fs-sm); }
.tf-row { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); }
.tf-sentence { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin: 0; font-size: var(--fs-base); }
.tf-stepper { display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: var(--r-input); background: var(--surface); }
.tf-stepper input { width: 3em; border: 0; text-align: center; font-variant-numeric: tabular-nums; -moz-appearance: textfield; }
.tf-stepper input::-webkit-inner-spin-button, .tf-stepper input::-webkit-outer-spin-button { -webkit-appearance: none; }
.tf-stepper .btn { padding: var(--sp-0-5) var(--sp-2-5); font-size: var(--fs-body); }
.tf-locked { position: relative; }
.tf-locked input, .tf-locked label, .tf-locked select { color: var(--faint-text); }
.icon-choice.tf-locked label { opacity: 0.55; cursor: not-allowed; }
.icon-choice.tf-locked label:has(input:checked) { opacity: 0.85; }
.tf-lock { display: inline-flex; color: var(--faint-text); }
.icon-choice.tf-locked > .tf-lock { position: absolute; top: -8px; right: -6px; }
.tf-lock-icon { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; }
.tf-belongs { display: flex; align-items: center; gap: var(--sp-2-5); }
.tf-swatch { flex: 0 0 auto; width: 22px; height: 22px; border-radius: var(--r-block); background: #8a8f98; box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.12); }
.tf-belongs select { flex: 1; min-width: 0; }
.task-form textarea { width: 100%; }
#task-edit-dialog { border-top: 6px solid var(--goal, var(--faint-text)); }

/* The zoom switch sits level with the middle of the calendar panel (Ed's call). */
.layout > .zoom { align-self: center; }

/* + New task: the calendar's one main action, big, bottom right of the row
   under the calendar, level with the small Check-in on the left (Ed's call). */
.calendar-main .footer-new {
  height: 46px;
  padding: 0 var(--sp-6) 0 var(--sp-4);
  border-radius: var(--r-pill);
  font-size: var(--fs-body);
  box-shadow: var(--shadow-bubble);
}
.calendar-main .footer-new-plus { font-size: var(--fs-heading); width: 16px; }
.calendar-main .footer-new-label { margin-left: var(--sp-2); }
.calendar-footer { height: 46px; }

/* Creating a task gets the whole rail if it needs it; Unscheduled shrinks
   (and scrolls) under it. The edge tab tucks away while the drawer's open -
   the drawer's own › closes it - rather than riding out over the zoom switch. */
.aside-drawer > dialog.slide-panel:is([open], :not([open])) { flex: 0 0 auto; max-height: 100%; }
.aside-drawer > .side-panel { flex: 0 1 auto; min-height: 0; }
body.s-cal.cal-aside-open .edge-tabs .aside-tab,
body.s-cal.cal-composing .edge-tabs .aside-tab { opacity: 0; pointer-events: none; }

/* Unscheduled stays open for good (Ed's call): no tab, no close button. */
.edge-tabs, .aside-close { display: none; }

/* New task, compact enough to fit a laptop screen with no scrolling (Ed's
   call): it has the rail to itself while it's open (Unscheduled and Loose
   ends step aside until it closes), a label and its "optional" tag share a
   line, and the tiles, gaps and schedule area are all a size tighter. */
body.s-cal.cal-composing .aside-drawer > .side-panel { display: none; }
:is(#task-dialog, #task-edit-dialog) .task-form { gap: var(--sp-2-5); }
:is(#task-dialog, #task-edit-dialog) .task-form > h2 { font-size: var(--fs-body); }
:is(#task-dialog, #task-edit-dialog) .tf-section { gap: var(--sp-2); }
.task-form .tf-field:not(.tf-inline) {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: var(--sp-2);
  row-gap: var(--sp-0-5);
}
.task-form .tf-field:not(.tf-inline) > input { grid-column: 1 / -1; }
.task-form .tf-field .optional-tag { justify-self: start; }
:is(#task-dialog, #task-edit-dialog) .icon-choice { margin: 0; gap: var(--sp-1-5); }
:is(#task-dialog, #task-edit-dialog) .icon-choice label { padding: var(--sp-1-5) var(--sp-1); gap: var(--sp-0-5); font-size: var(--fs-sm); }
:is(#task-dialog, #task-edit-dialog) .icon-choice svg { width: 18px; height: 18px; }
:is(#task-dialog, #task-edit-dialog) .tf-desc { margin-top: calc(-1 * var(--sp-0-5)); }
:is(#task-dialog, #task-edit-dialog) .tf-inline .muted { display: none; }
:is(#task-dialog, #task-edit-dialog) .tf-divider { margin-top: 0; padding-top: var(--sp-2); }
:is(#task-dialog, #task-edit-dialog) .tf-help { margin-top: calc(-1 * var(--sp-1)); }
:is(#task-dialog, #task-edit-dialog) .tf-lanes { min-height: 176px; }
:is(#task-dialog, #task-edit-dialog) .tf-lane { gap: var(--sp-2); }
#task-dialog .tf-tile { padding: var(--sp-1-5) var(--sp-2); font-size: var(--fs-sm); }
#task-dialog .tf-chip span { width: 30px; height: 30px; font-size: var(--fs-sm); }
#task-dialog .actions { margin-top: var(--sp-0-5); }

/* Zoom switch back on the calendar's left (Ed's call), with a matching empty
   column on the right so the calendar panel itself sits centred between the
   sidebar and Unscheduled. */
.layout { grid-template-columns: 56px minmax(0, 1fr) 56px; }
.layout > .zoom { grid-column: 1; grid-row: 1; }
.layout > .calendar-panel { grid-column: 2; grid-row: 1; }

/* A hovered or arrowed-to day: a soft ring that eases from cell to cell,
   rather than a dashed box jumping between them. */
#calendar-grid [data-day] { transition: box-shadow var(--motion-fast) var(--ease-fade); }
#calendar-grid [data-day].selected { outline: none; box-shadow: inset 0 0 0 2px rgb(58 65 77 / 0.22); }

/* Month: days from the months either side sit clearly back - a deeper grey,
   faded dates, and their bars muted (Ed's call). */
#calendar-grid .month-day.outside, #calendar-grid .month-day.outside.past {
  background-color: var(--line);
  border-color: var(--line);
}
#calendar-grid .month-day.outside .month-h { color: var(--faint-text); }
/* Its events barely there, at every density - a click on the day goes to
   that month (app.js, drillFrom), so they're not what it's for. */
/* Chunk 99 (A12): only the bars and linked cards fade; a goal pennant (its name and "over") stays full-strength, legible text. */
#calendar-grid .month-day.outside .month-day-events { filter: grayscale(0.7); }
#calendar-grid .month-day.outside .month-day-events :is(.entry, .ext-event) { opacity: 0.3; }
#calendar-grid .month-day.outside { cursor: pointer; }

/* -- Pick up and place (Ed's call) -- the held ghost, and its launchers. */
.pick-ghost {
  width: 190px;
  padding: var(--sp-1-5) var(--sp-2);
  border-width: 1.5px;
  box-shadow: 0 10px 28px rgb(0 0 0 / 0.22), 0 0 0 4px color-mix(in srgb, var(--goal, #8a8f98) 18%, transparent);
  transform: rotate(-2deg);
  opacity: 0.96;
}
.pick-ghost { display: flex; flex-direction: column; white-space: normal; }
.pick-ghost .entry-owner { margin: 0; }
.pick-ghost .entry-owner::before { content: none; }
.pick-ghost .pick-hint { font-size: var(--fs-2xs); color: var(--muted); margin-top: var(--sp-0-5); }
body.picking, body.picking * { cursor: copy !important; }
body.picking :is(.toolbar, .zoom, .calendar-footer) :is(button, button *) { cursor: pointer !important; }
body.picking.drop-refused, body.picking.drop-refused * { cursor: not-allowed !important; }
.pick-date { padding: var(--sp-0-5) var(--sp-2); font-size: var(--fs-sm); }

/* Month under the mouse stays still (Ed's call): no selection ring or darker
   bar following the pointer from day to day - that's for the arrow keys. */
body:not(.kbd-select) #calendar-grid.month [data-day].selected { box-shadow: none; }

/* -- Check-in panel (Ed's call) --
   In from the right like Unscheduled, but wide: the page moves over by its
   width, so the calendar carries on as a narrow column on the left while it's
   open. It takes Unscheduled's place for as long as it's out. */
body { --checkin-w: min(60vw, 900px); }
.checkin-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 42;
  width: var(--checkin-w);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-left: 1px solid var(--line);
  transform: translateX(100%);
  visibility: hidden;
  transition: transform var(--sidebar-ms) var(--sidebar-ease), visibility 0s linear var(--sidebar-ms);
}
body.checking .checkin-panel { transform: none; visibility: visible; transition: transform var(--sidebar-ms) var(--sidebar-ease), visibility 0s; }
body.checking #calendar-aside { visibility: hidden; }
body.checking[data-view="calendar"] .content,
body.checking[data-view="calendar"].s-cal.cal-aside-open .content { margin-right: var(--checkin-w); }
.checkin-panel-head { display: flex; align-items: center; justify-content: space-between; padding: var(--sp-4) var(--sp-6) var(--sp-2-5); }
.checkin-panel-head h2 { margin: 0; font-size: var(--fs-heading); }
.checkin-panel-body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--sp-1) var(--sp-6) var(--sp-7); display: flex; flex-direction: column; gap: var(--sp-4); }
.ck-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-3); }
.ck-stat { display: flex; flex-direction: column; gap: var(--sp-0-5); padding: var(--sp-3) var(--sp-3); border: 1px solid var(--faint); border-radius: var(--r-small); background: var(--surface); }
.ck-stat-value { font-size: var(--fs-xl); font-weight: 650; line-height: 1.1; color: var(--ink); font-variant-numeric: tabular-nums; }
.ck-stat-label { font-size: var(--fs-sm); color: var(--muted); }
.ck-card { position: relative; padding: var(--sp-3) var(--sp-4); border: 1px solid var(--faint); border-radius: var(--r-small); background: var(--surface); }
.ck-card h3 { margin: 0; font-size: var(--fs-base); color: var(--ink); }
.ck-sub { margin: var(--sp-0-5) 0 var(--sp-2-5); font-size: var(--fs-sm); color: var(--muted); }
.ck-legend { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3); margin-bottom: var(--sp-1-5); font-size: var(--fs-sm); color: var(--text-2); }
.ck-legend-item { display: inline-flex; align-items: center; gap: var(--sp-1-5); }
.ck-swatch { display: inline-block; width: 10px; height: 10px; border-radius: var(--r-mini); flex: 0 0 auto; }
.ck-chart-box { position: relative; }
.ck-chart { display: block; width: 100%; height: auto; }
.ck-grid { stroke: var(--on-feature); stroke-width: 1; }
.ck-axis { stroke: var(--on-feature-2); stroke-width: 1; }
.ck-tick { fill: var(--muted); font-size: var(--fs-2xs); font-family: inherit; font-variant-numeric: tabular-nums; }
.ck-value { fill: var(--ink); font-size: var(--fs-xs); font-weight: var(--fw-semi); font-family: inherit; }
.ck-hit { fill: transparent; cursor: default; }
.ck-hit:hover { fill: rgb(58 65 77 / 0.05); }
.ck-tip {
  position: absolute;
  z-index: 2;
  min-width: 160px;
  padding: var(--sp-2) var(--sp-2-5);
  border-radius: var(--r-input);
  background: var(--feature-2);
  color: var(--on-feature);
  font-size: var(--fs-sm);
  pointer-events: none;
  box-shadow: 0 6px 18px rgb(0 0 0 / 0.2);
}
.ck-tip-head { font-weight: var(--fw-semi); margin-bottom: var(--sp-1); }
.ck-tip-row { display: flex; align-items: center; gap: var(--sp-1-5); }
.ck-tip-row strong { margin-left: auto; font-variant-numeric: tabular-nums; }
.ck-goals { display: flex; flex-direction: column; gap: var(--sp-1-5); }
.ck-goal {
  display: grid;
  grid-template-columns: minmax(0, 180px) minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-1) var(--sp-1-5);
  border: 0;
  border-radius: var(--r-block);
  background: none;
  text-align: left;
  font: inherit;
  cursor: pointer;
}
.ck-goal:hover { background: var(--page); }
.ck-goal-name { font-size: var(--fs-md); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); }
.ck-track { position: relative; height: 8px; border-radius: var(--r-mini); background: var(--sunk); overflow: hidden; }
.ck-fill { position: absolute; inset: 0 auto 0 0; border-radius: var(--r-mini); background: var(--goal); }
.ck-goal-value { font-size: var(--fs-sm); color: var(--text-2); font-variant-numeric: tabular-nums; }
.ck-actions .section { padding: var(--sp-3) var(--sp-4); border: 1px solid var(--faint); border-radius: var(--r-small); background: var(--surface); margin-top: var(--sp-4); }
.ck-actions .section:first-child { margin-top: 0; }
.ck-actions .section h3 { margin-top: 0; }
@media (prefers-reduced-motion: reduce) { .checkin-panel { transition: none; } }


/* Completed and the dark-mode switch sit together at the foot of the sidebar. */
.sidebar [data-view="completed"] { margin-top: auto; }

/* Check-in's board of pies takes the calendar's place while it's out (Ed's
   call), and the panel on the right narrows back to a side panel. Hovering a
   figure in the panel brings its pies forward and quiets the rest. */
body { --checkin-w: 380px; }
.checkin-charts { display: none; }
body.checking .layout > .calendar-panel, body.checking .layout > .zoom { display: none; }
body.checking .checkin-charts {
  grid-column: 1 / -1;
  grid-row: 1;
  position: relative;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: var(--sp-4);
  align-content: start;
  padding: var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--cal-panel);
  animation: board-in var(--motion-panel) var(--ease-enter) var(--motion-delay) both;
}
@keyframes board-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.ck-pie {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-4);
  border: 1px solid var(--faint);
  border-radius: var(--r-card);
  background: var(--surface);
  transition: opacity var(--motion-fast) var(--ease-fade), transform var(--motion-panel) var(--ease-enter),
              box-shadow var(--motion-panel) var(--ease-fade);
}
.ck-pie h3 { margin: 0; align-self: flex-start; font-size: var(--fs-base); color: var(--ink); }
.ck-pie .ck-sub { align-self: flex-start; margin: calc(-1 * var(--sp-1-5)) 0 var(--sp-0-5); }
.ck-goal-rings { grid-column: 1 / -1; }
.focusing .ck-pie:not(.focused) { opacity: 0.3; }
.focusing .ck-pie.focused { transform: scale(1.03); box-shadow: 0 8px 24px rgb(0 0 0 / 0.1); }
.ck-donut { width: 168px; height: 168px; overflow: visible; }
.ck-ring { stroke: var(--on-feature); }
.ck-slice { stroke: var(--on-feature); stroke-width: 2; transition: opacity var(--motion-fast) var(--ease-fade); }
.ck-donut:has(.ck-slice:hover) .ck-slice:not(:hover) { opacity: 0.45; }
.ck-centre { fill: var(--ink); font-size: var(--fs-xl); font-weight: 650; font-family: inherit; font-variant-numeric: tabular-nums; }
.ck-centre-label { fill: var(--muted); font-size: var(--fs-xs); font-family: inherit; }
.ck-legend { justify-content: center; }
.ck-legend-item strong { margin-left: var(--sp-1); font-variant-numeric: tabular-nums; color: var(--ink); }
.ck-rings { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: var(--sp-3); width: 100%; }
.ck-ring-item {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-1);
  padding: var(--sp-2); border: 0; border-radius: var(--r-small); background: none; font: inherit; cursor: pointer;
}
.ck-ring-item:hover { background: var(--page); }
.ck-ring-item svg { width: 92px; height: 92px; }
.ck-ring-item .ck-centre { font-size: var(--fs-lg); }
.ck-ring-name { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--ink); text-align: center; }
.ck-ring-value { font-size: var(--fs-xs); color: var(--muted); }
.ck-stats { grid-template-columns: 1fr; }
.ck-stat { cursor: default; transition: border-color var(--motion-fast) var(--ease-fade), box-shadow var(--motion-fast) var(--ease-fade); }
.ck-stat:hover, .ck-stat:focus-visible { border-color: var(--faint-text); box-shadow: var(--shadow-lift); }
@media (prefers-reduced-motion: reduce) { .checkin-charts, .ck-pie { animation: none; transition: none; } }

/* + New task at the foot of the Unscheduled rail, bottom right of the screen,
   the calendar's main action as before; the drawer stops short of it. */
#calendar-aside .aside-drawer { bottom: 80px; }
#calendar-aside #footer-new {
  position: absolute;
  right: 16px;
  bottom: 18px;
  z-index: 1;
  height: 46px;
  padding: 0 var(--sp-6) 0 var(--sp-4);
  border: 0;
  border-radius: var(--r-pill);
  background: var(--today);
  color: var(--on-feature);
  font-size: var(--fs-body);
  font-weight: var(--fw-semi);
  box-shadow: var(--shadow-bubble);
}
#calendar-aside #footer-new:hover, #calendar-aside #footer-new:focus-visible { background: var(--feature-2); }
#calendar-aside .footer-new-plus { font-size: var(--fs-heading); width: 16px; }
#calendar-aside .footer-new-label { max-width: none; margin-left: var(--sp-2); opacity: 1; }

/* Check-in at the foot of the left sidebar, above Completed: round in the
   rail, with its count on the corner, widening into its pill on hover. */
.sidebar #footer-checkin.footer-checkin {
  position: relative;
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  height: 38px;
  min-width: 38px;
  margin: 0 0 var(--sp-1-5) var(--sp-2);
  padding: 0 var(--sp-2);
  border: 1px solid var(--done-fill);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text-2);
  cursor: pointer;
  box-shadow: var(--shadow-soft);
}
.sidebar #footer-checkin.footer-checkin:hover,
.sidebar #footer-checkin.footer-checkin:focus-visible { background: var(--page); border-color: var(--faint-text); color: var(--ink); }
.sidebar [data-view="completed"] { margin-top: 0; }
.sidebar #footer-checkin { margin-top: auto; }
.sidebar .footer-checkin .checkin-badge { box-shadow: 0 0 0 2px var(--surface); }

/* Nothing animates into place on load (app.js lifts this after first paint). */
body.preload, body.preload *, body.preload *::before, body.preload *::after { transition: none !important; }

/* Check-in's board fits the screen: pies a size smaller, four to a row where
   there's room, the board itself scrolling if it still can't fit. */
body.checking .checkin-charts {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  max-height: calc(100vh - 44px);
  overflow-y: auto;
}
.ck-donut { width: 140px; height: 140px; }
.ck-pie { padding: var(--sp-3); }
.ck-rings { grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); }
.ck-ring-item svg { width: 78px; height: 78px; }
.sidebar #footer-checkin.footer-checkin { margin-top: auto; }

/* The sidebar's foot, in order: Completed, Dark mode, then Check-in last,
   right at the bottom (Ed's call) - its round button the same 36px as the
   rows' own icon column, centred on the same line as their icons. */
.sidebar [data-view="completed"] { margin-top: auto; }
.sidebar #footer-checkin.footer-checkin {
  height: 36px;
  min-width: 36px;
  margin: var(--sp-1-5) 0 0 var(--sp-0-5);
  padding: 0 var(--sp-2);
}

/* -- Linked calendars (Ed's call) --
   Nothing like your own Events: a dotted edge in the feed's colour over a
   plain pale wash (Ed's call, replacing the stripes - they hurt legibility),
   a link glyph and the time. Read only, so no hover change at all - the edge
   stays dotted whatever happens. At bar density a thin dotted bar; in Day a
   band behind the day's own Events over the hours it covers. */
.ext-event {
  --ext: #5b6b8c;
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  width: 100%;
  min-width: 0;
  margin-top: var(--sp-1);
  padding: var(--sp-0-5) var(--sp-1-5);
  border: 2px dotted var(--ext);
  border-radius: var(--r-block);
  background: color-mix(in srgb, var(--ext) 9%, var(--surface));
  color: color-mix(in srgb, var(--ext) 40%, var(--ink));
  font: inherit;
  font-size: var(--fs-xs);
  line-height: 14px;
  text-align: left;
  cursor: help;
}
.ext-icon { flex: 0 0 auto; display: inline-flex; }
.ext-icon svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.ext-time { flex: 0 0 auto; font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; }
.ext-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ext-owner { display: none; }
/* Linked entries take the density of the Goal boxes around them (Ed's call -
   "make everything consistent"): a chip wherever those are chips - Week's own
   row, an open Month row, and Day's band - with the linked calendar's name on
   top, the title wrapping to two lines inside the box, then the link glyph
   and the time where a chip's icon row sits; a strip in a strip row; a bar
   in a bar row, a Week neighbour, and the month either side's days. */
:is(.week.focused, .month-week[data-density="chip"] .month-day:not(.outside)) .ext-event:not(.class-hit),
.day-ext .ext-event {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "owner owner" "title title" "icon time";
  align-items: center;
  align-content: start;
  column-gap: var(--sp-1);
  font-size: var(--fs-sm);
  line-height: 15px;
}
:is(.week.focused, .month-week[data-density="chip"] .month-day:not(.outside)) .ext-event:not(.class-hit) .ext-owner,
.day-ext .ext-event .ext-owner {
  grid-area: owner;
  display: block;
  overflow: hidden;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semi);
  line-height: 13px;
  text-overflow: ellipsis;
  white-space: nowrap;
}
:is(.week.focused, .month-week[data-density="chip"] .month-day:not(.outside)) .ext-event:not(.class-hit) .ext-title,
.day-ext .ext-event .ext-title {
  grid-area: title;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow-wrap: anywhere;
  white-space: normal;
}
:is(.week.focused, .month-week[data-density="chip"] .month-day:not(.outside)) .ext-event:not(.class-hit) .ext-icon,
.day-ext .ext-event .ext-icon { grid-area: icon; margin: var(--sp-0-5) 0 var(--sp-px); }
:is(.week.focused, .month-week[data-density="chip"] .month-day:not(.outside)) .ext-event:not(.class-hit) .ext-time,
.day-ext .ext-event .ext-time { grid-area: time; font-size: var(--fs-2xs); font-weight: var(--fw-semi); }
/* Bar density (Month's resting rows, Week's neighbours): a thin dotted bar. */
.month-week[data-density="bar"] .ext-event, .week.neighbour .ext-event, .month-day.outside .ext-event {
  height: 9px;
  margin-top: var(--sp-1);
  padding: 0;
  border-width: 1.5px;
  border-radius: var(--r-mini);
  background: color-mix(in srgb, var(--ext) 30%, var(--surface));
}
.month-week[data-density="bar"] .ext-event > *, .week.neighbour .ext-event > *, .month-day.outside .ext-event > * { display: none; }
/* Day: bands behind the day's own lanes, over the hours they cover. */
.day-ext { position: absolute; top: 0; bottom: 0; left: 56px; right: 8px; }
.ext-event.ext-band {
  position: absolute;
  left: 0;
  right: 0;
  width: auto;
  margin: 0;
  align-items: flex-start;
  padding: var(--sp-1) var(--sp-2);
  opacity: 0.9;
  font-size: var(--fs-sm);
}
.day-view.neighbour .ext-event { pointer-events: none; }
.day-flags .ext-event { width: auto; }
.ext-detail { margin: 0; font-size: var(--fs-md); }
.ext-notes { white-space: pre-line; }

#feeds-dialog { width: min(560px, calc(100vw - 32px)); border: 0; border-radius: var(--r-card); padding: var(--sp-4) var(--sp-5); box-shadow: var(--shadow-dialog); }
#feeds-dialog::backdrop { background: rgb(0 0 0 / 0.3); }
.feeds-head { display: flex; align-items: center; justify-content: space-between; }
.feeds-head h2 { margin: 0; }
.feeds-list { display: flex; flex-direction: column; gap: var(--sp-2); margin: var(--sp-3) 0; }
.feed-row { display: flex; align-items: center; gap: var(--sp-2-5); padding: var(--sp-2) var(--sp-2-5); border: 1px solid var(--faint); border-radius: var(--r-input); }
.feed-row.has-error { border-color: color-mix(in srgb, var(--missed) 40%, var(--surface)); }
.feed-row input[type=color] { width: 28px; height: 28px; padding: 0; border: 0; background: none; }
.feed-main { display: flex; flex-direction: column; flex: 1; min-width: 0; font-size: var(--fs-md); }
.feed-main span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.feed-status { font-size: var(--fs-sm); }
.error-text { color: var(--missed); }
.feeds-add { display: flex; flex-direction: column; gap: var(--sp-2); padding-top: var(--sp-3); border-top: 1px solid var(--divider); }
.feeds-add h3 { margin: 0; font-size: var(--fs-base); }
.feeds-add label { display: flex; flex-direction: column; gap: var(--sp-1); font-size: var(--fs-md); }
.feeds-add input[type=text], .feeds-add input[type=url] { width: 100%; }
.feeds-add-row { display: flex; align-items: center; }
.feeds-colour { flex-direction: row !important; align-items: center; }
/* Day's own Events layer covers the whole column; only its boxes take the
   pointer, so a linked-calendar band behind them can still be clicked. */
.day-events { pointer-events: none; }
.day-events > * { pointer-events: auto; }
/* Linked calendars joins the sidebar's foot: Linked calendars, Completed,
   Dark mode, then Check-in last. */
.sidebar .feeds-entry { margin-top: auto; }
.sidebar .feeds-entry ~ [data-view="completed"] { margin-top: 0; }

/* Unscheduled tucked away behind a menu button (Ed's call): closed, the rail
   is gone entirely and only the button shows, top right, in the page's own
   right-hand margin; open, the rail slides out and the page moves over. */
.aside-menu {
  position: fixed;
  top: 14px;
  right: 10px;
  z-index: 46;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surface);
  color: var(--text-2);
  cursor: pointer;
  box-shadow: var(--shadow-soft);
  transition: background-color var(--motion-fast) var(--ease-fade);
}
.aside-menu:hover, .aside-menu:focus-visible { background: var(--page); color: var(--ink); }
.aside-menu[aria-expanded="true"] { background: var(--feature-3); border-color: var(--ink); color: var(--on-feature); }
.aside-menu svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
body:not([data-view="calendar"]) .aside-menu, body.checking .aside-menu { display: none; }
body.s-cal:not(.cal-aside-open):not(.cal-composing) #calendar-aside { clip-path: inset(0 0 0 100%); }
body.s-cal:not(.cal-aside-open):not(.cal-composing) #calendar-aside::before { display: none; }
/* Open: the drawer starts under the menu button, the button its close. */
#calendar-aside .aside-drawer { top: 60px; bottom: 16px; transform: none; }

/* Linked in the sidebar: rows like Goals and Routines, but the colour tab
   striped like the entries themselves - the sidebar as their key. */
.nav-linked .nav-goal::before {
  box-sizing: border-box;
  border: 2px dotted var(--goal);
  background: color-mix(in srgb, var(--goal) 18%, var(--surface));
}
.nav-linked .nav-goal.feed-broken .nav-label::after { content: " · sync failed"; color: var(--missed); font-size: var(--fs-xs); }
.nav-linked .nav-empty { display: block; padding: var(--sp-1) var(--sp-2); }
.sidebar:not(.expanded) .nav-linked .nav-empty { visibility: hidden; }
/* Highlighted from its sidebar row, a linked entry does what a Goal's Events
   do: no glow, and - on a full-size day or a Month bar row - the same
   one-line strip, its edge still dotted. On a Week neighbour it stays a bar,
   just stronger. */
#calendar-grid :is(.week:not(.neighbour), .month-week) .ext-event.class-hit:not(.ext-band),
#calendar-grid .month-week[data-density="strip"] .month-day:not(.outside) .ext-event {
  height: auto;
  margin-top: var(--sp-0-5);
  padding: 0 var(--sp-1);
  border-width: 1.5px;
  border-radius: var(--r-mini);
  font-size: var(--fs-xs);
  line-height: 15px;
}
#calendar-grid :is(.week:not(.neighbour), .month-week) .ext-event.class-hit:not(.ext-band) > :not(.ext-title),
#calendar-grid .month-week[data-density="strip"] .month-day:not(.outside) .ext-event > :not(.ext-title) { display: none; }
#calendar-grid .month-week[data-density="bar"] .ext-event.class-hit > .ext-title { display: block; }
#calendar-grid .week.neighbour .ext-event.class-hit { background: color-mix(in srgb, var(--ext) 60%, var(--surface)); }

#feed-info-dialog { width: min(520px, calc(100vw - 32px)); border: 0; border-top: 6px solid var(--goal, #5b6b8c); border-radius: var(--r-card); padding: var(--sp-4) var(--sp-5); box-shadow: var(--shadow-dialog); }
#feed-info-dialog::backdrop { background: rgb(0 0 0 / 0.3); }
#feed-info-dialog h3 { margin: var(--sp-3) 0 var(--sp-1-5); font-size: var(--fs-md); text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.feed-link { margin: var(--sp-0-5) 0 0; font-size: var(--fs-sm); }
.feed-upcoming { display: flex; flex-direction: column; gap: var(--sp-2); max-height: 50vh; overflow-y: auto; }
.feed-day { display: grid; grid-template-columns: 100px 1fr; gap: var(--sp-2); align-items: start; }
.feed-day-name { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--text-2); padding-top: var(--sp-1); }
.feed-day-items { display: flex; flex-direction: column; gap: var(--sp-1); }
.feed-item {
  text-align: left; font: inherit; font-size: var(--fs-md); padding: var(--sp-1) var(--sp-2); cursor: pointer;
  border: 2px dotted var(--goal); border-radius: var(--r-block);
  background: color-mix(in srgb, var(--goal) 9%, var(--surface));
}
.feed-item strong { font-variant-numeric: tabular-nums; }

/* Anywhere but the calendar the sidebar stays open (Ed's call), names and
   all, and the page sits beside it; on the calendar it folds to its rail. */
.sidebar.expanded { clip-path: inset(0 -24px 0 0); }

/* The left sidebar opens and closes from its menu button (Ed's call - no
   hover pop-out). Closed, it's the slim rail: an icon per entry and a colour
   tab per Goal, Routine and linked calendar; open, it's full width and pushes
   the page over. The button sits at the top of the rail in the icons' own
   column, and beside the app's name once open. */
.sidebar { transition: clip-path var(--sidebar-ms) var(--sidebar-ease); }
.sidebar h1 { min-height: 36px; padding: 0 var(--sp-1-5) var(--sp-2-5) var(--sp-0-5); gap: var(--sp-2-5); }
.nav-menu {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: var(--r-input);
  background: none;
  color: var(--text-2);
  cursor: pointer;
  transition: background-color var(--motion-fast) var(--ease-fade);
}
.nav-menu:hover, .nav-menu:focus-visible { background: var(--sunk); color: var(--ink); }
.nav-menu svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.sidebar h1 .nav-label { font-size: var(--fs-lg); font-weight: var(--fw-bold); letter-spacing: -0.01em; }

/* The zoom switch in the calendar's own footer, bottom left, level with
   + New task on the right (Ed's call - the vertical pill beside the panel
   left an odd gap and needed a matching empty column to keep the panel
   centred). A horizontal pill now, same slate; the highlight still slides
   along it like a dial. With it gone from the side, the panel has the
   layout's whole width. */
.layout { grid-template-columns: minmax(0, 1fr); }
.layout > .calendar-panel { grid-column: 1; grid-row: 1; }
.calendar-footer .zoom {
  --seg: 76px;
  --pad: 4px;
  position: relative;
  display: flex;
  gap: 0;
  height: 46px;
  box-sizing: border-box;
  padding: var(--pad);
  border-radius: var(--r-pill);
  background: var(--feature-3);
  box-shadow: var(--shadow-bubble);
}
.calendar-footer .zoom::before {
  content: "";
  position: absolute;
  top: var(--pad);
  bottom: var(--pad);
  left: var(--pad);
  width: var(--seg);
  border-radius: var(--r-pill);
  background: var(--divider);
  transform: translateX(calc(var(--zoom-i, 1) * var(--seg)));
  transition: transform var(--spring-switch-ms) var(--spring-switch);
}
.calendar-footer .zoom .btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-1-5);
  width: var(--seg);
  height: 100%;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: none;
  color: var(--on-feature-2);
  font-weight: var(--fw-medium);
  transition: color var(--motion-fast) var(--ease-fade);
}
.calendar-footer .zoom .btn:hover:not(.active) { background: color-mix(in srgb, var(--surface) 8%, transparent); color: var(--on-feature); }
.calendar-footer .zoom .btn.active { background: none; color: var(--text-2); }
.calendar-footer .zoom .zoom-icon { width: 17px; height: 17px; }
.calendar-footer .zoom .zoom-label { font-size: var(--fs-sm); }
@media (prefers-reduced-motion: reduce) { .calendar-footer .zoom::before { transition: none; } }

/* Calendar is the main screen, so its sidebar entry reads as the first stop
   rather than one quiet entry among many (Ed's call). */
.sidebar .nav-entry[data-view="calendar"] { margin-bottom: var(--sp-1-5); font-size: var(--fs-body); font-weight: var(--fw-semi); color: var(--ink); }
.sidebar .nav-entry[data-view="calendar"] .nav-icon { stroke-width: 2; }

/* Night on Day's hour axis (Ed's call): a cool wash over the small hours and
   the evening, fading in and out over its edge hour, and a moon on each. */
.day-night {
  position: absolute;
  left: 0;
  right: 0;
  pointer-events: none;
  --night: rgb(52 64 110 / 0.09);
}
.day-night.evening { background: linear-gradient(to bottom, transparent 0, var(--night) 8%, var(--night)); }
.day-night.morning { background: linear-gradient(to top, transparent 0, var(--night) 12%, var(--night)); }
.day-moon {
  position: absolute;
  right: 8px;
  width: 13px;
  height: 13px;
  fill: rgb(70 84 140 / 0.35);
  stroke: none;
}
.day-night.evening .day-moon { top: 14%; }
.day-night.morning .day-moon { bottom: 20%; }


/* -- Visual audit, 30 Sept -- */
/* A dialog holding focus itself (see showModal in app.js) has no ring. */
dialog:focus-visible { outline: none; }
/* A linked entry's details each take their own line. */
/* Confirm dialogs dressed like the app's other dialogs. */
#confirm-dialog {
  border: 0;
  border-radius: var(--r-card);
  padding: var(--sp-4) var(--sp-5) var(--sp-3);
  box-shadow: var(--shadow-dialog);
}
#confirm-dialog::backdrop { background: rgb(0 0 0 / 0.3); }
#confirm-dialog p { font-size: var(--fs-base); line-height: 1.45; }
#confirm-dialog .actions { margin-top: var(--sp-4); gap: var(--sp-2); }
/* Linked calendars: the colour picker and Add aren't jammed together. */
.feeds-add-row { gap: var(--sp-3); }
.feeds-add-row label { flex-direction: row; align-items: center; gap: var(--sp-2); }
/* The task form's section headings carry their optional tag inline. */
.tf-divider .optional-tag { margin-left: var(--sp-1-5); text-transform: none; letter-spacing: 0; font-weight: var(--fw-regular); }
/* Check-in in the sidebar reads as one more entry - an icon in the rail's
   column, its label once open, its count on the icon's corner - not a
   bordered button of its own. */
.sidebar #footer-checkin.footer-checkin {
  display: flex;
  align-self: stretch;
  gap: var(--sp-3);
  height: auto;
  min-width: 0;
  margin: 0;
  padding: var(--sp-1-5) var(--sp-2-5);
  border: 0;
  border-radius: var(--r-input);
  background: none;
  box-shadow: none;
  color: inherit;
  font: inherit;
  text-align: left;
}
.sidebar #footer-checkin.footer-checkin:hover,
.sidebar #footer-checkin.footer-checkin:focus-visible { background: var(--divider); border-color: transparent; }
.sidebar .footer-checkin-icon { width: 20px; height: 20px; }
.sidebar .footer-checkin .footer-checkin-label {
  max-width: none;
  margin-left: 0;
  font-weight: var(--fw-regular);
  opacity: 0;
  transition: opacity var(--motion-fast) var(--ease-fade);
}
.sidebar.expanded .footer-checkin .footer-checkin-label { opacity: 1; transition: opacity var(--motion-fast) var(--ease-fade) var(--motion-settle); }
.sidebar .footer-checkin .checkin-badge { top: 1px; left: 22px; right: auto; }
/* The two menu buttons match: a plain icon, no box - the left one in the
   sidebar's header, the right one in the page's top-right margin. */
.aside-menu { border: 0; background: none; box-shadow: none; }
.aside-menu:hover, .aside-menu:focus-visible { background: var(--sunk); }
.aside-menu[aria-expanded="true"] { background: var(--sunk); color: var(--ink); }


/* -- Status look (Chunks 49-52) --
   One grammar for every calendar Event (calendar-status-design.md; app.js
   "Status look"): the status a large region on the left, the parent's colour
   a solid zone on the right, one divider between them at 38.7deg from
   vertical (0.8 across for every 1 down).

   A crop, not a redraw (Ed's call, after Chunks 49-52): every box draws the
   same fixed picture, centred in it, whatever its density - the divider
   through the box's middle the colour tip's width in from the right, at one
   stroke weight. A bar is that picture's middle band, a card more of it, so
   opening or closing a box only changes how much of it shows. What isn't
   the picture - text, icons, a card's fill, ring and rounding - fades or
   blends across the resize (see app.js frameOf).

   ::before is the status region and ::after the colour zone, both a canvas
   --canvas tall centred on the box, so the slant never depends on the box's
   own height. The gap between their slanted edges is the divider - the
   background showing through. Done moves the divider to the left, the grey
   zone mirroring the tip, and cuts the tick's short arm out of the grey at
   the middle; the tick's long arm is the divider itself. All measured in px
   around the middle: a stroke of 3.4 (2.177px either side of the line
   across), and a tick the size of a 10px bar's. */
body {
  --cal-pending: var(--faint);
  --cal-done: var(--done-fill);
}
.entry.cal-entry {
  --h: 10px;
  --canvas: max(var(--h), 64px);
  --tip: min(27%, 56px);
  --mid: calc(100% - var(--tip));
  --left: var(--cal-pending);
  --ring: inset 0 0 0 1px transparent;
  --lift: 0 0 0 0 transparent;
  position: relative;
  isolation: isolate;
  display: block;
  width: 100%;
  height: var(--h);
  margin: var(--sp-1) 0 0;
  padding: 0;
  border: 0;
  border-radius: var(--r-mini);
  background: transparent;
  box-shadow: var(--ring), var(--lift);
  color: var(--ink);
  overflow: hidden;
  white-space: nowrap;
  filter: none;
  container-type: inline-size;
  transition: opacity var(--motion-fast) var(--ease-fade);
}
/* A drag's source dims at once (motion.md M9); only other dims fade. */
.entry.cal-entry.drag-source { transition: none; }
@media (prefers-reduced-motion: reduce) { .entry.cal-entry { transition: none; } }
.entry.cal-entry:hover { background: transparent; filter: none; }
.entry.cal-entry.selected { outline: none; }
.entry.cal-entry::before,
.entry.cal-entry::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: var(--canvas);
  transform: translateY(-50%);
  z-index: -1;
  pointer-events: none;
}
.entry.cal-entry::before {
  background: var(--left);
  clip-path: polygon(0 0, calc(var(--mid) + var(--canvas) * 0.4 - 2.177px) 0, calc(var(--mid) - var(--canvas) * 0.4 - 2.177px) 100%, 0 100%);
}
.entry.cal-entry::after {
  background: var(--goal);
  clip-path: polygon(calc(var(--mid) + var(--canvas) * 0.4 + 2.177px) 0, 100% 0, 100% 100%, calc(var(--mid) - var(--canvas) * 0.4 + 2.177px) 100%);
}
.entry.cal-entry.state-done { --mid: var(--tip); --left: var(--cal-done); }
.entry.cal-entry.state-done::before {
  clip-path: polygon(0 0, calc(var(--mid) + var(--canvas) * 0.4 - 2.177px) 0,
    calc(var(--mid) - 4.426px) calc(50% + 2.812px), calc(var(--mid) - 8.184px) calc(50% - 1.167px),
    calc(var(--mid) - 10.656px) calc(50% + 1.167px), calc(var(--mid) - 6.571px) calc(50% + 5.49px),
    calc(var(--mid) - var(--canvas) * 0.4 - 2.177px) 100%, 0 100%);
}

/* Bar: Month's resting rows, Week's neighbours - the picture's middle 10px,
   no text or icons. */
.entry.cal-entry[data-density="bar"] > * { display: none; }

/* Strip: a class highlight's match, and a dragged bar's ghost - 16px of the
   same picture, a Pending one's title on the grey. */
.entry.cal-entry[data-density="strip"] { --h: 16px !important; }
.entry.cal-entry[data-density="strip"] > :not(.entry-text),
.entry.cal-entry[data-density="strip"] .entry-line,
.entry.cal-entry[data-density="strip"]:is(.missed, .state-done) .entry-text { display: none; }
.entry.cal-entry[data-density="strip"] .entry-text { position: absolute; inset: 0 calc(var(--tip) + 12px) 0 6px; }
.entry.cal-entry[data-density="strip"] .entry-title { font-size: var(--fs-2xs); line-height: 16px; color: var(--ink); }
.day-events > .entry.cal-entry[data-density="strip"] { position: absolute; margin: 0; height: 16px; }

/* Cards: Week's focused week (chip) and Day's Lanes - 46px (Done 40px) of
   the picture, on white, in a ring of the parent colour. A Lane is its
   duration, floored at those (app.js sets its --h). --tipw is the tip's
   width for the card's own content to lay out against. */
.entry.cal-entry:is([data-density="chip"], [data-density="lane"]) {
  --h: 46px;
  --tipw: min(27cqw, 56px);
  --ring: inset 0 0 0 1px var(--goal);
  border-radius: var(--r-block);
  background: var(--surface);
}
.entry.cal-entry.state-done:is([data-density="chip"], [data-density="lane"]) { --h: 40px; }
.cal-entry .entry-text { display: block; }
.cal-entry .entry-title {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-md);
  line-height: 17px;
  color: var(--ink);
}
.cal-entry .entry-line {
  display: flex;
  gap: var(--sp-1);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semi);
  line-height: 13px;
  color: var(--muted);
}
.cal-entry .entry-owner {
  min-width: 0;
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: inherit;
  color: inherit;
}
.cal-entry .entry-owner::before, .cal-entry .entry-icons::before { content: none; }
.cal-entry .entry-time { display: inline; flex: none; font-variant-numeric: tabular-nums; }
.cal-entry .entry-time::before { content: "· "; }
.cal-entry .entry-sub {
  display: block;
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: var(--fs-2xs);
  line-height: 14px;
  color: var(--on-soft);
}
/* The text spans the card, padded clear of the tip, and is centred on the
   box like the picture is - so while a card opens or closes, its text is
   cropped along with everything else as it fades. On a Missed card it also
   lays a white veil over the stipple's own shape, so the text reads - and
   fades with it, leaving the bar's stipple exactly as it is. */
.cal-entry:is([data-density="chip"], [data-density="lane"]) .entry-text {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: var(--h);
  transform: translateY(-50%);
  padding: var(--sp-1-5) calc(var(--tipw) + var(--sp-1-5)) 0 var(--sp-2-5);
}
.cal-entry.state-done:is([data-density="chip"], [data-density="lane"]) .entry-text { padding: var(--sp-1) var(--sp-2) 0 calc(var(--tipw) + var(--sp-3)); }
.cal-entry.state-done .entry-title { color: var(--on); }
/* The icon stack sits on the colour tip, in whichever ink reads on it. */
.cal-entry:is([data-density="chip"], [data-density="lane"]) .entry-icons {
  position: absolute;
  top: 50%;
  right: 7px;
  display: flex;
  flex-direction: column;
  gap: var(--sp-0-5);
  margin: 0;
  transform: translateY(-50%);
  color: var(--on);
}
.cal-entry .entry-icon svg { width: 11px; height: 11px; stroke-width: 1.2; }
/* Hovered, a card lifts on a soft shadow; selected from the keyboard, its
   ring thickens a pixel. The pointer's selection follows hover, so it shows
   only the shadow - the two never show at once. */
body:not(.kbd-select):not(.dragging) .entry.cal-entry:is([data-density="chip"], [data-density="lane"]):hover {
  z-index: 2;
  --lift: 0 3px 10px rgb(31 41 55 / 0.25);
}
body.kbd-select .entry.cal-entry.selected:is([data-density="chip"], [data-density="lane"]) { --ring: inset 0 0 0 2px var(--goal); }
body.kbd-select .entry.cal-entry.selected:is([data-density="bar"], [data-density="strip"]) { outline: var(--focus-width) solid var(--focus-color); outline-offset: var(--focus-offset); }
.entry.cal-entry.drag-ghost { position: fixed; margin: 0; }

/* Day's Lanes: placed on the hour axis by app.js (top, height, left, width). */
.entry.cal-entry[data-density="lane"] { position: absolute; margin: 0; }
.entry.cal-entry[data-density="lane"].time-dragging { z-index: 5; --lift: 0 2px 8px rgb(0 0 0 / 0.25); }

/* Month's open row (Chunk 51): a smaller, sparser card - 28px of the
   picture, the title and its completion icon alone. */
.month .entry.cal-entry[data-density="chip"],
.month .entry.cal-entry.state-done[data-density="chip"] { --h: 28px; }
.month .cal-entry[data-density="chip"] :is(.entry-line, .entry-sub) { display: none; }
.month .cal-entry[data-density="chip"] .entry-text,
.month .cal-entry.state-done[data-density="chip"] .entry-text { padding-top: var(--sp-1); }
.month .cal-entry[data-density="chip"] .entry-icon:not(.icon-boolean, .icon-quantitative, .icon-qualitative) { display: none; }

/* Past days: the grey cell, and everything on it faded - bars to about 40%,
   cards to about 50% (eased between, like the rest of a change of density).
   Day's own focused column never fades; its neighbours are blurred. */
#calendar-grid :is(.day, .month-day).past .entry.cal-entry:is([data-density="bar"], [data-density="strip"]) { opacity: 0.4; }
#calendar-grid :is(.day, .month-day).past .entry.cal-entry[data-density="chip"] { opacity: 0.5; }
.year-day.past .year-bars { opacity: 0.4; }

/* Class highlight: everything but the matches dims. */
#calendar-grid.class-highlighting :is(.entry.event, .flag, .year-bar, .year-more, .ext-event):not(.class-hit) { opacity: 0.35; }

/* Folded overflow (Chunks 50, 51): a Week day or an open Month row's day with
   more than fits fades out at the foot, with a count of what's below. */
.folded { mask-image: linear-gradient(to bottom, #000 calc(100% - 30px), transparent); }
.fold-more {
  flex: none;
  display: block;
  padding-top: var(--sp-1);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  line-height: 13px;
  color: var(--muted);
  text-align: center;
}
/* A highlight's strips scroll instead. */
.month-week .class-lane.folded { mask-image: none; }
.month-week .class-lane ~ .fold-more { display: none; }

/* Week (Chunk 50): Mon-Sun once across the top, every cell headed by its
   date number alone; Today's a dark edge, a dark number pill and its name in
   bold. */
.week-head {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--sp-2-5);
  padding: 0 0 var(--sp-1-5);
}
.week-head-day { padding-left: var(--sp-2); font-size: var(--fs-sm); font-weight: var(--fw-semi); letter-spacing: 0.02em; color: var(--muted); }
.week-head-day.today { color: var(--ink); font-weight: var(--fw-bold); }
.week-stack .day {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  padding: var(--sp-1-5) var(--sp-1-5);
}
.week-stack .day h3 { flex: none; margin: 0 0 var(--sp-0-5); font-size: var(--fs-sm); font-weight: var(--fw-medium); }
.week-date { display: inline-block; min-width: 22px; }
.week .day.today .week-date { padding: var(--sp-px) var(--sp-1-5); border-radius: var(--r-small); background: var(--today); color: var(--on-feature); font-weight: var(--fw-semi); text-align: center; }
.week-day-events { flex: 1 1 0; min-height: 0; overflow: hidden; }
.week.neighbour .muted { display: none; }

/* Month: Today marked as in Week - a dark top edge, the number pill and its
   name bold in the header row. */
.month-day.today { box-shadow: inset 0 3px 0 var(--today); }
.calendar-main .month-head.today { color: var(--ink); font-weight: var(--fw-bold); }

/* Year (Chunk 52): thin bars at the cell's foot, 4px high and 2px apart, the
   date top left, a target flag and the "+n" top right. Year never opens or
   closes, so its bars keep the grammar scaled to their own 4px: a stroke
   of 0.34 x the height and a tick to match. */
.year-bars {
  position: absolute;
  left: 4px;
  right: 4px;
  bottom: 3px;
  display: flex;
  flex-direction: column;
  gap: var(--sp-0-5);
}
.year-bar {
  --h: 4px;
  --g2: calc(var(--h) * 0.2177);
  --mid: calc(100% - 8px);
  --left: var(--cal-pending);
  position: relative;
  isolation: isolate;
  display: block;
  height: var(--h);
  border-radius: var(--r-mini);
  overflow: hidden;
}
.year-bar::before, .year-bar::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
.year-bar::before {
  background: var(--left);
  clip-path: polygon(0 0, calc(var(--mid) + var(--h) * 0.4 - var(--g2)) 0, calc(var(--mid) - var(--h) * 0.4 - var(--g2)) 100%, 0 100%);
}
.year-bar::after {
  background: var(--goal);
  clip-path: polygon(calc(var(--mid) + var(--h) * 0.4 + var(--g2)) 0, 100% 0, 100% 100%, calc(var(--mid) - var(--h) * 0.4 + var(--g2)) 100%);
}
.year-bar.missed { --left: var(--missed-stripes); }
.year-bar.state-done { --mid: 8px; --left: var(--cal-done); }
.year-bar.state-done::before {
  clip-path: polygon(0 0, calc(var(--mid) + var(--h) * 0.1823) 0, calc(var(--mid) - var(--h) * 0.4426) 78.12%,
    calc(var(--mid) - var(--h) * 0.8184) 38.33%, calc(var(--mid) - var(--h) * 1.0656) 61.67%,
    calc(var(--mid) - var(--h) * 0.7036) 100%, 0 100%);
}
.year-bar.state-done::after {
  clip-path: polygon(calc(var(--mid) + var(--h) * 0.6177) 0, 100% 0, 100% 100%, calc(var(--mid) - var(--h) * 0.1823) 100%);
}
.year-bar.year-ext { background: color-mix(in srgb, var(--ext) 45%, var(--surface)); }
.year-bar.year-ext::before, .year-bar.year-ext::after { content: none; }
.year-corner {
  position: absolute;
  top: 1px;
  right: 2px;
  display: flex;
  align-items: center;
  gap: var(--sp-px);
}
.year-more { font-size: var(--fs-2xs); font-weight: var(--fw-semi); line-height: 12px; color: var(--muted); }

/* ---- Chunk 53: drawer restyle + top bar with the global + New ----
   The mocks' visual language: warm off-white page, white cards, near-black
   accent, quiet uppercase section labels, a Goal or Routine as a slim colour
   stripe beside its name rather than a tinted tab. Mechanics unchanged. */
body { background: var(--page); color: var(--ink); }
.sidebar { background: var(--page); }
.sidebar::after { background: var(--faint); }
.sidebar.expanded { box-shadow: 4px 0 18px rgb(0 0 0 / 0.08), 1px 0 0 var(--faint); }
.sidebar h1 .nav-label { font-weight: var(--fw-bold); letter-spacing: -0.01em; }
.sidebar .nav-entry { border-radius: var(--r-input); }
.sidebar .nav-entry.active { background: var(--surface); box-shadow: var(--shadow-soft); }
.nav-goals h2 .nav-label { font-size: var(--fs-xs); font-weight: var(--fw-semi); letter-spacing: 0.08em; text-transform: uppercase; color: var(--faint-text); }
.sidebar.expanded .nav-goal { background: transparent; }
.sidebar.expanded .nav-goal:hover { background: rgb(0 0 0 / 0.04); }
.sidebar.expanded .nav-goal.active { background: var(--surface); box-shadow: var(--shadow-soft); }
.sidebar.expanded .nav-goal::before { top: 6px; bottom: 6px; left: 6px; width: 3px; border-radius: var(--r-dash); }

.topbar { display: flex; align-items: center; height: 60px; gap: var(--sp-3); }
.new-fan { position: relative; z-index: 45; }
.global-new {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  height: 40px; padding: 0 var(--sp-4) 0 var(--sp-3);
  border: 0; border-radius: var(--r-small);
  background: var(--primary-fill); color: var(--on-primary);
  font: inherit; font-size: var(--fs-body); font-weight: var(--fw-semi); cursor: pointer;
}
.global-new:hover, .global-new:focus-visible { background: var(--feature-2); }
.global-new-plus { font-size: var(--fs-heading); line-height: 1; font-weight: var(--fw-regular); }
.new-fan-menu {
  position: absolute; top: calc(100% + 8px); right: 0;
  display: flex; gap: var(--sp-1-5); padding: var(--sp-1-5);
  background: var(--surface); border: 1px solid var(--faint); border-radius: var(--r-card);
  box-shadow: var(--shadow-menu);
  animation: fan-in var(--motion-fast) var(--ease-enter);
}
.new-fan-menu button {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-1);
  width: 72px; padding: var(--sp-2-5) var(--sp-1) var(--sp-2);
  border: 0; border-radius: var(--r-input); background: transparent;
  font: inherit; font-size: var(--fs-sm); color: var(--ink); cursor: pointer;
}
.new-fan-menu button:hover, .new-fan-menu button:focus-visible { background: var(--page); }
.new-fan-menu svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
@keyframes fan-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .new-fan-menu { animation: none; } }
#goal-view > .panel, #routine-view > .panel, #completed-view > .panel, #checkin-view > .panel, #history-view > .panel, #collection-view > .panel { margin-top: 0; }
.topbar > .spacer { flex: 1; }
.topbar { padding-right: var(--sp-10); }


/* ---- Chunk 55: the shown day's note in Day view's header ---- */
.toolbar .day-note {
  flex: 1 1 auto; min-width: 0; margin: 0 var(--sp-4);
  padding: var(--sp-1) var(--sp-2-5); border-left: 3px solid var(--ink); border-radius: var(--r-dash);
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  color: var(--text-2); font-size: var(--fs-md);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ---- Chunk 56: Week review ---- */
.topbar-review {
  position: relative; height: 40px; padding: 0 var(--sp-3);
  border: 1px solid var(--line); border-radius: var(--r-small); background: var(--surface);
  font: inherit; font-size: var(--fs-base); font-weight: var(--fw-medium); color: var(--ink); cursor: pointer;
}
.topbar-review:hover { background: var(--page); }
.topbar-badge {
  position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px; padding: 0 var(--sp-1);
  border-radius: var(--r-input); background: var(--badge-fill); color: var(--on-badge);
  font-size: var(--fs-xs); font-weight: var(--fw-semi); line-height: 18px; text-align: center;
}
.ck-week { display: flex; align-items: baseline; gap: var(--sp-2); margin-bottom: var(--sp-2-5); font-weight: var(--fw-semi); font-size: var(--fs-body); }
.ck-week-closed { font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--muted); }
.ck-slipped h3 { display: flex; justify-content: space-between; align-items: baseline; }
.ck-count { font-size: var(--fs-sm); font-weight: var(--fw-regular); }
.ck-slip { margin: var(--sp-2) 0 var(--sp-3); }
.ck-slip-head {
  display: flex; justify-content: space-between; gap: var(--sp-2); align-items: center;
  padding: var(--sp-2) var(--sp-2-5); border-left: 4px solid var(--goal, var(--faint-text)); border-radius: var(--r-mini);
}
.ck-slip-missed { color: var(--missed-ink); font-size: var(--fs-sm); white-space: nowrap; }
.ck-slip-actions { display: flex; flex-wrap: wrap; gap: var(--sp-1-5); margin-top: var(--sp-1-5); }
.ck-slip-actions .btn { font-size: var(--fs-sm); }
.ck-slip-result { font-size: var(--fs-md); color: var(--text-2); }
.ck-slip.handled .ck-slip-head { background: var(--divider); }
.ck-shortfalls { font-size: var(--fs-sm); margin: var(--sp-2-5) 0 0; }
.ck-note { margin: var(--sp-1-5) 0; }
.ck-note-day { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--muted); }
.ck-note p { margin: var(--sp-0-5) 0 0; white-space: pre-wrap; }
.ck-close { display: flex; align-items: center; gap: var(--sp-2-5); margin: var(--sp-4) 0 var(--sp-2); }
.ck-close #close-week { width: 100%; height: 40px; }

/* ---- Chunk 71: Today ---- */
.view-switch { display: flex; gap: var(--sp-0-5); padding: var(--sp-1); border-radius: var(--r-card); background: var(--faint); }
.view-switch button {
  height: 34px; padding: 0 var(--sp-4); border: 0; border-radius: var(--r-input); background: transparent;
  font: inherit; font-size: var(--fs-body); font-weight: var(--fw-medium); color: var(--muted); cursor: pointer;
}
.view-switch button.active { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-soft); }
.topbar > .spacer:first-child { flex: 1; }

.today-page { max-width: 1240px; margin: 0 auto; padding: var(--sp-4) var(--sp-6) var(--sp-10); }
.today-head { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--sp-6); margin-bottom: var(--sp-6); }
.today-greeting { margin: 0; font-size: var(--fs-lg); color: var(--text-2); }
.today-date { margin: var(--sp-0-5) 0 0; font-size: var(--fs-display); line-height: 1; font-weight: var(--fw-heavy); letter-spacing: -0.04em; color: var(--ink); }
.today-progress { min-width: 220px; text-align: right; }
.today-progress p { margin: 0 0 var(--sp-2); font-size: var(--fs-body); color: var(--text-2); font-variant-numeric: tabular-nums; }
.today-progress strong { color: var(--ink); }
.today-bar { height: 4px; border-radius: var(--r-dash); background: var(--faint); overflow: hidden; }
.today-bar span { display: block; height: 100%; background: var(--ink); }
.today-grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: var(--sp-5); align-items: start; }
.today-card { background: var(--surface); border-radius: var(--r-popover); padding: var(--sp-5) var(--sp-6); box-shadow: 0 1px 2px rgb(0 0 0 / 0.04); }
.today-card h2 { margin: 0 0 var(--sp-3); font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--ink); }
.today-timeline { display: flex; flex-direction: column; gap: var(--sp-2); }
.today-slot { display: grid; grid-template-columns: 52px minmax(0, 1fr); align-items: center; gap: var(--sp-3); }
.today-time { font-size: var(--fs-base); color: var(--muted); font-variant-numeric: tabular-nums; }
.today-entry.cal-entry { width: 100%; min-height: 64px; font-size: var(--fs-body); }
.today-entry.cal-entry .entry-title { font-size: var(--fs-lg); }
.today-entry.selected { outline: 2px solid var(--ink); outline-offset: 2px; }
.today-now { display: grid; grid-template-columns: 52px auto minmax(0, 1fr); align-items: center; gap: var(--sp-3); margin: var(--sp-0-5) 0; }
.today-now .today-time { color: var(--ink); font-weight: var(--fw-semi); }
.today-now-label { font-size: var(--fs-sm); font-weight: var(--fw-bold); letter-spacing: 0.1em; }
.today-now-rule { height: 2px; background: var(--ink); }
.today-side { display: flex; flex-direction: column; gap: var(--sp-4); }
.today-next { background: var(--feature); color: var(--on-feature); }
.today-next h2 { color: var(--on-feature); margin: 0; }
.today-next-head { display: flex; justify-content: space-between; align-items: baseline; padding-bottom: var(--sp-2-5); border-bottom: 1px solid var(--ink); }
.today-next-head span { font-size: var(--fs-md); color: var(--faint-text); }
.today-next-row { display: grid; grid-template-columns: 52px 1fr auto; gap: var(--sp-2); padding: var(--sp-3) 0; border-bottom: 1px solid var(--ink); font-size: var(--fs-body); font-variant-numeric: tabular-nums; }
.today-next-row:last-child { border-bottom: 0; }
.today-next-time, .today-next-dur { font-weight: var(--fw-semi); }
.today-next-none { margin: var(--sp-3) 0 0; color: var(--faint-text); }
.today-note { width: 100%; padding: var(--sp-3) var(--sp-3); border: 1px solid var(--line); border-radius: var(--r-small); background: var(--page); font: inherit; font-size: var(--fs-body); resize: vertical; }
.today-note-status { margin: var(--sp-2) 0 0; font-size: var(--fs-sm); min-height: 1em; }
.today-review { display: flex; align-items: center; gap: var(--sp-3); width: 100%; border: 1px solid var(--line); font: inherit; font-size: var(--fs-body); text-align: left; cursor: pointer; padding: var(--sp-4) var(--sp-5); }
.today-review:hover { background: var(--page); }
.today-review-arrow { margin-left: auto; font-size: var(--fs-lg); }
@media (max-width: 1100px) {
  .today-grid { grid-template-columns: 1fr; }
}

/* ---- Chunk 58: calendar-grid card rework ----
   Every calendar-grid card (Bar, Strip, Chip, Lane, Month's half-open card,
   the drag ghost and the highlight's strips) is a plain rounded block with a
   left stripe in the parent's colour: Pending a light fill, Done a darker
   flat grey with a muted title, Missed pale orange with a fine diagonal
   stripe. No slanted divider, tip, cut-out tick or completion line. Today's
   own card (.today-entry) is a separate component and keeps the old look -
   every rule here excludes it. */
body {
  --grid-pending: var(--block);
  --grid-done: var(--done-fill);
}
.entry.cal-entry:not(.today-entry) {
  --ring: inset 0 0 0 1px transparent;
  background: var(--grid-pending);
  border-radius: var(--r-mini);
}
.entry.cal-entry:not(.today-entry):hover { background: var(--grid-pending); }
.entry.cal-entry:not(.today-entry).state-done,
.entry.cal-entry:not(.today-entry).state-done:hover { background: var(--grid-done); }
.entry.cal-entry:not(.today-entry)::before,
.entry.cal-entry:not(.today-entry).state-done::before {
  top: 0; bottom: 0; height: auto; transform: none;
  width: 4px; right: auto;
  background: var(--goal);
  clip-path: none;
}
.entry.cal-entry:not(.today-entry)::after { content: none; }
.entry.cal-entry:not(.today-entry):is([data-density="chip"], [data-density="lane"]) {
  --ring: inset 0 0 0 1px transparent;
  border-radius: var(--r-block);
  background: var(--grid-pending);
}
.entry.cal-entry:not(.today-entry).state-done:is([data-density="chip"], [data-density="lane"]) { --h: 46px; background: var(--grid-done); }
/* Text: subtitle over title, padded clear of the stripe; no icons, owner
   line or completion line on the grid. */
.cal-entry:not(.today-entry) :is(.entry-line, .entry-icons, .entry-sub) { display: none !important; }
.cal-entry .grid-sub { display: none; }
.cal-entry:not(.today-entry):is([data-density="chip"], [data-density="lane"]) .grid-sub:not(:empty) {
  display: block;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--fs-xs); line-height: 14px; color: var(--muted); font-variant-numeric: tabular-nums;
}
.cal-entry:not(.today-entry):is([data-density="chip"], [data-density="lane"]) .entry-text,
.cal-entry:not(.today-entry).state-done:is([data-density="chip"], [data-density="lane"]) .entry-text {
  padding: var(--sp-1-5) var(--sp-2) 0 var(--sp-3);
  background: none;
  clip-path: none;
}
.cal-entry:not(.today-entry) .entry-title { color: var(--ink); }
.cal-entry:not(.today-entry).state-done .entry-title { color: var(--muted); }
.entry.cal-entry:not(.today-entry)[data-density="strip"] .entry-text { inset: 0 6px 0 10px; }
.entry.cal-entry:not(.today-entry)[data-density="strip"]:is(.missed, .state-done) .entry-text { display: none; }
body.kbd-select .entry.cal-entry:not(.today-entry).selected:is([data-density="chip"], [data-density="lane"]) {
  --ring: inset 0 0 0 2px var(--ink);
}
/* Month's half-open card: title only, as before. */
.month .cal-entry:not(.today-entry)[data-density="chip"] .grid-sub { display: none !important; }
.month .cal-entry:not(.today-entry)[data-density="chip"] .entry-text { padding: var(--sp-1) var(--sp-2) 0 var(--sp-2-5); }
/* Overlapping Day lanes keep an edge in the card's own colour so one doesn't
   run into the next (Chunk 84: was #fff, a white ring in dark). */
.entry.cal-entry:not(.today-entry)[data-density="lane"] { --ring: 0 0 0 1.5px var(--surface); }

/* ---- Chunk 59: Year heatmap + Goals across the year ---- */
#calendar-grid.year { display: flex; flex-direction: column; gap: var(--sp-4); overflow-y: auto; grid-template-columns: none; }
.year-heat-card, .year-goals { background: var(--surface); border-radius: var(--r-popover); padding: var(--sp-4) var(--sp-5); }
.year-legend { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--sp-1-5) var(--sp-4); margin-bottom: var(--sp-2-5); font-size: var(--fs-md); color: var(--text-2); }
.year-key { display: inline-flex; align-items: center; gap: var(--sp-1-5); }
.year-key i { width: 11px; height: 11px; border-radius: var(--r-mini); display: inline-block; }
.year-key .key-miss { background: var(--missed-b); }
.year-key .key-ahead { background: var(--surface); box-shadow: inset 0 0 0 1px var(--line); }
.year-heat-wrap { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: var(--sp-1) var(--sp-2); }
.year-heat-months, .year-heat { display: grid; grid-template-columns: repeat(var(--weeks), minmax(0, 1fr)); gap: var(--sp-0-5); }
.year-heat-months span { font-size: var(--fs-sm); color: var(--text-2); white-space: nowrap; }
.year-heat { grid-template-rows: repeat(7, auto); }
.year-heat-days { display: grid; grid-template-rows: repeat(7, 1fr); gap: var(--sp-0-5); font-size: var(--fs-2xs); color: var(--faint-text); align-items: center; }
.year-cell { aspect-ratio: 1; border-radius: var(--r-mini); background: var(--track); cursor: pointer; position: relative; }
.year-cell.has-done { background: var(--cell); }
.year-cell.ahead { background: var(--surface); box-shadow: inset 0 0 0 1px var(--line); }
.year-cell.outside { background: transparent; cursor: default; }
.year-cell.today-cell { box-shadow: 0 0 0 2px var(--ink); z-index: 1; }
.year-cell.has-target::after { content: ""; position: absolute; top: 1px; right: 1px; width: 0; height: 0; border-top: 5px solid var(--ink); border-left: 5px solid transparent; }
.year-cell:hover { outline: 1px solid var(--ink); }
#calendar-grid.class-highlighting .year-cell:not(.class-hit):not(.ahead):not(.outside) { opacity: 0.25; }
.year-goals h3 { margin: 0 0 var(--sp-3); font-size: var(--fs-lg); }
.year-goal-rows { position: relative; display: flex; flex-direction: column; gap: var(--sp-2-5); }
.year-goal-row {
  display: grid; grid-template-columns: 200px minmax(0, 1fr); align-items: center; gap: var(--sp-4);
  padding: var(--sp-1-5) 0 var(--sp-4); border: 0; background: transparent; font: inherit; text-align: left; cursor: pointer;
}
.year-goal-name { display: flex; flex-direction: column; min-width: 0; }
.year-goal-name strong { font-weight: var(--fw-medium); font-size: var(--fs-body); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.year-goal-name .muted { font-size: var(--fs-sm); }
.year-track { position: relative; height: 14px; }
.year-track::before { content: ""; position: absolute; left: 0; right: 0; top: 6px; height: 2px; background: var(--sunk); }
.year-solid { position: absolute; top: 4px; height: 6px; border-radius: var(--r-mini); background: var(--goal); }
.year-ahead { position: absolute; top: 4px; height: 6px; background: repeating-linear-gradient(90deg, var(--goal) 0 5px, transparent 5px 9px); }
.year-node { position: absolute; top: 0; width: 14px; height: 14px; margin-left: -7px; /* exact: centres the 14px node, geometry not spacing */ border-radius: 50%; box-sizing: border-box; }
.year-node.done { background: var(--ink); }
.year-node.ahead { background: repeating-linear-gradient(135deg, var(--goal) 0 2px, #fff 2px 4px); border: 2px solid var(--ink); }
.year-node-label { position: absolute; top: 17px; transform: translateX(-50%); font-size: var(--fs-xs); color: var(--text-2); white-space: nowrap; }
.year-goal-target { position: absolute; top: -4px; margin-left: calc(-1 * var(--sp-1)); font-size: var(--fs-sm); color: var(--goal); }
.year-now-line { position: absolute; top: 0; bottom: 0; left: calc(216px + (100% - 216px) * var(--now) / 100); width: 2px; background: var(--ink); pointer-events: none; }
.year-goals-note { font-size: var(--fs-sm); margin: var(--sp-2-5) 0 0; }

/* ---- Chunk 71: no drawer - Settings, Goals & Routines, Place in the top bar ---- */
body { --rail: 0px; --panel-w: 300px; }
.content, body.s-cal.s-sidebar .content { margin-left: 0; }
.topbar { padding-right: 0; }
.aside-menu, .edge-tabs, .nav-menu { display: none !important; }
.brand { display: inline-flex; align-items: center; gap: var(--sp-2-5); font-size: var(--fs-lg); font-weight: var(--fw-bold); letter-spacing: -0.02em; color: var(--ink); white-space: nowrap; }
.brand svg { width: 28px; height: 28px; fill: var(--ink); stroke: var(--on-feature); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.topbar > .brand + .spacer { flex: 1; }
.topbar-panel[aria-expanded="true"] { background: var(--primary-fill); border-color: var(--primary-fill); color: var(--on-primary); }
.topbar-panel[aria-expanded="true"]:hover { background: var(--feature-2); }
.topbar-icon { width: 40px; padding: 0; display: inline-flex; align-items: center; justify-content: center; }
.topbar-icon svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
.topbar-count { background: var(--muted); }

/* Goals & Routines: the old drawer's content, in from the right like To place. */
.sidebar {
  left: auto; right: 0; z-index: 41;
  width: var(--panel-w);
  padding: var(--sp-4) var(--sp-3);
  border-right: 0; border-left: 1px solid var(--line);
  clip-path: none; box-shadow: none;
  transform: translateX(100%); visibility: hidden;
  transition: transform var(--sidebar-ms) var(--sidebar-ease), visibility 0s linear var(--sidebar-ms);
}
.sidebar.expanded { box-shadow: none; }
.sidebar::after { display: none; }
body.nav-open .sidebar { transform: none; visibility: visible; transition: transform var(--sidebar-ms) var(--sidebar-ease), visibility 0s; }
body.nav-open .content { margin-right: var(--panel-w); }
.nav-panel-head { display: flex; align-items: center; justify-content: space-between; padding: 0 var(--sp-1) var(--sp-2-5) var(--sp-2); }
.nav-panel-head h2 { margin: 0; font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--ink); }
.sidebar [data-view="completed"] { margin-top: auto; }
@media (prefers-reduced-motion: reduce) { .sidebar { transition: none; } }

/* To place: nothing at rest any more - Place opens it. */
body.s-cal:not(.cal-aside-open):not(.cal-composing) #calendar-aside { visibility: hidden; }
#calendar-aside { width: var(--panel-w); }
body.s-cal.cal-composing #calendar-aside { width: var(--aside-open); }

/* ---- Chunk 63: Settings popover ---- */
.settings-wrap { position: relative; z-index: 46; }
.settings-pop {
  position: absolute; top: calc(100% + 8px); right: 0;
  width: 380px; max-height: calc(100vh - 90px); overflow-y: auto;
  padding: var(--sp-4) var(--sp-5) var(--sp-5);
  background: var(--surface); border: 1px solid var(--faint); border-radius: var(--r-popover);
  box-shadow: var(--shadow-menu);
  animation: fan-in var(--motion-fast) var(--ease-enter);
}
.settings-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-1); }
.settings-head h2 { margin: 0; font-size: var(--fs-heading); font-weight: var(--fw-bold); color: var(--ink); }
.settings-close { width: 32px; height: 32px; border: 0; border-radius: var(--r-input); background: transparent; font-size: var(--fs-heading); line-height: 1; color: var(--text-2); cursor: pointer; }
.settings-close:hover { background: var(--page); }
.settings-pop > h3, .settings-plan > h3 { margin: var(--sp-4) 0 var(--sp-2); font-size: var(--fs-xs); font-weight: var(--fw-semi); letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.theme-seg { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-0-5); padding: var(--sp-1); border-radius: var(--r-card); background: var(--divider); }
.theme-seg button { height: 36px; border: 0; border-radius: var(--r-input); background: transparent; font: inherit; font-size: var(--fs-base); font-weight: var(--fw-medium); color: var(--text-2); cursor: pointer; }
.theme-seg button[aria-pressed="true"] { background: var(--surface); color: var(--ink); font-weight: var(--fw-semi); box-shadow: var(--shadow-soft); }
.settings-note { margin: var(--sp-2) 0 0; font-size: var(--fs-sm); color: var(--muted); }
.settings-pop .feeds-list { margin: 0 0 var(--sp-2-5); }
.settings-pop .feed-row { flex-wrap: wrap; padding: var(--sp-2) var(--sp-2-5); }
.settings-pop .feed-main { flex: 1 1 140px; }
.settings-link { border: 1px solid var(--line); border-radius: var(--r-small); padding: var(--sp-1-5) var(--sp-3); font-weight: var(--fw-medium); }
.settings-pop .feeds-add { margin-top: var(--sp-3); }

/* ---- Chunks 61 and 64: Month's cards, Week's bar ---- */
.calendar-main { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; }
.calendar-main > * { grid-column: 1; }
.calendar-main > .cal-side {
  grid-column: 2; grid-row: 1 / span 3; align-self: stretch;
  width: 300px; margin-left: var(--sp-4); contain: size; overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--sp-3);
}
.side-card, .year-sofar { background: var(--surface); border-radius: var(--r-popover); padding: var(--sp-4) var(--sp-4); }
.side-card h3, .year-sofar h3 { display: flex; justify-content: space-between; align-items: baseline; margin: 0 0 var(--sp-2-5); font-size: var(--fs-body); font-weight: var(--fw-bold); color: var(--ink); }
.sofar-big { display: flex; align-items: baseline; gap: var(--sp-1-5); margin: 0 0 var(--sp-2-5); color: var(--text-2); font-size: var(--fs-base); }
.sofar-big strong { font-size: var(--fs-title); line-height: 1; font-weight: var(--fw-bold); letter-spacing: -0.03em; color: var(--ink); }
.sofar-bar { height: 6px; border-radius: var(--r-mini); background: var(--faint); overflow: hidden; }
.sofar-bar span { display: block; height: 100%; background: var(--ink); }
.time-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-0-5) var(--sp-2); margin-bottom: var(--sp-2-5); font-size: var(--fs-md); color: var(--ink); }
.time-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.time-track { grid-column: 1 / -1; height: 5px; border-radius: var(--r-mini); background: var(--sunk); overflow: hidden; }
.time-track span { display: block; height: 100%; background: var(--goal); border-radius: var(--r-mini); }

.week-going { margin-top: var(--sp-2-5); padding: var(--sp-3) var(--sp-4); background: var(--surface); border-radius: var(--r-popover); }
.going-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: var(--sp-2-5); }
.going-head h3 { margin: 0; font-size: var(--fs-body); font-weight: var(--fw-bold); color: var(--ink); }
.going-head .muted { font-size: var(--fs-md); }
.going-bar { display: flex; gap: var(--sp-0-5); height: 12px; border-radius: var(--r-mini); overflow: hidden; }
.going-bar span { background: var(--goal); min-width: 2px; }
.going-legend { display: flex; flex-wrap: wrap; gap: var(--sp-1-5) var(--sp-5); margin-top: var(--sp-2-5); font-size: var(--fs-md); color: var(--text-2); }
.going-key { display: inline-flex; align-items: center; gap: var(--sp-1-5); }
.going-key i { width: 10px; height: 10px; border-radius: var(--r-dash); background: var(--goal); }
.going-key strong { color: var(--ink); }

/* ---- Chunk 62: The year so far ---- */
.year-lower { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-4); align-items: start; }
.year-lower > .year-goals { min-width: 0; }
.year-sofar { width: 320px; background: var(--feature); color: var(--on-feature); padding: var(--sp-4) var(--sp-5); }
.year-sofar h3 { font-size: var(--fs-xs); font-weight: var(--fw-semi); letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint-text); }
.year-sofar .sofar-big { color: var(--on-feature-2); }
.year-sofar .sofar-big strong { font-size: var(--fs-3xl); color: var(--on-feature); }
.year-sofar .time-row { color: var(--on-feature); }
.year-sofar .time-track { background: var(--feature-2); }
#calendar-aside #unscheduled > h2 { display: flex; align-items: center; justify-content: space-between; }
#calendar-aside .aside-close { display: inline-block; font-size: var(--fs-md); font-weight: var(--fw-regular); }

/* ---- Calendar to the mocks (02-05): no grey panel, tabs on top, big headings ---- */
.calendar-panel {
  background: transparent; border: 0; box-shadow: none; border-radius: 0;
  padding: 0; column-gap: 0;
}
.layout.s-cal { max-width: none; padding-top: 0; }
.calendar-footer { display: none !important; }
.zoom-row { grid-column: 1 / -1; padding: var(--sp-2-5) 0 var(--sp-1-5); }
.zoom-row .zoom { display: flex; gap: var(--sp-1); height: auto; padding: 0; background: none; box-shadow: none; border-radius: 0; }
.zoom-row .zoom::before { display: none; }
.zoom-row .zoom button {
  height: 40px; padding: 0 var(--sp-4); border: 0; border-radius: var(--r-small); background: transparent;
  font: inherit; font-size: var(--fs-body); font-weight: var(--fw-medium); color: var(--muted); cursor: pointer;
}
.zoom-row .zoom button:hover { color: var(--ink); }
.zoom-row .zoom button.active { background: var(--surface); color: var(--ink); font-weight: var(--fw-semi); box-shadow: var(--shadow-soft); }
.zoom-row .zoom-icon { display: none; }
.zoom-row .zoom-label { max-width: none; opacity: 1; margin: 0; color: inherit; }

.calendar-panel > .toolbar { display: flex; align-items: flex-end; padding: var(--sp-2) 0 var(--sp-3); }
#range-label { display: flex; flex-direction: column; gap: var(--sp-1); }
.range-kicker { font-size: var(--fs-body); font-weight: var(--fw-medium); color: var(--text-2); letter-spacing: 0; }
.range-kicker:empty { display: none; }
.range-big { font-size: var(--fs-3xl); line-height: 1; font-weight: var(--fw-heavy); letter-spacing: -0.045em; color: var(--ink); }
.calendar-controls { display: flex; align-items: center; gap: var(--sp-2); margin-left: auto; }
.calendar-controls .range-paging { display: contents; }
#prev-range { order: 1; } #today { order: 2; } #next-range { order: 3; }
.calendar-controls :is(#today, .page-arrow) {
  height: 44px; min-width: 44px; padding: 0 var(--sp-4); border: 1px solid var(--line); border-radius: var(--r-small);
  background: var(--surface); color: var(--ink); font: inherit; font-size: var(--fs-body); font-weight: var(--fw-semi); box-shadow: none; cursor: pointer;
}
.calendar-controls .page-arrow { padding: 0; font-size: var(--fs-heading); font-weight: var(--fw-regular); }
.calendar-controls :is(#today, .page-arrow):hover { background: var(--page); }
.calendar-panel[data-zoom="day"] :is(#today, .range-paging) { display: none; }

/* Day: the week strip */
.day-strip { display: flex; gap: var(--sp-2); }
.strip-day {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-0-5);
  width: 52px; padding: var(--sp-2) 0 var(--sp-1-5); border: 0; border-radius: var(--r-small); background: var(--surface);
  font: inherit; color: var(--ink); cursor: pointer;
}
.strip-day:hover { background: var(--page); }
.strip-name { font-size: var(--fs-xs); color: var(--muted); }
.strip-date { font-size: var(--fs-lg); font-weight: var(--fw-bold); line-height: 1.1; }
.strip-bar { width: 26px; height: 3px; margin-top: var(--sp-0-5); border-radius: var(--r-dash); background: var(--faint); overflow: hidden; }
.strip-bar > span { display: block; height: 100%; background: var(--ink); }
.strip-day.current { background: var(--feature); color: var(--on-feature); }
.strip-day.current .strip-name { color: var(--on-feature-2); }
.strip-day.current .strip-bar { background: var(--feature-3); }
.strip-day.current .strip-bar > span { background: var(--surface); }

/* Day: one white timeline card */
#calendar-grid.day-stack { display: block; }
#calendar-grid.day-stack > .day-view { background: var(--surface); border: 0; border-radius: var(--r-popover); --pane-bg: var(--surface); box-shadow: none; }
#calendar-grid.day-stack .day-night, #calendar-grid.day-stack .day-view-head { display: none; }
#calendar-grid.day-stack .day-pane .hour { left: 64px; border-top-color: var(--divider); }
#calendar-grid.day-stack .day-pane .hour.minor { left: 64px; border-top-color: var(--divider); }
#calendar-grid.day-stack .day-pane .hour span { left: -54px; top: -9px; font-size: var(--fs-sm); color: var(--muted); background: none; font-variant-numeric: tabular-nums; }
#calendar-grid.day-stack .day-pane .hour:first-child span { top: -9px; }
#calendar-grid.day-stack .day-events { left: 74px; right: 18px; }
#calendar-grid.day-stack .entry.cal-entry[data-density="lane"]::before { width: 6px; }
#calendar-grid.day-stack .cal-entry[data-density="lane"] .entry-text,
#calendar-grid.day-stack .cal-entry.state-done[data-density="lane"] .entry-text {
  display: flex; align-items: baseline; gap: var(--sp-3); padding: var(--sp-2-5) var(--sp-3) 0 var(--sp-5);
}
#calendar-grid.day-stack .cal-entry[data-density="lane"] .entry-title { order: 0; font-size: var(--fs-body); font-weight: var(--fw-medium); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#calendar-grid.day-stack .cal-entry[data-density="lane"] .grid-sub:not(:empty) { order: 1; font-size: var(--fs-md); line-height: 18px; flex: 0 0 auto; }
#calendar-grid.day-stack .cal-entry.state-done[data-density="lane"] .entry-title { color: var(--ink); }
#calendar-grid .day-view.past .entry.cal-entry { opacity: 1; }
.day-now { position: absolute; left: 58px; right: 0; height: 2px; margin-top: calc(-1 * var(--sp-px)); background: var(--ink); z-index: 4; pointer-events: none; }
.day-now::before { content: ""; position: absolute; left: -4px; top: -4px; width: 10px; height: 10px; border-radius: 50%; background: var(--ink); }
.day-now-time { position: absolute; left: -56px; top: -9px; font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--ink); background: var(--surface); padding: 0 var(--sp-0-5); font-variant-numeric: tabular-nums; }

/* Day: the right column */
.day-next { display: flex; flex-direction: column; gap: var(--sp-1-5); width: 100%; padding: var(--sp-4) var(--sp-5); border: 0; background: var(--feature); color: var(--on-feature); text-align: left; font: inherit; cursor: pointer; }
.day-next-kicker { font-size: var(--fs-xs); font-weight: var(--fw-semi); letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint-text); }
.day-next-title { font-size: var(--fs-xl); font-weight: var(--fw-bold); letter-spacing: -0.03em; line-height: 1.1; }
.day-next-sub { font-size: var(--fs-md); color: var(--on-feature-2); }
.day-sum .going-bar { margin: var(--sp-1) 0 var(--sp-3); height: 8px; }
.day-sum-row { display: flex; justify-content: space-between; gap: var(--sp-2); padding: var(--sp-1) 0 var(--sp-1) var(--sp-2-5); border-left: 3px solid var(--goal); margin-bottom: var(--sp-1); font-size: var(--fs-base); color: var(--ink); }
.day-sum .sofar-big strong { font-size: var(--fs-title); }

/* Week: one week, a card per day - name left, date right, done at the foot */
#calendar-grid.week-stack > .week.focused { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--sp-3); }
#calendar-grid.week-stack .day {
  display: flex; flex-direction: column; min-height: 0;
  padding: var(--sp-3) var(--sp-3) var(--sp-3); border: 0; border-radius: var(--r-popover); background: var(--surface); box-shadow: none;
}
#calendar-grid.week-stack .day.past { background: var(--track); }
#calendar-grid.week-stack .day.today { background: var(--feature); box-shadow: none; }
#calendar-grid.week-stack .day h3 { display: flex; justify-content: space-between; align-items: baseline; margin: 0 0 var(--sp-2-5); }
.week-dayname { font-size: var(--fs-body); font-weight: var(--fw-medium); color: var(--text-2); }
#calendar-grid.week-stack .week-date { font-size: var(--fs-2xl); font-weight: var(--fw-bold); letter-spacing: -0.03em; color: var(--ink); background: none; padding: 0; min-width: 0; height: auto; }
#calendar-grid.week-stack .day.today .week-dayname { color: var(--on-feature-2); }
#calendar-grid.week-stack .day.today .week-date { color: var(--on-feature); }
#calendar-grid.week-stack .week-day-events { flex: 1 1 auto; min-height: 0; }
#calendar-grid.week-stack .day.past .entry.cal-entry { opacity: 1; }
#calendar-grid.week-stack .day.today .entry.cal-entry:not(.missed) { background: var(--feature-2); }
#calendar-grid.week-stack .day.today .entry.cal-entry.state-done { background: var(--feature-3); }
#calendar-grid.week-stack .day.today .cal-entry .entry-title { color: var(--on-feature); }
#calendar-grid.week-stack .day.today .cal-entry .grid-sub { color: var(--on-feature-2); }
#calendar-grid.week-stack .day.today .muted, #calendar-grid.week-stack .day.today .fold-more { color: var(--faint-text); }
#calendar-grid.week-stack .cal-entry[data-density="chip"] .entry-title { font-size: var(--fs-base); }
#calendar-grid.week-stack .cal-entry[data-density="chip"] .grid-sub:not(:empty) { font-size: var(--fs-sm); }
.week-day-foot { display: flex; flex-direction: column; gap: var(--sp-2); padding-top: var(--sp-2-5); font-size: var(--fs-md); color: var(--text-2); }
.week-day-bar { height: 4px; border-radius: var(--r-dash); background: var(--faint); overflow: hidden; }
.week-day-bar > span { display: block; height: 100%; background: var(--ink); }
#calendar-grid.week-stack .day.today .week-day-foot { color: var(--on-feature-2); }
#calendar-grid.week-stack .day.today .week-day-bar { background: var(--feature-2); }
#calendar-grid.week-stack .day.today .week-day-bar > span { background: var(--surface); }
.week-going { margin-top: var(--sp-3); padding: var(--sp-4) var(--sp-5); border-radius: var(--r-popover); }

/* Month: white days ahead, shaded days behind, today dark, the month either side faded */
#calendar-grid .month-day { background: var(--surface); border: 0; border-radius: var(--r-card); padding: var(--sp-2) var(--sp-2-5); box-shadow: none; }
#calendar-grid .month-day.past { background: var(--track); }
#calendar-grid .month-day.today { background: var(--feature); box-shadow: none; }
#calendar-grid .month-day .month-h { font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--ink); margin: 0 0 var(--sp-1-5); }
#calendar-grid .month-day.past .month-h { color: var(--text-2); }
#calendar-grid .month-day.today .month-h, #calendar-grid .month-day.today .month-date { color: var(--on-feature); background: none; }
#calendar-grid .month-day.outside, #calendar-grid .month-day.outside.past { background: var(--divider); border: 0; }
#calendar-grid .month-day.outside .month-h { color: var(--faint-text); }
#calendar-grid .month-day.past .entry.cal-entry { opacity: 1; }
#calendar-grid .month-day.today .entry.cal-entry:not(.missed) { background: var(--feature-2); }
#calendar-grid .month-day.today .entry.cal-entry.state-done { background: var(--feature-3); }
#calendar-grid .month-day.today .fold-more { color: var(--faint-text); }
.week-going.is-key { margin-top: var(--sp-2-5); padding: 0; background: none; display: flex; gap: var(--sp-5); font-size: var(--fs-md); color: var(--text-2); }
.key-item { display: inline-flex; align-items: center; gap: var(--sp-1-5); }
.key-item i { width: 20px; height: 8px; border-radius: var(--r-dash); }
.key-done { background: var(--grid-done); }
.key-planned { background: var(--grid-pending); box-shadow: inset 0 0 0 1px var(--line); }

/* Year: no panel round it - just its two cards on the page */
#calendar-grid.year .year-heat-card, #calendar-grid.year .year-goals { border-radius: var(--r-popover); }
.zoom-row .zoom .zoom-label { font-size: var(--fs-body); }

/* ---- Linked entries drawn like a Goal's card (Ed, 28 Oct) ----
   Same block, time line and title; a dashed stripe and the link glyph say
   it's from a linked calendar. A highlight still turns it to a strip, as it
   does an Event. */
#calendar-grid .ext-event.linked-card:not(.class-hit) {
  display: block; position: relative; width: 100%; height: auto; min-width: 0;
  margin: 0 0 var(--sp-1-5); padding: var(--sp-1-5) var(--sp-2) var(--sp-1-5) var(--sp-3);
  border: 0; border-radius: var(--r-block); background: var(--grid-pending); box-shadow: none; opacity: 1;
  color: var(--ink); font-size: var(--fs-base); line-height: 18px; text-align: left; cursor: pointer; overflow: hidden;
}
#calendar-grid .ext-event.linked-card::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: repeating-linear-gradient(180deg, var(--ext) 0 6px, transparent 6px 9px);
}
#calendar-grid .ext-event.linked-card:not(.class-hit) .ext-owner { display: none; }
#calendar-grid .ext-event.linked-card:not(.class-hit) .ext-sub {
  display: flex; align-items: center; gap: var(--sp-1); min-width: 0;
  font-size: var(--fs-sm); line-height: 14px; color: var(--muted); font-variant-numeric: tabular-nums;
}
#calendar-grid .ext-event.linked-card:not(.class-hit) .ext-icon { color: var(--ext); margin: 0; }
#calendar-grid .ext-event.linked-card:not(.class-hit) .ext-icon svg { width: 11px; height: 11px; }
#calendar-grid .ext-event.linked-card:not(.class-hit) .ext-time { font-size: var(--fs-sm); font-weight: var(--fw-regular); }
#calendar-grid .ext-event.linked-card:not(.class-hit) .ext-title {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); font-size: var(--fs-base);
}
/* Month's resting rows and the month either side: a bar like an Event's. */
#calendar-grid .month-week[data-density="bar"] .ext-event.linked-card:not(.class-hit),
#calendar-grid .month-day.outside .ext-event.linked-card:not(.class-hit) {
  height: 9px; margin: var(--sp-1) 0 0; padding: 0; border-radius: var(--r-dash);
}
#calendar-grid .month-week[data-density="bar"] .ext-event.linked-card:not(.class-hit) > *,
#calendar-grid .month-day.outside .ext-event.linked-card:not(.class-hit) > * { display: none; }
/* Day: its own lane, title then time, like the Events beside it. */
#calendar-grid .day-events > .ext-event.linked-card { position: absolute; margin: 0; }
#calendar-grid.day-stack .day-events > .ext-event.linked-card:not(.class-hit) {
  display: flex; align-items: baseline; gap: var(--sp-3); padding: var(--sp-2-5) var(--sp-3) 0 var(--sp-5);
}
#calendar-grid.day-stack .day-events > .ext-event.linked-card::before { width: 6px; }
#calendar-grid.day-stack .day-events > .ext-event.linked-card:not(.class-hit) .ext-title { order: 0; font-size: var(--fs-body); font-weight: var(--fw-medium); }
#calendar-grid.day-stack .day-events > .ext-event.linked-card:not(.class-hit) .ext-sub { order: 1; flex: 0 0 auto; font-size: var(--fs-md); }
/* On today's dark column/cell */
#calendar-grid :is(.day.today, .month-day.today) .ext-event.linked-card:not(.class-hit) { background: var(--feature-2); }
#calendar-grid :is(.day.today, .month-day.today) .ext-event.linked-card:not(.class-hit) .ext-title { color: var(--on-feature); }
#calendar-grid :is(.day.today, .month-day.today) .ext-event.linked-card:not(.class-hit) .ext-sub { color: var(--on-feature-2); }
#calendar-grid .month-day.today .month-week[data-density="bar"] .ext-event.linked-card { background: var(--feature-2); }

/* ---- The pace. brand (Chunk 66; switch mark since 28 Oct) ----
   The switch mark then "pace.", in the theme's ink with the accent full stop.
   The mark's inner and pill move with the view (syncBrandMark in app.js); the
   mark alone once the bar gets tight. */
.brand { position: absolute; top: 18px; left: 32px; z-index: 50; display: flex; align-items: center; gap: var(--sp-2); height: 24px; color: var(--ink); }
.brand .logo { display: block; width: auto; }
.brand .sw-ring, .brand .sw-inner { fill: currentColor; }
.brand .sw-pill { fill: var(--page); }
.brand .logo-word .accent { fill: var(--brand-accent); }
.brand .sw-inner, .brand .sw-pill {
  /* The mark follows the view on the switch's spring (motion.md M8). */
  transition: x var(--spring-switch-ms) var(--spring-switch), width var(--spring-switch-ms) var(--spring-switch), opacity var(--motion-fast) var(--ease-fade);
}
.brand-slot { flex: 0 0 auto; width: 151px; height: 24px; }
/* The mark alone under 1100px wide; at exactly 1100 the word stays (Chunk 82, look audit F4). */
@media (max-width: 1099.98px) {
  .brand .logo-word { display: none; }
  .brand-slot { width: 67px; }
}
@media (prefers-reduced-motion: reduce) { .brand .sw-inner, .brand .sw-pill { transition: none; } }

/* ==== pace. build checklist (docs/brand-identity, 28 Oct) ====
   Last in the file on purpose: the checklist's values win over every earlier
   chunk's. Light values via tokens; dark swaps the tokens only. */

/* -- Type -- */
body { font-family: var(--font-ui); font-variant-numeric: tabular-nums; background: var(--page); color: var(--ink); }
button, input, select, textarea { font-family: inherit; }
.range-big, .today-date, .today-card h2, .side-card h3, .going-head h3, .year-goals h3,
.settings-head h2, #calendar-grid.week-stack .week-date, .strip-date, #calendar-grid .month-day .month-h,
.sofar-big strong, .day-next-title, .rv-title, .rv-card h2, .rv-stat strong, .rv-year h2, .rv-year-num,
.checkin-panel-head h2 { font-family: var(--font-head); }
.range-kicker { font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--muted); }
.range-big { font-size: var(--fs-title); line-height: 44px; font-weight: var(--fw-heavy); letter-spacing: -0.03em; color: var(--ink); }
#range-label { gap: var(--sp-0-5); }
.today-card h2, .side-card h3, .going-head h3, .year-goals h3 { font-size: var(--fs-heading); font-weight: var(--fw-semi); letter-spacing: 0; color: inherit; }
.sofar-big strong { font-weight: var(--fw-heavy); letter-spacing: -0.02em; }
.settings-pop > h3, .settings-plan > h3, .unsched-heading, .nav-goals h2 .nav-label {
  font-size: var(--fs-xs); font-weight: var(--fw-semi); letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
}
.muted { color: var(--muted); }

/* -- Corners -- */
.btn, .topbar-review, .topbar-icon, .global-new, .today-btn, .page-arrow,
.view-switch button, .zoom-row .zoom button, .theme-seg, .theme-seg button, .settings-link, .settings-close { border-radius: var(--r-pill); }
dialog input[type=text], dialog input[type=date], dialog input[type=number], dialog select, dialog textarea,
.today-note, .settings-pop input { border-radius: var(--r-input); }

/* -- No selection outlines (keyboard focus keeps its ring) -- */
.entry.selected, .entry.cal-entry.selected, .today-entry.selected, #calendar-grid [data-day].selected { outline: none; }
body:not(.kbd-select) .entry.cal-entry.selected { --ring: inset 0 0 0 1px transparent; }

/* -- Top bar -- */
.content { padding: 0 var(--sp-8) var(--sp-7); }
.topbar {
  height: auto; min-height: 77px; margin: 0 calc(-1 * var(--sp-8)) 0; padding: var(--sp-4) var(--sp-8); gap: var(--sp-2);
  border-bottom: 1px solid var(--line);
}
.brand { top: 28px; left: 32px; }
.view-switch { gap: var(--sp-1); padding: var(--sp-1); border-radius: var(--r-pill); background: var(--track); }
.view-switch button {
  min-height: 40px; height: auto; padding: 0 var(--sp-4); border-radius: var(--r-pill);
  font-size: var(--fs-body); font-weight: var(--fw-semi); color: var(--muted); background: transparent;
}
.view-switch button.active { background: var(--surface); color: var(--ink); box-shadow: none; }
.topbar-review {
  min-height: 44px; height: 44px; padding: 0 var(--sp-4); border: 1px solid var(--line); background: var(--surface);
  font-size: var(--fs-base); font-weight: var(--fw-semi); color: var(--ink);
}
.topbar-review:hover { background: var(--page); }
.topbar-icon { width: 44px; height: 44px; padding: 0; }
.topbar-icon svg { width: 18px; height: 18px; stroke-width: 1.8; stroke-linejoin: round; }
.topbar-panel[aria-expanded="true"]:hover { background: var(--primary-fill); }
.global-new {
  min-height: 44px; height: 44px; padding: 0 var(--sp-4); gap: var(--sp-2); border: 0;
  background: var(--primary-fill); color: var(--on-primary); font-size: var(--fs-base); font-weight: var(--fw-semi);
}
.global-new:hover, .global-new:focus-visible { background: color-mix(in srgb, var(--primary-fill) 86%, var(--page)); }
.global-new-plus { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.new-fan-menu { border: 1px solid var(--line); border-radius: var(--r-popover); background: var(--surface); }
.new-fan-menu button { color: var(--ink); border-radius: var(--r-small); }

/* -- Cards: white, no border, a 1px Line shadow -- */
.today-card, .side-card, .week-going:not(.is-key), .year-heat-card, .year-goals,
#calendar-grid.day-stack > .day-view, .rv-card, .rv-stat, .ck-pie, .ck-stat {
  background: var(--surface); border: 0; box-shadow: var(--shadow-line);
}
.today-main-card, #calendar-grid.day-stack > .day-view, .year-heat-card, .year-goals,
#calendar-grid.year .year-heat-card, #calendar-grid.year .year-goals { border-radius: var(--r-popover); }
.today-next, .today-notes, .today-review, .side-card, .week-going, .year-sofar, .day-next,
#calendar-grid.week-stack .day { border-radius: var(--r-card); }
.today-next, .day-next, .year-sofar { background: var(--feature); color: var(--on-feature); box-shadow: none; }
.settings-pop { border: 1px solid var(--line); border-radius: var(--r-popover); background: var(--surface); box-shadow: var(--shadow-menu); }
dialog { background: var(--surface); color: var(--ink); border: 1px solid var(--line); border-radius: var(--r-popover); }

/* -- Goal dash: vertical 4 x 20, 2px radius -- */
.goal-dash { flex: 0 0 auto; width: 4px; height: 20px; border-radius: var(--r-dash); background: var(--goal); }

/* ===== Today ===== */
.today-page { max-width: 1240px; padding: var(--sp-8) var(--sp-8) var(--sp-10); }
.today-head { margin-bottom: var(--sp-7); align-items: flex-end; flex-wrap: wrap; }
.today-hero { display: flex; flex-direction: column; gap: var(--sp-1-5); }
.today-greeting { margin: 0; font-size: var(--fs-heading); font-weight: var(--fw-medium); color: var(--text-2); }
/* The title step, not a hero (Ed, 2 Nov): the next block is seen first. */
.today-date { margin: 0; font-size: var(--fs-title); line-height: var(--lh-title); font-weight: var(--fw-heavy); letter-spacing: -0.03em; color: var(--ink); }
.today-summary { margin: 0; padding-top: var(--sp-1-5); font-size: var(--fs-body); color: var(--text-2); }
.today-progress { min-width: 220px; padding-bottom: var(--sp-1-5); display: flex; flex-direction: column; align-items: flex-end; gap: var(--sp-2); }
.today-progress p { margin: 0; font-size: var(--fs-md); color: var(--text-2); }
.today-progress strong { font-weight: var(--fw-semi); color: var(--ink); }
.today-bar { width: 220px; height: 4px; border-radius: var(--r-dash); background: var(--faint); }
.today-bar span { background: var(--ink); }
.today-grid { grid-template-columns: minmax(0, 1fr) 360px; gap: var(--sp-6); }
@media (max-width: 1000px) { .today-grid { grid-template-columns: minmax(0, 1fr); } }
/* Tasks take the whole card (Ed, 2 Nov): no Working on column. */
.today-main-card { display: flex; padding: var(--sp-6); }
.today-tasks { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; }
.today-tasks .today-timeline { margin-top: var(--sp-2-5); }
.today-timeline { gap: var(--sp-2-5); }
.today-slot { grid-template-columns: 48px minmax(0, 1fr); gap: var(--sp-2-5); }
.today-time { font-size: var(--fs-md); font-weight: var(--fw-medium); color: var(--muted); }
.today-now { grid-template-columns: 48px auto minmax(0, 1fr); gap: var(--sp-2-5); margin: 0; padding: var(--sp-0-5) 0; }
.today-now .today-time { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--ink); }
.today-now-label { font-size: var(--fs-xs); font-weight: var(--fw-semi); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink); }
.today-now-rule { height: 2px; background: var(--ink); }

/* Today's task card (mock 01): 60px, 58 degree cut, colour on the right. */
.today-card-task {
  position: relative; display: block; width: 100%; height: 60px; padding: 0; margin: 0;
  border: 1px solid var(--goal); border-radius: var(--r-block); background: var(--surface); overflow: hidden;
  font: inherit; text-align: left; color: var(--ink); cursor: pointer;
}
.today-card-task .tc-left, .today-card-task .tc-right { position: absolute; inset: 0; }
.today-card-task .tc-left { background: var(--faint); clip-path: polygon(0 0, calc(100% - 47px) 0, calc(100% - 84.5px) 100%, 0 100%); }
.today-card-task .tc-right { background: var(--goal); clip-path: polygon(calc(100% - 26px) 0, 100% 0, 100% 100%, calc(100% - 63.5px) 100%); }
.today-card-task .tc-text { position: absolute; inset: 0 96px 0 14px; display: flex; flex-direction: column; justify-content: center; gap: var(--sp-0-5); min-width: 0; }
.tc-top, .tc-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tc-top { font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--muted); }
.tc-title { font-size: var(--fs-lg); font-weight: var(--fw-medium); color: var(--ink); }
.today-card-task .tc-icons { position: absolute; right: 12px; top: 0; bottom: 0; display: flex; flex-direction: column; justify-content: center; gap: var(--sp-1); color: var(--on); }
.today-card-task .tc-icons .entry-icon svg { width: 14px; height: 14px; stroke-width: 1.2; }
.today-card-task.state-done { height: 56px; }
.today-card-task.state-done .tc-left { background: var(--done-fill); clip-path: polygon(0 0, 121.6px 0, 86.7px 100%, 0 100%); }
.today-card-task.state-done .tc-right { clip-path: polygon(142.6px 0, 100% 0, 100% 100%, 107.7px 100%); }
.today-card-task .tc-tick { position: absolute; left: 60px; top: 0; width: 82.8px; height: 56px; }
.today-card-task .tc-tick svg { display: block; width: 100%; height: 100%; fill: var(--surface); }
.today-card-task.state-done .tc-text { inset: 0 14px 0 154px; flex-direction: column-reverse; }
.today-card-task.state-done .tc-title { color: var(--on); }
.today-card-task.state-done .tc-top { color: var(--on-soft); }
.today-card-task:hover { box-shadow: var(--shadow-lift); }

.today-side { gap: var(--sp-4); min-width: 0; }
.today-next { display: flex; flex-direction: column; gap: var(--sp-1-5); padding: var(--sp-5) var(--sp-5); }
.today-next-head { padding: 0; border: 0; }
.today-next h2 { margin: 0; font-size: var(--fs-heading); font-weight: var(--fw-semi); color: inherit; }
.today-next-head span { font-size: var(--fs-sm); color: var(--on-feature-3); }
.today-next-row { grid-template-columns: 52px minmax(0, 1fr) auto; gap: 0; padding: var(--sp-2) 0; border-top: 1px solid var(--feature-line); border-bottom: 0; font-size: var(--fs-base); }
.today-next-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-right: var(--sp-2); }
.today-next-dur { color: var(--on-feature-2); }
.today-next-none { color: var(--on-feature-3); }
.today-notes { display: flex; flex-direction: column; gap: var(--sp-2-5); padding: var(--sp-5) var(--sp-5); }
.today-notes h2 { margin: 0; }
.today-note { min-height: 150px; padding: var(--sp-3) var(--sp-3); border: 1px solid var(--faint); background: var(--page); color: var(--ink); font-size: var(--fs-body); line-height: 1.5; }
.today-note-status { margin: 0; font-size: var(--fs-sm); color: var(--muted); }
/* Missed on Today (Ed, 2 Nov): one calm card, only while something's missed. */
.today-missed { display: flex; flex-direction: column; gap: var(--sp-2-5); padding: var(--sp-4) var(--sp-5); }
.today-missed h2 { margin: 0; font-size: var(--fs-heading); font-weight: var(--fw-semi); }
.today-missed-list { display: flex; flex-direction: column; gap: 0; max-height: 28vh; overflow-y: auto; }
.today-missed-row { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-2-5) 0 var(--sp-2-5) var(--sp-2-5); border-top: 1px solid var(--divider); box-shadow: inset 2px 0 0 var(--goal); }
.today-missed-row:first-child { border-top: 0; }
.today-missed-title { display: flex; flex-direction: column; gap: var(--sp-0-5); padding: 0; border: 0; background: none; font: inherit; text-align: left; color: var(--ink); cursor: pointer; }
.today-missed-name { font-weight: var(--fw-semi); font-size: var(--fs-base); }
.today-missed-when { font-size: var(--fs-sm); color: var(--missed-ink-2); }
.today-missed-actions { display: flex; flex-wrap: wrap; gap: var(--sp-0-5) var(--sp-1); }
.today-missed-actions .btn { min-height: 30px; padding: var(--sp-0-5) var(--sp-2); font-size: var(--fs-sm); }
.today-missed-pick .ev-daterow { display: flex; gap: var(--sp-1-5); align-items: center; }
.ev-done-on-field { display: flex; flex-direction: column; gap: var(--sp-1); }
.ck-slipped .ck-slip { gap: var(--sp-1-5); }
.ck-slipped .ck-slip-head { display: flex; align-items: center; gap: var(--sp-2-5); padding: var(--sp-2) var(--sp-2-5) var(--sp-2) var(--sp-3); }
.ck-slip-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-px); }
.ck-slip-mark { flex: none; min-height: 30px; padding: var(--sp-0-5) var(--sp-3); border: 1px solid var(--line); background: var(--surface); font-size: var(--fs-md); color: var(--ink); }
.ck-slip-confirm { color: var(--missed-ink); }
.ck-close-left { font-size: var(--fs-md); }
.ck-slip-group { display: flex; flex-direction: column; gap: var(--sp-2-5); }
.ck-slip-group + .ck-slip-group { margin-top: var(--sp-3); }
.ck-slip-group h3 { margin: 0; font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; }
.ck-slip-done { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-2); }
.ck-slip-done .ev-field { flex: 1 1 160px; }
.today-notes { overflow: hidden; }
.today-review { display: flex; align-items: center; gap: var(--sp-2-5); min-height: 48px; padding: 0 var(--sp-4); border: 1px solid var(--line); box-shadow: none; font-size: var(--fs-base); color: var(--ink); }
.today-review strong { font-weight: var(--fw-semi); }
.today-review-sub { flex: 1; color: var(--muted); }
.today-review-arrow svg { display: block; width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* ===== Calendar chrome ===== */
.zoom-row { padding: var(--sp-6) 0 var(--sp-3); }
.zoom-row .zoom button { min-height: 40px; height: auto; padding: 0 var(--sp-4); font-size: var(--fs-base); font-weight: var(--fw-semi); color: var(--muted); }
.zoom-row .zoom .zoom-label { font-size: var(--fs-base); }
.zoom-row .zoom button.active { background: var(--surface); color: var(--ink); box-shadow: none; }
.calendar-panel > .toolbar { padding: 0 0 var(--sp-5); }
.calendar-controls :is(#today, .page-arrow) {
  border-radius: var(--r-pill);
  height: 44px; min-width: 44px; padding: 0 var(--sp-4); border: 1px solid var(--line); background: var(--surface);
  color: var(--ink); font-size: var(--fs-base); font-weight: var(--fw-semi);
}
.calendar-controls .page-arrow { width: 44px; padding: 0; display: inline-flex; align-items: center; justify-content: center; }
.calendar-controls .page-arrow svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* Task blocks (calendar views): 6px goal stripe; Pending the Past/sunk fill,
   Done the Done fill + tick, Missed 148 degree stripes. 6px corners. */
.entry.cal-entry:not(.today-entry) { border-radius: var(--r-block); background: var(--block); }
.entry.cal-entry:not(.today-entry):is([data-density="chip"], [data-density="lane"]) { border-radius: var(--r-block); background: var(--block); }
.entry.cal-entry:not(.today-entry).state-done,
.entry.cal-entry:not(.today-entry).state-done:is([data-density="chip"], [data-density="lane"]) { background: var(--done-fill); }
.entry.cal-entry:not(.today-entry)::before { width: 6px; }
.cal-entry:not(.today-entry):is([data-density="chip"], [data-density="lane"]) .grid-sub:not(:empty) { font-size: var(--fs-xs); font-weight: var(--fw-medium); line-height: 14px; color: var(--muted); }
.cal-entry:not(.today-entry).state-done .grid-sub:not(:empty) { color: var(--text-2); }
.cal-entry:not(.today-entry) .entry-title, .cal-entry:not(.today-entry).state-done .entry-title { color: var(--ink); font-weight: var(--fw-medium); }
.cal-entry:not(.today-entry):is([data-density="chip"], [data-density="lane"]) .entry-text { padding: var(--sp-1) var(--sp-2) 0 var(--sp-3); z-index: 1; }
/* Done carries the logo tick, faint, on its right. */
.entry.cal-entry:not(.today-entry).state-done:is([data-density="chip"], [data-density="lane"])::after {
  content: ""; position: absolute; top: 0; bottom: 0; right: 6px; left: auto; height: auto; transform: none;
  width: calc(var(--h) * 1.48); max-width: 60%; clip-path: none; z-index: 0;
  background: var(--done-tick, #b4b3ac);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -1118 1653 1118'%3E%3Cpath d='M492 0L953.6 0L969.7 -25.8L503.5 -492L0 -492Z'/%3E%3Cpath d='M533.8 0L953.6 0L1652.2 -1118L1232.4 -1118Z'/%3E%3C/svg%3E") right center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -1118 1653 1118'%3E%3Cpath d='M492 0L953.6 0L969.7 -25.8L503.5 -492L0 -492Z'/%3E%3Cpath d='M533.8 0L953.6 0L1652.2 -1118L1232.4 -1118Z'/%3E%3C/svg%3E") right center / contain no-repeat;
}
:root[data-theme="dark"] { --done-tick: #40434a; }

/* ===== Day ===== */
.day-strip { gap: var(--sp-1-5); }
.strip-day { width: 52px; min-height: 56px; padding: 0; justify-content: center; gap: var(--sp-1); border-radius: var(--r-small); background: var(--surface); color: var(--ink); }
.strip-name { font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--muted); }
.strip-date { font-size: var(--fs-lg); font-weight: var(--fw-bold); }
.strip-bar { width: 28px; height: 3px; margin: 0; background: var(--faint); }
.strip-day.current { background: var(--feature); color: var(--on-feature); }
.strip-day.current .strip-name { color: var(--on-feature-2); }
.strip-day.current .strip-bar { background: var(--feature-line); }
.strip-day.current .strip-bar > span { background: var(--on-feature); }
#calendar-grid.day-stack > .day-view { padding: var(--sp-4) var(--sp-5) var(--sp-5) var(--sp-3); --pane-bg: var(--surface); }
#calendar-grid.day-stack .day-pane .hour { left: 54px; border-top-color: var(--divider); }
#calendar-grid.day-stack .day-pane .hour.minor { display: none; }
#calendar-grid.day-stack .day-pane .hour span { left: -54px; width: 44px; text-align: right; top: -7px; font-size: var(--fs-xs); color: var(--faint-text); }
#calendar-grid.day-stack .day-events { left: 64px; right: 8px; }
#calendar-grid.day-stack .day-night { display: none; }
#calendar-grid.day-stack .cal-entry[data-density="lane"] .entry-text,
#calendar-grid.day-stack .cal-entry.state-done[data-density="lane"] .entry-text {
  top: 0; height: 30px; transform: none; display: flex; align-items: center; gap: var(--sp-2-5); padding: 0 var(--sp-3) 0 var(--sp-4);
}
#calendar-grid.day-stack .cal-entry[data-density="lane"] .entry-title { font-size: var(--fs-base); font-weight: var(--fw-medium); }
#calendar-grid.day-stack .cal-entry[data-density="lane"] .grid-sub:not(:empty) { font-size: var(--fs-sm); font-weight: var(--fw-regular); line-height: 16px; }
.day-now { left: 54px; background: var(--ink); }
.day-now::before { background: var(--ink); }
.day-now-time { left: -54px; width: 44px; text-align: right; top: -8px; font-size: var(--fs-xs); color: var(--ink); background: var(--surface); }
.day-next { gap: var(--sp-1-5); padding: var(--sp-5) var(--sp-5); }
.day-next-kicker { font-size: var(--fs-xs); font-weight: var(--fw-semi); letter-spacing: 0.08em; color: var(--on-feature-3); }
.day-next-title { font-size: var(--fs-xl); font-weight: var(--fw-bold); letter-spacing: -0.02em; }
.day-next-sub { font-size: var(--fs-md); color: var(--on-feature-2); }
.day-sum-row { padding: var(--sp-1) 0; border-left: 0; display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-base); }
.day-sum-row::before { content: ""; width: 4px; height: 20px; border-radius: var(--r-dash); background: var(--goal); flex: 0 0 auto; }
.day-sum-row strong { margin-left: auto; }

/* ===== Week ===== */
#calendar-grid.week-stack > .week.focused { gap: var(--sp-2-5); }
#calendar-grid.week-stack .day { padding: var(--sp-3) var(--sp-2-5); gap: var(--sp-1-5); background: var(--surface); }
#calendar-grid.week-stack .day.past { background: var(--sunk); }
/* Chunk 189 (a11y 1): past boxes no longer fade to 60% - the grey past column marks the past. */
#calendar-grid.week-stack .day.today { background: var(--feature); }
#calendar-grid.week-stack .day h3 { padding: 0 var(--sp-0-5) var(--sp-1-5); margin: 0; }
.week-dayname { font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--muted); }
#calendar-grid.week-stack .week-date { font-size: var(--fs-heading); font-weight: var(--fw-bold); letter-spacing: -0.02em; color: var(--ink); }
#calendar-grid.week-stack .day.today .week-dayname { color: var(--on-feature-2); }
#calendar-grid.week-stack .day.today .week-date { color: var(--on-feature); }
#calendar-grid.week-stack .week-day-events > * + * { margin-top: var(--sp-1-5); }
#calendar-grid.week-stack .entry.cal-entry[data-density="chip"] { margin: 0; }
#calendar-grid.week-stack .entry.cal-entry[data-density="chip"] + .entry.cal-entry { margin-top: var(--sp-1-5); }
#calendar-grid.week-stack .cal-entry[data-density="chip"] .entry-title { font-size: var(--fs-md); }
#calendar-grid.week-stack .cal-entry[data-density="chip"] .grid-sub:not(:empty) { font-size: var(--fs-xs); }
#calendar-grid.week-stack .day.today .entry.cal-entry:not(.missed) { background: var(--on-feature-block); }
#calendar-grid.week-stack .day.today .entry.cal-entry.state-done { background: var(--on-feature-done); }
#calendar-grid.week-stack .day.today .cal-entry .entry-title { color: var(--on-feature); }
#calendar-grid.week-stack .day.today .cal-entry .grid-sub:not(:empty) { color: var(--on-feature-3); }
#calendar-grid.week-stack .day.today .cal-entry.state-done .grid-sub:not(:empty) { color: var(--on-feature-2); }
#calendar-grid.week-stack .day.today { --done-tick: #40434a; }
.week-day-foot { gap: var(--sp-1-5); padding: var(--sp-2) var(--sp-0-5) 0; font-size: var(--fs-sm); color: var(--muted); }
.week-day-bar { height: 4px; border-radius: var(--r-dash); background: var(--faint); }
.week-day-bar > span { background: var(--ink); }
#calendar-grid.week-stack .day.today .week-day-foot { color: var(--on-feature-2); }
#calendar-grid.week-stack .day.today .week-day-bar { background: var(--feature-line); }
#calendar-grid.week-stack .day.today .week-day-bar > span { background: var(--on-feature); }
.week .flag[data-density="chip"] { border-left: 0; padding: 0 var(--sp-0-5) var(--sp-1); gap: var(--sp-1-5); color: var(--muted); background: none; }
.week .flag[data-density="chip"] .flag-kind { font-size: var(--fs-xs); letter-spacing: 0.06em; }
.week .flag[data-density="chip"] .flag-title { font-size: var(--fs-xs); font-weight: var(--fw-semi); letter-spacing: 0.06em; text-transform: uppercase; }
#calendar-grid.week-stack .day.today .flag { color: var(--on-feature-2); }
.week-going:not(.is-key) { padding: var(--sp-4) var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-3); }
.going-head { margin: 0; }
.going-head .muted { font-size: var(--fs-md); color: var(--muted); }
.going-bar { height: 14px; border-radius: var(--r-mini); gap: var(--sp-0-5); }
.going-legend { margin: 0; gap: var(--sp-1-5) var(--sp-5); font-size: var(--fs-md); color: var(--text-2); }
.going-key strong { font-weight: var(--fw-semi); color: var(--ink); }
.going-key i { width: 10px; height: 10px; border-radius: var(--r-dash); }

/* ===== Month ===== */
#calendar-grid .month-day { border-radius: var(--r-small); padding: var(--sp-2); gap: var(--sp-0-5); background: var(--surface); }
#calendar-grid .month-day .month-h { font-size: var(--fs-body); font-weight: var(--fw-bold); color: var(--ink); margin: 0 0 var(--sp-0-5); }
#calendar-grid .month-day.past { background: var(--sunk); }
#calendar-grid .month-day.past .month-h { color: var(--muted); }
#calendar-grid .month-day.today { background: var(--feature); }
#calendar-grid .month-day.today .month-h, #calendar-grid .month-day.today .month-date { color: var(--on-feature); }
/* Tighter date heading, so a day holds three bars at a laptop's height (Ed, 28 Oct). */
#calendar-grid .month-day { padding: var(--sp-1-5) var(--sp-1-5) var(--sp-1) var(--sp-2); gap: 0; }
#calendar-grid .month-day .month-h { line-height: 18px; margin: 0 0 var(--sp-px); }
#calendar-grid .month-day.today .month-more { color: var(--on-feature-2); }
/* Chunk 99 (A12): no cell-wide opacity - it dropped the dates and "+N more" to 1.5-2.5:1. The cell is faded by its sunk fill and the
   dates keep AA text colours. */
#calendar-grid .month-day.outside, #calendar-grid .month-day.outside.past { background: var(--sunk); }
#calendar-grid .month-day.outside .month-h { color: var(--faint-text); }
.month .entry.cal-entry[data-density="bar"] { margin-top: var(--sp-0-5); border-radius: var(--r-mini); }
.month .entry.cal-entry[data-density="bar"]::before { width: 4px; }
/* Month's missed bar: grey stripes, Chunk 180, see the end of this file. */
#calendar-grid .month-day.today .entry.cal-entry:not(.missed) { background: var(--on-feature-block); }
#calendar-grid .month-day.today .entry.cal-entry.state-done { background: var(--on-feature-done); }
.month-head { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--muted); }
.calendar-main .month-head.today { color: var(--ink); font-weight: var(--fw-semi); }
.week-going.is-key { gap: var(--sp-4); font-size: var(--fs-md); color: var(--muted); }
.key-item i { width: 20px; height: 8px; border-radius: var(--r-dash); }
.key-planned { background: var(--block); box-shadow: inset 0 0 0 1px var(--line); }
.sofar-bar { height: 4px; border-radius: var(--r-dash); background: var(--faint); }
.time-track { height: 4px; border-radius: var(--r-dash); background: var(--faint); }
.time-track span { border-radius: var(--r-dash); }

/* ===== Year ===== */
.year-cell { border-radius: var(--r-mini); background: var(--track); }
.year-cell.has-done { background: var(--goal); }
.year-cell.has-miss { background: var(--missed-a); }
.year-cell.ahead { background: var(--surface); box-shadow: inset 0 0 0 1px var(--line); }
.year-cell.today-cell { box-shadow: 0 0 0 2px var(--ink); }
.year-key i { border-radius: var(--r-mini); background: var(--goal); }
.year-key .key-miss { background: var(--missed-a); }
.year-key .key-ahead { background: var(--surface); box-shadow: inset 0 0 0 1px var(--line); }
.year-sofar { padding: var(--sp-5) var(--sp-5); }
.year-sofar h3 { font-size: var(--fs-xs); font-weight: var(--fw-semi); letter-spacing: 0.08em; text-transform: uppercase; color: var(--on-feature-3); font-family: var(--font-ui); }
.year-sofar .sofar-big { color: var(--on-feature-2); }
.year-sofar .sofar-big strong { color: var(--on-feature); font-size: var(--fs-title); }
.year-sofar .time-row { color: var(--on-feature); }
.year-sofar .time-track { background: var(--feature-line); }

/* ===== Settings ===== */
.settings-pop { width: 380px; padding: var(--sp-4) var(--sp-5) var(--sp-5); }
.settings-head h2 { font-size: var(--fs-heading); font-weight: var(--fw-semi); }
.settings-close { width: 44px; height: 44px; font-size: var(--fs-heading); color: var(--text-2); }
.settings-close:hover { background: var(--page); }
.theme-seg { padding: var(--sp-1); gap: var(--sp-1); background: var(--track); }
.theme-seg button { height: 40px; font-size: var(--fs-base); font-weight: var(--fw-medium); color: var(--muted); }
.theme-seg button[aria-pressed="true"] { background: var(--surface); color: var(--ink); font-weight: var(--fw-semi); box-shadow: none; }
.settings-note { font-size: var(--fs-sm); color: var(--muted); }
.settings-link { min-height: 44px; padding: 0 var(--sp-4); border: 1px solid var(--line); background: var(--surface); color: var(--ink); font-weight: var(--fw-semi); }
.settings-pop .feed-row { display: flex; align-items: center; gap: var(--sp-2-5); border: 0; border-top: 1px solid var(--divider); border-radius: 0; padding: var(--sp-2-5) 0; background: none; }
.settings-pop .feed-row input[type=color] { width: 24px; height: 44px; padding: 0; border: 0; background: none; cursor: pointer; flex: 0 0 auto; }
.settings-pop .feed-row input[type=color]::-webkit-color-swatch-wrapper { padding: var(--sp-3) var(--sp-2-5); }
.settings-pop .feed-row input[type=color]::-webkit-color-swatch { border: 0; border-radius: var(--r-dash); }
.settings-pop .feed-main strong { font-size: var(--fs-base); font-weight: var(--fw-medium); }
.settings-pop .feed-status { font-size: var(--fs-sm); }
.week .flag[data-density="chip"] { flex-wrap: nowrap; }
.week .flag[data-density="chip"] .flag-kind { display: none; }
.week .flag[data-density="chip"] .flag-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.week .flag[data-density="chip"] .flag-title::after { content: " due"; }

/* ===== Week review page (brand checklist + mock 06) ===== */
.review-page { position: fixed; inset: 0; z-index: 60; overflow-y: auto; background: var(--page); color: var(--ink); }
body.reviewing { overflow: hidden; }
.rv-bar {
  position: sticky; top: 0; z-index: 2; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  min-height: 77px; padding: var(--sp-4) var(--sp-8); border-bottom: 1px solid var(--line); background: var(--page);
}
.rv-logo { display: flex; align-items: center; min-height: 44px; justify-self: start; }
.rv-logo { gap: var(--sp-2); color: var(--ink); }
.rv-logo .logo { height: 24px; width: auto; display: block; }
.rv-logo .logo-switch { height: 20px; }
.rv-logo .sw-ring, .rv-logo .sw-inner { fill: currentColor; }
.rv-logo .sw-pill { fill: var(--page); }
.rv-logo .logo-word .accent { fill: var(--brand-accent); }
.rv-bar-title { font-size: var(--fs-base); font-weight: var(--fw-medium); color: var(--muted); }
.rv-bar-actions { justify-self: end; display: flex; align-items: center; gap: var(--sp-2); }
.rv-bar-close { min-height: 44px; padding: 0 var(--sp-4); font-size: var(--fs-base); }
.rv-bar-close:disabled { opacity: var(--state-disabled); cursor: default; }
.rv-later { min-height: 44px; padding: 0 var(--sp-4); font-size: var(--fs-base); font-weight: var(--fw-semi); color: var(--ink); }
.rv-later:hover { background: var(--track); }
.rv-body { max-width: 1240px; margin: 0 auto; padding: var(--sp-7) var(--sp-8) var(--sp-12); display: flex; flex-direction: column; gap: var(--sp-5); }

.rv-head { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--sp-6); flex-wrap: wrap; }
.rv-kicker { margin: 0 0 var(--sp-0-5); font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--muted); }
.rv-title { margin: 0; font-size: var(--fs-title); line-height: 44px; font-weight: var(--fw-heavy); letter-spacing: -0.03em; }
.rv-stats { display: flex; gap: var(--sp-2-5); flex-wrap: wrap; }
.rv-stat { display: flex; flex-direction: column; gap: var(--sp-0-5); min-width: 136px; padding: var(--sp-3) var(--sp-4); border-radius: var(--r-small); }
.rv-stat strong { font-size: var(--fs-xl); line-height: 1.1; font-weight: var(--fw-heavy); letter-spacing: -0.02em; color: var(--ink); }
.rv-stat span { font-size: var(--fs-sm); color: var(--muted); }
.rv-stat.is-missed strong { color: var(--missed-ink-2); }

.rv-year { padding: var(--sp-5) var(--sp-6); border-radius: var(--r-card); background: var(--feature); color: var(--on-feature); }
.rv-year-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: var(--sp-3); }
.rv-year h2 { margin: 0; font-size: var(--fs-heading); font-weight: var(--fw-semi); }
.rv-year-num { font-size: var(--fs-xl); font-weight: var(--fw-heavy); letter-spacing: -0.02em; }
.rv-year-grid { display: grid; grid-template-columns: repeat(var(--weeks), minmax(0, 14px)); grid-template-rows: repeat(7, 14px); gap: var(--sp-0-5); }
.rv-cell { border-radius: var(--r-mini); background: var(--on-feature-block); }
.rv-cell.outside { background: transparent; }
.rv-cell.ahead { opacity: 0.55; }
.rv-cell.has-done { background: var(--goal); }
.rv-cell.has-miss { background: var(--missed-accent); }
.rv-cell.this-week { box-shadow: 0 0 0 1.5px var(--on-feature); }
.rv-year-legend { display: flex; flex-wrap: wrap; gap: var(--sp-1-5) var(--sp-4); margin-top: var(--sp-3); font-size: var(--fs-sm); color: var(--on-feature-2); }
.rv-key { display: inline-flex; align-items: center; gap: var(--sp-1-5); }
.rv-key i { width: 10px; height: 10px; border-radius: var(--r-dash); background: var(--goal); }
.rv-key.is-miss i { background: var(--missed-accent); }

.rv-two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-5); align-items: start; }
@media (max-width: 1000px) { .rv-two { grid-template-columns: minmax(0, 1fr); } }
.rv-card { padding: var(--sp-5) var(--sp-6); border-radius: var(--r-card); display: flex; flex-direction: column; gap: var(--sp-3); }
.rv-card-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-3); }
.rv-card h2 { margin: 0; font-size: var(--fs-heading); font-weight: var(--fw-semi); }
.rv-card-head .muted { font-size: var(--fs-md); }

.ck-slipped .ck-slip { margin: 0; display: flex; flex-direction: column; gap: var(--sp-2-5); }
.ck-slip-head {
  padding: var(--sp-3) var(--sp-3); border-left: 4px solid var(--goal, var(--muted)); border-radius: var(--r-block);
  font-size: var(--fs-base); font-weight: var(--fw-medium); color: var(--ink);
}
.ck-slip-missed { font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--missed-ink); }
.ck-slip-actions { margin: 0; gap: var(--sp-2); }
.ck-slip-actions .btn.ck-slot {
  min-height: 40px; padding: 0 var(--sp-3); border: 1px solid var(--line); background: var(--surface);
  font-size: var(--fs-base); font-weight: var(--fw-medium); color: var(--ink);
}
.ck-slip-actions .btn.ck-slot:hover:not(:disabled) { background: var(--page); }
.ck-slip-actions .btn.ck-slot.chosen, .ck-slip-actions .btn.ck-slot.chosen:disabled {
  background: var(--primary-fill); border-color: var(--primary-fill); color: var(--on-primary); opacity: 1; font-weight: var(--fw-semi);
}
.ck-slip.handled .ck-slip-head { background: var(--sunk); }
.ck-slip-result { font-size: var(--fs-sm); color: var(--muted); }

.rv-went .going-bar { height: 14px; }
.rv-went-row { display: grid; grid-template-columns: 4px minmax(0, 1fr) auto 90px; align-items: center; gap: var(--sp-2-5); min-height: 36px; font-size: var(--fs-base); }
.rv-went-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rv-went-row .muted { font-size: var(--fs-md); }
.rv-went-row strong { text-align: right; font-weight: var(--fw-semi); }
.rv-note { margin: var(--sp-1) 0 0; font-size: var(--fs-md); color: var(--text-2); }

.rv-foot { align-items: end; }
.rv-next-line { margin: 0; font-size: var(--fs-md); color: var(--text-2); }
.rv-bars { display: flex; align-items: flex-end; gap: var(--sp-2); height: 76px; margin-top: var(--sp-1); }
.rv-nbar { display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: var(--sp-1); flex: 0 0 28px; height: 100%; }
.rv-nbar i { display: block; width: 28px; border-radius: var(--r-mini); background: var(--ink); }
.rv-nbar b { font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--muted); }
.rv-foot .ck-close { margin: 0; justify-content: flex-end; }
.rv-foot .ck-close #close-week { width: auto; min-height: 44px; height: 44px; padding: 0 var(--sp-5); font-size: var(--fs-base); }

.rv-more { margin-top: var(--sp-7); display: flex; flex-direction: column; gap: var(--sp-4); }
.rv-more-label { margin: 0; font-size: var(--fs-xs); font-weight: var(--fw-semi); letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.rv-more .section { padding: var(--sp-5) var(--sp-6); border: 0; border-radius: var(--r-card); background: var(--surface); box-shadow: var(--shadow-line); margin: 0 0 var(--sp-4); }
.rv-more .section h3 { margin: 0 0 var(--sp-1); font-family: var(--font-head); font-size: var(--fs-lg); font-weight: var(--fw-semi); }
.rv-board {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--sp-4); position: relative;
  padding: 0; border: 0; background: none; max-height: none; overflow: visible;
}
.rv-board .ck-pie { border-radius: var(--r-card); }
.ck-ring { stroke: var(--divider); }
.ck-slice { stroke: var(--surface); }
.ck-centre { fill: var(--ink); font-family: var(--font-head); font-weight: var(--fw-heavy); }
.ck-centre-label, .ck-ring-value, .ck-sub { fill: var(--muted); color: var(--muted); }
.ck-tip { background: var(--feature); color: var(--on-feature); }
.settings-pop .feed-main { min-width: 0; }
.settings-pop .feed-status { white-space: normal; overflow-wrap: anywhere; }
/* Inputs follow the tokens in both themes. */
:is(dialog, .settings-pop, .review-page) :is(input:not([type=checkbox], [type=radio], [type=color], [type=range]), select, textarea) {
  background: var(--surface); color: var(--ink); border: 1px solid var(--line);
}

/* ===== Nav update (28 Oct, docs/brand-identity/mockups/navigation/) ===== */
body { --topbar-h: 77px; --left-w: 184px; --tray-w: 272px; }

/* Top bar: menu + logo left, Today/Calendar centred, Settings right. */
.topbar { position: relative; z-index: 31; padding: var(--sp-4) var(--sp-8) var(--sp-4) var(--sp-4); background: var(--page); }
.topbar-left { display: flex; align-items: center; gap: var(--sp-3); }
.topbar .brand { position: static; display: flex; align-items: center; min-height: 44px; height: auto; }
.topbar .brand .logo-word { height: 24px; }
.topbar .brand .logo-switch { height: 20px; }
.nav-toggle {
  width: 44px; height: 44px; padding: 0; border: 0; border-radius: var(--r-pill); background: transparent; color: var(--ink);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
}
.nav-toggle:hover, .nav-toggle[aria-expanded="true"] { background: var(--track); }
.nav-toggle svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.topbar .view-switch { position: absolute; left: 50%; transform: translateX(-50%); }
.view-switch button { position: relative; }
.calendar-badge {
  position: absolute; top: -10px; right: -8px; min-width: 22px; height: 22px; padding: 0 var(--sp-1-5); box-sizing: border-box;
  border-radius: var(--r-pill); background: var(--badge-fill); color: var(--on-badge); border: 2px solid var(--page);
  font-size: var(--fs-xs); font-weight: var(--fw-bold); line-height: 18px; text-align: center;
}

/* Left panel: under the top bar, pushes the page over. */
.sidebar {
  position: fixed; top: var(--topbar-h); bottom: 0; left: 0; right: auto; z-index: 30;
  width: var(--left-w); padding: var(--sp-5) var(--sp-4); gap: var(--sp-5);
  background: var(--surface); border: 0; border-right: 1px solid var(--line); box-shadow: none; clip-path: none;
  transform: translateX(-100%); visibility: hidden; overflow-y: auto;
  transition: transform var(--sidebar-ms) var(--sidebar-ease), visibility 0s linear var(--sidebar-ms);
}
body.left-open .sidebar { transform: none; visibility: visible; transition: transform var(--sidebar-ms) var(--sidebar-ease), visibility 0s; }
body.nav-open .content { margin-right: 0; }
.content > :not(.topbar):not(.error) { margin-left: var(--sp-12); transition: margin-left var(--sidebar-ms) var(--sidebar-ease); }
body.left-open .content > :not(.topbar):not(.error) { margin-left: calc(var(--left-w) - var(--sp-1)); }
@media (prefers-reduced-motion: reduce) { .sidebar, .content > * { transition: none; } }
.sidebar .nav-goals { margin: 0; gap: var(--sp-0-5); }
.sidebar .nav-goals h2 { padding: 0 var(--sp-2) var(--sp-1-5); margin: 0; }
.sidebar .nav-routines h2,
.sidebar .nav-collections h2 { margin-top: var(--sp-4); }
.sidebar .nav-goals h2 .icon-btn { display: none; }
.sidebar .nav-row { margin: 0; }
.sidebar .nav-goal, .sidebar.expanded .nav-goal {
  display: flex; align-items: center; gap: var(--sp-2-5); width: 100%; min-height: 44px; margin: 0; padding: 0 var(--sp-2);
  border: 0; border-radius: var(--r-small); background: transparent; box-shadow: none;
  font-size: var(--fs-base); font-weight: var(--fw-medium); color: var(--ink); text-align: left; white-space: nowrap;
}
.sidebar .nav-goal::before, .sidebar.expanded .nav-goal::before { content: none; }
.sidebar .nav-goal:hover, .sidebar.expanded .nav-goal:hover, .sidebar .nav-goal.active, .sidebar.expanded .nav-goal.active { background: var(--page); box-shadow: none; }
.sidebar .nav-dot { display: block; flex: 0 0 auto; width: 4px; height: 20px; border-radius: var(--r-dash); background: var(--goal); margin: 0; }
.sidebar .nav-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; opacity: 1; max-width: none; }
.sidebar .nav-meta { flex: 0 0 auto; font-size: var(--fs-sm); font-weight: var(--fw-regular); color: var(--muted); }
.sidebar .nav-entry { display: flex; align-items: center; gap: var(--sp-2-5); min-height: 44px; padding: 0 var(--sp-2); border-radius: var(--r-small); color: var(--muted); font-size: var(--fs-base); }
.sidebar .nav-entry:hover, .sidebar .nav-entry.active { background: var(--page); color: var(--ink); }
.sidebar .nav-entry .nav-icon { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.7; }
.sidebar [data-view="completed"] { margin-top: auto; }

/* New: a pill at the top of the open panel; closed, a round + at the page's left. */
.new-float { position: fixed; left: 16px; top: calc(var(--topbar-h) + 20px); z-index: 29; }
.sidebar > .new-fan { align-self: flex-start; }
.new-float .global-new { width: 44px; padding: 0; justify-content: center; gap: 0; font-size: 0; }
.new-float .global-new-plus { width: 16px; height: 16px; }
.new-float .new-fan-menu { top: 0; left: calc(100% + 8px); right: auto; }
.sidebar .new-fan-menu { left: 0; right: auto; }
body.reviewing .new-float { display: none; }

/* Day / Week / Month / Year moved to the top bar (see .cal-seg). */
.zoom-row { display: none !important; }
.tray-chev { display: inline-flex; }
.tray-chev svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
#calendar-view .calendar-panel[data-zoom="day"] #today { display: inline-block; }
#calendar-view .calendar-panel[data-zoom="day"] .range-paging { display: contents; }
.calendar-panel > .toolbar { padding-top: var(--sp-5); }
#day-strip { display: none !important; }

/* Side tray: the same on every view. */
.calendar-main { position: relative; }
.calendar-main > .cal-side {
  width: var(--tray-w); margin-left: var(--sp-5); gap: var(--sp-3); overflow: hidden;
  display: flex; flex-direction: column;
}
.calendar-main > .cal-side[hidden] { display: none; }
.cal-side > .side-card { flex: 0 0 auto; padding: var(--sp-4) var(--sp-5); }
.cal-side .side-card h3 { margin: 0; }
.cal-side .month-sofar { display: flex; flex-direction: column; gap: var(--sp-3); }
.cal-side .sofar-big { margin: 0; }
.cal-side .sofar-big strong { font-size: var(--fs-2xl); }
.cal-side .sofar-bar { height: 6px; border-radius: var(--r-mini); }
.tray-card-head { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-2); }
.tray-fold {
  width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--r-pill); background: var(--page); color: var(--ink);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer; flex: 0 0 auto;
}
.tray-time { display: flex; flex-direction: column; gap: var(--sp-3); }
.tray-time.open { flex: 0 1 auto; min-height: 0; }
.tray-time-rows { display: flex; flex-direction: column; gap: var(--sp-2-5); min-height: 0; overflow-y: auto; }
.tray-time .going-bar { height: 8px; border-radius: var(--r-mini); }
.tray-time .time-row { margin: 0; gap: var(--sp-1) var(--sp-2); font-size: var(--fs-md); }
.tray-time .time-name { color: var(--text-2); }
.tray-time .time-track { height: 6px; border-radius: var(--r-mini); background: var(--divider); }
.tray-more { align-self: flex-start; padding: 0; border: 0; background: none; font: inherit; font-size: var(--fs-sm); color: var(--muted); cursor: pointer; }
.tray-more:hover { color: var(--ink); }
.cal-side .year-sofar { flex: 0 1 auto; min-height: 0; overflow-y: auto; width: auto; display: flex; flex-direction: column; gap: var(--sp-2-5); }
.cal-side .year-sofar .time-row { margin: 0; gap: var(--sp-1) var(--sp-2); font-size: var(--fs-md); }
/* The same split bars as Month's Time by goal (Chunk 85, look audit Y4). */
.cal-side .year-sofar .time-track { height: 6px; border-radius: var(--r-mini); }
.tray-foot { margin-top: auto; flex: 0 0 auto; }

/* No Place drawer: the old right rail only appears to hold New task. */
body.s-cal:not(.cal-composing) #calendar-aside { display: none; }
body[data-view="calendar"].s-cal:not(.cal-composing) .content { margin-right: 0; }

/* Year: a blank spot for now. */
.year-blank { min-height: 360px; }

/* Week review: Goals across the year. */
.rv-goals .year-goal-rows { margin-top: var(--sp-1); }
.sidebar .new-fan-menu { flex-wrap: wrap; width: calc(var(--left-w) - 32px); }
.sidebar .new-fan-menu button { flex: 1 0 calc(50% - 6px); width: auto; }

/* Today fits the window - no page scroll (Ed, 28 Oct). The task list scrolls
   inside its own card; Next up, Notes and the Week review link stay in view.
   Stacked under 1000px wide, the page scrolls as before. */
@media (min-width: 1000px) {
  body[data-view="today"] .content { padding-bottom: 0; }
  body[data-view="today"] { overflow: hidden; }
  .today-page { height: calc(100vh - var(--topbar-h)); display: flex; flex-direction: column; padding: var(--sp-7) var(--sp-8) var(--sp-6); }
  .today-head { flex: none; margin-bottom: var(--sp-6); }
  .today-grid { flex: 1 1 0; min-height: 0; align-items: stretch; }
  .today-main-card { min-height: 0; overflow: hidden; }
  .today-tasks { min-height: 0; }
  .today-timeline { flex: 1 1 0; min-height: 0; overflow-y: auto; padding-right: var(--sp-1); }
  /* Nothing in the column is ever out of reach (Ed, 2 Nov: on a short
     window with a lot missed, Week review fell off the bottom). Cards keep a
     readable size and the column scrolls inside itself when they don't all
     fit, rather than squashing them. */
  .today-side { min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
  .today-next, .today-review, .today-missed { flex: none; }
  .today-notes { flex: 1 0 auto; min-height: 170px; }
  .today-note { flex: 1 1 0; min-height: 60px; resize: none; }
}
@media (min-width: 1000px) and (max-height: 820px) {
  .today-page { padding-top: var(--sp-5); }
  .today-head { margin-bottom: var(--sp-4); }
}

/* Class highlight: matches always at full strength (past days included),
   everything else well back; a matching strip keeps its title even when
   Done or Missed. */
#calendar-grid.class-highlighting :is(.entry.event, .flag, .ext-event).class-hit { opacity: 1 !important; }
#calendar-grid.class-highlighting :is(.entry.event, .flag, .year-bar, .year-more, .ext-event):not(.class-hit) { opacity: 0.25 !important; }
#calendar-grid.class-highlighting .entry.cal-entry.class-hit[data-density="strip"] .entry-text { display: block !important; }

/* Left panel: narrow; a long name cuts off with an ellipsis (full name on hover). */
.sidebar .nav-row { min-width: 0; }
.sidebar .nav-goal { overflow: hidden; }
.sidebar .nav-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar .nav-dot { box-shadow: none; }

/* Low-key scrollbars everywhere: thin, no track, a soft thumb (Ed, 28 Oct). */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: var(--r-pill); border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background-color: var(--faint-text); }
::-webkit-scrollbar-corner { background: transparent; }
#calendar-grid.day-stack .day-scroll { overflow-x: hidden; overflow-y: auto; }

/* Day's now time sits just under the black line, right of the hour labels. */
.day-now-time {
  left: 4px; top: 5px; width: auto; text-align: left; padding: 0 var(--sp-1); border-radius: var(--r-pill);
  background: var(--ink); color: var(--page); font-size: var(--fs-2xs); line-height: 15px; z-index: 5;
}

/* Waiting to be placed sits under the last card; it only reaches the foot
   when the cards fill the tray (Time by goal gives way first). */
.tray-foot { margin-top: 0; }

/* The tray arrow snaps to the very bottom. */

/* The left panel opens and closes instantly - sliding while the page re-laid
   out flashed. */
.sidebar, body.left-open .sidebar, .content > :not(.topbar):not(.error) { transition: none !important; }
.cal-side > .side-card { flex: 0 1 auto; min-height: 0; overflow-y: auto; }
.cal-side > .day-next { flex: none; }
.day-now-time { left: auto; right: 6px; }
::-webkit-scrollbar-button { display: none; width: 0; height: 0; }

/* No selection box on a hovered day in any zoom - only the keyboard shows one. */
body:not(.kbd-select) #calendar-grid [data-day].selected { box-shadow: none; }


/* Only Time by goal (and Day's The day) give way when the tray fills; the so-far card keeps its size. */
.cal-side > .month-sofar { flex: none; overflow: visible; }

/* Linked calendar entries are Events visually (Ed, 28 Oct): the link glyph
   before the time is the only difference. */
.linked-icon { display: inline-flex; vertical-align: -1px; margin-right: var(--sp-1); }
.linked-icon svg { width: 11px; height: 11px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.tc-icons .linked-icon { margin: 0; }
.tc-icons .linked-icon svg { width: 14px; height: 14px; stroke-width: 1.8; }
.entry.cal-entry.linked-event { cursor: pointer; }

/* A not-done block on a past day (shaded cell) used to share the cell's own
   colour and vanish; it takes the Done shading there instead (Ed). Past
   blocks sit at 60%. */
#calendar-grid :is(.month-day.past, .month-day.outside, .day.past) .entry.cal-entry:not(.state-done):not(.missed) { background: var(--done-fill); }

/* A Month bar tall enough for a line (16px+, about an hour) shows its title. */
.month .entry.cal-entry.bar-titled[data-density="bar"] > .entry-text {
  display: block !important; position: absolute; left: 10px; right: 4px; top: 1px; height: auto; transform: none; padding: 0;
}
.month .entry.cal-entry.bar-titled[data-density="bar"] > .entry-text > :not(.entry-title) { display: none !important; }
.month .entry.cal-entry.bar-titled[data-density="bar"] .entry-title { font-size: var(--fs-2xs); line-height: var(--lh-meta); font-weight: var(--fw-medium); color: var(--ink); }
#calendar-grid .month-day.today .entry.cal-entry.bar-titled .entry-title { color: var(--on-feature); }
/* A day from the month either side keeps its bars plain, no title (Ed). */
.month .month-day.outside .entry.cal-entry.bar-titled[data-density="bar"] > .entry-text { display: none !important; }
/* Chunk 240: a done bar's tick (right 7px, 8px wide, turned 45deg: about 21px of the bar's right
   edge) sits after the title, not over it, so the title gives up that room and ellipsises before it. */
.month .entry.cal-entry.state-done.bar-titled[data-density="bar"] > .entry-text { right: 24px; }
.month .entry.cal-entry.state-done.bar-titled[data-density="bar"] .entry-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Month bar thickness (planned time) applies only while the row rests at bar density. */
.month .entry.cal-entry[data-density="bar"] { --h: var(--bar-h, 10px); }
#calendar-grid.month .entry.cal-entry[data-density="chip"], #calendar-grid .month-week .entry.cal-entry[data-density="chip"] { --h: 28px; }

/* ===== Menus redesign (28 Oct) =====
   Goal and Routine focus views, every "…" menu, the + New menu, the event
   dialog, the New task panel, Edit task and the Goal / Milestone / Routine
   form. Mocks: docs/brand-identity/mockups/goals-routines-events/. Colours
   come from the tokens above, so dark mode follows. */

/* -- Focus views: a title block, cards and a side column, no panel box -- */
#goal-detail, #routine-detail, #collection-detail, #completed-detail, #history-detail {
  border: 0; background: none; min-height: 0; box-sizing: border-box;
  max-width: 1240px; margin: 0 auto; padding: var(--sp-7) var(--sp-8) var(--sp-10);
}
.fv-head { display: flex; align-items: flex-end; gap: var(--sp-4); padding-bottom: var(--sp-5); }
.fv-stripe { width: 6px; align-self: stretch; border-radius: var(--r-mini); background: var(--goal, var(--line)); flex: none; }
.fv-titles { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-1); }
.fv-kicker { font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--muted); }
.fv-head h2 {
  margin: 0; font-family: var(--font-head); font-weight: var(--fw-heavy); font-size: var(--fs-title); line-height: 44px;
  letter-spacing: -0.03em; color: var(--ink); overflow-wrap: anywhere;
}
.fv-desc { margin: 0; font-size: var(--fs-body); color: var(--text-2); }
.fv-head .review-badge { align-self: flex-start; margin-top: var(--sp-1); }
.fv-actions { display: flex; align-items: center; gap: var(--sp-2); flex: none; }
.fv-body { display: flex; gap: var(--sp-5); align-items: flex-start; }
.fv-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-4); }
.fv-side { width: 320px; flex: none; display: flex; flex-direction: column; gap: var(--sp-4); }
@media (max-width: 1100px) {
  .fv-body { flex-direction: column; align-items: stretch; }
  .fv-side { width: auto; }
}
@media (max-width: 700px) {
  .fv-head { flex-wrap: wrap; }
  .fv-head h2 { font-size: var(--fs-2xl); line-height: 36px; }
}

:is(#goal-detail, #routine-detail) .fv-card,
:is(#goal-detail, #collection-detail, #completed-detail, #history-detail) .fv-card {
  background: var(--surface); border: 0; border-radius: var(--r-popover); box-shadow: var(--shadow-line);
  margin: 0; padding: var(--sp-5) var(--sp-5) var(--sp-2-5);
}
:is(#goal-detail, #routine-detail) .fv-card-head,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-card-head { display: flex; align-items: flex-start; gap: var(--sp-4); padding: 0 var(--sp-2-5) var(--sp-3); }
:is(#goal-detail, #routine-detail) .fv-tasks .fv-card-head,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-tasks .fv-card-head { align-items: center; }
:is(#goal-detail, #routine-detail) .fv-card-titles,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-card-titles { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-1); }
:is(#goal-detail, #routine-detail) .fv-label,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-label {
  font-size: var(--fs-xs); font-weight: var(--fw-semi); letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
}
:is(#goal-detail, #routine-detail) .fv-card-titles h3,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-card-titles h3 {
  display: block; margin: 0; font-family: var(--font-head); font-weight: var(--fw-semi); font-size: var(--fs-heading); line-height: 1.2;
  letter-spacing: -0.01em; color: var(--ink); text-decoration: none;
}
:is(#goal-detail, #routine-detail) .milestone-item.completed .fv-card-titles h3,
:is(#goal-detail, #collection-detail, #completed-detail) .milestone-item.completed .fv-card-titles h3 { color: var(--muted); }
:is(#goal-detail, #routine-detail) .fv-meta,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-meta { display: flex; align-items: center; gap: var(--sp-1-5); font-size: var(--fs-md); color: var(--muted); }
:is(#goal-detail, #routine-detail) .fv-progress,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-progress { display: flex; align-items: center; gap: var(--sp-3); padding: 0 var(--sp-2-5) var(--sp-4); }
:is(#goal-detail, #routine-detail) .fv-big,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-big {
  font-family: var(--font-head); font-weight: var(--fw-heavy); font-size: var(--fs-xl); letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
}
:is(#goal-detail, #routine-detail) .fv-of,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-of { font-size: var(--fs-base); color: var(--muted); white-space: nowrap; }
:is(#goal-detail, #routine-detail) .fv-progress .fv-bar,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-progress .fv-bar { flex: 1; }
:is(#goal-detail, #routine-detail) .fv-bar,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-bar { display: block; height: 8px; border-radius: var(--r-dash); background: var(--divider); overflow: hidden; }
:is(#goal-detail, #routine-detail) .fv-bar > span,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-bar > span { display: block; height: 100%; border-radius: inherit; background: var(--goal, var(--ink)); }
:is(#goal-detail, #routine-detail) .fv-bar.quiet,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-bar.quiet { height: 4px; flex: 0 1 240px; }
:is(#goal-detail, #routine-detail) .fv-bar.quiet > span,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-bar.quiet > span { background: var(--done-fill); }
:is(#goal-detail, #routine-detail) .fv-rows,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-rows { display: flex; flex-direction: column; margin: 0; padding: var(--sp-1-5) 0; border-top: 1px solid var(--divider); }
:is(#goal-detail, #routine-detail) .fv-empty,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-empty { margin: 0; padding: var(--sp-3) var(--sp-2-5) var(--sp-2-5); border-top: 1px solid var(--divider); color: var(--muted); font-size: var(--fs-base); }

/* Task rows */
:is(#goal-detail, #routine-detail) .fv-row, :is(#goal-detail, #collection-detail, #completed-detail) .fv-row {
  display: flex; align-items: center; gap: var(--sp-3); min-height: 56px; margin: 0; padding: var(--sp-1-5) var(--sp-2-5);
  border: 0; border-radius: var(--r-small);
}
:is(#goal-detail, #routine-detail) .fv-row:hover, :is(#goal-detail, #routine-detail) .fv-row:focus-within,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-row:hover, :is(#goal-detail, #collection-detail, #completed-detail) .fv-row:focus-within { background: var(--page); }
:is(#goal-detail, #routine-detail) .fv-dash,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-dash { width: 4px; height: 20px; border-radius: var(--r-dash); background: var(--goal, var(--line)); flex: none; }
:is(#goal-detail, #routine-detail) .fv-row-text,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-row-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-0-5); }
:is(#goal-detail, #routine-detail) .fv-row .title,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-row .title { display: block; margin: 0; font-size: var(--fs-body); font-weight: var(--fw-medium); color: var(--ink); text-decoration: none; }
:is(#goal-detail, #routine-detail) .fv-row.completed .title,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-row.completed .title { color: var(--muted); }
:is(#goal-detail, #routine-detail) .fv-row-meta,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-row-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); font-size: var(--fs-md); color: var(--muted); }
:is(#goal-detail, #routine-detail) .fv-row-meta .entry-icons,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-row-meta .entry-icons { margin: 0; color: var(--muted); }
:is(#goal-detail, #routine-detail) .fv-row-meta .entry-icons::before,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-row-meta .entry-icons::before { content: none; }
:is(#goal-detail, #routine-detail) .fv-period,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-period { display: flex; align-items: center; gap: var(--sp-2-5); padding-top: var(--sp-1-5); }
:is(#goal-detail, #routine-detail) .fv-period .task-progress,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-period .task-progress { margin: 0; font-size: var(--fs-sm); color: var(--muted); white-space: nowrap; }
:is(#goal-detail, #routine-detail) .fv-row-actions,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-row-actions { display: flex; align-items: center; gap: var(--sp-1); flex: none; }
:is(#goal-detail, #routine-detail) .fv-hover,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-hover { visibility: hidden; }
:is(#goal-detail, #routine-detail) .fv-row:hover .fv-hover,
:is(#goal-detail, #routine-detail) .fv-row:focus-within .fv-hover,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-row:hover .fv-hover,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-row:focus-within .fv-hover { visibility: visible; }
@media (hover: none) { :is(#goal-detail, #routine-detail) .fv-hover { display: none; } }
:is(#goal-detail, #routine-detail) .done-group,
:is(#goal-detail, #collection-detail, #completed-detail) .done-group { margin: 0; border-top: 1px solid var(--divider); }
:is(#goal-detail, #routine-detail) .done-group > summary,
:is(#goal-detail, #collection-detail, #completed-detail) .done-group > summary {
  display: flex; align-items: center; min-height: 48px; padding: 0 var(--sp-2-5); font-size: var(--fs-base); color: var(--muted);
}

/* Side column: the summary card and Notes */
:is(#goal-detail, #routine-detail) .fv-summary, :is(#goal-detail, #collection-detail, #completed-detail) .fv-summary {
  display: flex; flex-direction: column; gap: var(--sp-3); padding: var(--sp-5); border-radius: var(--r-popover);
  background: var(--feature); color: var(--on-feature);
}
:is(#goal-detail, #routine-detail) .fv-summary .fv-label,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-summary .fv-label { color: var(--on-feature-3); }
:is(#goal-detail, #routine-detail) .fv-summary-big,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-summary-big { display: flex; align-items: baseline; gap: var(--sp-2); font-size: var(--fs-base); color: var(--on-feature-2); }
:is(#goal-detail, #routine-detail) .fv-summary-big .fv-big,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-summary-big .fv-big { font-size: var(--fs-title); letter-spacing: -0.03em; color: var(--on-feature); }
:is(#goal-detail, #routine-detail) .fv-summary-big.over .fv-big,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-summary-big.over .fv-big { color: var(--on-feature); }
:is(#goal-detail, #routine-detail) .fv-summary dl,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-summary dl { display: flex; flex-direction: column; gap: var(--sp-2); margin: 0; font-size: var(--fs-md); }
:is(#goal-detail, #routine-detail) .fv-summary dl > div,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-summary dl > div { display: flex; justify-content: space-between; gap: var(--sp-3); }
:is(#goal-detail, #routine-detail) .fv-summary dt,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-summary dt { color: var(--on-feature-2); }
:is(#goal-detail, #routine-detail) .fv-summary dd,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-summary dd { margin: 0; font-weight: var(--fw-semi); color: var(--on-feature); font-variant-numeric: tabular-nums; }
:is(#goal-detail, #routine-detail) .notes-block,
:is(#goal-detail, #collection-detail, #completed-detail) .notes-block { display: flex; flex-direction: column; gap: var(--sp-2-5); padding: var(--sp-5); }
:is(#goal-detail, #routine-detail) .notes-block h3,
:is(#goal-detail, #collection-detail, #completed-detail) .notes-block h3 { margin: 0; font-family: var(--font-head); font-weight: var(--fw-semi); font-size: var(--fs-heading); color: var(--ink); }
:is(#goal-detail, #routine-detail) .notes-block .notes-body,
:is(#goal-detail, #collection-detail, #completed-detail) .notes-block .notes-body {
  min-height: 96px; margin: 0; padding: var(--sp-3) var(--sp-3); border: 1px solid var(--faint); border-radius: var(--r-input);
  background: var(--page); color: var(--ink); font: inherit; font-size: var(--fs-body); line-height: 1.5;
  text-align: left; white-space: pre-wrap; cursor: text;
}
:is(#goal-detail, #routine-detail) .notes-block .notes-body.empty,
:is(#goal-detail, #collection-detail, #completed-detail) .notes-block .notes-body.empty { color: var(--faint-text); font-style: normal; }

/* Buttons */
.fv-btn { font: inherit; display: inline-flex; align-items: center; gap: var(--sp-1-5); border-radius: var(--r-pill); cursor: pointer; white-space: nowrap; }
.fv-quiet, .fv-hover { min-height: 36px; padding: 0 var(--sp-3); border: 0; background: transparent; color: var(--text-2); font-size: var(--fs-md); font-weight: var(--fw-medium); }
.fv-quiet:hover, .fv-hover:hover { background: var(--sunk); color: var(--ink); }
.fv-pill { min-height: 44px; padding: 0 var(--sp-4); border: 1px solid var(--line); background: var(--surface); color: var(--ink); font-size: var(--fs-base); font-weight: var(--fw-semi); }
.fv-pill:hover { border-color: var(--faint-text); }
.fv-primary { min-height: 44px; padding: 0 var(--sp-5); border: 0; background: var(--primary-fill); color: var(--on-primary); font-size: var(--fs-base); font-weight: var(--fw-semi); }
.fv-primary:hover { background: color-mix(in srgb, var(--primary-fill) 86%, var(--page)); }
.fv-icon { display: inline-flex; }
.fv-icon svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.fv-icon-plus svg { width: 12px; height: 12px; stroke-width: 2; }
.fv-icon-more svg { width: 16px; height: 16px; fill: currentColor; stroke: none; }

/* "…" menus */
.fv-menu-wrap { position: relative; display: inline-flex; }
.fv-more {
  width: 36px; height: 36px; border: 0; border-radius: var(--r-pill); background: transparent; color: var(--muted);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
}
.fv-more:hover, .fv-more[aria-expanded="true"] { background: var(--sunk); color: var(--ink); }
.fv-head .fv-more { width: 44px; height: 44px; border: 1px solid var(--line); background: var(--surface); color: var(--ink); }
.fv-head .fv-more[aria-expanded="true"] { box-shadow: 0 0 0 3px var(--track); }
.fv-menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 40; min-width: 220px; padding: var(--sp-1-5);
  display: flex; flex-direction: column; gap: var(--sp-0-5);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow-menu);
  animation: fan-in var(--motion-fast) var(--ease-enter);
}
.fv-menu[hidden] { display: none; }
.fv-menu-item {
  font: inherit; font-size: var(--fs-base); font-weight: var(--fw-medium); min-height: 40px; padding: 0 var(--sp-3); border: 0; border-radius: var(--r-input);
  background: transparent; color: var(--ink); display: flex; align-items: center; gap: var(--sp-2-5); text-align: left;
  cursor: pointer; white-space: nowrap;
}
.fv-menu-item .fv-icon { color: var(--muted); }
.fv-menu-item:hover, .fv-menu-item:focus-visible { background: var(--page); }
.fv-menu-item.danger, .fv-menu-item.danger .fv-icon { color: var(--danger); }
.fv-menu-item.danger:hover, .fv-menu-item.danger:focus-visible { background: var(--danger-bg); }
.fv-menu-divider { height: 1px; margin: var(--sp-1) var(--sp-1-5); background: var(--divider); }
@media (prefers-reduced-motion: reduce) { .fv-menu { animation: none; } }

/* -- + New: a list with a line on each, and where a new task lands -- */
#new-fan-menu {
  flex-direction: column; flex-wrap: nowrap; gap: var(--sp-0-5); width: 320px; padding: var(--sp-2); box-sizing: border-box;
  border: 1px solid var(--line); border-radius: var(--r-popover); box-shadow: var(--shadow-menu);
}
#new-fan-menu button {
  flex: none; width: auto; flex-direction: row; align-items: center; gap: var(--sp-3); padding: var(--sp-2-5) var(--sp-3);
  border-radius: var(--r-small); text-align: left;
}
#new-fan-menu svg { width: 40px; height: 40px; padding: var(--sp-2-5); box-sizing: border-box; border-radius: var(--r-small); background: var(--page); flex: none; }
#new-fan-menu button:hover svg, #new-fan-menu button:focus-visible svg { background: var(--surface); }
.nf-text { display: flex; flex-direction: column; gap: var(--sp-0-5); }
.nf-name { font-size: var(--fs-body); font-weight: var(--fw-semi); color: var(--ink); }
.nf-desc { font-size: var(--fs-md); color: var(--muted); }
.nf-hint { margin: var(--sp-1-5) var(--sp-2) var(--sp-0-5); padding: var(--sp-2) var(--sp-1) var(--sp-0-5); border-top: 1px solid var(--divider); font-size: var(--fs-sm); color: var(--muted); }

/* -- New task: a side panel under the top bar, Create always in view -- */
dialog#task-dialog.slide-panel:is([open], :not([open])) {
  inset: var(--topbar-h, 77px) 0 0 auto; width: min(480px, 100vw); height: calc(100vh - var(--topbar-h, 77px));
  max-height: none; padding: var(--sp-5) var(--sp-6) 0; box-sizing: border-box; border: 0; border-left: 1px solid var(--line);
  border-radius: 0; box-shadow: var(--shadow-panel);
}
/* On the Calendar it sits in the right-hand rail, which widens to the panel's
   full width (Ed: it used to overflow the narrower rail and get cropped). */
body.s-cal.cal-composing { --aside-open: min(var(--side-panel-w), 100vw); }
/* Under the top bar, never over it (Ed, 28 Oct). */
body.s-cal.cal-composing #calendar-aside { top: var(--topbar-h, 77px); }
body.s-cal.cal-composing #calendar-aside .aside-drawer { inset: 0; }
.aside-drawer > dialog:is(#task-dialog, #task-edit-dialog).slide-panel:is([open], :not([open])) { width: 100%; height: 100%; max-height: 100%; }
#task-dialog .task-form > h2, #task-edit-dialog .task-form > h2 {
  font-family: var(--font-head); font-weight: var(--fw-heavy); font-size: var(--fs-xl); letter-spacing: -0.02em;
}
:is(#task-dialog, #task-edit-dialog) .task-form > .actions {
  position: sticky; bottom: 0; z-index: 1; margin: 0 calc(-1 * var(--sp-6)); padding: var(--sp-3) var(--sp-6) var(--sp-4);
  background: var(--surface); border-top: 1px solid var(--divider);
}
/* Edit task: taller than the screen on a laptop, so it scrolls inside
   itself and Save stays in view. */
#task-edit-dialog:is([open], :not([open])) { max-height: calc(100vh - 32px); overflow-y: auto; padding: var(--sp-5) var(--sp-6) 0; box-sizing: border-box; }

/* -- Goal, Milestone and Routine form -- */
#goal-dialog {
  width: min(520px, calc(100vw - 32px)); padding: var(--sp-5) var(--sp-7) var(--sp-6); box-sizing: border-box; border: 0;
  border-top: 6px solid var(--goal, var(--line)); border-radius: var(--r-dialog); box-shadow: var(--shadow-dialog);
}
#goal-dialog.tinted { background: var(--surface); }
#goal-dialog h2, #goal-dialog.tinted h2 {
  margin: 0 0 var(--sp-2); font-family: var(--font-head); font-weight: var(--fw-heavy); font-size: var(--fs-xl); letter-spacing: -0.02em; color: var(--ink);
}
#goal-dialog.tinted .btn { --primary: var(--primary-fill); }
#goal-dialog .gd-remove { color: var(--danger); }
#goal-dialog .gd-remove:hover { background: var(--danger-bg); }
#new-fan-menu { position: fixed; right: auto; z-index: 60; }
/* Form fields at the brand's 44px, in every form this pass touches. */
:is(#task-dialog, #task-edit-dialog, #goal-dialog) :is(input[type=text], input[type=date], input[type=number], select) {
  min-height: 44px; padding: 0 var(--sp-3); border: 1px solid var(--line); border-radius: var(--r-small);
  background: var(--surface); color: var(--ink); font: inherit; font-size: var(--fs-body); box-sizing: border-box;
}
:is(#task-dialog, #task-edit-dialog, #goal-dialog) textarea {
  padding: var(--sp-3) var(--sp-3); border: 1px solid var(--line); border-radius: var(--r-small); background: var(--surface); font-size: var(--fs-body);
}
:is(#task-dialog, #task-edit-dialog, #goal-dialog) input[name=title] { min-height: 48px; font-size: var(--fs-lg); }
:is(#task-dialog, #task-edit-dialog, #goal-dialog) :is(input, select, textarea):focus-visible { border-color: var(--ink); }
:is(#task-dialog, #task-edit-dialog) .tf-field, #goal-dialog form > label { font-size: var(--fs-md); font-weight: var(--fw-semi); }
:is(#task-dialog, #task-edit-dialog) .tf-field input, #goal-dialog form > label input { margin-top: var(--sp-1-5); font-weight: var(--fw-regular); }
:is(#task-dialog, #task-edit-dialog) .icon-choice label { border-radius: var(--r-small); }
#task-dialog input.time-input, #task-edit-dialog input.time-input { width: 100%; }
#new-fan-menu svg { width: 40px; height: 40px; padding: var(--sp-2-5); box-sizing: border-box; border-radius: var(--r-small); background: var(--page); flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

/* Linked calendars' colour (Ed, 28 Oct): the Goal swatches, in Settings. */
.feeds-colour-pick { display: flex; flex-direction: column; gap: var(--sp-1-5); margin: var(--sp-1) 0 var(--sp-2); }
.feeds-colour-pick .field-label { font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--ink); }
.feed-colour-field { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
.settings-pop .feed-colour-field:not(.feeds-colour-pick *) { padding: 0 0 var(--sp-2-5) var(--sp-8); }
.feed-colour-field label.colour-custom { display: inline-flex; flex-direction: row; align-items: center; gap: var(--sp-1-5); margin: 0; font-size: var(--fs-sm); color: var(--muted); }
.feed-colour-dot {
  flex: 0 0 auto; width: 20px; height: 20px; padding: 0; border: 0; border-radius: 50%;
  background: var(--swatch); cursor: pointer; box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 15%, transparent);
}
.feed-colour-dot[aria-expanded="true"] { box-shadow: 0 0 0 2px var(--ink); }

/* -- Top bar switch, version C (Ed, 28 Oct) --
   On the Calendar its half of the switch goes dark and opens out to hold Day /
   Week / Month / Year; back on Today it closes. Dark in both themes. */
/* The switch's motion is a spring run from script (see setSwitch); colours
   ride along on an ease-out of the same length. */
.view-switch { --switch-ease: var(--ease-snappy); isolation: isolate; will-change: transform; }
.cal-seg { display: inline-flex; align-items: center; transition: background-color var(--dur-240) var(--ease-soft), padding var(--switch-ms) var(--switch-ease); }
.view-zooms { display: inline-flex; align-items: center; gap: var(--sp-0-5); width: 0; overflow: hidden; }
.view-zooms button { flex: none; }
/* One highlight that springs between choices (see setSwitch). */
.view-thumb {
  position: absolute; z-index: 2; top: 50%; left: 0; height: 36px; transform: translate(0, -50%); opacity: 0; overflow: hidden;
  background: var(--surface); box-shadow: var(--shadow-soft); pointer-events: none; will-change: transform, width;
  transition: background-color var(--switch-ms) var(--switch-ease), opacity var(--dur-140) ease;
}
.view-thumb.shown { opacity: 1; }
.view-thumb-labels { position: absolute; left: 0; top: 0; width: 0; height: 0; will-change: transform; }
.view-thumb-label { position: absolute; display: flex; align-items: center; justify-content: center; color: var(--ink); white-space: nowrap; }
.view-thumb.on-dark .view-thumb-label { color: var(--feature); }
.view-thumb-label svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.calendar-badge { z-index: 3; }
/* A press dips the segment a touch before the highlight springs over. */
.view-switch button > * { transition: transform var(--motion-fast) var(--ease-standard); }
.view-switch button:active { transform: scale(0.96); transition: transform var(--dur-90) ease; }
.view-switch button { transition: color var(--dur-240) var(--ease-soft), transform var(--dur-220) var(--ease-snappy); }
.view-thumb.on-dark { background: var(--on-feature); box-shadow: none; }
.view-switch button { position: relative; z-index: 1; }
.view-switch button.active, .view-zooms button.active { background: transparent !important; box-shadow: none !important; }
.view-zooms button, .view-zooms button.active { font-weight: var(--fw-medium); }
body[data-view="calendar"] .cal-seg { background: var(--feature); padding-right: var(--sp-0-5); }
body[data-view="calendar"] .view-switch .cal-seg [data-go="calendar"] { background: transparent; color: var(--on-feature); box-shadow: none; font-weight: var(--fw-semi); }
.view-zooms button {
  display: inline-flex; align-items: center; gap: var(--sp-1-5); height: 36px; padding: 0 var(--sp-3); border: 0; border-radius: var(--r-pill);
  background: transparent; color: color-mix(in srgb, var(--on-feature) 65%, transparent);
  font: inherit; font-size: var(--fs-base); font-weight: var(--fw-medium); white-space: nowrap; cursor: pointer;
}
.view-zooms button:hover { color: var(--on-feature); }
.view-zooms button.active { background: var(--on-feature); color: var(--feature); font-weight: var(--fw-semi); }
.view-zooms svg { display: none; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
@media (max-width: 1100px) {
  .view-zooms svg { display: block; }
  .view-zoom-label { display: none; }
  .view-zooms button { padding: 0 var(--sp-2-5); }
}
@media (prefers-reduced-motion: reduce) { .cal-seg, .view-zooms, .view-thumb, .view-switch button { transition: none; } }
/* The switch drawn like the logo (Ed, 28 Oct): an ink ring instead of the grey
   track. The sliding highlight stays white everywhere, Today included - a
   dark Today highlight was tried and dropped at Ed's word. */
.topbar .view-switch { background: transparent; box-shadow: inset 0 0 0 2px var(--ink); }

/* The calendar's title: plain arrows to its left, like a tool's (Ed, 28 Oct). */
#calendar-view .calendar-panel .range-title { display: flex; align-items: flex-end; gap: var(--sp-2-5); }
#calendar-view .calendar-panel .range-title .range-paging { display: inline-flex; gap: 0; margin-bottom: var(--sp-1); }
.range-title .page-arrow {
  display: inline-grid; place-items: center; width: 28px; height: 28px; min-height: 0; padding: 0;
  border: 0; border-radius: var(--r-block); background: transparent; color: var(--ink); box-shadow: none; cursor: pointer;
}
.range-title .page-arrow:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink); }
.range-title .page-arrow svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

/* Every event's colour edge is a 2px hairline that rolls round the block's
   left corners and fades along the top and bottom (Ed, 28 Oct - it was a
   solid 6px bar; the colour carries without weighing the page down). */
#calendar-grid .entry.cal-entry::before {
  top: 0; bottom: 0; height: auto; transform: none; left: 0; right: 0; width: auto;
  background: none; clip-path: none;
  border: 0 solid transparent; border-left: 2px solid var(--goal); border-radius: inherit;
  -webkit-mask: linear-gradient(to right, #000 0 3px, transparent 14px);
  mask: linear-gradient(to right, #000 0 3px, transparent 14px);
}

/* Today: a plain outlined button, like the arrows (Ed, 28 Oct). */
#calendar-view .calendar-controls #today {
  height: 28px; min-height: 0; padding: 0 var(--sp-2-5); border: 1px solid var(--line); border-radius: var(--r-pill);
  background: transparent; color: var(--ink); font-size: var(--fs-md); font-weight: var(--fw-semi); box-shadow: none;
}
#calendar-view .calendar-controls #today:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); }

/* The top bar's Today / Calendar switch is always a full bubble. (The 28 Oct
   0.35x corners pass was undone in Chunk 80: pills and 12-14px cards.) */
.view-switch, .view-switch button, .cal-seg, .view-zooms button, .view-thumb { border-radius: var(--r-pill) !important; }

/* -- Targets as pills (Ed, 28 Oct; option A on the brand canvas) --
   The switch's rounded shape, outlined in the goal colour with a solid dot,
   the name and a small when-line. Over goes Ink; met fills with the goal
   colour. (The .pennant class name is kept for the highlight and click code.) */
.pennant {
  display: inline-flex; align-items: center; gap: var(--sp-1-5); align-self: flex-start; flex: none; max-width: 100%; min-width: 0;
  box-sizing: border-box; margin: 0; padding: 0 var(--sp-3) 0 var(--sp-2); border: 1.5px solid var(--goal); border-radius: var(--r-pill) !important;
  background: none; color: var(--ink); font: inherit; text-align: left; white-space: nowrap; overflow: hidden; cursor: pointer;
}
.pennant:hover { background: color-mix(in srgb, var(--goal) 10%, transparent); }
.pennant-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--goal); }
.pennant-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; font-weight: var(--fw-semi); }
.pennant-when { flex: none; font-size: var(--fs-xs); font-weight: var(--fw-medium); color: var(--muted); }
.pennant.is-today .pennant-when { color: var(--ink); font-weight: var(--fw-semi); }
/* Over goes Ink, never orange (Ed, 2 Nov: orange is missed and waiting only;
   Chunk 85). One component, so Day, Week and Today follow. */
.pennant.is-over { border-color: var(--over-ink); }
.pennant.is-over .pennant-dot { background: var(--over-ink); }
.pennant.is-over .pennant-when { color: var(--over-ink); font-weight: var(--fw-semi); }
.pennant.is-met { background: var(--goal); color: var(--on-goal); }
.pennant.is-met .pennant-dot { background: var(--on-goal); }
.pennant.is-met .pennant-when { color: color-mix(in srgb, var(--on-goal) 75%, var(--goal)); }
.pennant.is-met:hover { background: color-mix(in srgb, var(--goal) 88%, var(--ink)); }
/* Month: a 16px pill, first in the day */
.pennant.p-month { height: 16px; margin-top: var(--sp-0-5); padding: 0 var(--sp-1-5) 0 var(--sp-1); gap: var(--sp-1); border-width: 1px; font-size: var(--fs-2xs); line-height: var(--lh-meta); }
.pennant.p-month .pennant-dot { width: 6px; height: 6px; }
.pennant.p-month .pennant-when { font-size: var(--fs-2xs); }
/* Week: one row under the day's header */
.pennant.p-week { height: 28px; margin: 0 0 var(--sp-1-5); font-size: var(--fs-md); }
/* Day: a row above the timeline */
.pennant.p-day { height: 30px; font-size: var(--fs-md); }
.day-flags { display: flex; flex-wrap: wrap; gap: var(--sp-1-5); }
/* On today's ink cell */
#calendar-grid :is(.month-day.today, .day.today) .pennant:not(.is-met) { color: var(--on-feature); }
#calendar-grid :is(.month-day.today, .day.today) .pennant:not(.is-met) .pennant-when { color: color-mix(in srgb, var(--on-feature) 70%, transparent); }
#calendar-grid :is(.month-day.today, .day.today) .pennant.is-over { border-color: var(--on-feature); }
#calendar-grid :is(.month-day.today, .day.today) .pennant.is-over .pennant-dot { background: var(--on-feature); }
#calendar-grid :is(.month-day.today, .day.today) .pennant.is-over .pennant-when { color: var(--on-feature); }

/* Today: targets ride in the summary line - no pills */
.today-summary-target { color: var(--ink); font-weight: var(--fw-semi); }

/* Year: each Goal's track to its target, light - a hairline, a tint for the
   time gone, diamonds for Milestones, an outlined pennant at the end. */
.year-goals { padding: var(--sp-5) var(--sp-6); background: var(--surface); }
.year-goals h3 { margin: 0 0 var(--sp-3); font-size: var(--fs-body); }
.year-goal-rows .year-solid { top: 4px; height: 6px; background: color-mix(in srgb, var(--goal) 16%, transparent); box-shadow: inset 0 0 0 1px var(--goal); }
.year-goal-rows .year-ahead { top: 6px; height: 2px; background: repeating-linear-gradient(90deg, var(--goal) 0 4px, transparent 4px 8px); }
.year-goal-rows .year-node { top: 2px; width: 10px; height: 10px; margin-left: -5px; /* exact: centres the 10px node */ border-radius: var(--r-dash); transform: rotate(45deg); background: var(--surface); border: 1.5px solid var(--goal); }
.year-goal-rows .year-node.done { background: var(--goal); border-color: var(--goal); }
.year-goal-rows .year-node.over { border-color: var(--over-ink); }
/* The Goal's target at the track's end: the same pill as the calendar's targets */
.year-goal-target {
  position: absolute; top: -5px; height: 22px; box-sizing: border-box; padding: 0 var(--sp-2) 0 var(--sp-1-5); display: flex; align-items: center; gap: var(--sp-1);
  border: 1.5px solid var(--goal); border-radius: var(--r-pill) !important; background: var(--surface);
  font-size: var(--fs-xs); color: var(--ink); white-space: nowrap; transform: translateX(-100%); margin-left: 0;
}
.year-goal-target::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--goal); }
.year-goal-target.is-over { border-color: var(--over-ink); color: var(--over-ink); font-weight: var(--fw-semi); }
.year-goal-target.is-over::before { background: var(--over-ink); }

/* -- Lighter charts (Ed, 28 Oct) --
   Where a chart used a solid slab of goal colour it's now a tint with one
   solid edge: the proportions still read, the page isn't loud. */
.going-bar span { background: color-mix(in srgb, var(--goal) 18%, transparent); box-shadow: inset 0 -2px 0 var(--goal); }
.going-key i { background: color-mix(in srgb, var(--goal) 18%, transparent); box-shadow: inset 0 0 0 1.5px var(--goal); }
.time-track span { background: color-mix(in srgb, var(--goal) 22%, transparent); box-shadow: inset -2px 0 0 var(--goal); }
:is(#goal-detail, #routine-detail) .fv-bar,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-bar { background: transparent; box-shadow: inset 0 0 0 1px var(--divider); }
:is(#goal-detail, #routine-detail) .fv-bar > span,
:is(#goal-detail, #collection-detail, #completed-detail) .fv-bar > span { background: color-mix(in srgb, var(--goal, var(--ink)) 20%, transparent); box-shadow: inset -2px 0 0 var(--goal, var(--ink)); }

/* + New: a divider under One-off (Ed, 28 Oct). */
.new-fan-menu .nf-divider { flex: none; height: 1px; margin: var(--sp-1) var(--sp-2); background: var(--divider); }

/* -- Side panels (Ed, 28 Oct) --
   New task, the Goal / Routine / Milestone form and Edit task are one screen:
   a slim panel on the right, under the top bar, over nothing else. */
body { --side-panel-w: 360px; }
body > dialog.slide-panel:is(#task-dialog, #goal-dialog, #task-edit-dialog):is([open], :not([open])),
.aside-drawer > dialog:is(#task-dialog, #task-edit-dialog).slide-panel:is([open], :not([open])) {
  position: fixed; inset: var(--topbar-h, 77px) 0 0 auto; z-index: 30;
  width: min(var(--side-panel-w), 100vw); height: calc(100vh - var(--topbar-h, 77px)); max-height: none;
  margin: 0; padding: var(--sp-4) var(--sp-5) 0; box-sizing: border-box; overflow-y: auto;
  border: 0; border-left: 1px solid var(--line); border-radius: 0;
  background: var(--surface); box-shadow: var(--shadow-panel);
}
.aside-drawer > dialog:is(#task-dialog, #task-edit-dialog).slide-panel:is([open], :not([open])) { position: static; width: 100%; height: 100%; box-shadow: none; border-left: 0; }
/* The goal colour stays a thin line along the top, not a slab. */
#goal-dialog.slide-panel, #task-edit-dialog.slide-panel { border-top: 2px solid var(--goal, var(--line)) !important; }
/* Slimmer insides: smaller heading, shorter fields, tighter tiles. */
:is(#task-dialog, #task-edit-dialog, #goal-dialog) :is(.task-form > h2, form > h2) { font-size: var(--fs-heading); margin: 0 0 var(--sp-1-5); }
:is(#task-dialog, #task-edit-dialog, #goal-dialog) :is(input[type=text], input[type=date], input[type=number], select) { min-height: 34px; height: 34px; padding: 0 var(--sp-2-5); font-size: var(--fs-base); }
:is(#task-dialog, #task-edit-dialog, #goal-dialog) input[name=title] { min-height: 38px; height: 38px; font-size: var(--fs-body); }
:is(#task-dialog, #task-edit-dialog, #goal-dialog) textarea { min-height: 64px; font-size: var(--fs-base); }
:is(#task-dialog, #task-edit-dialog) .task-form { gap: var(--sp-2); }
:is(#task-dialog, #task-edit-dialog) .icon-choice label { padding: var(--sp-1-5) var(--sp-1); font-size: var(--fs-sm); }
:is(#task-dialog, #task-edit-dialog) .tf-tile { padding: var(--sp-1-5) var(--sp-2); font-size: var(--fs-sm); }
:is(#task-dialog, #task-edit-dialog, #goal-dialog) :is(.task-form > .actions, form > .actions) {
  position: sticky; bottom: 0; z-index: 1; margin: var(--sp-2) calc(-1 * var(--sp-5)) 0; padding: var(--sp-3) var(--sp-5) var(--sp-3);
  background: var(--surface); border-top: 1px solid var(--divider);
}
/* The top bar doesn't move when a panel opens on the Calendar - the switch
   stays put and only the page under it gives way. */
body[data-view="calendar"].s-cal.cal-composing .topbar { margin-right: calc(calc(-1 * var(--sp-8)) - var(--aside-open)); }

/* -- Task form (Ed, 28 Oct) --
   Title, description, time, a quiet "+ Add duration", completion (None by
   default), then the day - with repeating folded behind "+ Repeat…". */
.tf-add-duration {
  align-self: flex-start; margin: calc(-1 * var(--sp-0-5)) 0 var(--sp-0-5); padding: 0; border: 0; background: none;
  font: inherit; font-size: var(--fs-sm); color: var(--muted); cursor: pointer;
}
.tf-add-duration:hover { color: var(--ink); text-decoration: underline; }
.tf-lane .tf-add-duration { margin-top: var(--sp-1-5); }
:is(#task-dialog, #task-edit-dialog) .icon-choice { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
:is(#task-dialog, #task-edit-dialog) .icon-choice label[hidden] { display: none; }
#task-dialog .icon-choice:has(label[hidden]) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
#task-dialog .tf-lanes, #task-dialog .tf-lanes { min-height: 0; }

/* Date fields: typed or picked from a small month (Ed, 28 Oct). */
.date-field { display: inline-flex; align-items: stretch; gap: 0; }
.date-field .date-text {
  width: 118px; height: 34px; min-height: 34px; padding: 0 var(--sp-2-5); box-sizing: border-box;
  border: 1px solid var(--line); border-right: 0; border-radius: var(--r-input) 0 0 var(--r-input); background: var(--surface);
  color: var(--ink); font: inherit; font-size: var(--fs-base); font-variant-numeric: tabular-nums;
}
.date-field .date-text.invalid { border-color: var(--danger); }
.date-field .date-pick {
  display: inline-grid; place-items: center; width: 34px; height: 34px; padding: 0;
  border: 1px solid var(--line); border-radius: 0 var(--r-input) var(--r-input) 0; background: var(--surface); color: var(--ink); cursor: pointer;
}
.date-field .date-pick:hover { background: var(--page); }
.date-field .date-pick svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.date-field :disabled { opacity: var(--state-disabled); cursor: default; }
.date-pop {
  position: fixed; z-index: 70; width: 252px; padding: var(--sp-2-5); box-sizing: border-box;
  background: var(--surface); border: 1px solid var(--faint); border-radius: var(--r-card); box-shadow: var(--shadow-menu);
  animation: fan-in var(--motion-fast) var(--ease-enter);
}
.date-pop-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-1-5); font-size: var(--fs-md); color: var(--ink); }
.date-pop-nav { width: 26px; height: 26px; border: 0; border-radius: var(--r-input); background: none; color: var(--ink); font-size: var(--fs-body); cursor: pointer; }
.date-pop-nav:hover { background: var(--page); }
.date-pop-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--sp-0-5); }
.date-pop-dow { font-size: var(--fs-2xs); font-weight: var(--fw-semi); color: var(--muted); text-align: center; padding: var(--sp-0-5) 0; }
.date-pop-day {
  height: 30px; border: 0; border-radius: var(--r-input); background: none; color: var(--ink);
  font: inherit; font-size: var(--fs-sm); font-variant-numeric: tabular-nums; cursor: pointer;
}
.date-pop-day:hover { background: var(--page); }
.date-pop-day.outside { color: var(--faint-text); }
.date-pop-day.is-today { box-shadow: inset 0 0 0 1px var(--ink); }
.date-pop-day.selected { background: var(--ink); color: var(--surface); }
.date-pop-day:disabled { color: var(--faint-text); opacity: 0.4; cursor: default; background: none; }
.date-pop-foot { display: flex; justify-content: space-between; margin-top: var(--sp-1-5); }
.date-pop-foot .btn { height: 26px; min-height: 0; padding: 0 var(--sp-2); font-size: var(--fs-sm); }
@media (prefers-reduced-motion: reduce) { .date-pop { animation: none; } }

/* Naming a new Goal or Routine in place (Ed, 28 Oct). */
.nav-edit { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-1) var(--sp-1-5) var(--sp-1) var(--sp-2); }
.nav-colour-dot {
  flex: none; width: 18px; height: 18px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: var(--swatch); box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 15%, transparent);
}
.nav-colour-dot:hover { box-shadow: 0 0 0 2px var(--ink); }
.nav-name-input {
  flex: 1; min-width: 0; height: 30px; padding: 0 var(--sp-2); box-sizing: border-box;
  border: 1px solid var(--ink); border-radius: var(--r-input); background: var(--surface); color: var(--ink); font: inherit; font-size: var(--fs-base);
}
.nav-colour-pop {
  position: fixed; z-index: 70; width: 230px; padding: var(--sp-3); box-sizing: border-box;
  background: var(--surface); border: 1px solid var(--faint); border-radius: var(--r-card); box-shadow: var(--shadow-menu);
}

/* -- Adding something (Ed, 28 Oct) --
   The top bar's controls and the rest of the left panel step back, grey and
   quiet, while a task is being added; the relevant Goal / Milestone /
   Routine opens out as a small tree with the new task's place in it. */
.topbar :is(.topbar-left, .view-switch, .settings-wrap),
.sidebar :is(h2, .nav-row, .nav-entry, .muted), #new-fan {
  transition: opacity var(--motion-fast) var(--ease-fade), filter var(--motion-fast) var(--ease-fade);
}
body.adding .topbar :is(.topbar-left, .view-switch, .settings-wrap),
body.adding .sidebar :is(h2, .nav-row:not(.add-focus), .nav-entry, .muted),
body.adding #new-fan { opacity: 0.35; filter: grayscale(1); pointer-events: none; user-select: none; }
.nav-tree { position: relative; margin: var(--sp-0-5) 0 var(--sp-2) var(--sp-4); padding-left: var(--sp-3); border-left: 1.5px solid color-mix(in srgb, var(--goal) 55%, var(--line)); }
.nav-tree-node {
  position: relative; padding: var(--sp-1) var(--sp-1-5); font-size: var(--fs-md); color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.nav-tree-node::before {
  content: ""; position: absolute; left: -12px; top: 50%; width: 9px;
  border-top: 1.5px solid color-mix(in srgb, var(--goal) 55%, var(--line));
}
.nav-tree-node.selected { color: var(--ink); font-weight: 650; }
.nav-tree-branch { margin-left: var(--sp-3); padding-left: var(--sp-3); border-left: 1.5px solid color-mix(in srgb, var(--goal) 55%, var(--line)); }
.nav-tree-new {
  margin: var(--sp-0-5) 0; border-radius: var(--r-block); color: var(--ink); font-weight: var(--fw-semi); font-style: italic;
  background: color-mix(in srgb, var(--goal) 12%, var(--surface)); box-shadow: inset 0 0 0 1px var(--goal);
}
@media (prefers-reduced-motion: reduce) { body.adding * { transition: none !important; } }
:is(#task-dialog, #task-edit-dialog, #goal-dialog) .date-field .date-text { width: 118px; flex: none; margin: 0; }
:is(#task-dialog, #task-edit-dialog, #goal-dialog) .tf-inline:has(.date-field),
#goal-dialog label:has(.date-field) { display: flex; align-items: center; gap: var(--sp-2-5); flex-wrap: nowrap; }
:is(#task-dialog, #task-edit-dialog) .tf-lane[data-lane="one_off"] { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1) var(--sp-3); }
:is(#task-dialog, #task-edit-dialog) .tf-lane[data-lane="one_off"] .tf-add-duration { flex-basis: 100%; }

/* Adding a task is one movement (Ed, 28 Oct): the page gives way, the panel
   slides in and everything else greys - same length, same curve. */
body { --panel-ms: var(--motion-panel); --panel-ease: var(--ease-enter); }
.content { transition: margin-left var(--sidebar-ms) var(--sidebar-ease) var(--motion-delay), margin-right var(--panel-ms) var(--panel-ease); }
.topbar :is(.topbar-left, .view-switch, .settings-wrap),
.sidebar :is(h2, .nav-row, .nav-entry, .muted), #new-fan {
  transition: opacity var(--panel-ms) var(--panel-ease), filter var(--panel-ms) var(--panel-ease);
}
.nav-tree { animation: tree-in var(--motion-fast) var(--ease-enter); }
@keyframes tree-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .nav-tree { animation: none; } .content { transition: none; } }

/* The calendar's heading row never wraps: a long day note trims with "…"
   rather than pushing Today onto a second line (Ed, 28 Oct - that made Day
   taller than the window). */
.calendar-panel > .toolbar { flex-wrap: nowrap; }
.calendar-panel > .toolbar .range-title, .calendar-panel > .toolbar .calendar-controls { flex: none; }
.calendar-panel > .toolbar .day-note { flex: 1 1 0; max-width: 520px; }



/* -- The right rail (Ed, 28 Oct; option R2) --
   A slim strip down the window's right edge, under the top bar, on the
   Calendar: the panel button, then an icon per card (Waiting with its orange
   count). The calendar - and the panel, open - stops the same 28px short of
   it as it sits from the left panel, so the grid reads centred. */
body { --rail-w: 44px; --rail-gap: 28px; }
.tray-rail {
  position: fixed; z-index: 30; top: var(--topbar-h); right: 0; bottom: 0; width: var(--rail-w);
  box-sizing: border-box; padding: var(--sp-3) 0; display: flex; flex-direction: column; align-items: center; gap: var(--sp-1-5);
  background: var(--surface); border-left: 1px solid var(--line);
}
body:not([data-view="calendar"]) .tray-rail, body.s-cal.cal-composing .tray-rail, body.s-cal.dlg-form-open .tray-rail, .tray-rail[hidden] { display: none; }
.rail-btn {
  position: relative; display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0;
  border: 0; border-radius: var(--r-input); background: none; color: var(--muted); cursor: pointer;
}
.rail-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.rail-btn:hover, .rail-btn:focus-visible { background: var(--sunk); color: var(--ink); }
.rail-btn.on { background: var(--sunk); color: var(--ink); }
.rail-panel { color: var(--ink); }
.rail-sep { width: 20px; height: 1px; margin: var(--sp-1) 0; background: var(--line); }
.rail-count {
  position: absolute; top: -3px; right: -6px; padding: 0 var(--sp-1); border-radius: var(--r-pill);
  background: var(--badge-fill); color: var(--on-badge); font-size: var(--fs-2xs); font-weight: var(--fw-bold); line-height: 14px;
}
body[data-view="calendar"].s-cal:not(.cal-composing) .calendar-main {
  padding-right: calc(var(--rail-w) + var(--rail-gap) - var(--sp-8));
}
.calendar-main > .cal-side { margin-left: var(--sp-4); }

/* Month: done looks the same as planned; a missed bar is the grey stripes
   (Chunk 180). The key under the grid says just "Missed". */
#calendar-grid.month .month-day:not(.today) .entry.cal-entry:not(.today-entry)[data-density="bar"] { background: var(--block); }
#calendar-grid.month .month-day.today .entry.cal-entry:not(.today-entry):not(.missed)[data-density="bar"] { background: var(--on-feature-block); }
/* A past day's cell is the planned bar's own grey, so its bars go a step
   lighter to stay bars rather than bare text. */
#calendar-grid.month .month-day.past .entry.cal-entry:not(.today-entry)[data-density="bar"] { background: var(--surface); }
#calendar-grid.month:not(.class-highlighting) .month-day.past .entry.cal-entry:not(.today-entry):not(.missed)[data-density="bar"] { opacity: 1; }
#calendar-grid.month .month-day.past .entry.cal-entry:not(.today-entry)[data-density="bar"] .entry-title { color: var(--text-2); }

/* Renaming in place on a double-click (Ed, 29 Oct): the name becomes a box
   in its own type, so nothing jumps. */
.rename-input {
  width: 100%; min-width: 6ch; box-sizing: border-box; margin: 0 0 0 calc(-1 * var(--sp-1)); padding: 0 var(--sp-1);
  font: inherit; letter-spacing: inherit; color: inherit; line-height: inherit;
  background: var(--surface); border: 0; border-radius: var(--r-input); outline: 1px solid var(--line);
}
.rename-input:focus { border-color: var(--ink); }
#day-note:has(.rename-input) { overflow: visible; }

/* -- Year as a calendar (Ed, 29 Oct; option Y1) --
   Twelve small months, dates only. Today a black circle, a target date ringed
   in its colour (orange once over); a hovered Goal or Routine rings every day
   it has something on. */
#calendar-grid.year { overflow-y: auto; overscroll-behavior: contain; }
.year-months { display: grid; grid-template-columns: repeat(var(--year-cols), minmax(0, 1fr)); gap: var(--sp-6) var(--sp-5); padding: var(--sp-0-5) 0 var(--sp-2); }
.ym-name {
  display: block; margin: 0 0 var(--sp-2); padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: var(--fs-body); font-weight: var(--fw-bold); color: var(--ink); text-align: left;
}
.ym-name:hover { text-decoration: underline; text-underline-offset: 3px; }
/* The current month in Ink at full weight, the others a step back (Chunk 85,
   look audit Y1: orange is only the full stop and missed / waiting). */
.ym-month:not(.now) .ym-name { font-weight: var(--fw-semi); color: var(--text-2); }
.ym-month.now .ym-name { font-weight: var(--fw-heavy); color: var(--ink); }
.ym-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); row-gap: var(--sp-0-5); text-align: center; }
.ym-wd { padding-bottom: var(--sp-1); font-size: var(--fs-2xs); font-weight: var(--fw-semi); color: var(--muted); }
.ym-d {
  display: flex; align-items: center; justify-content: center; height: 26px; padding: 0;
  border: 0; border-radius: var(--r-input); background: none; cursor: pointer;
  font: inherit; font-size: var(--fs-sm); color: var(--ink); font-variant-numeric: tabular-nums;
}
.ym-d:hover { background: var(--sunk); }
.ym-d.past { color: var(--muted); }
.ym-n { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: var(--r-pill); }
.ym-d.today .ym-n { background: var(--ink); color: var(--surface); font-weight: var(--fw-bold); }
.ym-d.target .ym-n { box-shadow: inset 0 0 0 1.5px var(--t); color: var(--ink); font-weight: var(--fw-semi); }
/* Over its target date: an Ink ring, never orange (Ed, 2 Nov: lateness is
   Ink or the goal's own colour; orange is missed and waiting only). */
.ym-d.target.over .ym-n { box-shadow: inset 0 0 0 2px var(--over-ink); }
/* Year's eyes (Ed, 2 Nov): a day with shown classes gets a ring just outside
   its number, sliced like a pie when there are several. Hovering a row
   shows that class alone, so the rings step back meanwhile. */
.ym-n { position: relative; }
.ym-d.ringed .ym-n::before {
  content: ""; position: absolute; inset: -2px; border-radius: var(--r-pill); background: var(--ring);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2px));
  pointer-events: none;
}
.ym-d.ringed .ym-n { color: var(--ink); font-weight: var(--fw-semi); }
.ym-d.today.ringed .ym-n { color: var(--surface); }
.ym-d.today.ringed .ym-n::before { inset: -4px; }
#calendar-grid.class-highlighting .ym-d.ringed .ym-n::before { display: none; }
#calendar-grid.class-highlighting .ym-d.class-hit .ym-n { box-shadow: inset 0 0 0 1.5px var(--hit); color: var(--ink); }
#calendar-grid.class-highlighting .ym-d.today.class-hit .ym-n { color: var(--surface); box-shadow: 0 0 0 2px var(--surface), 0 0 0 3.5px var(--hit); }

/* -- Collections (Ed, 2 Nov) --
   Its page lists the Events: upcoming with their day, past with whether they
   happened - happened in ink, didn't happen in quiet grey (never orange: a
   Collection's Events aren't missed). */
#collection-detail .coll-row {
  width: 100%; border: 0; background: none; font: inherit; text-align: left; cursor: pointer; color: var(--ink);
}
#collection-detail .coll-state { flex: none; margin-left: auto; font-size: var(--fs-md); color: var(--muted); white-space: nowrap; }
#collection-detail .coll-row.is-happened .coll-state { color: var(--ink); font-weight: var(--fw-semi); }
#collection-detail .coll-row.is-didnt .title { color: var(--muted); }
#collection-detail .coll-row.is-didnt .fv-dash { background: var(--done-fill); }
#collection-detail .coll-tasks > summary { align-items: center; list-style: none; cursor: pointer; }
#collection-detail .coll-tasks > summary::-webkit-details-marker { display: none; }
#collection-detail .coll-tasks > summary::after { content: "›"; color: var(--muted); font-size: var(--fs-lg); }
#collection-detail .coll-tasks[open] > summary::after { content: "⌄"; }
/* Chunk 74: a Collection reads as a set of things - a date tile per item
   (in the Collection's colour while coming up), Past grouped by year. */
#collection-detail .coll-items { display: flex; flex-direction: column; }
#collection-detail .coll-item {
  display: grid; grid-template-columns: 56px 1fr auto; gap: var(--sp-4); align-items: center; width: 100%;
  padding: var(--sp-2-5); border: 0; border-top: 1px solid var(--divider); background: none; font: inherit; text-align: left; cursor: pointer; color: var(--ink);
}
#collection-detail .coll-text { display: flex; flex-direction: column; gap: var(--sp-0-5); min-width: 0; }
#collection-detail .coll-text .title { font-size: var(--fs-body); font-weight: var(--fw-medium); }
#collection-detail .coll-date { text-align: center; border-radius: var(--r-small); padding: var(--sp-1-5) 0 var(--sp-1-5); background: var(--sunk); }
#collection-detail .coll-date small { display: block; font-size: var(--fs-xs); font-weight: var(--fw-semi); letter-spacing: .06em; color: var(--muted); text-transform: uppercase; }
#collection-detail .coll-date b { display: block; font: 800 var(--fs-heading)/1 var(--font-head); font-variant-numeric: tabular-nums; margin-top: var(--sp-0-5); }
#collection-detail .coll-item.is-up .coll-date { background: var(--goal); color: var(--on-goal, #fff); }
#collection-detail .coll-item.is-up .coll-date small { color: color-mix(in srgb, var(--on-goal, #fff) 85%, transparent); }
#collection-detail .coll-item.is-didnt .title, #collection-detail .coll-item.is-didnt .coll-date b { color: var(--muted); }
#collection-detail .coll-year { display: flex; align-items: baseline; gap: var(--sp-2-5); padding: var(--sp-3) var(--sp-2-5) var(--sp-1); }
#collection-detail .coll-year h4 { margin: 0; font: 800 var(--fs-xl) var(--font-head); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
#collection-detail .coll-year span { font-size: var(--fs-md); color: var(--muted); }
#collection-detail .coll-year-group.shut > summary { list-style: none; cursor: pointer; border-top: 1px solid var(--divider); }
#collection-detail .coll-year-group.shut > summary::-webkit-details-marker { display: none; }
#collection-detail .coll-year-group.shut .coll-year { padding: var(--sp-3) var(--sp-2-5); }
#collection-detail .coll-year-group.shut .coll-year h4 { font-size: var(--fs-lg); }
#collection-detail .coll-year-group.shut .coll-year::after { content: "›"; margin-left: auto; color: var(--muted); font-size: var(--fs-lg); }
#collection-detail .coll-year-group.shut[open] .coll-year::after { content: "⌄"; }
#collection-detail .coll-more { display: block; width: 100%; padding: var(--sp-3) var(--sp-2-5); border: 0; border-top: 1px solid var(--divider); background: none; font: inherit; font-size: var(--fs-base); color: var(--muted); text-align: left; cursor: pointer; }
#collection-detail .coll-more:hover { color: var(--ink); }

/* Chunk 74: Routine stats - the Routine's colour only, never orange. */
#routine-detail .rs-card .fv-card-head { align-items: baseline; }
#routine-detail .rs-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--sp-8); }
#routine-detail .rs-bars { display: flex; align-items: flex-end; gap: var(--sp-1-5); height: 120px; margin: 0 var(--sp-2-5); border-bottom: 1px solid var(--line); }
#routine-detail .rs-b { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; height: 100%; }
#routine-detail .rs-b i { display: block; background: var(--goal); border-radius: var(--r-block) var(--r-block) 0 0; min-height: 2px; }
#routine-detail .rs-b.now i { background: repeating-linear-gradient(58deg, var(--goal) 0 4px, transparent 4px 7px); border: 1px solid var(--goal); border-bottom: 0; }
#routine-detail .rs-b.none i { background: var(--faint); border: 0; }
#routine-detail .rs-axis { display: flex; gap: var(--sp-1-5); margin: var(--sp-1-5) var(--sp-2-5) 0; font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
#routine-detail .rs-axis span { flex: 1; text-align: center; white-space: nowrap; }
#routine-detail .rs-wk { display: flex; flex-direction: column; gap: var(--sp-2); padding: 0 var(--sp-2-5); }
#routine-detail .rs-wk div { display: grid; grid-template-columns: 34px 1fr 40px; gap: var(--sp-2-5); align-items: center; font-size: var(--fs-md); color: var(--muted); }
#routine-detail .rs-wk s { text-decoration: none; height: 10px; background: var(--divider); border-radius: var(--r-block); overflow: hidden; }
#routine-detail .rs-wk s i { display: block; height: 100%; background: var(--goal); }
#routine-detail .rs-wk b { text-align: right; font-weight: var(--fw-semi); color: var(--ink); font-variant-numeric: tabular-nums; }
#routine-detail .rs-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--sp-1-5); padding: 0 var(--sp-2-5); }
#routine-detail .rs-days div { text-align: center; font-size: var(--fs-xs); color: var(--muted); }
#routine-detail .rs-days i { display: block; height: 34px; border-radius: var(--r-block); margin-top: var(--sp-1-5); background: var(--sunk); }
#routine-detail .rs-days i.done { background: var(--goal); }
#routine-detail .rs-days i.part { background: linear-gradient(to top, var(--goal) var(--fill), var(--sunk) var(--fill)); }
#routine-detail .rs-days i.miss { box-shadow: inset 0 0 0 1px var(--line); }
#routine-detail .rs-days i.before, #routine-detail .rs-days i.free { background: transparent; border: 1px dashed var(--line); }
#routine-detail .rs-days div.today { color: var(--ink); font-weight: var(--fw-semi); }
@media (max-width: 720px) { #routine-detail .rs-stats { grid-template-columns: 1fr; gap: var(--sp-6); } }

/* -- No time set (Ed, 2 Nov) --
   Day pins its untimed events above the hours, at a card's ordinary height,
   beside the day's targets and all-day linked entries. On the day in focus
   the strip is always there - empty, it just says so - so a timed event can
   be dragged up into it to lose its time. */
.day-untimed.drop-over { outline: 1.5px dashed var(--ink); outline-offset: 2px; }
.cal-entry.leaving-time { opacity: 0.35; }
.drag-ghost.timed { outline: 1.5px solid var(--ink); }

/* -- The left panel's eye (Ed, 2 Nov) --
   Over the row's right end, so the panel never widens: shown on hover, and
   always (crossed out) while that item is hidden on this zoom. */
.sidebar .nav-row { position: relative; }
.nav-eye {
  position: absolute; top: 50%; right: 4px; transform: translateY(-50%);
  display: none; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0;
  border: 0; border-radius: var(--r-input); background: none; color: var(--muted); cursor: pointer;
}
/* The name trims a little sooner to make room for it, the row's own width unchanged. */
.sidebar .nav-row:hover:not(:has(.nav-eye[hidden])) .nav-goal, .sidebar .nav-row.class-hidden:not(:has(.nav-eye[hidden])) .nav-goal { padding-right: var(--sp-7); } /* Gate 2 YR4: not where the eye is hidden (a linked calendar on Year) */
.nav-eye svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.nav-eye:hover, .nav-eye:focus-visible { color: var(--ink); }
.sidebar .nav-row:hover .nav-eye, .nav-row.class-hidden .nav-eye, .nav-eye:focus-visible { display: inline-flex; }
.nav-eye[hidden] { display: none !important; }
.nav-row.class-hidden .nav-goal .nav-label { color: var(--muted); }
.nav-row:has(.nav-edit) .nav-eye, body.adding .nav-eye { display: none; }
#calendar-grid .ym-d.ring-off .ym-n { box-shadow: none; font-weight: inherit; }

/* -- The Task being made, on the calendar (Ed, 2 Nov) --
   Its preview faint, with a dashed edge (not saved yet); a hovered day's copy
   fainter still; the day under the pointer outlined; a "times per period"
   Task's week or month shaded; while editing, its own events faded. */
#calendar-grid .cal-entry.draft-preview { opacity: 0.62; outline: 1.5px dashed var(--goal, var(--ink)); outline-offset: -1.5px; }
#calendar-grid .cal-entry.draft-hover { opacity: 0.35; pointer-events: none; }
#calendar-grid .cal-entry.draft-original { opacity: 0.3; }
#calendar-grid .compose-hover { outline: 2px solid var(--ink); outline-offset: -2px; }
#calendar-grid .draft-window { box-shadow: inset 0 0 0 999px color-mix(in srgb, var(--draft, var(--ink)) 9%, transparent); }
body.s-cal.cal-composing #calendar-grid [data-day] { cursor: pointer; }

/* -- A thinner top bar (Ed, 2 Nov) --
   77px down to 60, its buttons and the Today/Calendar switch slimmer to match. */
body { --topbar-h: 60px; }
.topbar { min-height: var(--topbar-h); padding-top: var(--sp-2-5); padding-bottom: var(--sp-2-5); }
.topbar .brand { min-height: 36px; }
.nav-toggle { width: 36px; height: 36px; }
.topbar .topbar-review { min-height: 36px; height: 36px; }
#topbar-settings { width: 36px; padding: 0; }
.view-switch { padding: var(--sp-0-5); }
.view-switch button { min-height: 32px; font-size: var(--fs-base); }
.view-thumb { height: 30px; }
.calendar-badge { top: -8px; min-width: 20px; height: 20px; font-size: var(--fs-xs); }
.rv-bar { min-height: var(--topbar-h); padding-top: var(--sp-2-5); padding-bottom: var(--sp-2-5); }

/* Opening splash (Ed, 2 Nov): the brand loop once, over the page, then gone. */
.splash { position: fixed; inset: 0; z-index: 10000; display: grid; place-items: center; background: var(--page); transition: opacity var(--motion-panel) var(--ease-fade); }
.splash svg { display: block; }
.splash.gone { opacity: 0; pointer-events: none; }

.today-review-dot { width: 10px; height: 10px; border-radius: var(--r-pill); background: var(--ink); transition: transform var(--motion-out) var(--ease-move); }

/* ===== 3 Nov quick drops ===== */

/* Where the week is going: quieter. */
.week-going:not(.is-key) { padding: var(--sp-3) var(--sp-4); gap: var(--sp-2-5); }
.week-going .going-head h3 { font-size: var(--fs-lg); font-weight: var(--fw-medium); }
.week-going .going-bar { height: 8px; opacity: 0.7; }
.week-going .going-legend { font-size: var(--fs-sm); color: var(--muted); }
.week-going .going-key strong { font-weight: var(--fw-medium); }


/* Left panel closed: shown Goals, Routines and Collections peek in from the edge. */
.edge-peek { position: fixed; left: 0; top: calc(var(--topbar-h) + 96px); z-index: 28; display: flex; flex-direction: column; gap: var(--sp-1); }
body:not([data-view="calendar"]) .edge-peek, body.left-open .edge-peek, body.reviewing .edge-peek, .edge-peek:empty { display: none; }
.peek-item {
  display: flex; align-items: center; justify-content: flex-end; width: 38px; height: 26px;
  border-left: 8px solid var(--goal, var(--muted)); border-radius: 0 var(--r-block) var(--r-block) 0;
  background: var(--surface); box-shadow: 0 1px 4px rgb(0 0 0 / 0.12);
  transform: translateX(-30px); transition: transform var(--motion-fast) var(--ease-enter);
}
.peek-item:hover, .peek-item:focus-within { transform: none; }
.peek-item .nav-eye { display: inline-flex; position: static; transform: none; margin-right: var(--sp-1); color: var(--ink); }
@media (prefers-reduced-motion: reduce) { .peek-item { transition: none; } }

/* Day labels (Chunk 71): one row per picked day, in week order. */
.tf-day-labels { margin: 0 0 var(--sp-3); }
.tf-day-labels > .tf-field { display: block; margin-bottom: var(--sp-2); }
.tf-label-row { display: grid; grid-template-columns: 40px 1fr; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-1-5); }
.tf-label-row > span { font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--text-2); }
.tf-label-row input { height: 32px; font-size: var(--fs-md); margin: 0; }
.fv-day-labels { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3); margin-top: var(--sp-1); font-size: var(--fs-md); color: var(--text-2); }
.fv-day-labels b { color: var(--muted); font-weight: var(--fw-medium); margin-right: var(--sp-1); }
.history-row.labelled { grid-template-columns: minmax(9em, 1.4fr) minmax(7em, 1.2fr) minmax(7em, 1fr) minmax(0, 2fr) 5em; }
.history-label.none { color: var(--faint-text); }
@media (max-width: 600px) {
  .history-row.labelled { grid-template-columns: 1fr 1fr; }
}

/* -- Milestone Schedule and Log (Chunk 72, docs/brand-identity/mockups/milestone-schedule-log/) -- */
.fv-outline { min-height: 36px; padding: 0 var(--sp-3); border: 1px solid var(--line); background: var(--surface); color: var(--ink); font-size: var(--fs-md); font-weight: var(--fw-medium); }
:is(#goal-detail) .fv-bar.split { display: flex; }
:is(#goal-detail) .fv-bar.split > span { flex: none; }
:is(#goal-detail) .fv-bar > span.fv-bar-logged {
  border-radius: 0; box-shadow: none;
  background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--goal, var(--ink)) 30%, transparent) 0 4px,
    color-mix(in srgb, var(--goal, var(--ink)) 12%, transparent) 4px 7px);
}
#goal-detail .fv-dash.hollow { background: none; border-left: 3px dotted var(--goal, var(--line)); width: 0; }
.pace-slot[hidden] { display: none; }
.tf-eyebrow { margin: 0 0 var(--sp-1); color: var(--muted); font-size: var(--fs-sm); }
.log-sentence b { font-weight: var(--fw-semi); }
#log-dialog, #log-history-dialog { width: min(360px, calc(100vw - 32px)); }
#log-dialog h2, #log-history-dialog h2 { margin: 0 0 var(--sp-3); }
.log-sentence { font-size: var(--fs-body); line-height: 2.2; margin: 0 0 var(--sp-2); }
.log-stepper { display: inline-flex; align-items: stretch; border: 1px solid var(--line); border-radius: var(--r-popover); overflow: hidden; vertical-align: middle; }
.log-stepper[hidden] { display: none; }
.log-stepper button { border: 0; background: none; color: var(--muted); padding: var(--sp-1) var(--sp-2-5); font: inherit; cursor: pointer; }
.log-stepper input { width: 44px !important; text-align: center; font-weight: var(--fw-semi); border: 0; border-left: 1px solid var(--line); border-right: 1px solid var(--line); border-radius: 0; }
.log-amount { width: 72px !important; }
.log-amount[hidden] { display: none; }
.log-result { display: flex; align-items: baseline; gap: var(--sp-1-5); background: var(--page); border-radius: var(--r-block); padding: var(--sp-2-5) var(--sp-3); margin: var(--sp-3) 0 0; font-size: var(--fs-md); color: var(--muted); }
.log-result strong { font-size: var(--fs-lg); color: var(--ink); }
.log-history-list { display: flex; flex-direction: column; max-height: 50vh; overflow: auto; }
.log-entry { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2-5) 0; border-bottom: 1px solid var(--divider); }
.log-entry-text { flex: 1; display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-2-5); align-items: baseline; }
.log-entry-note { flex-basis: 100%; color: var(--text-2); font-size: var(--fs-md); }
.log-entry-actions { display: flex; gap: var(--sp-0-5); }
#log-form .tf-field:not(.tf-inline) { display: block; }
#log-form textarea { width: 100%; resize: vertical; }

/* ---- Chunk 73: goal pace (docs/brand-identity/mockups/goal-pace/) ---- */
.pace-late { color: var(--over-ink); font-weight: var(--fw-semi); }
#goal-detail .pace-slot { padding: 0 var(--sp-2-5) var(--sp-3); }
.pace-chart-box { width: 100%; }
.pace-chart { display: block; width: 100%; height: auto; overflow: visible; }
.pace-chart .pc-target { stroke: var(--line, var(--divider)); stroke-dasharray: 2 3; }
.pace-chart .pc-base { stroke: var(--line, var(--divider)); }
.pace-chart .pc-fill { fill: color-mix(in srgb, var(--goal) 14%, transparent); stroke: none; }
.pace-chart .pc-run { fill: none; stroke: var(--goal); stroke-width: 2; }
.pace-chart .pc-proj { stroke: var(--goal); stroke-width: 2; stroke-dasharray: 5 4; }
.pace-chart .pc-needs { stroke: var(--muted); stroke-width: 1; opacity: .7; }
.pace-chart .pc-tick { stroke: var(--ink); stroke-width: 1.5; }
.pace-chart .pc-finish { fill: var(--goal); stroke: var(--surface); stroke-width: 1.5; }
.pace-chart .pc-finish.late { fill: var(--over-ink); }
.pace-chart text { font-size: var(--fs-xs); fill: var(--muted); }
.pace-lines { margin: var(--sp-1-5) 0 0; display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3); align-items: baseline; font-size: var(--fs-md); color: var(--ink); }
.pace-line2 { color: var(--muted); font-size: var(--fs-sm); }
#goal-detail .fv-pace { margin: calc(-1 * var(--sp-1)) 0 var(--sp-1-5); font-size: var(--fs-body); font-weight: var(--fw-semi); color: inherit; }
#goal-detail .fv-pace .pace-late { color: var(--on-feature); }
.nav-late { flex: none; width: 7px; height: 7px; margin-left: auto; border-radius: 50%; background: var(--over-ink); }
.year-goal-rows .year-proj { position: absolute; top: 6px; height: 2px; background: repeating-linear-gradient(90deg, var(--goal) 0 4px, transparent 4px 8px); }
/* Chunk 99 (Y1): a projected late stretch is Ink stripes - lateness is Ink everywhere else; orange is missed and waiting only. */
.year-goal-rows .year-proj-late { position: absolute; top: 4px; height: 6px; background: repeating-linear-gradient(148deg, var(--over-ink) 0 2px, transparent 2px 5px); }
.year-goal-pace { display: block; font-size: var(--fs-sm); }
.ym-d.projected .ym-n { outline: 1.5px dashed var(--p); outline-offset: 1px; }
.ym-d.projected.late .ym-n { outline-color: var(--over-ink); }
.rv-goals-pair { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
@media (max-width: 1000px) { .rv-goals-pair { grid-template-columns: minmax(0, 1fr); } }
.rv-pace-rows { display: flex; flex-direction: column; gap: var(--sp-1); }
.rv-pace-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--sp-2-5); align-items: start; padding: var(--sp-2) var(--sp-1-5); border: 0; background: none; text-align: left; font: inherit; color: var(--ink); cursor: pointer; border-radius: var(--r-input); }
.rv-pace-row:hover { background: var(--divider); }
.rv-pace-name { display: flex; flex-direction: column; font-weight: var(--fw-semi); min-width: 0; }
.rv-pace-name .pace-line { font-weight: var(--fw-regular); font-size: var(--fs-sm); }
.rv-pace-moved { font-size: var(--fs-sm); color: var(--muted); white-space: nowrap; }
.rv-pace-moved.later { color: var(--over-ink); font-weight: var(--fw-semi); }

/* -- Waiting to be placed (Chunk 75; docs/to-place-audit.md) --
   The one set of tray rules for the block and the list: a slim header (an
   orange edge and a filled count only while something's waiting), a peek of
   the top item under it when closed, then fixed 44px two-line rows - title
   and due date, then left / owner / duration / later periods. Nothing opens
   on hover. */
.tray-foot, .tray-wait-wrap { display: flex; flex-direction: column; gap: var(--sp-1-5); }
.tray-wait {
  display: flex; align-items: center; gap: var(--sp-2); width: 100%; min-height: 40px; padding: 0 var(--sp-2) 0 var(--sp-3); flex: 0 0 auto;
  background: var(--surface); color: var(--ink); font: inherit; text-align: left; cursor: pointer;
  border: 1px solid var(--line); border-left: 2px solid var(--missed-accent); border-radius: var(--r-input);
}
.tray-wait.empty { border-left-color: var(--line); color: var(--muted); }
.tray-wait:hover { background: var(--sunk); }
.tray-wait-title { flex: 1; min-width: 0; font-size: var(--fs-base); font-weight: var(--fw-semi); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tray-wait-count {
  font-size: var(--fs-xs); font-weight: var(--fw-bold); line-height: 18px;
  padding: 0 var(--sp-1-5); border-radius: var(--r-pill); background: var(--badge-fill); color: var(--on-badge);
}
.tray-wait .tray-chev { display: inline-flex; width: 24px; height: 24px; align-items: center; justify-content: center; color: var(--muted); }
.tray-wait .tray-chev svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.8; }
.tray-place { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.tray-place > .side-panel { padding: 0; border: 0; background: none; box-shadow: none; }
.tray-place #unscheduled > h2 { display: none; }
#unscheduled-list { display: flex; flex-direction: column; gap: var(--sp-1); overflow: visible; }

.place-head {
  display: flex; justify-content: space-between; align-items: baseline; width: 100%;
  margin: var(--sp-3) 0 var(--sp-0-5); padding: 0 var(--sp-0-5); border: 0; background: none; font: inherit; cursor: pointer;
  font-size: var(--fs-2xs); font-weight: var(--fw-semi); letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted);
}
.place-head:first-child, .place-tools + .place-head { margin-top: var(--sp-0-5); }
.place-head[aria-expanded="false"]::after { content: none; }
.place-head-n { font-weight: var(--fw-medium); letter-spacing: 0; }
.place-empty { margin: var(--sp-1-5) var(--sp-0-5); font-size: var(--fs-md); }
.btn.quiet.place-more { align-self: flex-start; padding: var(--sp-0-5) var(--sp-1); font-size: var(--fs-sm); color: var(--muted); }
.place-tools { display: flex; gap: var(--sp-1-5); margin-bottom: var(--sp-1); }
.place-search, .place-owner-filter {
  min-width: 0; height: 28px; padding: 0 var(--sp-2); border: 1px solid var(--line); border-radius: var(--r-input);
  background: var(--surface); color: var(--ink); font: inherit; font-size: var(--fs-sm);
}
.place-search { flex: 1 1 auto; }
.place-owner-filter { flex: 0 1 96px; }

.entry.event.tab.place-row {
  display: flex; flex-direction: column; justify-content: center; gap: var(--sp-px); height: 44px; box-sizing: border-box;
  margin: 0; padding: 0 var(--sp-2) 0 var(--sp-2-5); box-shadow: none; flex: 0 0 auto;
  background: var(--surface); border: 1px solid var(--line); border-left: 2px solid var(--goal); border-radius: var(--r-input);
}
.entry.event.tab.place-row:hover, .entry.event.tab.place-row.selected { border-color: var(--muted); border-left-color: var(--goal); }
.entry.event.tab.place-row.place-sub { height: 36px; margin-left: var(--sp-3); }
.place-line, .place-meta { display: flex; align-items: baseline; gap: var(--sp-2); min-width: 0; }
.entry.event.tab.place-row .place-line .entry-title {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--fs-md); font-weight: var(--fw-medium); line-height: 17px; color: var(--ink);
}
.place-due { flex: 0 0 auto; font-size: var(--fs-xs); line-height: 14px; color: var(--muted); white-space: nowrap; }
.place-meta { font-size: var(--fs-xs); line-height: 14px; color: var(--muted); }
.place-left, .place-dur { flex: 0 0 auto; white-space: nowrap; }
.entry.event.tab.place-row .place-owner {
  flex: 0 100 auto; min-width: 0; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--fs-xs); font-weight: var(--fw-regular); color: var(--muted);
}
.entry.event.tab.place-row .place-owner::before {
  content: ""; display: inline-block; width: 6px; height: 6px; margin-right: var(--sp-1); border-radius: 50%; background: var(--goal); vertical-align: 1px;
}
.entry.event.tab.place-row.drag-source { opacity: 0.35; }
.entry.event.tab.place-row { position: relative; cursor: pointer; }
.place-open { position: absolute; inset: 0; z-index: 0; padding: 0; border: 0; border-radius: inherit; background: none; cursor: inherit; }
.place-open:focus-visible { outline: var(--focus-width) solid var(--focus-color); outline-offset: var(--focus-offset); }
.place-row .place-line, .place-row .place-meta { pointer-events: none; }
.place-row .place-fold { position: relative; z-index: 1; pointer-events: auto; }
.place-fold {
  flex: 0 0 auto; margin-left: auto; padding: 0 var(--sp-1); border: 1px solid var(--line); border-radius: var(--r-pill);
  background: none; font: inherit; font-size: var(--fs-2xs); line-height: 14px; color: var(--muted); cursor: pointer;
}
.place-fold:hover, .place-fold[aria-expanded="true"] { color: var(--ink); border-color: var(--muted); }
.tray-wait-wrap .entry.event.tab.place-row.place-peek { margin-left: 0; height: 36px; }
.tray-wait-wrap .place-peek .place-meta { display: none; }

/* Narrow windows (Chunk 75): once the grid would drop under 840px, the tray
   opens over the calendar instead of taking room from it. */
.calendar-main > .cal-side.tray-over {
  position: absolute; z-index: 25; top: 0; bottom: 0; right: calc(var(--rail-w) + var(--rail-gap) - 32px); margin: 0;
  padding: var(--sp-3); box-sizing: border-box; width: calc(var(--tray-w) + 24px); background: var(--page);
  border-left: 1px solid var(--line); box-shadow: -12px 0 24px -12px rgb(0 0 0 / 0.25);
}
.calendar-main > .cal-side.stepped-aside { opacity: 0; pointer-events: none; transition: opacity var(--motion-out) var(--ease-exit); }
@media (prefers-reduced-motion: reduce) { .calendar-main > .cal-side.stepped-aside { transition: none; } }
.pick-ghost kbd {
  display: inline-block; margin-left: var(--sp-1); padding: 0 var(--sp-1); border: 1px solid var(--line); border-radius: var(--r-input);
  font: inherit; font-size: var(--fs-2xs); line-height: 13px; color: var(--muted); background: var(--surface);
}

/* -- Free time while placing (Chunk 76) --
   Absolutely placed over each day so nothing in the layout moves. Grows in
   over --motion-move, staggered --stagger per day outward from the pointer's
   day, the stagger capped at --motion-fast (M14); fades out over
   --motion-out. Dashed (tight) where no gap fits the item. */
#calendar-grid [data-day] { position: relative; }
.free-mark { pointer-events: none; z-index: 3; }
.free-bar { position: absolute; inset: 0; font-size: var(--fs-2xs); font-weight: var(--fw-semi); color: var(--goal); }
.free-bar .free-label { position: absolute; top: 7px; right: 8px; white-space: nowrap; }
.free-bar .free-fill {
  position: absolute; left: 0; bottom: 0; height: 4px; border-radius: var(--r-dash); background: var(--goal); transform-origin: left;
  animation: free-grow var(--motion-move) var(--ease-enter) both; animation-delay: min(calc(var(--i) * var(--stagger)), var(--motion-fast));
}
.free-bar.tight .free-fill { background: none; border-top: 2px dashed var(--goal); height: 2px; }
body.placing-free .week-day-foot { visibility: hidden; }
.free-strip {
  position: absolute; left: 10px; right: 10px; bottom: 10px; white-space: nowrap; display: flex; flex-direction: column; gap: var(--sp-0-5);
  font-size: var(--fs-2xs); font-weight: var(--fw-semi); color: var(--goal);
}
.free-strip .free-track { position: relative; height: 6px; border-radius: var(--r-dash); background: var(--sunk); overflow: hidden; }
.free-strip .free-track > span {
  position: absolute; top: 0; bottom: 0; background: var(--goal); transform-origin: left;
  animation: free-grow var(--motion-move) var(--ease-enter) both; animation-delay: min(calc(var(--i) * var(--stagger)), var(--motion-fast));
}
.free-strip.tight .free-track > span { background: none; border: 1px dashed var(--goal); box-sizing: border-box; }
.free-gap {
  position: absolute; left: 52px; right: 6px; box-sizing: border-box; border-radius: var(--r-input);
  background: color-mix(in srgb, var(--goal) 14%, transparent); border: 1px solid color-mix(in srgb, var(--goal) 45%, transparent);
  font-size: var(--fs-2xs); font-weight: var(--fw-semi); color: var(--goal); padding: var(--sp-0-5) var(--sp-1-5); overflow: hidden;
  transform-origin: top; animation: free-grow-y var(--motion-move) var(--ease-enter) both;
}
.free-gap.tight { background: none; border-style: dashed; }
.free-slot {
  position: absolute; left: 52px; right: 6px; z-index: 4; box-sizing: border-box; border-radius: var(--r-input);
  border: 1.5px dashed var(--goal); background: color-mix(in srgb, var(--goal) 22%, var(--surface));
  font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--ink); padding: var(--sp-0-5) var(--sp-1-5); overflow: hidden;
}
.free-mark.leaving { opacity: 0; transition: opacity var(--motion-out) var(--ease-exit); }
@keyframes free-grow { from { transform: scaleX(0); } to { transform: none; } }
@keyframes free-grow-y { from { transform: scaleY(0); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .free-bar .free-fill, .free-strip .free-track > span, .free-gap { animation: none; }
  .free-mark.leaving { transition: none; }
}

/* -- Drop preview (motion.md M10, Chunk 91) --
   Where a held item lands: one faint slot in its colour (Day takes
   .free-slot's look and place). It fades in from JS over --motion-fast, then
   jumps with the pointer. The drop outline fades in too while dragging;
   a refused one steps in, as a state, not a movement (M9). */
.drop-slot { position: absolute; z-index: 4; pointer-events: none; box-sizing: border-box; }
.drop-slot:not(.free-slot) {
  border: 1.5px dashed var(--goal, var(--muted)); border-radius: var(--r-block);
  background: color-mix(in srgb, var(--goal, var(--muted)) 16%, transparent);
}
body.dragging #calendar-grid [data-day], body.dragging .drop-target {
  outline: 2px solid transparent; outline-offset: -2px;
  transition: box-shadow var(--motion-fast) var(--ease-fade), outline-color var(--motion-fast) var(--ease-fade);
}
body.dragging #calendar-grid [data-day].drop-over, body.dragging .drop-target.drop-over { outline-color: var(--muted); }
body.dragging #calendar-grid [data-day].drop-invalid, body.dragging .drop-target.drop-invalid { transition: none; }
body.dragging #calendar-grid [data-day].drop-over.drop-invalid, body.dragging .drop-target.drop-over.drop-invalid { outline: 2px dashed var(--danger); }
@media (prefers-reduced-motion: reduce) {
  body.dragging #calendar-grid [data-day], body.dragging .drop-target { transition: none; }
}

/* Day layout (day-layout mock, 2 Nov): one hour column (--gut) and one event
   column. The no-time strip, the timed blocks and the now line all start on
   the event column's edge; "No time" and the now time sit in the hour column. */
#calendar-grid.day-stack > .day-view { --gut: 76px; --pad-r: 20px; position: relative; }
#calendar-grid.day-stack .day-flags {
  display: grid; grid-template-columns: var(--gut) minmax(0, 1fr); align-items: start; gap: 0;
  padding: var(--sp-3) var(--pad-r) var(--sp-3) 0; border-bottom: 1px solid var(--faint); box-sizing: border-box;
}
.day-strip-label { justify-self: end; padding-right: var(--sp-3); font-size: var(--fs-sm); line-height: 32px; color: var(--muted); white-space: nowrap; }
.day-untimed { display: flex; flex-wrap: wrap; gap: var(--sp-2); min-height: 32px; border-radius: var(--r-block); }
.day-untimed > * { flex: 0 1 auto; min-width: 150px; max-width: 280px; height: 32px; box-sizing: border-box; margin: 0; }
.day-untimed > .entry.cal-entry { position: relative; width: auto; --h: 32px; }
#calendar-grid.day-stack .day-untimed > .cal-entry[data-density="lane"] .entry-text { padding-top: var(--sp-1-5); }
.day-untimed > .pennant { display: inline-flex; align-items: center; }
.day-untimed > .ext-event { width: auto; }
.day-untimed-slot { width: 150px; height: 32px; border-radius: var(--r-block); border: 1.5px dashed var(--line); box-sizing: border-box; }
.day-strip-more {
  min-width: 0; padding: 0 var(--sp-3); border: 0; border-radius: var(--r-block); background: var(--track);
  font: inherit; font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--muted); cursor: pointer;
}
.day-strip-more:hover { color: var(--ink); }
#calendar-grid.day-stack .day-pane .hour,
#calendar-grid.day-stack .day-pane .hour.minor { left: var(--gut); right: var(--pad-r); }
#calendar-grid.day-stack .day-pane .hour span { left: auto; right: calc(100% + 12px); top: -9px; line-height: 18px; padding: 0; }
#calendar-grid.day-stack .day-pane .hour.past span { color: var(--faint-text); }
#calendar-grid.day-stack .day-events { left: var(--gut); right: var(--pad-r); }
#calendar-grid.day-stack .day-now { left: calc(var(--gut) - 4px); right: var(--pad-r); }
#calendar-grid.day-stack .day-now::before { left: -1px; }
#calendar-grid.day-stack .day-now-time {
  left: auto; right: calc(100% + 8px); top: -10px; height: 20px; padding: 0 var(--sp-1-5); border-radius: var(--r-pill);
  background: var(--ink); color: var(--surface); font-size: var(--fs-xs); line-height: 20px;
}
#calendar-grid.day-stack :is(.free-gap, .free-slot) { left: var(--gut); right: var(--pad-r); }
.day-blank {
  position: absolute; left: var(--gut); right: var(--pad-r); top: 50%; text-align: center;
  font-size: var(--fs-md); color: var(--faint-text); pointer-events: none;
}

/* ==== Calendar Day and Week, new look (Chunk 84; look-audit.md D and W) ====
   Day's Lanes and Week's cards are one block: 6px goal stripe, 6px corners,
   the text 12px in, title medium Ink over a medium Muted meta line with
   tabular numbers. Week runs a step smaller (seven columns); Day's title
   leads its line, the meta beside it. */
#calendar-grid.day-stack .cal-entry[data-density="lane"] .entry-text,
#calendar-grid.day-stack .cal-entry.state-done[data-density="lane"] .entry-text { padding-left: var(--sp-3); }
#calendar-grid.day-stack .cal-entry[data-density="lane"] .entry-title { font-size: var(--fs-base); font-weight: var(--fw-medium); }
#calendar-grid.day-stack .cal-entry[data-density="lane"] .grid-sub:not(:empty) { font-size: var(--fs-sm); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }
#calendar-grid.week-stack .cal-entry[data-density="chip"] .grid-sub:not(:empty) { font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }
/* "+ N more": the same quiet count on both. */
#calendar-grid.week-stack .fold-more { font-size: var(--fs-md); line-height: var(--lh-meta); }
/* Today's column: a target pill's ring steps back into the Ink (W4). */
#calendar-grid.week-stack .day.today .pennant:not(.is-met):not(.is-over) { border-color: color-mix(in srgb, var(--goal) 60%, var(--feature)); }

#calendar-grid.day-stack .day-pane .hour.under-now span { visibility: hidden; }

/* The day note: a quiet field like the app's other inputs, no Ink edge (D4). */
.calendar-panel > .toolbar .day-note {
  padding: var(--sp-1-5) var(--sp-3); border: 1px solid var(--faint); border-radius: var(--r-input);
  background: var(--surface); line-height: var(--lh-body);
}

/* Up next: drawn like Today's Next up - a card title with the time beside it,
   then the item (D6). */
.day-next { gap: var(--sp-1); }
.day-next-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-2); margin-bottom: var(--sp-1); }
.day-next-kicker { font-family: var(--font-head); font-size: var(--fs-heading); line-height: var(--lh-heading); font-weight: var(--fw-semi); letter-spacing: 0; text-transform: none; color: var(--on-feature); }
.day-next-time { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--on-feature-3); font-variant-numeric: tabular-nums; }
.day-next-title { font-family: var(--font-ui); font-size: var(--fs-lg); line-height: var(--lh-heading); font-weight: var(--fw-semi); letter-spacing: 0; }

/* The day: the stat sits like Month's "so far", planned time on its own line (D5). */
.cal-side .day-sum .sofar-big { margin: 0; }
.cal-side .day-sum .sofar-big strong { font-size: var(--fs-2xl); }
.day-sum-planned { margin: var(--sp-1) 0 0; font-size: var(--fs-md); color: var(--muted); font-variant-numeric: tabular-nums; }

/* Where the week is going: the legend keys are the goal dash, 4 x 20 (W1). */
.week-going .going-legend { align-items: center; }
.week-going .going-key i { width: 4px; height: 20px; border-radius: var(--r-dash); background: var(--goal); box-shadow: none; }

/* Chunk 94: the missed block's suggested slot, first in its actions. */
.slot-move[hidden] { display: none; }

/* The limit card (Chunk 95) */
#limit-dialog { width: min(420px, calc(100vw - 32px)); border: 0; border-radius: var(--r-card); padding: var(--sp-5); background: var(--surface); color: var(--ink); box-shadow: 0 12px 40px rgb(0 0 0 / 0.18); }
#limit-dialog::backdrop { background: rgb(0 0 0 / 0.3); }
#limit-dialog h2 { margin: 0 0 var(--sp-1-5); font-size: var(--fs-lg); }
#limit-dialog p { margin: 0; font-size: var(--fs-base); line-height: 1.45; color: var(--text-2); }
#limit-dialog .actions { display: flex; justify-content: flex-end; gap: var(--sp-2); margin-top: var(--sp-4); }
.plan-seg { grid-template-columns: repeat(2, 1fr); }
.settings-plan.flash .plan-seg { outline: 2px solid var(--ink); outline-offset: 2px; }
.colour-near-note:empty { display: none; }

/* ===== Chunk 86: Goal, Routine, Collection, Milestone and Completed pages =====
   The detail pages on the tokens, from the look audit's P1-P12. */

/* Task rows: the dash and the actions sit with the title and its meta line
   (two lines, about 41px), not centred on a row a period bar or day labels
   make taller. 8 + 41 + 8 is the 56px row. */
:is(#goal-detail, #routine-detail, #collection-detail) .fv-row { align-items: flex-start; padding-block: var(--sp-2); }
:is(#goal-detail, #routine-detail, #collection-detail) .fv-row > .fv-dash { margin-top: var(--sp-2-5); }
:is(#goal-detail, #routine-detail, #collection-detail) .fv-row > .fv-row-actions { margin-top: var(--sp-0-5); }

/* The top bar stays put while a detail page scrolls under it. */
body:is([data-view="goal"], [data-view="routine"], [data-view="collection"], [data-view="completed"]) .topbar { position: sticky; top: 0; }

/* Confirm and Reopen in a Milestone card's head match its 36px buttons. */
#goal-detail .milestone-item .fv-card-head :is(.fv-primary, .fv-pill) { min-height: 36px; padding: 0 var(--sp-4); font-size: var(--fs-md); }
#goal-detail .milestone-item .fv-card-head > .review-badge { align-self: flex-start; margin-top: var(--sp-2); }

/* The Milestone form's Target: a field label like the others, no box. */
#goal-dialog fieldset { margin: var(--sp-2-5) 0; padding: 0; border: 0; }
#goal-dialog legend { padding: 0; font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--ink); }

/* ===== Chunk 101: polish sweep - Goal, Routine, Collection, Milestone and Completed =====
   docs/brand-identity/design-principles.md. Tight margins that fill the page,
   one top edge, no eyebrow labels, Notes as one quiet row, actions as pills
   (one Ink), Completed's goals folded to a row each. Only these four pages. */
.content > :is(#goal-view, #routine-view, #collection-view, #completed-view) { margin-left: 36px; margin-right: -12px; }
body.left-open .content > :is(#goal-view, #routine-view, #collection-view, #completed-view) { margin-left: calc(var(--left-w) - 12px); }
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) { max-width: none; margin: 0; padding: var(--sp-5) 0 var(--sp-6); }
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-head { align-items: center; padding-bottom: var(--sp-4); }
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-titles { gap: var(--sp-0-5); }
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-head h2 { line-height: 40px; }
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-head :is(.fv-pill, .fv-primary, .fv-more) { min-height: 40px; }
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-head .fv-more { width: 40px; height: 40px; border: 0; background: var(--track); }
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-head .fv-more:hover,
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-head .fv-more[aria-expanded="true"] { background: var(--faint); box-shadow: none; }
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-head .fv-pill { border: 0; background: var(--track); }
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-head .fv-pill:hover { background: var(--faint); }
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-body,
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-main,
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-side { gap: var(--sp-4); }
:is(#goal-detail, #routine-detail, #collection-detail) .fv-side { width: 360px; }
/* Stacked, the summary and notes come first, not after the last milestone. */
@media (max-width: 1100px) { :is(#goal-detail, #routine-detail, #collection-detail) .fv-side { width: auto; order: -1; } }

/* Cards: normal padding, ending under the last row. */
:is(#goal-detail, #routine-detail) .fv-card, :is(#collection-detail, #completed-detail) .fv-card { padding: var(--sp-4) var(--sp-5) var(--sp-2); }
:is(#goal-detail, #routine-detail, #collection-detail) .fv-card-head { padding-bottom: var(--sp-2-5); }
:is(#goal-detail, #routine-detail, #collection-detail) .fv-progress { padding-bottom: var(--sp-3); }
:is(#goal-detail, #routine-detail, #collection-detail) .fv-tasks > .fv-rows:first-child,
:is(#goal-detail, #routine-detail, #collection-detail) .fv-tasks > .coll-items:first-child,
:is(#goal-detail, #routine-detail, #collection-detail) .fv-tasks > .fv-empty:first-child { border-top: 0; padding-top: 0; }
:is(#goal-detail, #routine-detail) .fv-tasks > .fv-empty:first-child { padding-bottom: var(--sp-3); }
:is(#goal-detail, #routine-detail, #collection-detail) .fv-card .fv-actions .fv-btn:not(.fv-primary) { min-height: 32px; border: 0; background: var(--track); color: var(--ink); }
:is(#goal-detail, #routine-detail, #collection-detail) .fv-card .fv-actions .fv-btn:not(.fv-primary):hover { background: var(--faint); }
:is(#goal-detail, #routine-detail, #collection-detail) .fv-card-head .fv-more { width: 32px; height: 32px; }
:is(#goal-detail, #routine-detail, #collection-detail) .fv-row-actions .fv-btn { min-height: 32px; }

/* Labels read as plain text, not small caps. */
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-label { font-size: var(--fs-md); letter-spacing: 0; text-transform: none; }
#routine-detail .rs-card .fv-label { font-weight: var(--fw-semi); color: var(--ink); }
:is(#goal-detail, #routine-detail) .fv-summary { padding: var(--sp-4) var(--sp-5); gap: var(--sp-2-5); }

/* Notes: one quiet row, as on Today. */
:is(#goal-detail, #routine-detail, #collection-detail) .notes-block { gap: 0; padding: var(--sp-1) var(--sp-2); }
:is(#goal-detail, #routine-detail, #collection-detail) .notes-block .notes-body {
  display: flex; align-items: center; gap: var(--sp-2); width: 100%; min-height: 44px; padding: var(--sp-2) var(--sp-3);
  border: 0; border-radius: var(--r-input); background: transparent; color: var(--text-2); cursor: pointer; white-space: normal;
}
:is(#goal-detail, #routine-detail, #collection-detail) .notes-block .notes-body.empty { color: var(--muted); }
:is(#goal-detail, #routine-detail, #collection-detail) .notes-block .notes-body:hover { background: var(--page); color: var(--ink); }
:is(#goal-detail, #routine-detail, #collection-detail) .notes-block .notes-body:not(.empty):hover::after { content: "Edit"; flex: none; font-size: var(--fs-sm); color: var(--muted); }
.notes-text { flex: 1; min-width: 0; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; line-height: 1.4; }
.notes-plus { font-size: var(--fs-lg); line-height: 1; }

/* Collection: the next one is the anchor; the rest are quiet. */
#collection-detail .coll-item.is-up:not(:first-child) .coll-date { background: var(--sunk); color: var(--ink); }
#collection-detail .coll-item.is-up:not(:first-child) .coll-date small { color: var(--muted); }

/* ==== The frame, launch look (Chunk 82; docs/look-audit.md F1-F10) ====
   The top bar, the left panel and its rail, taken to the snapshot's launch
   top bar and sidebar within the build checklist's rules. */

/* Top bar: fixed room for quick add, sync status and account (Ed, 2 Nov), so
   nothing shifts when they're built. Empty and inert until then. */
.topbar-slot { flex: none; height: 36px; pointer-events: none; }
.slot-quickadd { width: 200px; }
.slot-sync { width: 64px; }
.slot-account { width: 36px; }
@media (max-width: 1100px) { .slot-quickadd { width: 160px; } }
@media (max-width: 999.98px) { .slot-quickadd { width: 36px; } }

/* The 36px round menu and Settings buttons of the thinner top bar (Ed, 2 Nov)
   take taps over 44px (F2). */
.nav-toggle, #topbar-settings { position: relative; }
.nav-toggle::after, #topbar-settings::after { content: ""; position: absolute; inset: calc(-1 * var(--sp-1)); border-radius: var(--r-pill); }

/* Rail: the round + sits centred under the menu button. */
.new-float { left: var(--sp-3); }

/* Left panel: a little wider so the usual names fit (F6; Ed's narrow panel
   kept), sentence-case labels at meta size, rows in body type (F5). */
body { --left-w: 212px; }
.sidebar .nav-goals h2 .nav-label {
  font-size: var(--fs-sm); font-weight: var(--fw-semi); letter-spacing: 0; text-transform: none; color: var(--muted);
}
.sidebar .nav-goal, .sidebar.expanded .nav-goal { font-weight: var(--fw-regular); color: var(--text-2); }
.sidebar .nav-goal:hover, .sidebar .nav-goal.active, .sidebar.expanded .nav-goal.active { color: var(--ink); }
.sidebar .nav-goal.active { font-weight: var(--fw-medium); }
/* A late Goal's dot is Ink: orange is only missed and waiting (Ed, 2 Nov). */
.nav-late { background: var(--over-ink); }

/* Closed panel's edge tabs (F1): at rest only the colour shows; hover or
   focus slides the tab out to its eye. */
.peek-item { box-sizing: border-box; background: var(--goal, var(--muted)); box-shadow: none; }
.peek-item .nav-eye { opacity: 0; }
.peek-item:hover, .peek-item:focus-within { background: var(--surface); box-shadow: var(--shadow-soft); }
.peek-item:hover .nav-eye, .peek-item:focus-within .nav-eye { opacity: 1; }

/* Calendar header (look audit D3): ‹ › are 44px round and Today a 44px pill,
   white with a 1px border on every zoom, in Chunk 81's surface states. Ed's
   28 Oct placement kept: ‹ › left of the title, Today at the grid's top right. */
#calendar-view .calendar-panel .range-title .range-paging { gap: var(--sp-1); margin-bottom: 0; }
#calendar-view .calendar-panel .range-title .page-arrow,
#calendar-view .calendar-panel .calendar-controls #today {
  height: 44px; min-height: 44px; border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--surface); color: var(--ink); box-shadow: none;
}
#calendar-view .calendar-panel .range-title .page-arrow { width: 44px; padding: 0; }
#calendar-view .calendar-panel .calendar-controls #today { padding: 0 var(--sp-4); font-size: var(--fs-base); font-weight: var(--fw-semi); }
#calendar-view .calendar-panel :is(.range-title .page-arrow, .calendar-controls #today):is(:hover, .is-hover) { background: var(--state-hover-surface); border-color: var(--faint-text); color: var(--ink); }
#calendar-view .calendar-panel :is(.range-title .page-arrow, .calendar-controls #today):is(:active, .is-active) { background: var(--state-active-surface); border-color: var(--faint-text); }
#calendar-view .calendar-panel .range-title .page-arrow svg { stroke-width: 1.8; }

/* ==== Overlays, new look (Chunk 88) ====
   Dialogs, menus, + New, the side-panel forms and Settings on one set of
   surfaces (docs/look-audit.md, O1-O12). Three kinds of overlay:
   - menus ("…", + New, the date picker): 12px, 1px line, menu shadow;
   - popovers (Settings, One-off): 14px, 1px line, menu shadow;
   - modal dialogs (Event, Log, History, confirm, notes, limit): 16px, no border, dialog shadow.
   The forms stay one slim 360px side panel (Ed, 28 Oct). */

/* -- Surfaces -- */
#new-fan-menu, .date-pop { border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow-menu); }
.settings-pop { border: 1px solid var(--line); border-radius: var(--r-popover); box-shadow: var(--shadow-menu); }
dialog:is(#event-dialog, #log-dialog, #log-history-dialog, #confirm-dialog, #notes-dialog, #pattern-dialog, #limit-dialog) {
  border: 0; border-radius: var(--r-dialog); box-shadow: var(--shadow-dialog);
}
dialog:is(#log-dialog, #log-history-dialog, #confirm-dialog, #notes-dialog, #pattern-dialog)::backdrop { background: rgb(20 21 23 / 0.38); }
dialog:is(#log-dialog, #log-history-dialog, #notes-dialog, #pattern-dialog) { padding: var(--sp-5) var(--sp-6); }
body > dialog.slide-panel:is(#task-dialog, #goal-dialog, #task-edit-dialog):is([open], :not([open])) { box-shadow: var(--shadow-panel); }

/* -- Fields: one height (40px) and one shape in every overlay -- */
:is(#task-dialog, #task-edit-dialog, #goal-dialog, #log-dialog, #notes-dialog, .settings-pop)
  :is(input[type=text], input[type=date], input[type=number], input:not([type]), select) {
  height: var(--sp-10); min-height: var(--sp-10); padding: 0 var(--sp-3); box-sizing: border-box;
  border: 1px solid var(--line); border-radius: var(--r-input); background: var(--surface); color: var(--ink);
  font: inherit; font-size: var(--fs-base);
}
:is(#task-dialog, #task-edit-dialog, #goal-dialog) input[name=title] { height: var(--sp-10); min-height: var(--sp-10); font-size: var(--fs-body); }
:is(#task-dialog, #task-edit-dialog, #goal-dialog, #log-dialog, #notes-dialog) textarea {
  padding: var(--sp-2-5) var(--sp-3); border: 1px solid var(--line); border-radius: var(--r-input); font-size: var(--fs-base);
}
/* The stepper's own box draws the border, and the focus ring. */
.log-stepper { border-radius: var(--r-input); }
.log-stepper input:focus-visible { outline: none !important; }
.log-stepper:has(input:focus-visible) { outline: var(--focus-width) solid var(--focus-color); outline-offset: var(--focus-offset); }
/* Small dialogs head like the side panels. */
dialog:is(#log-dialog, #log-history-dialog, #notes-dialog, #pattern-dialog) h2 {
  font-family: var(--font-head); font-weight: var(--fw-heavy); font-size: var(--fs-heading); letter-spacing: -0.02em; color: var(--ink);
}
.log-stepper input { height: auto !important; min-height: 0 !important; border-top: 0 !important; border-bottom: 0 !important; border-radius: 0 !important; }
/* Selects: one chevron in every browser. */
:is(#task-dialog, #task-edit-dialog, #goal-dialog, .settings-pop) select:not([multiple]) {
  appearance: none; -webkit-appearance: none; padding-right: var(--sp-8);
  background: var(--surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5 6 7.5 9 4.5' fill='none' stroke='%2362646B' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right var(--sp-3) center / 12px 12px;
  cursor: pointer;
}
.tf-sentence select { height: var(--sp-8); min-height: var(--sp-8); }

/* -- Buttons along an overlay's foot: 40px pills -- */
:is(dialog) .actions .btn, #confirm-dialog .btn {
  min-height: var(--sp-10); padding: 0 var(--sp-3); border-radius: var(--r-pill); font-size: var(--fs-base);
}
:is(dialog) .actions .btn.primary.primary, #confirm-dialog .btn.primary { padding: 0 var(--sp-4); }
:is(dialog) .actions { gap: var(--sp-1); }
:is(dialog) .actions .btn.danger:has(svg) { width: var(--sp-10); padding: 0; }

/* -- "optional": a quiet word, not a chip (O12) -- */
.optional-tag, .task-form .tf-field .optional-tag, .tf-divider .optional-tag {
  padding: 0; margin-left: var(--sp-1); background: none; border-radius: 0;
  font-size: var(--fs-sm); font-weight: var(--fw-regular); letter-spacing: 0; text-transform: none; color: var(--muted);
}

/* -- Completion and How it repeats: the same segmented pill as Settings' theme (O3) -- */
:is(#task-dialog, #task-edit-dialog) .icon-choice, :is(#task-dialog, #task-edit-dialog) .tf-tiles {
  gap: var(--sp-1); padding: var(--sp-1); border-radius: var(--r-pill); background: var(--track);
}
:is(#task-dialog, #task-edit-dialog) .tf-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border-radius: var(--r-popover); }
:is(#task-dialog, #task-edit-dialog) :is(.icon-choice label, .tf-tile) {
  position: relative; display: flex; align-items: center; justify-content: center; min-height: var(--sp-8);
  padding: 0 var(--sp-1-5); border: 0; border-radius: var(--r-pill); background: transparent; box-shadow: none;
  font-size: var(--fs-md); font-weight: var(--fw-medium); color: var(--muted); text-align: center; cursor: pointer;
}
:is(#task-dialog, #task-edit-dialog) .tf-tile { min-height: var(--sp-10); padding: var(--sp-1) var(--sp-2-5); border-radius: var(--r-card); line-height: var(--lh-meta); }
:is(#task-dialog, #task-edit-dialog) .icon-choice label svg { display: none; }
:is(#task-dialog, #task-edit-dialog) :is(.icon-choice label, .tf-tile) input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
:is(#task-dialog, #task-edit-dialog) :is(.icon-choice label, .tf-tile):has(input:checked) {
  background: var(--surface); color: var(--ink); font-weight: var(--fw-semi); border: 0;
}
:is(#task-dialog, #task-edit-dialog) :is(.icon-choice label, .tf-tile):not(:has(input:checked)):hover { background: var(--state-hover); color: var(--ink); }
:is(#task-dialog, #task-edit-dialog) :is(.icon-choice label, .tf-tile):has(input:focus-visible) {
  outline: var(--focus-width) solid var(--focus-color); outline-offset: calc(-1 * var(--focus-width));
}
:is(#task-dialog, #task-edit-dialog) :is(.icon-choice label, .tf-tile):has(input:disabled) { opacity: var(--state-disabled); pointer-events: none; }

/* -- Date field: one box, the calendar button inside it (O4) -- */
.date-field {
  align-items: center; height: var(--sp-10); box-sizing: border-box; border: 1px solid var(--line); border-radius: var(--r-input);
  background: var(--surface);
}
.date-field:hover:not(:has(:disabled)) { border-color: var(--faint-text); }
.date-field:has(.date-text:focus-visible) { border-color: var(--ink); }
.date-field:has(.date-text.invalid) { border-color: var(--danger); }
.date-field .date-text, :is(#task-dialog, #task-edit-dialog, #goal-dialog, #log-dialog) .date-field .date-text {
  width: 112px; height: 100%; min-height: 0; padding: 0 0 0 var(--sp-3); border: 0; border-radius: var(--r-input) 0 0 var(--r-input); background: transparent;
}
.date-field .date-text:focus-visible { outline: none !important; }
.date-field .date-pick {
  width: var(--sp-8); height: var(--sp-8); margin-right: var(--sp-1); border: 0; border-radius: var(--r-pill); background: transparent; color: var(--muted);
}
.date-field .date-pick:hover { background: var(--state-hover); color: var(--ink); }

/* -- Belongs to: the goal dash, not a square swatch (O5) -- */
.tf-belongs { display: flex; align-items: center; gap: var(--sp-2-5); }
.tf-swatch { width: 4px; height: 20px; border-radius: var(--r-dash); background: var(--muted); box-shadow: none; }
.tf-belongs select { flex: 1; min-width: 0; }

/* -- + New -- */
#new-fan-menu { padding: var(--sp-1-5); }
#new-fan-menu button { border-radius: var(--r-input); }
#new-fan-menu svg { border-radius: var(--r-input); }
.nf-hint { margin: var(--sp-1) var(--sp-1-5) 0; padding: var(--sp-2) var(--sp-1-5) var(--sp-1); }

/* -- Settings: linked calendars carry the goal dash (O8) -- */
.settings-pop .feed-row .feed-colour-dot {
  position: relative; width: 20px; height: var(--sp-10); border-radius: var(--r-input); background: transparent; box-shadow: none;
}
.settings-pop .feed-row .feed-colour-dot::before {
  content: ""; position: absolute; inset: 0; margin: auto; width: 4px; height: 20px; border-radius: var(--r-dash); background: var(--swatch);
}
.settings-pop .feed-row .feed-colour-dot:hover { background: var(--state-hover); }
.settings-pop .feed-row .feed-colour-dot[aria-expanded="true"] { background: var(--state-active); box-shadow: none; }
.settings-link { padding: 0 var(--sp-4); }

/* ==== Component states (Chunk 81) ====
   Every shared component draws default, hover, focus-visible, active,
   disabled and (where it can) loading from these tokens, in one place.
   The .is-hover / .is-focus / .is-active classes only exist so
   docs/brand-identity/components.html can show a state without a pointer. */
:root {
  --focus-color: var(--ink);
  --focus-width: 2px;
  --focus-offset: 2px;
  --state-hover: color-mix(in srgb, var(--ink) 6%, transparent);   /* quiet and icon buttons, menu rows */
  --state-active: color-mix(in srgb, var(--ink) 12%, transparent);
  --state-hover-surface: color-mix(in srgb, var(--ink) 4%, var(--surface)); /* white pills, inputs */
  --state-active-surface: color-mix(in srgb, var(--ink) 9%, var(--surface));
  --state-hover-primary: color-mix(in srgb, var(--primary-fill) 86%, var(--page));
  --state-active-primary: color-mix(in srgb, var(--primary-fill) 72%, var(--page));
  --state-disabled: 0.4;
  --spinner-size: 14px;
}

/* -- Focus: one ring, keyboard only. Ink outside the control; on Ink
   feature cards it flips to the paper colour so it stays visible. -- */
:focus:not(:focus-visible) { outline: none; }
:is(:focus-visible, .is-focus):not(dialog) {
  outline: var(--focus-width) solid var(--focus-color) !important;
  outline-offset: var(--focus-offset) !important;
}
:is(.today-next, .day-next, .year-sofar, .rv-year, .ck-tip, .month-day.today, .week-stack .day.today, body[data-view="calendar"] .cal-seg) :is(:focus-visible, .is-focus) { --focus-color: var(--on-feature); }
/* Segments of the switch draw the ring inside their own pill. */
.theme-seg button { --focus-offset: calc(-1 * var(--focus-width)); }
.view-switch button { --focus-offset: calc(-1 * (var(--focus-width) + 2px)); } /* 2px clear of the track's own ring (Chunk 230) */
/* Rows that fill a scrolled menu or list draw the ring inside, so it isn't clipped. */
:is(.fv-menu-item, .new-fan-menu button, .today-card-task, .peek-item, .entry.cal-entry) { --focus-offset: calc(-1 * var(--focus-width)); }

/* -- Buttons -- */
/* Primary (Ink) */
:is(.btn.primary, .global-new, .fv-primary):is(:hover, .is-hover) { background: var(--state-hover-primary); border-color: var(--state-hover-primary); filter: none; }
:is(.btn.primary, .global-new, .fv-primary):is(:active, .is-active) { background: var(--state-active-primary); border-color: var(--state-active-primary); }
/* Secondary (white pill, 1px border) */
:is(.topbar-review, .today-btn, .settings-link, .fv-pill):is(:hover, .is-hover) { background: var(--state-hover-surface); border-color: var(--faint-text); }
:is(.topbar-review, .today-btn, .settings-link, .fv-pill):is(:active, .is-active) { background: var(--state-active-surface); border-color: var(--faint-text); }
/* Quiet text buttons, icon buttons and the round 44px icon button */
:is(.btn.quiet, .btn.icon-btn, .topbar-icon, .page-arrow, .rail-btn, .settings-close, .aside-menu, .nav-menu):is(:hover, .is-hover) { background: var(--state-hover); color: var(--ink); }
:is(.btn.quiet, .btn.icon-btn, .topbar-icon, .page-arrow, .rail-btn, .settings-close, .aside-menu, .nav-menu):is(:active, .is-active) { background: var(--state-active); color: var(--ink); }
.topbar-panel[aria-expanded="true"]:is(:hover, .is-hover, :active, .is-active) { background: var(--primary-fill); color: var(--on-primary); }
/* Danger keeps its red hover; pressing deepens it. */
:is(.btn.danger, .btn.danger-text, .fv-menu-item.danger):is(:active, .is-active) { background: color-mix(in srgb, var(--danger) 18%, var(--surface)); color: var(--danger); }

/* -- Pills: targets (.flag) and filter chips (.tf-chip) -- */
.flag:is(.is-hover) { background: color-mix(in srgb, var(--goal) 14%, var(--surface)); }
.flag:is(:active, .is-active) { background: color-mix(in srgb, var(--goal) 26%, var(--surface)); }
.tf-chip:is(:hover, .is-hover) input:not(:checked):not(:disabled) + span { background: var(--state-hover-surface); border-color: var(--faint-text); }
.tf-chip:is(:active, .is-active) input:not(:checked):not(:disabled) + span { background: var(--state-active-surface); }
.tf-chip:is(:active, .is-active) input:checked:not(:disabled) + span { background: var(--state-active-primary); }
.tf-chip:is(:hover, .is-hover) input:checked + span { background: var(--state-hover-primary); }
.tf-chip input:disabled + span { opacity: var(--state-disabled); }
.tf-chip:has(input:disabled) { pointer-events: none; }

/* -- The switch and segmented controls (Today | Calendar, zoom, theme) -- */
:is(.view-switch button, .zoom-row .zoom button, .theme-seg button):not(.active):not([aria-pressed="true"]):is(:hover, .is-hover) { color: var(--ink); background: var(--state-hover); }
:is(.view-switch button, .zoom-row .zoom button, .theme-seg button):not(.active):not([aria-pressed="true"]):is(:active, .is-active) { color: var(--ink); background: var(--state-active); }

/* -- Task blocks and Today cards -- */
.entry.cal-entry.is-hover { z-index: 2; --lift: 0 3px 10px rgb(31 41 55 / 0.25); } /* mirrors the real :hover lift */
.entry.cal-entry:is(:active, .is-active):not(.dragging) { filter: brightness(0.96); }
.today-card-task:is(.is-hover) { box-shadow: var(--shadow-lift); }
.today-card-task:is(:active, .is-active) { box-shadow: var(--shadow-line); filter: brightness(0.97); }

/* -- Menus -- */
:is(.fv-menu-item, .new-fan-menu button):not(.danger):is(:hover, :focus-visible, .is-hover, .is-focus) { background: var(--state-hover); }
:is(.fv-menu-item, .new-fan-menu button):not(.danger):is(:active, .is-active) { background: var(--state-active); }

/* -- Inputs -- */
:is(dialog, .settings-pop) :is(input[type=text], input[type=date], input[type=number], input:not([type]), select, textarea):is(:hover, .is-hover):not(:focus):not(:disabled) { border-color: var(--faint-text); }
:is(dialog, .settings-pop) :is(input, select, textarea):is(:focus-visible, .is-focus) { border-color: var(--ink); --focus-offset: 0px; }

/* -- Disabled: faded, not clickable. Native disabled controls also leave
   the tab order; anything else marks aria-disabled and tabindex=-1. -- */
/* :where keeps this at the lowest weight, so a control that hides its own
   input (opacity 0 chips) or keeps a chosen slot solid still wins. */
:where(button, input, select, textarea):disabled:where(:not([aria-busy="true"])),
[aria-disabled="true"] { opacity: var(--state-disabled); cursor: default; }
:is(button, input, select, textarea, .btn):disabled, [aria-disabled="true"] { pointer-events: none; }

/* -- Loading: the label hides behind a spinner; the button stays its size. -- */
:is(.btn, button)[aria-busy="true"] { position: relative; color: transparent !important; pointer-events: none; }
:is(.btn, button)[aria-busy="true"]::after {
  content: ""; position: absolute; inset: 0; margin: auto; width: var(--spinner-size); height: var(--spinner-size);
  border: 2px solid var(--ink); border-right-color: transparent; border-radius: var(--r-pill);
  animation: pace-spin calc(var(--motion-max) * 2.5) linear infinite;
}
:is(.btn.primary, .global-new, .fv-primary)[aria-busy="true"]::after { border-color: var(--on-primary); border-right-color: transparent; }
@keyframes pace-spin { to { transform: rotate(1turn); } }
@media (prefers-reduced-motion: reduce) { :is(.btn, button)[aria-busy="true"]::after { animation: none; border-right-color: currentColor; opacity: 0.5; } }

/* -- Toast: an Ink pill at the foot of the window, with an optional quiet action. -- */
.toast {
  position: fixed; left: 50%; bottom: var(--sp-6); z-index: 50; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: var(--sp-3); min-height: 44px; padding: 0 var(--sp-2) 0 var(--sp-4);
  border-radius: var(--r-pill); background: var(--primary-fill); color: var(--on-primary); box-shadow: var(--shadow-bubble);
  font-size: var(--fs-base); font-weight: var(--fw-medium);
}
.toast-action {
  min-height: 32px; padding: 0 var(--sp-3); border: 0; border-radius: var(--r-pill); background: transparent;
  color: var(--on-primary); font: inherit; font-weight: var(--fw-semi); cursor: pointer;
}
.toast-action:is(:hover, .is-hover) { background: color-mix(in srgb, var(--on-primary) 14%, transparent); }
.toast-action:is(:active, .is-active) { background: color-mix(in srgb, var(--on-primary) 24%, transparent); }
.toast :is(:focus-visible, .is-focus) { --focus-color: var(--on-primary); --focus-offset: 0px; }
.toast.is-loading::before {
  content: ""; width: var(--spinner-size); height: var(--spinner-size); border: 2px solid var(--on-primary);
  border-right-color: transparent; border-radius: var(--r-pill); animation: pace-spin calc(var(--motion-max) * 2.5) linear infinite;
}

/* ==== Chunk 87: To place, missed card and Week review, new look ==== */

/* Week while placing (to-place-audit mock 5): the slot says when and what
   ("11:00 · Code review · 45 min"); the entries after it step down by one
   slot. A translate, so nothing reflows; it jumps with the pointer (M9). */
.drop-slot.week-slot {
  display: flex; align-items: center; padding: 0 var(--sp-2); overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-size: var(--fs-xs); font-weight: var(--fw-semi); line-height: var(--lh-meta); color: var(--ink);
  background: color-mix(in srgb, var(--goal) 16%, var(--surface));
}
.week-day-events > .slot-shift { translate: 0 var(--slot-shift, 0); }

/* To place (look audit R5-R7). The Waiting row is the checklist's 52px white
   row, 12px corners, a 3px orange edge while anything waits, title 15/600.
   Rows are white cards led by the goal dash (4 x 20), not a coloured edge
   and an owner dot; Chunk 75's fixed 44px two-line row stays. Group labels
   are all Muted: Overdue's orange stays on the overdue date in the row, so
   the label isn't the loudest thing in the tray (R6). */
.tray-wait {
  min-height: 52px; padding: 0 var(--sp-2) 0 var(--sp-4);
  border-left: 3px solid var(--missed-accent); border-radius: var(--r-card);
}
.tray-wait-title { font-size: var(--fs-body); }
.tray-wait.empty .tray-wait-title { font-weight: var(--fw-medium); }
.entry.event.tab.place-row {
  position: relative; padding: 0 var(--sp-2-5) 0 var(--sp-6);
  border: 1px solid var(--line); border-radius: var(--r-small);
}
.entry.event.tab.place-row::before {
  content: ""; position: absolute; left: var(--sp-2-5); top: 50%; width: 4px; height: 20px; margin-top: -10px;
  border-radius: var(--r-dash); background: var(--goal);
}
.entry.event.tab.place-row:hover, .entry.event.tab.place-row.selected { border-color: var(--faint-text); }
.entry.event.tab.place-row.place-sub::before { height: 14px; margin-top: -7px; opacity: 0.6; }
.entry.event.tab.place-row .place-owner::before { content: none; }
.entry.event.tab.place-row .place-line .entry-title { font-size: var(--fs-base); }
.tray-wait-wrap .entry.event.tab.place-row.place-peek { border-radius: var(--r-small); }
.place-search, .place-owner-filter { height: 32px; border-radius: var(--r-pill); padding: 0 var(--sp-3); }

/* Week review (look audit R1-R3). */
.ck-slip-confirm { color: var(--ink); }
.ck-slip-mark { min-height: 32px; }
.rv-bar-left { font-size: var(--fs-md); color: var(--muted); white-space: nowrap; }
.rv-year-grid {
  grid-template-columns: var(--sp-4) repeat(var(--weeks), minmax(0, 14px));
  grid-template-rows: var(--sp-4) repeat(7, 14px);
}
.rv-dow, .rv-month {
  font-size: var(--fs-2xs); line-height: 14px; color: var(--on-feature-3); white-space: nowrap; pointer-events: none;
}
.rv-dow { justify-self: start; }
.rv-month { align-self: start; }
.rv-cell.this-week { box-shadow: none; }
.rv-band {
  margin: calc(-1 * var(--sp-0-5)); border: 1.5px solid var(--on-feature); border-radius: var(--r-mini);
  pointer-events: none; z-index: 1;
}
.rv-cell.ahead { opacity: 1; background: transparent; box-shadow: inset 0 0 0 1px var(--feature-3); }
.rv-cell.is-today { box-shadow: 0 0 0 2px var(--feature), 0 0 0 3.5px var(--on-feature); position: relative; z-index: 2; }

/* "Done on" (to-place-audit I15): the date as the app writes it, "Sun 8 Nov",
   in a white pill that opens the app's date picker. */
.ev-done-on-pick {
  display: inline-flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  min-height: 44px; padding: 0 var(--sp-3) 0 var(--sp-4); border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--surface); color: var(--ink); font: inherit; font-size: var(--fs-base); font-weight: var(--fw-medium);
  cursor: pointer; white-space: nowrap;
}
.ev-done-on-pick svg { flex: none; width: 16px; height: 16px; fill: none; stroke: var(--muted); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.ev-done-on-pick:is(:hover, .is-hover) { background: var(--state-hover-surface); border-color: var(--faint-text); }
.ev-done-on-pick:is(:active, .is-active) { background: var(--state-active-surface); }
.ck-slip-done .ev-done-on-field { flex: 0 1 auto; }

.ck-slip-done .btn.primary { min-height: 44px; }
.place-owner-filter { flex: 0 0 auto; max-width: 120px; padding-right: var(--sp-6); }
.ck-slipped .ck-slip-missed { white-space: normal; }

/* ==== Chunk 90: Motion pass, overlays and feedback ====
   docs/brand-identity/motion.md, on the motion tokens only. Each rule's
   number (M4, M5 ...) is the doc's. */

/* M6 Panel. Everything that slides in from an edge - Week review, To place,
   the side panels - and whatever gives way to it (the page's margin, the
   greying while adding) shares one timing: in on --motion-panel and the
   enter curve, out on --motion-move and the exit curve, so leaving is
   quicker than arriving and gathers speed. The left panel still cuts (Ed:
   sliding while the page re-laid out flashed). */
body { --sidebar-ms: var(--motion-move); --sidebar-ease: var(--ease-exit); --panel-ms: var(--motion-move); --panel-ease: var(--ease-exit); }
body:is(.checking, .nav-open),
body:is(.cal-aside-open, .cal-composing, .panel-open) {
  --sidebar-ms: var(--motion-panel); --sidebar-ease: var(--ease-enter); --panel-ms: var(--motion-panel); --panel-ease: var(--ease-enter);
}
/* Delays only on the way in: leaving, everything goes together. */
.content { transition-delay: 0s; }

/* The side panels (New task, Edit task, the Goal / Routine / Milestone form):
   one in and one out. A closed panel keeps its place (the [open] rules above
   match while it leaves) and fades out of the way of the pointer. */
dialog.slide-panel {
  translate: 24px 0; opacity: 0;
  transition: translate var(--motion-move) var(--ease-exit), opacity var(--motion-move) var(--ease-exit),
              display var(--motion-move) allow-discrete, overlay var(--motion-move) allow-discrete;
}
dialog.slide-panel[open] {
  translate: none; opacity: 1;
  transition-duration: var(--motion-panel); transition-timing-function: var(--ease-enter);
}
@starting-style { dialog.slide-panel[open] { translate: 24px 0; opacity: 0; } }
dialog:not([open]) { pointer-events: none; }
/* The column New task and Edit task dock in on the Calendar stays up while
   its panel leaves, its own reveal running out with it. */
#calendar-aside {
  transition: clip-path var(--sidebar-ms) var(--sidebar-ease), width var(--sidebar-ms) var(--sidebar-ease),
              display var(--motion-move) allow-discrete;
}
/* Event dialog to Edit task: one swaps for the other in place, a crossfade. */
dialog.slide-panel.swap-in { transition-duration: var(--motion-fast); transition-timing-function: var(--ease-fade); }
@starting-style { dialog.slide-panel.swap-in[open] { translate: none; } }

/* Week review is a page over the app now, so it comes and goes as a panel
   does: in from the right, out the same way, quicker. */
.review-page {
  transition: translate var(--motion-move) var(--ease-exit), opacity var(--motion-move) var(--ease-exit),
              display var(--motion-move) allow-discrete;
}
.review-page[hidden] { translate: 24px 0; opacity: 0; pointer-events: none; }
.review-page:not([hidden]) { transition-duration: var(--motion-panel); transition-timing-function: var(--ease-enter); }
@starting-style { .review-page:not([hidden]) { translate: 24px 0; opacity: 0; } }

/* M5 Modal dialog (Event, confirm, Log, History, notes, pattern, limit,
   linked calendars): in, a fade and a scale from 0.98 on --motion-fast with
   the backdrop fading alongside; out, a fade on --motion-out. Placed the way
   the browser places a modal, so it holds still while it fades out. */
dialog:not(.slide-panel) {
  position: fixed; inset: 0; margin: auto; max-height: calc(100% - 6px - 2em);
  opacity: 0;
  transition: opacity var(--motion-out) var(--ease-exit), scale var(--motion-out) var(--ease-exit),
              display var(--motion-out) allow-discrete, overlay var(--motion-out) allow-discrete;
}
dialog:not(.slide-panel)[open] {
  opacity: 1;
  transition-duration: var(--motion-fast); transition-timing-function: var(--ease-enter);
}
@starting-style { dialog:not(.slide-panel)[open] { opacity: 0; scale: 0.98; } }
dialog::backdrop {
  opacity: 0;
  transition: opacity var(--motion-out) var(--ease-exit), display var(--motion-out) allow-discrete, overlay var(--motion-out) allow-discrete;
}
dialog[open]::backdrop { opacity: 1; transition-duration: var(--motion-fast); transition-timing-function: var(--ease-fade); }
@starting-style { dialog[open]::backdrop { opacity: 0; } }

/* M4 Small overlay (+ New, "…" menus, Settings, One-off, the date popover,
   a toast): in, the fan-in - a fade and a 4px move - on --motion-fast; out,
   a fade on --motion-out. Opening another swaps with no out (menu-swap). */
:is(.new-fan-menu, .settings-pop, .fv-menu, .toast) {
  transition: opacity var(--motion-out) var(--ease-exit), display var(--motion-out) allow-discrete;
}
:is(.new-fan-menu, .settings-pop, .fv-menu, .toast)[hidden] { opacity: 0; pointer-events: none; }
body.menu-swap :is(.new-fan-menu, .settings-pop, .fv-menu, .toast)[hidden] { transition: none; }
.toast { animation: toast-in var(--motion-fast) var(--ease-enter); }
@keyframes toast-in { from { opacity: 0; translate: 0 4px; } to { opacity: 1; translate: none; } }
/* One-off and the date popover are taken off the page as they close; app.js
   fades them out first (leaveOverlay), under a stand-in id the #quick-add
   rules also match. */
.date-pop.leaving { pointer-events: none; }

/* M2 Colour and hover, on the controls inside the overlays and the missed
   card: a hover or press tint eases over --motion-fast. */
:is(.fv-menu-item, .new-fan-menu button, .date-pop-day, .date-pop-nav, .settings-close, .toast-action),
:is(dialog, .settings-pop, .today-missed) .btn {
  transition: background-color var(--motion-fast) var(--ease-fade), border-color var(--motion-fast) var(--ease-fade),
              color var(--motion-fast) var(--ease-fade), box-shadow var(--motion-fast) var(--ease-fade);
}

/* M12 Completion: the card takes its done look at once; only the tick moves,
   scaling up from 0.6 as it fades in. No celebration. */
.today-card-task.just-done .tc-tick { animation: tick-in var(--motion-fast) var(--ease-enter) both; transform-origin: 30% 70%; }
@keyframes tick-in { from { opacity: 0; scale: 0.6; } to { opacity: 1; scale: 1; } }

/* M13 Quiet confirmation: Today's notes line fades back in each time they
   save, so a save shows even when the words don't change. */
.today-note-status.saved-flash { animation: fade-in var(--motion-fast) var(--ease-fade); }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
/* "Jump to notes" scrolls there smoothly (app.js, jumpToNotes). */

/* Reduced motion: nothing slides or scales; fades of --motion-fast or less
   stay, everything else cuts. */
@media (prefers-reduced-motion: reduce) {
  dialog.slide-panel, dialog.slide-panel[open] { translate: none; transition-duration: var(--motion-fast); transition-timing-function: var(--ease-fade); }
  @starting-style { dialog.slide-panel[open] { translate: none; } }
  @starting-style { dialog:not(.slide-panel)[open] { scale: none; } }
  :is(.new-fan-menu, .settings-pop, .fv-menu, .date-pop, .toast) { animation: fade-in var(--motion-fast) var(--ease-fade); }
  .nav-tree, body.checking .checkin-charts { animation: fade-in var(--motion-fast) var(--ease-fade); }
  .review-page:not([hidden]), .review-page[hidden] { translate: none; transition-duration: var(--motion-fast); transition-timing-function: var(--ease-fade); }
  @starting-style { .review-page:not([hidden]) { translate: none; } }
  .checkin-panel { transform: none; opacity: 0; transition: opacity var(--motion-fast) var(--ease-fade), visibility 0s linear var(--motion-fast); }
  body.checking .checkin-panel { opacity: 1; transition: opacity var(--motion-fast) var(--ease-fade), visibility 0s; }
  .aside-drawer { transition: opacity var(--motion-fast) var(--ease-fade), visibility 0s linear var(--motion-fast); }
  body.s-cal.cal-aside-open .aside-drawer, body.s-cal.cal-composing .aside-drawer { transition: opacity var(--motion-fast) var(--ease-fade), visibility 0s; }
  #calendar-aside { transition: display var(--motion-fast) allow-discrete; }
  body.adding dialog.slide-panel {
    transition: opacity var(--motion-fast) var(--ease-fade), display var(--motion-fast) allow-discrete, overlay var(--motion-fast) allow-discrete !important;
  }
  #calendar-aside::before, .edge-tabs, #footer-checkin, .footer-checkin-label, .nav-entry::before, .peek-item, .today-review-dot { transition: none; }
  .today-card-task.just-done .tc-tick, .today-note-status.saved-flash { animation: none; }
}


/* ===== Chunk 99: AA contrast and targets ===== */
/* Text-field borders reach 3:1 (A13, 1.4.11). Every field rule draws its border
   from --line, --faint or --done-fill; re-pointing those three on the field
   itself fixes all of them at once, whatever the selector's weight. Radios,
   checkboxes, colour and range inputs keep their own look. */
:is(input:not([type=checkbox], [type=radio], [type=color], [type=range], [type=hidden], [type=file], [type=submit], [type=button]), select, textarea) {
  --line: var(--field-line); --faint: var(--field-line); --done-fill: var(--field-line);
}
/* -- Today polish: match the launch mock (Chunk 96) --
   Fewer pieces, each firmer: no "Tasks" heading, one quiet note row, tight
   outer margins and one even gap, the left panel on the page colour, the Ink
   switch, past tasks struck and faded, Missed as pills. */
.view-thumb:not(.on-dark) { background: var(--ink); box-shadow: none; }
.view-thumb:not(.on-dark) .view-thumb-label { color: var(--page); }
.sidebar { background: var(--page); border-right: 1px solid var(--line); }
.sidebar .nav-goal:hover, .sidebar.expanded .nav-goal:hover, .sidebar .nav-goal.active, .sidebar.expanded .nav-goal.active,
.sidebar .nav-entry:hover, .sidebar .nav-entry.active { background: var(--track); }
.sidebar .nav-goals[hidden], .sidebar [data-view="completed"][hidden] { display: none; }

/* The page fills the window: 20px from the panel's divider (or the rail) and from the right edge. */
.content > #today-view { margin-left: 36px; margin-right: -12px; }
body.left-open .content > #today-view { margin-left: calc(var(--left-w) - 12px); }
.today-page { max-width: none; padding: var(--sp-5) 0; }
.today-head { margin-bottom: var(--sp-4); }
.today-hero { gap: var(--sp-0-5); }
.today-greeting { font-size: var(--fs-body); }
.today-summary { padding-top: var(--sp-0-5); font-size: var(--fs-md); }
.today-grid, .today-side { gap: var(--sp-4); }
.today-main-card { padding: var(--sp-4); }
.today-card:not(.today-main-card) { padding: var(--sp-4) var(--sp-5); }
.today-tasks .today-timeline { margin-top: 0; }
.today-slot.is-past { opacity: 0.62; }
/* Chunk 121: past unactioned cards only fade; just Done looks done */

.today-card.today-notes { gap: 0; padding: var(--sp-1) var(--sp-2); }
.today-note-row {
  display: flex; align-items: center; gap: var(--sp-2); width: 100%; min-height: 44px; padding: var(--sp-2) var(--sp-3);
  border: 0; border-radius: var(--r-input); background: transparent; color: var(--muted); font: inherit; font-size: var(--fs-body);
  text-align: left; cursor: pointer;
}
.today-note-row:hover { color: var(--ink); background: var(--page); }
.today-note-row.has-note { color: var(--text-2); }
.today-note-text { flex: 1; min-width: 0; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; line-height: 1.4; }
.today-note-plus { font-size: var(--fs-lg); line-height: 1; }
.today-card.today-notes.is-open { padding: var(--sp-3) var(--sp-3) var(--sp-2); gap: var(--sp-2); }
.today-notes .today-note { min-height: 110px; }
.today-notes .today-note-status { padding: 0 var(--sp-1); }

.today-review { position: relative; min-height: 44px; padding: 0 var(--sp-4); }
.today-review-dot { flex: none; width: 8px; height: 8px; margin-left: calc(-1 * var(--sp-1)); border-radius: var(--r-pill); background: var(--ink); }

.today-missed-list { max-height: none; overflow: visible; }
.today-missed-actions { align-items: center; gap: var(--sp-1-5); }
.today-missed-actions .btn {
  min-height: 32px; padding: 0 var(--sp-3); border: 0; border-radius: var(--r-pill);
  background: var(--track); color: var(--ink); font-size: var(--fs-sm); font-weight: var(--fw-medium);
}
.today-missed-actions .btn:hover { background: var(--faint); }
.today-missed-actions .btn.primary { background: var(--ink); color: var(--page); }
.today-missed-actions .fv-more { width: 32px; height: 32px; border-radius: var(--r-pill); color: var(--ink); background: var(--track); }

@media (min-width: 1000px) {
  .today-page { padding: var(--sp-5) 0 var(--sp-4); }
  .today-card.today-notes { flex: none; min-height: 0; }
}

/* The switch's spacing as the mock: a thin ring, and the pill inset the same
   amount on every side (the ring was 2px with the pill flush to it, and
   5px of air above and below). */
.topbar .view-switch { padding: var(--sp-1); box-shadow: inset 0 0 0 1.5px var(--ink); }
.view-switch button { min-height: 32px; }
.view-thumb { height: 32px; }
.today-missed-actions .fv-more:hover, .today-missed-actions .fv-more[aria-expanded="true"] { background: var(--faint); }
.today-note-row.has-note:hover::after { content: "Edit"; flex: none; font-size: var(--fs-sm); color: var(--muted); }
.today-missed-actions .btn:disabled { opacity: 0.45; cursor: default; }

/* ---- Chunk 102: To place, the missed block's Event dialog and Week review,
   to the design principles (docs/brand-identity/design-principles.md). Uses the
   existing tokens only. ---- */

/* To place (principles 1, 3, 5): the block is one quiet white card with the
   count as the only orange; the list is one white card, rows divided by
   hairlines, group names in plain sentence case; nothing stays tall and empty. */
.tray-wait { border: 0; border-radius: var(--r-card); box-shadow: var(--shadow-line); min-height: 48px; }
.tray-wait.empty { color: var(--ink); }
.tray-place #unscheduled-list { padding: var(--sp-1) var(--sp-2) var(--sp-2); border-radius: var(--r-card); background: var(--surface); box-shadow: var(--shadow-line); gap: 0; }
.tray-place .place-tools { padding-top: var(--sp-1-5); margin-bottom: var(--sp-1-5); }
.place-head { margin: var(--sp-2-5) 0 var(--sp-0-5); padding: 0 var(--sp-1); font-size: var(--fs-sm); font-weight: var(--fw-semi); letter-spacing: 0; text-transform: none; color: var(--muted); }
.tray-place .entry.event.tab.place-row { height: 48px; border: 0; border-radius: var(--r-small); background: none; }
.tray-place .entry.event.tab.place-row + .entry.event.tab.place-row { box-shadow: 0 -1px 0 var(--divider); }
.tray-place .entry.event.tab.place-row:hover, .tray-place .entry.event.tab.place-row.selected { background: var(--faint); box-shadow: none; }
.tray-place .entry.event.tab.place-row:hover + .entry.event.tab.place-row { box-shadow: none; }
.tray-place .place-empty { margin: var(--sp-2) var(--sp-1); font-size: var(--fs-base); line-height: 1.4; }
.tray-place .btn.quiet.place-more { margin: var(--sp-1) 0 var(--sp-0-5) var(--sp-1); }

/* Week review (principles 1, 5, 6): What slipped rows read like Today's Missed
   card - a white row with the goal's bar, orange only on the "missed" words,
   Mark done as the Ink pill - instead of orange hatching on every row. */
.ck-slipped .ck-slip-head { padding: var(--sp-2-5) var(--sp-3); border-left: 0; border-radius: 0; background: none; box-shadow: inset 3px 0 0 var(--goal, var(--muted)); }
.ck-slipped .ck-slip + .ck-slip { border-top: 1px solid var(--divider); }
.ck-slipped .ck-slip { gap: 0; }
.ck-slipped .ck-slip-head .title { font-weight: var(--fw-semi); }
.ck-slipped .ck-slip-missed { color: var(--missed-ink-2); font-weight: var(--fw-regular); }
.ck-slipped .ck-slip.handled .ck-slip-head { background: none; opacity: 0.6; }
.ck-slipped .ck-slip-mark { min-height: 32px; padding: 0 var(--sp-3); border: 0; border-radius: var(--r-pill); background: var(--ink); color: var(--page); font-size: var(--fs-sm); font-weight: var(--fw-medium); }
.ck-slipped .ck-slip-mark:hover:not(:disabled) { background: var(--ink); opacity: 0.88; }
.ck-slipped .ck-slip-mark.ck-slip-confirm { background: var(--track); color: var(--ink); opacity: 1; }
.ck-slipped .ck-slip-mark.ck-slip-confirm:hover:not(:disabled) { background: var(--faint); }
.ck-slipped .ck-slip-head > .btn:not(.ck-slip-mark) { min-height: 32px; padding: 0 var(--sp-3); border: 0; border-radius: var(--r-pill); background: var(--track); color: var(--ink); font-size: var(--fs-sm); font-weight: var(--fw-medium); }
.ck-slipped .ck-slip-head > .btn:not(.ck-slip-mark):hover:not(:disabled) { background: var(--faint); }
.ck-slip-group h3 { font-size: var(--fs-base); letter-spacing: 0; text-transform: none; }
.ck-slip-group { gap: 0; }
.ck-slip-group > .muted { padding: var(--sp-1) 0; }
.rv-more-label { display: none; }

/* D5: the today line stays behind the labels, thin, and each label sits on the
   card so the line never runs through the words. */
.year-now-line { width: 1px; background: var(--muted); opacity: 0.7; z-index: 0; }
.year-track { z-index: 1; }
.year-node-label, .year-goal-target { z-index: 2; padding: 0 var(--sp-1); border-radius: var(--r-mini); background: var(--surface); }
.year-goal-target .pennant-name { background: var(--surface); }
.rv-goals .year-goal-row { padding-bottom: var(--sp-5); }

/* D6/D26: the old Check-in's lower half is two columns on one grid; the
   goals and finish dates cards share a top edge and height. */
.rv-goals-pair, .rv-foot { align-items: stretch; }
.rv-more { margin-top: 0; display: grid; align-items: start; }
.rv-pace-row { padding-left: 0; }
.rv-foot { align-items: center; }
.rv-goals-pair.no-pace { grid-template-columns: minmax(0, 1fr); }
.ck-slip-none { margin: 0; }
.ck-actions [hidden] { display: none; }

/* ==========================================================================
   Chunk 103: overlays to the design principles. Dialogs, menus, + New, the
   task forms, Pattern, Log, Link a calendar and Settings: one filled Ink
   pill for the main action, quiet pills for the rest, no red text, and
   Delete in a "…" menu that asks first. No tokens or shared rules change;
   everything here is scoped to overlays.
   ========================================================================== */

/* Actions as pills, in order. */
:is(dialog, .settings-pop) .actions { align-items: center; gap: var(--sp-2); }
:is(dialog, .settings-pop) .actions .btn, .feeds-add-row .btn, .ev-confirm .btn {
  min-height: 36px; padding: 0 var(--sp-4); border-radius: var(--r-pill); font-size: var(--fs-md); font-weight: var(--fw-medium);
}
:is(dialog, .settings-pop) .actions .btn.quiet, .feeds-add-row .btn.quiet {
  border-color: var(--line); background: var(--track); color: var(--ink);
}
:is(dialog, .settings-pop) .actions .btn.quiet:hover:not(:disabled), .feeds-add-row .btn.quiet:hover:not(:disabled) {
  background: var(--faint); color: var(--ink);
}
:is(dialog, .settings-pop) .actions .btn.primary, .feeds-add-row .btn.primary { padding: 0 var(--sp-5); font-weight: var(--fw-semi); }

/* The event dialog's text links become a row of quiet pills; Remove and
   Delete are no longer faint-then-red. */

/* "…" menus inside overlays: no red text, and they open upward from a footer. */
:is(dialog, .settings-pop) .fv-menu-item.danger, :is(dialog, .settings-pop) .fv-menu-item.danger .fv-icon { color: var(--ink); }
:is(dialog, .settings-pop) .fv-menu-item.danger:hover, :is(dialog, .settings-pop) .fv-menu-item.danger:focus-visible { background: var(--state-hover); }
.actions .fv-menu-wrap .fv-menu { top: auto; bottom: calc(100% + var(--sp-1)); left: 0; right: auto; }
.actions .fv-more { width: 36px; height: 36px; border-radius: var(--r-pill); border: 1px solid var(--line); background: var(--track); color: var(--ink); }
.actions .fv-more:hover, .actions .fv-more[aria-expanded="true"] { background: var(--faint); }
.actions [data-task-more] { display: inline-flex; }

/* Task forms: one top edge per section (the rule above every heading goes),
   time and duration fit their content, the add-links are easy to hit. */
.tf-divider { border-top: 0; padding-top: var(--sp-2); }
.tf-section + .tf-section { margin-top: var(--sp-1); }
.tf-field.tf-inline input.time-input { width: 6em; }
.tf-add-duration { min-height: 28px; display: inline-flex; align-items: center; }
.tf-label-row { grid-template-columns: 44px 1fr; }

/* Pattern: weekdays as the task form's chips (three letters, so pills),
   the end date as the app's own day-first field. */
.pattern-days { flex-wrap: wrap; margin: var(--sp-2) 0 var(--sp-3); }
.pattern-days .tf-chip span { width: auto; min-width: 44px; padding: 0 var(--sp-3); border-radius: var(--r-pill); box-sizing: border-box; }
#pattern-dialog h2 { margin-bottom: var(--sp-1); }
#pattern-dialog .muted { margin: 0 0 var(--sp-2); }
#pattern-dialog [data-pattern] label.tf-field { margin: var(--sp-2) 0; }
#pattern-dialog input[type=number], #pattern-dialog select {
  height: var(--sp-10); padding: 0 var(--sp-3); border: 1px solid var(--line); border-radius: var(--r-input); background: var(--surface); color: var(--ink); font: inherit; font-size: var(--fs-base);
}
#pattern-dialog [data-pattern=flexible_window] { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
#pattern-dialog [data-pattern=flexible_window] label { display: inline-flex; align-items: center; gap: var(--sp-2); margin: 0; }
#pattern-dialog input[type=number] { width: 5em; }

/* Linked calendars and Settings: the link field is a field like the others. */
.settings-pop input[type=url] {
  width: 100%; height: var(--sp-10); min-height: var(--sp-10); padding: 0 var(--sp-3); box-sizing: border-box;
  border: 1px solid var(--line); border-radius: var(--r-input); background: var(--surface); color: var(--ink); font: inherit; font-size: var(--fs-base);
}
.settings-pop input[type=url]:hover:not(:focus) { border-color: var(--faint-text); }
.settings-pop input[type=url]:focus-visible { border-color: var(--ink); }
.settings-pop .feeds-add { gap: var(--sp-2-5); }
.settings-pop .feeds-add label { gap: var(--sp-1-5); font-weight: var(--fw-medium); }
.settings-pop .settings-link { min-height: 36px; padding: 0 var(--sp-4); border: 1px solid var(--line); background: var(--track); color: var(--ink); font-size: var(--fs-md); font-weight: var(--fw-medium); }
.settings-pop .settings-link:hover { background: var(--faint); }
.settings-pop .feeds-add-row { gap: var(--sp-2); }
.settings-pop .feed-row .btn.icon-btn, .settings-pop .feed-row .btn.danger { color: var(--muted); }
.settings-pop .feed-row .btn.danger:hover { color: var(--ink); background: var(--faint); }
:is(#task-dialog, #task-edit-dialog) .tf-field.tf-inline input.time-input { width: 6.5em; margin-top: 0; }
:is(#task-dialog, #task-edit-dialog) .tf-field.tf-inline { align-items: center; }
:is(#task-dialog, #task-edit-dialog) .tf-field.tf-inline > .muted { flex: 1 1 100%; margin-top: calc(-1 * var(--sp-1)); font-weight: var(--fw-regular); font-size: var(--fs-sm); }
/* One label column for the inline fields (Time, Duration, Date, Starts, Ends). */
.tf-field.tf-inline > .tf-lbl { flex: 0 0 9em; }
:is(#task-dialog, #task-edit-dialog) .tf-field.tf-inline > .muted { margin-left: 9em; flex-basis: calc(100% - 9em); }
#pattern-dialog .tf-field.tf-inline > .tf-lbl, #log-dialog .tf-field.tf-inline > .tf-lbl { flex-basis: 5em; }
#pattern-dialog .tf-field.tf-inline > .tf-lbl, #log-dialog .tf-field.tf-inline > .tf-lbl { flex-basis: 7em; }
.log-sentence .log-stepper { margin: 0 var(--sp-1-5); }

/* -- Chunk 96 follow-up (Ed, 3 Nov) --
   Eyes only mean something on the Calendar; the menu button is as quiet as Settings;
   the Tasks card fits its tasks and scrolls inside only once it would pass the window. */
body:not([data-view="calendar"]) .sidebar .nav-eye { display: none !important; }
body:not([data-view="calendar"]) .sidebar .nav-row .nav-goal { padding-right: 0 !important; }
.nav-toggle[aria-expanded="true"] { background: transparent; }
.nav-toggle:hover, .nav-toggle[aria-expanded="true"]:hover { background: var(--state-hover); }
@media (min-width: 1000px) {
  .today-grid { align-items: start; }
  .today-side { align-self: stretch; }
  .today-main-card { max-height: 100%; }
  .today-timeline { flex: 0 1 auto; }
}

/* -- Chunk 106: New task and Edit task, one rhythm, and the return toast --
   One label style, always above its field. Groups are set apart by space
   (--sp-5), never by rules. When holds date, time, duration and repeat, in
   that order. The quiet "+ Add" pills sit in a row of their own. Footer
   pinned to the panel's foot. Scoped to the two task panels. */
:is(#task-dialog, #task-edit-dialog) [hidden] { display: none !important; }
:is(#task-dialog, #task-edit-dialog) .task-form { gap: var(--sp-5); min-height: 100%; }
:is(#task-dialog, #task-edit-dialog) .task-form > h2 { margin: 0 0 calc(-1 * var(--sp-2)); }
:is(#task-dialog, #task-edit-dialog) .task-form .tf-section { gap: var(--sp-3); }
:is(#task-dialog, #task-edit-dialog) .task-form .tf-divider {
  margin: 0; padding: 0; border: 0; font-size: var(--fs-base); font-weight: var(--fw-semi);
  letter-spacing: 0; text-transform: none; color: var(--ink);
}
:is(#task-dialog, #task-edit-dialog) .task-form .tf-divider .optional-tag { margin-left: var(--sp-1); }
/* A label: above the field, the same size and weight everywhere. */
:is(#task-dialog, #task-edit-dialog) .task-form .tf-field:not(.tf-sentence) {
  display: flex; flex-direction: column; align-items: stretch; gap: var(--sp-1-5);
  font-size: var(--fs-md); font-weight: var(--fw-medium); color: var(--text-2);
}
:is(#task-dialog, #task-edit-dialog) .task-form .tf-field:not(.tf-sentence) > input,
:is(#task-dialog, #task-edit-dialog) .task-form .tf-field:not(.tf-sentence) > .date-field { margin: 0; width: 100%; min-width: 0; }
:is(#task-dialog, #task-edit-dialog) .task-form .tf-lbl { font-size: var(--fs-md); font-weight: var(--fw-medium); color: var(--text-2); }
:is(#task-dialog, #task-edit-dialog) .task-form .optional-tag { margin-left: var(--sp-1); font-weight: var(--fw-regular); color: var(--muted); }
:is(#task-dialog, #task-edit-dialog) .task-form .date-field { display: flex; }
:is(#task-dialog, #task-edit-dialog) .task-form .date-field .date-text { flex: 1; width: auto; min-width: 0; }
/* Half and half. */
.tf-pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-3); align-items: start; }
.tf-pair:not(:has(> :not([hidden]))) { display: none; }
/* Quiet pills, at least 24px tall. */
.tf-pills { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.tf-pills:not(:has(> :not([hidden]))) { display: none; }
.tf-pill {
  display: inline-flex; align-items: center; min-height: 28px; padding: 0 var(--sp-3);
  border: 1px solid var(--line); border-radius: var(--r-pill); background: transparent;
  font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--text-2); cursor: pointer;
  transition: background var(--motion-fast), color var(--motion-fast), border-color var(--motion-fast);
}
.tf-pill:hover { background: var(--state-hover); color: var(--ink); border-color: var(--faint-text); }
.tf-pill:focus-visible { outline: var(--focus-width) solid var(--focus-color); outline-offset: 2px; }
/* The repeat settings. */
.tf-repeat, .tf-stack { display: flex; flex-direction: column; gap: var(--sp-3); }
:is(#task-dialog, #task-edit-dialog) .task-form .tf-presets { margin: 0; }
:is(#task-dialog, #task-edit-dialog) .task-form .tf-help { margin: 0; color: var(--muted); font-size: var(--fs-sm); line-height: 1.4; }
:is(#task-dialog, #task-edit-dialog) .task-form .tf-desc { margin: 0; }
:is(#task-dialog, #task-edit-dialog) .task-form .tf-tiles { border-radius: var(--r-pill); }
:is(#task-dialog, #task-edit-dialog) .task-form .tf-tile {
  min-height: var(--sp-8); padding: 0 var(--sp-2); border-radius: var(--r-pill); white-space: nowrap; font-size: var(--fs-md);
}
.tf-chips { gap: var(--sp-1-5); }
:is(#task-dialog, #task-edit-dialog) .task-form .tf-chip span { width: 36px; height: 36px; font-size: var(--fs-md); }
/* "Do this [- 3 +] times each [week]" on one line. */
.task-form .tf-sentence:not(.tf-field) { display: flex; flex-wrap: nowrap; align-items: center; gap: var(--sp-1-5); margin: 0; font-size: var(--fs-base); }
.task-form .tf-sentence:not(.tf-field) > span:not(.tf-stepper) { white-space: nowrap; }
.task-form .tf-stepper .btn { padding: 0; width: 28px; height: 32px; display: inline-flex; align-items: center; justify-content: center; }
:is(#task-dialog, #task-edit-dialog) .task-form .tf-stepper input { width: 36px; min-height: 32px; height: 32px; padding: 0; }
:is(#task-dialog, #task-edit-dialog) .task-form .tf-sentence select { width: auto; min-width: 76px; min-height: 32px; height: 32px; }
/* Day labels: a row per ticked day, spaced out. */
.tf-day-labels { display: flex; flex-direction: column; gap: var(--sp-2); margin: 0; }
.tf-day-labels [data-label-rows] { display: flex; flex-direction: column; gap: var(--sp-2); }
.tf-label-row { margin: 0; grid-template-columns: 44px minmax(0, 1fr); }
/* Footer pinned to the panel's foot, whatever the content's height. */
:is(#task-dialog, #task-edit-dialog) .task-form > .actions { margin-top: auto; }
:is(#task-dialog, #task-edit-dialog) .tf-belongs { margin: 0; }

/* The rail's colour tabs: a whole strip of colour, square on the window's edge;
   hover or focus widens it to show its eye. */
.peek-item {
  width: 10px; overflow: hidden; border-left: 0; transform: none;
  background: linear-gradient(to right, var(--goal, var(--muted)) 0 8px, var(--surface) 8px);
  transition: width var(--motion-fast) var(--ease-enter);
}
.peek-item:hover, .peek-item:focus-within { width: 38px; transform: none; }

/* Toast: "Added to Thu 5 Nov" with Show, or "Opened from Week review" with Back. */
.toast {
  position: fixed; z-index: 70; left: 50%; bottom: var(--sp-6); transform: translateX(-50%);
  display: flex; align-items: center; gap: var(--sp-3); max-width: calc(100vw - var(--sp-8));
  padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-4); border-radius: var(--r-pill);
  background: var(--primary-fill); color: var(--on-primary); box-shadow: var(--shadow-menu);
  font-size: var(--fs-base); animation: toast-in var(--motion-fast) var(--ease-enter);
}
.toast-text { min-width: 0; }
.toast-btn {
  min-height: 28px; padding: 0 var(--sp-3); border: 1px solid currentColor; border-radius: var(--r-pill); background: transparent;
  color: inherit; font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-semi); cursor: pointer;
}
.toast-btn:hover, .toast-x:hover { background: color-mix(in srgb, currentColor 16%, transparent); }
.toast-x { width: 28px; height: 28px; border: 0; border-radius: var(--r-pill); background: transparent; color: inherit; font-size: var(--fs-lg); line-height: 1; cursor: pointer; }
.toast :focus-visible { outline: var(--focus-width) solid currentColor; outline-offset: 2px; }
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 8px); } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }
/* The Calendar count is back (Ed, 3 Nov, reversing look audit F3): it sits on
   the outer top-right corner of the switch's ring - the Calendar half's corner
   whether the switch is closed or open - sat just off the corner (clear of the viewport edge) so it clears
   every pill inside the ring. Badge colours from Chunk 99. */
.topbar .view-switch > .calendar-badge {
  top: -6px; right: -16px; min-width: 20px; height: 20px; padding: 0 var(--sp-1-5); z-index: 4; pointer-events: none;
  font-size: var(--fs-xs); line-height: 16px; font-variant-numeric: tabular-nums;
}
/* ==== Calendar polish (Chunk 104, design-principles.md) ====
   Calendar-only rules; no shared token or component rule is changed. */

/* Month: a day outside the month shows only its number. Its bars had no
   titles left, so they read as empty white slots, and a "+3 more" sat under
   nothing (review gate 1, D18). */
#calendar-grid .month-day.outside .month-day-events > :not(.month-more),
#calendar-grid .month-day.outside .month-more { display: none; }

/* Day: when a lane is narrow (two overlapping events side by side), the
   title keeps its room and the time and length give way first. */
#calendar-grid.day-stack .cal-entry[data-density="lane"] .entry-title { flex: 0 0 auto; max-width: 100%; }
#calendar-grid.day-stack .cal-entry[data-density="lane"] .grid-sub:not(:empty) { display: block; white-space: nowrap; flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* Week below about 1250px wide: seven columns of around 127px. A step less
   padding and a 13px title keep a title like "Write a race plan" whole
   (review gate 1, D9). The tray overlays rather than squeezing further. */
@media (max-width: 1250px) {
  #calendar-grid.week-stack .week { gap: var(--sp-2); }
  #calendar-grid.week-stack .day { padding-left: var(--sp-1-5); padding-right: var(--sp-1-5); }
  #calendar-grid.week-stack .cal-entry[data-density="chip"] .entry-text { padding-left: var(--sp-2); padding-right: var(--sp-1-5); }
  #calendar-grid.week-stack .cal-entry[data-density="chip"] .entry-title { font-size: var(--fs-md); letter-spacing: -0.01em; }
}
#calendar-grid.week-stack .narrow-lane .cal-entry[data-density="chip"] .entry-title {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  white-space: normal; line-height: 15px;
}
#calendar-grid.week-stack .narrow-lane .cal-entry[data-density="chip"] .entry-text { padding-right: var(--sp-1); }
#calendar-grid.week-stack .narrow-lane .cal-entry[data-density="chip"].has-icons .entry-text { padding-right: var(--sp-5); }
#calendar-grid.week-stack .narrow-lane .cal-entry[data-density="chip"] .grid-sub:not(:empty) { font-size: var(--fs-2xs); letter-spacing: -0.01em; }

/* An empty week keeps its full-height columns (Chunk 192, designer 4): it used to shrink to seven short
   day heads (principle 3), which left nothing to click or drop on. See "Empty Week and Month" below. */

/* One scroll rule (Chunk 104, Ed 3 Nov): the page frame never scrolls; the
   calendar area does, and only when its content doesn't fit. Month fits unless
   the window is very short; then its frame scrolls inside. */
.calendar-frame.scrolls-inside { overflow-y: auto; overscroll-behavior: contain; }
.calendar-frame.scrolls-inside > #calendar-grid { flex: none; }

/* ===== Chunk 105: repeat range handles (only while New task or Edit task is open) =====
   A 3px line in the Task's own colour (--range) with a dot and a short Ink
   label at each end that's on screen. The layer has no height: it hangs off
   the top of a Week or Day column (in the gap above it) or off the top edge of
   each Month row, so no row, cell or column changes size. */
.week.focused, .month-week, .day-view.focused { position: relative; }
.range-layer {
  position: absolute; left: 0; right: 0; top: 0; height: 0;
  z-index: 6; pointer-events: none;
}
.range-layer.range-week { top: -8px; }
.range-layer.range-day { top: 20px; } /* inside the card's top padding: the toolbar sits over the gap above it */
.range-layer > * { position: absolute; }
.range-line {
  top: 0; height: 3px; border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--range) 70%, transparent);
}
.range-line.fade-l { mask-image: linear-gradient(to right, transparent, #000 56px); }
.range-line.fade-r { mask-image: linear-gradient(to left, transparent, #000 56px); }
.range-line.fade-l.fade-r { mask-image: linear-gradient(to right, transparent, #000 56px, #000 calc(100% - 56px), transparent); }
.range-handle {
  top: -10.5px; width: 24px; height: 24px; margin-left: -12px;
  padding: 0; border: 0; background: none; border-radius: var(--r-pill);
  cursor: grab; touch-action: none; pointer-events: auto;
}
.range-handle::before, .range-dot {
  content: ""; display: block; box-sizing: border-box;
  width: 12px; height: 12px; border-radius: var(--r-pill);
  background: var(--range); box-shadow: 0 0 0 2px var(--surface);
}
.range-handle::before { margin: 6px; transition: transform var(--motion-fast) var(--ease-move); }
.range-dot { top: -4.5px; margin-left: -6px; }
.range-handle:hover::before, .range-handle.dragging::before { transform: scale(1.3); }
.range-handle:focus-visible { outline: 2px solid var(--ink); outline-offset: 0; }
.range-handle.dragging { cursor: grabbing; }
body.range-dragging, body.range-dragging * { cursor: grabbing !important; user-select: none; }
.range-label, .range-chip {
  top: -7px; box-sizing: border-box; height: 16px; padding: 0 7px;
  display: inline-flex; align-items: center; white-space: nowrap;
  font: inherit; font-size: var(--fs-xs); line-height: 1; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-pill);
}
.range-label { pointer-events: none; }
.range-label.right { transform: translateX(-100%); }
.range-edge { top: -11px; display: flex; gap: var(--sp-1); }
.range-edge.left { left: 28px; }
.range-edge.right { right: 8px; }
.range-chip { position: relative; height: 24px; cursor: pointer; pointer-events: auto; } /* Gate 2 G-A3: 24px itself (2.5.8), not a pseudo-element's hit area */
.range-chip:hover { background: color-mix(in srgb, var(--range) 14%, var(--surface)); }
.range-chip:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
@media (prefers-reduced-motion: reduce) { .range-handle::before { transition: none; } }
/* ===== end Chunk 105 ===== */

/* ===== Chunk 107: hover never resizes text; Month bars at a 24px pitch =====
   Bars are 18px, 6px apart: Chunk 99's 24px targets kept by spacing (WCAG
   2.5.8), not by a taller cell. A highlighted match in Month swaps to a strip
   at the bar's own height and text position, so only its strength changes -
   it used to drop from a 24px bar to a 16px strip, which read as the text
   shrinking. --bar-h is MONTH_BAR_PX from app.js; 18px for an untimed bar. */
.month .entry.cal-entry[data-density="bar"] { margin-top: var(--sp-1-5); }
#calendar-grid .month-week .entry.cal-entry[data-density="strip"] { --h: var(--bar-h, 18px) !important; margin-top: var(--sp-1-5); }
#calendar-grid .month-week .entry.cal-entry[data-density="strip"] .entry-text { inset: 1px 4px auto 10px; }
#calendar-grid .month-week .entry.cal-entry[data-density="strip"] .entry-title { line-height: var(--lh-meta); font-weight: var(--fw-medium); }
/* The grid is only as tall as its rows now (layoutMonthRows), so it eases with them. */
#calendar-grid.month { transition: height var(--row-resize, var(--motion-move)) var(--row-ease, var(--ease-move)) var(--row-delay, 0s); }
#calendar-grid.month.no-anim { transition: none; }
@media (prefers-reduced-motion: reduce) { #calendar-grid.month { transition: none; } }

/* ===== Chunk 108: Add task to a Milestone ===== */
/* The simplified form keeps title, amount and when/repeat; More options opens the rest. */
#task-form.tf-simple [data-simple-hide] { display: none; }
#task-form:not(.tf-simple) [data-more-wrap] { display: none; }
#task-form .tf-section[hidden], #task-edit-form [data-action-tiles][hidden] { display: none; }
/* Under a Milestone the completion is fixed: one line, its icon in the Goal's colour (Chunk 108, 125). */
.tf-type-line { display: flex; align-items: center; gap: var(--sp-2); margin: 0; color: var(--text-2); font-size: var(--fs-md); }
.tf-type-line svg { flex: none; width: 18px; height: 18px; fill: none; stroke: var(--goal, currentColor);
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* ===== end Chunk 108 ===== */

/* ===== Chunk 112: the click model =====
   The quick menu is the "…" menu itself, opened at the pointer: fixed, so it
   sits over anything, and kept on screen by app.js. The page's colour dot
   opens the same swatch pop the left panel used; the panel's dots only show
   colour now. Edit task's scope line is one quiet line under its title. */
.quick-menu { position: fixed; z-index: 80; display: block; }
.quick-menu > .fv-menu { position: static; min-width: 200px; }
.fv-kicker-line { display: inline-flex; align-items: center; gap: var(--sp-2); }
.fv-colour-dot {
  position: relative; flex: none; width: 12px; height: 12px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: var(--swatch); box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 15%, transparent);
}
.fv-colour-dot::after { content: ""; position: absolute; inset: -6px; border-radius: 50%; } /* a 24px target */
.fv-colour-dot:hover, .fv-colour-dot[aria-expanded="true"] { box-shadow: 0 0 0 2px var(--surface), 0 0 0 3.5px var(--ink); }
.fv-colour-dot:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.tf-scope { margin: calc(-1 * var(--sp-2)) 0 0; font-size: var(--fs-sm); color: var(--muted); }
.tf-scope[hidden] { display: none; }
/* ===== end Chunk 112 ===== */

/* ===== Chunk 114: one count for the slipped pile =====
   Week review's badge is a dot: the one count on screen is To place's. */
.topbar-badge.is-dot { top: -4px; right: -4px; min-width: 0; width: 10px; height: 10px; padding: 0; border-radius: var(--r-pill); }
/* ===== end Chunk 114 ===== */

/* ===== Chunk 109: flagged-call follow-ups (calendar and lists, Ed 3 Nov) ===== */

/* #6 To place: the Task's day label, quiet, after the title ("Gym · Legs"). */
.place-label { flex: 0 1 auto; min-width: 0; font-size: var(--fs-sm); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.entry.event.tab.place-row .place-line .entry-title { flex: 0 1 auto; }
.place-row .place-line .place-due { margin-left: auto; padding-left: var(--sp-2); }

/* #41 The drop preview sits at its place in the day's list: Month's bars step
   down by one slot like Week's cards (a translate, so nothing reflows). */
.month-day-events > .slot-shift { translate: 0 var(--slot-shift, 0); }
/* Chunk 245: a title the shift would push onto "+N more" folds into the count while the slot shows. */
.month-day-events > .slot-fold { visibility: hidden; }

/* #29 Week blocks: title first, the grey meta line under it, as Day does. */
#calendar-grid.week-stack .cal-entry[data-density="chip"] .entry-text { display: flex; flex-direction: column; }
#calendar-grid.week-stack .cal-entry[data-density="chip"] .entry-title { order: 0; }
#calendar-grid.week-stack .cal-entry[data-density="chip"] .grid-sub { order: 1; }
#calendar-grid.week-stack .cal-entry[data-density="chip"] .entry-sub { order: 2; }
#calendar-grid.week-stack .cal-entry[data-density="chip"] .entry-line { order: 3; }

/* Zoom while composing (Ed): only the switch's Today and Calendar halves step
   back; Day, Week, Month and Year stay in use. */
body.adding .topbar .view-switch { opacity: 1; filter: none; pointer-events: auto; user-select: auto; }
body.adding .topbar .view-switch [data-go] { opacity: 0.35; filter: grayscale(1); pointer-events: none; user-select: none; }
body.adding .topbar .view-switch .cal-seg { filter: none; }

/* The Starts / Ends labels merged when the two are close (Chunk 105 follow-up). */
.range-label.merged { font-variant-numeric: tabular-nums; }

/* Duration handle (Ed): a bottom handle in the item's colour on Day's timed
   blocks and the New task preview. The grip is a 28 x 5 pill on the block's
   foot; the target is 48 x 24 around it. Pointer drag as before (Chunk 46);
   keyboard: Shift+Up / Shift+Down with the block picked. */
.lane-edge.lane-handle {
  left: 50%; right: auto; width: 48px; height: 24px; bottom: 0; margin-left: -24px;
  display: flex; align-items: flex-end; justify-content: center; z-index: 3; touch-action: none;
}
.lane-handle .lane-grip {
  width: 28px; height: 5px; margin-bottom: 3px; border-radius: var(--r-pill);
  background: var(--goal, var(--ink));
  transition: transform var(--motion-fast) var(--ease-fade);
}
.lane-handle:hover .lane-grip, .dragging .lane-handle .lane-grip, .entry.selected .lane-handle .lane-grip { transform: scaleX(1.3); }
@media (prefers-reduced-motion: reduce) { .lane-handle .lane-grip { transition: none; } }
/* ===== end Chunk 109 ===== */

/* ===== Chunk 116: gate 1 leftovers (review-gate-1.md, low items) ===== */
:root {
  --over-ink: var(--ink);                          /* S3: "over" and "late" are Ink, named once */
  --shadow-lift: 0 2px 8px rgb(0 0 0 / 0.08);      /* D24: a card lifting on hover */
}
/* A26: the typed date grows with the text and its spacing instead of clipping. */
.date-field .date-text,
:is(#task-dialog, #task-edit-dialog, #goal-dialog, #log-dialog) .date-field .date-text {
  height: auto; min-height: 34px; width: 14ch; min-width: 118px; padding-block: 0.35em; line-height: 1.4;
}
.date-field .date-pick { height: auto; min-height: 34px; align-self: stretch; }
:is(#task-dialog, #task-edit-dialog) .task-form .date-field .date-text { width: auto; min-width: 0; }
/* D17: a dark dialog or popover gets a hairline edge, since a shadow doesn't show on dark. */
:root[data-theme="dark"] :is(dialog, .settings-pop, .date-pop) { box-shadow: var(--shadow-dialog), 0 0 0 1px var(--line); }
/* D23: the Plan row's flash is one ring on the track, not a ring beside the pill's own edge. */
.settings-plan.flash .plan-seg { outline-offset: 0; }
/* A28: a done bar says so with a tick as well as its fill. */
.entry.cal-entry.state-done:is([data-density="bar"], [data-density="strip"])::after {
  content: ""; position: absolute; right: 7px; top: 50%; width: 8px; height: 4px;
  border-left: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: translateY(-70%) rotate(-45deg); pointer-events: none; color: var(--surface);
}
/* ===== end Chunk 116 ===== */

/* ===== Chunk 119: first run and empty states ===== */
/* The welcome: a full page with a logo-only bar; the question is the only large type. */
.welcome { position: fixed; inset: 0; z-index: 400; background: var(--page); color: var(--ink); display: flex; flex-direction: column; overflow: auto; }
.welcome-bar { height: 60px; flex: none; display: flex; align-items: center; padding: 0 var(--sp-4); border-bottom: 1px solid var(--divider); }
.welcome-bar .brand { position: static; }
.welcome-step { flex: 1; display: flex; flex-direction: column; justify-content: center; padding: var(--sp-5) clamp(20px, 11vw, 160px) 80px; max-width: 760px; box-sizing: content-box; }
.welcome-step h1 { margin: 0; font: var(--fw-bold) clamp(40px, 5vw, 64px)/1.06 var(--font-head); letter-spacing: -0.05em; }
.welcome-step h1.welcome-small { font-size: clamp(34px, 3.6vw, 52px); }
.welcome-step h2 { margin: 40px 0 0; font: var(--fw-semi) var(--fs-xl)/32px var(--font-head); letter-spacing: -0.025em; }
.welcome-goal-line { display: flex; align-items: center; gap: 10px; margin: 0 0 10px; font-size: var(--fs-body); color: var(--muted); }
.welcome-dash { width: 4px; height: 16px; border-radius: var(--r-dash); background: var(--goal); }
.welcome-field { margin-top: 20px; max-width: 560px; }
.welcome-field label { display: block; margin-bottom: 6px; font-size: var(--fs-md); font-weight: var(--fw-medium, 500); color: var(--muted); }
.welcome-field input { width: 100%; height: 56px; box-sizing: border-box; padding: 0 18px; font: inherit; font-size: var(--fs-lg); color: var(--ink); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-input); }
.welcome-field input:focus-visible { outline: 2px solid var(--ink); outline-offset: 0; border-color: var(--ink); }
.welcome-two { display: flex; gap: var(--sp-4); max-width: 560px; }
.welcome-two .welcome-field { flex: 1; }
.welcome-error { margin: var(--sp-2) 0 0; font-size: var(--fs-base); color: var(--ink); }
.welcome-actions { display: flex; gap: var(--sp-2); margin-top: 28px; }
.welcome-btn { min-height: 44px; padding: 0 20px; border-radius: var(--r-pill); font-weight: var(--fw-semi); }
.welcome-skip { border-color: transparent; font-weight: 500; }
/* Empty Today: one fact and one button. */
.today-clear { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3) var(--sp-2-5); }
.today-clear p { margin: 0; }
.today-clear-new { min-height: 36px; border-color: var(--line); background: var(--surface); }
/* Week and Month's one-line fact beside the title; Year's under its count. */
.cal-empty { margin-left: auto; align-self: flex-end; padding-bottom: 10px; font-size: var(--fs-body); }
.year-sofar .year-none { margin: var(--sp-2) 0 0; }
/* The empty week shrinks to its day heads; the To place tray beside it keeps room for its one line. */
.cal-side:not([hidden]) { min-height: 200px; }
/* ===== end Chunk 119 ===== */

/* ===== Chunk 120: Today fixes from section check 1 ===== */
/* Under 1000px the right column drops below the main card: Chunk 120 removed
   a repeated two-column .today-grid rule further down that beat the media
   rule beside the Chunk 96 one (search "max-width: 1000px) { .today-grid"). */
/* Untimed items: a quiet "Anytime" (and "All day") in the time column, as a
   group at the top, set a little apart from the timed list. */
.today-slot.is-anytime .today-time { font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--muted); }
.today-slot.is-anytime + :not(.is-anytime) { margin-top: var(--sp-2); }
/* The Missed card's "..." menu: under its button, inside the card. */
.today-missed .fv-menu { min-width: 150px; right: 0; left: auto; top: calc(100% + 6px); }
/* Skip link: off screen until focused, then a pill at the top left. */
.skip-link {
  position: fixed; top: var(--sp-2); left: var(--sp-2); z-index: 1000;
  padding: var(--sp-2) var(--sp-4); border-radius: var(--r-pill);
  background: var(--ink); color: var(--page); font-weight: var(--fw-semi); text-decoration: none;
  transform: translateY(calc(-100% - var(--sp-4)));
}
.skip-link:focus { transform: none; outline: var(--focus-width) solid var(--focus-color); outline-offset: 2px; }
@media (prefers-reduced-motion: no-preference) { .skip-link { transition: transform var(--motion-fast) var(--ease-enter); } }
body.welcome-open .skip-link { display: none; }
/* ===== end Chunk 120 ===== */

/* Chunk 128: the time picker. A listbox of 15-minute steps (or common
   durations) under a time field; the field itself stays a plain input. */
.tp-list {
  position: fixed; z-index: 90; margin: 0; padding: var(--sp-1); list-style: none; overflow-y: auto; box-sizing: border-box;
  background: var(--surface); border: 1px solid var(--faint); border-radius: var(--r-card); box-shadow: var(--shadow-menu);
  animation: fade-in var(--motion-fast) var(--ease-fade);
}
.tp-opt {
  min-height: 28px; display: flex; align-items: center; padding: 0 var(--sp-2-5); border-radius: var(--r-input);
  font-size: var(--fs-base); font-variant-numeric: tabular-nums; color: var(--ink); cursor: pointer;
}
.tp-opt.active { background: var(--track); }
.tp-opt[aria-selected="true"] { font-weight: var(--fw-bold); box-shadow: inset 3px 0 0 var(--ink); }
.time-input[role="combobox"] { cursor: text; }
@media (prefers-reduced-motion: reduce) { .tp-list { animation: none; } }

/* Chunk 128: quick add's "Advanced" sits at the foot, left, quiet. */

/* ===== Chunk 125: Milestone forms =====
   The New and Edit milestone form takes the task form's rhythm (Chunk 106):
   every label above its field in one quiet style, 12px inside a group, 20px
   between the two groups (about it; its target), the target type as two
   tiles with one help line, amount and unit side by side, the footer at the
   panel's foot. Scoped by .ms-form (set in milestone modes); the Goal and Routine forms that
   share the dialog are unchanged. */
#goal-form.ms-form {
  display: flex; flex-direction: column; gap: var(--sp-3); min-height: 100%;
}
#goal-form.ms-form > h2 { margin: 0 0 var(--sp-2); }
/* A label: its text and any "optional" on one line, the field under them. */
#goal-form.ms-form label:not(.tf-tile) {
  display: grid; grid-template-columns: auto 1fr; column-gap: var(--sp-1); row-gap: var(--sp-1-5); align-items: baseline; margin: 0;
  font-size: var(--fs-md); font-weight: var(--fw-medium); color: var(--text-2);
}
#goal-form.ms-form label:not(.tf-tile) > :is(input, select, textarea, .date-field) {
  grid-column: 1 / -1; margin: 0; width: 100%; min-width: 0; font-weight: var(--fw-regular);
}
#goal-form.ms-form label .date-field { display: flex; }
#goal-form.ms-form label .date-field .date-text { flex: 1; width: auto; }
#goal-form.ms-form .optional-tag { margin: 0; font-weight: var(--fw-regular); color: var(--muted); }
/* The target: its own group, set apart by space, not a rule. */
#goal-form.ms-form fieldset {
  display: flex; flex-direction: column; gap: var(--sp-3); margin: var(--sp-2) 0 0; padding: 0; border: 0; min-width: 0;
}
#goal-form.ms-form legend {
  margin: 0; padding: 0; font-size: var(--fs-base); font-weight: var(--fw-semi); color: var(--ink);
}
#goal-form.ms-form .tf-tiles { border-radius: var(--r-pill); }
#goal-form.ms-form .tf-tile { min-height: var(--sp-8); padding: 0 var(--sp-3); border-radius: var(--r-pill); white-space: nowrap; }
#goal-form.ms-form .tf-desc { min-height: 0; color: var(--muted); line-height: 1.4; }
#goal-form.ms-form > .actions { margin-top: auto; }
/* The task forms' fixed completion line: the type in ink, then what it logs. */
.tf-type-line b { font-weight: var(--fw-semi); color: var(--ink); }
/* ===== end Chunk 125 ===== */

/* ===== Chunk 126: composing on the calendar (Ed's note 15b) =====
   While New task or Edit task is open, everything but the Task being made
   steps back: faded and greyed, most of all on Month, the busiest grid. A
   filter, not opacity, so the many per-state opacity rules (missed, done,
   past) keep their own say and this only ever adds to them. Its own class,
   kept apart from the left panel's hidden-item fade (Chunk 127). */
#calendar-grid.composing-fade { --fade: saturate(0.3) opacity(0.45); }
#calendar-grid.composing-fade.month { --fade: saturate(0.2) opacity(0.3); }
#calendar-grid.composing-fade :is(.cal-entry:not(.draft-preview, .draft-hover, .draft-original), .ext-event, .pennant, .month-more) {
  filter: var(--fade);
}
/* The Task itself comes forward a little, so its dashed outline reads first;
   Edit task's own entries keep their own (already faint) look. */
#calendar-grid.composing-fade .cal-entry.draft-preview { opacity: 0.85; }
/* ===== end Chunk 126 ===== */

/* ===== Chunk 127: consistency pass (Ed's notes 1, 7, 8, 10, 12) ===== */
/* A key for every graph: swatches drawn like the marks, text in the text colour. */
.c127-key { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4); margin: var(--sp-2-5) 0 0; padding: 0; list-style: none; font-size: var(--fs-sm); color: var(--text-2); }
.c127-key li { display: inline-flex; align-items: center; gap: var(--sp-1-5); }
.c127-sw { display: inline-block; flex: none; box-sizing: border-box; width: 22px; height: 10px; }
.c127-sw.sw-line { height: 0; border-top: 2px solid var(--goal, var(--ink)); }
.c127-sw.sw-dash { height: 0; border-top: 2px dashed var(--goal, var(--ink)); }
.c127-sw.sw-goal { height: 0; border-top: 2px dotted var(--muted); }
.c127-sw.sw-needs { height: 0; border-top: 1px solid var(--muted); }
.c127-sw.sw-dot { width: 10px; height: 10px; margin: 0 6px; border-radius: 50%; background: var(--goal, var(--ink)); }
.c127-sw.sw-tick { width: 2px; height: 14px; margin: 0 10px; background: var(--ink); }
.c127-sw.sw-now { width: 2px; height: 14px; margin: 0 10px; background: var(--ink); }
.c127-sw.sw-tint { height: 8px; border-radius: var(--r-mini); background: color-mix(in srgb, var(--goal, var(--ink)) 16%, transparent); box-shadow: inset 0 0 0 1px var(--goal, var(--ink)); }
.c127-sw.sw-diamond { width: 9px; height: 9px; margin: 0 6px; transform: rotate(45deg); border: 1.5px solid var(--goal, var(--ink)); background: var(--surface); }
.c127-sw.sw-diamond.done { background: var(--goal, var(--ink)); }
.c127-sw.sw-diamond.over { border-color: var(--over-ink); }
.c127-sw.sw-bar { width: 10px; height: 14px; margin: 0 6px; border-radius: var(--r-block) var(--r-block) 0 0; background: var(--goal, var(--ink)); }
.c127-sw.sw-hatch { width: 10px; height: 14px; margin: 0 6px; border-radius: var(--r-block) var(--r-block) 0 0; border: 1px solid var(--goal, var(--ink)); border-bottom: 0; background: repeating-linear-gradient(58deg, var(--goal, var(--ink)) 0 4px, transparent 4px 7px); }
.c127-sw.sw-day { width: 14px; height: 14px; border-radius: var(--r-block); background: var(--sunk); }
.c127-sw.sw-day.done { background: var(--goal, var(--ink)); }
.c127-sw.sw-day.part { background: linear-gradient(to top, var(--goal, var(--ink)) 50%, var(--sunk) 50%); }
.c127-sw.sw-day.miss { box-shadow: inset 0 0 0 1px var(--line); }
.c127-sw.sw-day.free { background: transparent; border: 1px dashed var(--line); }
.pace-chart-box .c127-key { margin-top: var(--sp-1-5); }
.rs-card .c127-key { margin: var(--sp-2) var(--sp-2-5) 0; }

/* Day's and Month's key (notes 7, 8): the boxes as each view draws them. */
.c127-sw.sw-box { width: 22px; height: 12px; border-radius: var(--r-mini); }
.c127-sw.sw-planned { background: var(--grid-pending); box-shadow: inset 0 0 0 1px var(--line); }
.c127-sw.sw-box.sw-done { background: var(--grid-done); }
.c127-sw.sw-box.sw-missed { background: var(--grid-pending); box-shadow: inset 0 0 0 1px var(--line); opacity: 0.75; filter: grayscale(0.9); }
#week-going[data-zoom="month"] .c127-sw.sw-box { height: 10px; }
#week-going[data-zoom="month"] .c127-sw.sw-box.sw-done { background: var(--surface); box-shadow: inset 0 0 0 1px var(--line); }
#week-going[data-zoom="month"] .c127-sw.sw-box.sw-done::after { content: ""; position: absolute; right: 4px; top: 50%; width: 6px; height: 3px; border-left: 1.5px solid var(--text-2); border-bottom: 1.5px solid var(--text-2); transform: translateY(-70%) rotate(-45deg); }
#week-going .c127-sw.sw-box { position: relative; }

/* Note 7: the "odd symbol" on a done bar in Month was Chunk 116's tick drawn on
   top of the old status grammar's colour slice (a slanted sliver in the Goal's
   colour) and in the surface colour, so on a light bar only the sliver showed.
   The slice goes; the tick is drawn in the text colour, so it reads. */
.entry.cal-entry.state-done:is([data-density="bar"], [data-density="strip"])::after {
  background: none; clip-path: none; left: auto; color: var(--text-2);
}
#calendar-grid .month-day.today .entry.cal-entry.state-done:is([data-density="bar"], [data-density="strip"])::after { color: var(--on-feature); }

/* Note 10: a hidden Goal or Routine fades on Day, Week and Month alike (its
   own class: Chunk 126's compose fade is separate). Opacity .75 keeps a title
   at 4.9:1 or better on the grid, light and dark (worked out in the build
   notes). The Month rule below beats "a past day's entry stays opaque". */
#calendar-grid .class-faded,
#calendar-grid.month:not(.class-highlighting) .month-day.past .entry.cal-entry.class-faded:not(.today-entry)[data-density] { opacity: 0.75; filter: grayscale(0.9); }
#calendar-grid .class-faded:is(:hover, :focus-visible),
#calendar-grid.month:not(.class-highlighting) .month-day.past .entry.cal-entry.class-faded:not(.today-entry)[data-density]:is(:hover, :focus-visible) { opacity: 1; filter: none; }

/* Note 12: a done box is the size of an open one, in every section. Day's
   Anytime strip is 32px; Today's cards are 60px. */
.day-untimed > .entry.cal-entry:not(.today-entry).state-done:is([data-density="chip"], [data-density="lane"]) { --h: 32px; }
.today-card-task.state-done { height: 60px; }
.today-card-task .tc-tick { height: 60px; }
/* ===== end Chunk 127 ===== */

/* ===== Chunk 141: pages fixes (section check 03) ===== */
/* Long titles and descriptions wrap inside their card instead of running out of it (03 #5). */
.fv-head h2, .fv-desc, .fv-card-titles h3, .fv-row-text .title, .fv-meta, .fv-row-meta, .history-note, .log-entry-note {
  overflow-wrap: anywhere; min-width: 0;
}
.fv-card-head { min-width: 0; }
.fv-actions, .fv-row-actions { flex: none; }

/* The colour dot keeps its 12px look inside a larger target (03 #13, Ed's call): 32px around it. */
.fv-colour-dot::after { inset: -10px; }
.fv-colour-dot.static { cursor: default; pointer-events: none; }
.fv-colour-dot.static::after { content: none; }

/* A Task's History, by month (03 #6): the latest month open, older ones folded. */
.history-month > summary { list-style: none; cursor: pointer; border-top: 1px solid var(--divider); }
.history-month:first-child > summary { border-top: 0; }
.history-month > summary::-webkit-details-marker { display: none; }
.history-month-head { display: flex; align-items: baseline; gap: var(--sp-2-5); padding: var(--sp-3) var(--sp-2-5); min-height: 44px; box-sizing: border-box; }
.history-month-head h4 { margin: 0; font: var(--fw-semi) var(--fs-lg) var(--font-head); }
.history-month-head span { font-size: var(--fs-sm); color: var(--muted); }
.history-month-head::after { content: "›"; margin-left: auto; color: var(--muted); font-size: var(--fs-lg); }
.history-month[open] .history-month-head::after { content: "⌄"; }
.history-month > summary:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }

/* "Past" outranks its years (03 #16). */
#collection-detail .coll-year h4, #collection-detail .coll-year-group.shut .coll-year h4 { font-size: var(--fs-lg); }
/* Goals in the left panel never scroll inside themselves; the panel does (03 #17). */
.sidebar .nav-goals { flex: none; }
/* ===== end Chunk 141 ===== */

/* ---- Chunk 129: the Event dialog, every state, and Move (mock 124,
   docs/brand-identity/mockups/event-popups/, with Ed's answers of 3 Nov).
   The header in the goal's tint, one row of actions in a fixed order
   (filled Mark done, outlined Move to, red-outline Remove, a round "…"),
   "Open in Day" as the quiet footer. Remove is red text on a thin red
   outline, never filled (answer 1; principle 6 amended for this dialog). ---- */
#event-dialog { width: min(460px, calc(100vw - 32px)); padding: 0; overflow: visible; background: var(--surface); }
#event-dialog::backdrop, #move-dialog::backdrop { background: rgb(0 0 0 / 0.3); }
:root[data-theme="dark"] :is(#event-dialog, #move-dialog)::backdrop { background: rgb(0 0 0 / 0.6); }
#event-detail { --goal: #8a8f98; display: flex; flex-direction: column; border-radius: var(--r-dialog); overflow: visible; }
#event-detail .ev-head {
  padding: var(--sp-3) var(--sp-4); border-top: 6px solid var(--goal); border-radius: var(--r-dialog) var(--r-dialog) 0 0;
  background: color-mix(in srgb, var(--goal) 12%, var(--surface));
}
#event-detail .ev-head-meta { display: flex; align-items: center; gap: var(--sp-2); min-height: 28px; }
#event-detail .ev-owner { min-width: 0; font-size: var(--fs-sm); font-weight: var(--fw-semi); color: color-mix(in srgb, var(--goal) 55%, var(--ink)); }
#event-detail .ev-state {
  margin-left: auto; padding: 1px var(--sp-2); border-radius: var(--r-pill); background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--goal) 35%, var(--line)); font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--text-2);
}
#event-detail .ev-state[data-kind="done"] { background: var(--ink); border-color: var(--ink); color: var(--surface); }
#event-detail .ev-state[data-kind="missed"] { color: var(--missed-ink); border-color: color-mix(in srgb, var(--missed) 45%, var(--surface)); background: var(--missed-a); }
#event-detail .ev-state[data-kind="linked"] { background: none; border-style: dashed; }
#event-detail .ev-close {
  flex: none; width: 28px; height: 28px; padding: 0; border: 0; border-radius: var(--r-pill); display: grid; place-items: center;
  background: color-mix(in srgb, var(--ink) 7%, transparent); color: var(--text-2); cursor: pointer;
}
#event-detail .ev-close:hover { background: color-mix(in srgb, var(--ink) 13%, transparent); color: var(--ink); }
#event-detail .ev-close svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
#event-detail .ev-head h2 {
  margin: var(--sp-0-5) 0 0; font: var(--fw-heavy) var(--fs-dialog-title)/1.15 var(--font-head); letter-spacing: -0.02em; color: var(--ink); text-wrap: balance;
}
#event-detail .ev-when { margin: var(--sp-1-5) 0 0; display: flex; align-items: center; gap: var(--sp-2); color: var(--text-2); font-size: var(--fs-md); }
#event-detail .ev-when .is-missed { color: var(--missed-ink); font-weight: var(--fw-semi); }
#event-detail .ev-icons { margin: 0 0 0 auto; display: inline-flex; gap: 5px; color: var(--muted); }
#event-detail .ev-icons::before { content: none; }
#event-detail .ev-icons .entry-icon svg { width: 14px; height: 14px; }
#event-detail .ev-noteline { margin: var(--sp-2-5) 0 0; font-style: italic; color: var(--text-2); font-size: var(--fs-md); }
#event-detail > .error { margin: var(--sp-3) var(--sp-4) 0; }
#event-detail .ev-body { display: flex; flex-direction: column; gap: var(--sp-3); padding: 14px var(--sp-4) var(--sp-3); }
#event-detail .ev-body:empty { display: none; }
#event-detail .ev-ro { margin: 0; color: var(--text-2); font-size: var(--fs-md); line-height: 1.45; }
#event-detail .ev-ro + .ev-ro { margin-top: calc(-1 * var(--sp-2)); }

/* The amount or note to log, above the actions (answer 4). */
#event-detail .ev-complete { display: flex; flex-direction: column; align-items: stretch; gap: var(--sp-3); }
#event-detail .ev-field { flex: none; gap: var(--sp-1); }
#event-detail .ev-field-label, #event-detail .ev-fld-l { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--text-2); }
#event-detail .ev-required { font-weight: var(--fw-medium); color: var(--muted); text-transform: lowercase; }
#event-detail .ev-amount { height: 40px; border: 1px solid var(--field-line); border-radius: var(--r-block); background: var(--surface); }
#event-detail .ev-amount:focus-within { border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink); }
#event-detail .ev-amount input { flex: 1; min-width: 0; height: 100%; padding: 0 10px; border: 0; background: none; outline: 0; font-size: var(--fs-md); color: var(--ink); }
#event-detail .ev-unit { padding: 0 var(--sp-3); color: var(--text-2); font-size: var(--fs-md); }
#event-detail .ev-field textarea { margin: 0; padding: var(--sp-2) 10px; border: 1px solid var(--field-line); border-radius: var(--r-block); background: var(--surface); }
#event-detail .ev-done-on-field { gap: var(--sp-1); }
/* What a done one logged, with Edit beside it. */
#event-detail .ev-result { display: flex; flex-direction: column; gap: var(--sp-0-5); }
#event-detail .ev-result-main { margin: 0; font-size: var(--fs-body); font-weight: var(--fw-semi); color: var(--ink); }
#event-detail .ev-result .ev-field-label { margin: 0; }
#event-detail .ev-result .ev-note { font-style: italic; font-weight: var(--fw-regular); }
#event-detail .ev-edit { margin-left: var(--sp-2); font-size: var(--fs-sm); font-weight: var(--fw-regular); color: var(--text-2); text-decoration: underline; }
#event-detail .ev-total { margin: 0; color: var(--muted); font-size: var(--fs-sm); }
#event-detail .ev-dur { display: flex; flex-direction: column; gap: var(--sp-1); margin: 0; }
#event-detail .ev-dur-row { display: flex; gap: var(--sp-2); }
#event-detail .ev-dur input { flex: 1; width: auto; height: 40px; margin: 0; padding: 0 10px; border: 1px solid var(--field-line); border-radius: var(--r-block); }

/* One row of actions, always in the same order. */
#event-detail .ev-acts { display: flex; gap: var(--sp-2); align-items: center; }
#event-detail .ev-acts.is-wide { flex-wrap: wrap; }
#event-detail .ev-acts.is-wide > .ev-b-main { flex-basis: 100%; }
#event-detail .ev-acts.is-wide > .ev-b-slot { flex: 1; min-width: 0; }
#event-detail .ev-b {
  height: 40px; padding: 0 14px; border-radius: var(--r-pill); border: 1px solid var(--field-line); background: var(--surface); color: var(--ink);
  font: var(--fw-semi) var(--fs-md)/1 var(--font-ui); display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  white-space: nowrap; cursor: pointer;
}
#event-detail .ev-b:hover:not(:disabled) { background: var(--state-hover-surface, var(--sunk)); }
#event-detail .ev-b:active:not(:disabled) { background: var(--state-active-surface, var(--sunk)); }
#event-detail .ev-b-main { flex: 1; min-width: 108px; background: var(--primary-fill); border-color: var(--primary-fill); color: var(--on-primary); }
#event-detail .ev-b-main:hover:not(:disabled), #event-detail .ev-b-main:active:not(:disabled) { background: var(--primary-fill); filter: brightness(1.2); }
#event-detail .ev-b:disabled { opacity: 0.45; cursor: default; }
#event-detail .ev-b-quiet { border-color: var(--line); background: color-mix(in srgb, var(--ink) 5%, var(--surface)); }
#event-detail .ev-b-red { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, var(--surface)); background: var(--surface); }
#event-detail .ev-b-red:hover:not(:disabled) { background: var(--danger-bg); }
#event-detail .ev-b-slot { overflow: hidden; text-overflow: ellipsis; }
#event-detail .ev-b:focus-visible, #event-detail .ev-day:focus-visible, #event-detail .ev-mi:focus-visible, #event-detail .ev-close:focus-visible {
  outline: 2px solid var(--ink); outline-offset: 2px;
}
#event-detail .ev-more { position: relative; margin-left: auto; flex: none; }
#event-detail .ev-b-more { width: 40px; padding: 0; border-color: var(--line); }
#event-detail .ev-b.ev-b-more[aria-expanded="true"] { background: var(--ink); color: var(--surface); border-color: var(--ink); }
#event-detail .ev-ic { display: inline-flex; flex: none; }
#event-detail .ev-ic svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
#event-detail .ev-b-more .ev-ic svg { width: 16px; height: 16px; fill: currentColor; stroke: none; }

/* What's behind "…": hangs under the button, right edges lined up. */
#event-detail .ev-menu {
  position: absolute; right: 0; top: calc(100% + var(--sp-1-5)); z-index: 3; min-width: 210px; padding: 6px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow-dialog);
}
#event-detail .ev-mi {
  display: flex; align-items: center; gap: 10px; width: 100%; height: 34px; padding: 0 10px; border: 0; border-radius: var(--r-input);
  background: none; color: var(--ink); font: var(--fw-medium) var(--fs-md)/1 var(--font-ui); text-align: left; cursor: pointer; white-space: nowrap;
}
#event-detail .ev-mi:hover, #event-detail .ev-mi:focus-visible { background: var(--sunk); }
#event-detail .ev-mi .ev-ic { color: var(--muted); }
#event-detail .ev-mi-dot { width: 8px; height: 8px; margin: 0 3.5px; border-radius: 50%; background: var(--goal); flex: none; }
#event-detail .ev-mi-red, #event-detail .ev-mi-red .ev-ic { color: var(--danger); }
#event-detail .ev-menu-rule { border-top: 1px solid var(--divider); margin: var(--sp-1) 2px; }

/* "Open in Day": the quiet footer, on every event (answer 2). */
#event-detail .ev-foot { display: flex; align-items: center; padding: var(--sp-2) var(--sp-3); border-top: 1px solid var(--divider); }
#event-detail .ev-head + .error[hidden] + .ev-body:empty + .ev-foot { border-top: 0; }
#event-detail .ev-day {
  height: 32px; padding: 0 10px; border: 0; border-radius: var(--r-pill); background: none; color: var(--text-2);
  font: var(--fw-semi) var(--fs-md)/1 var(--font-ui); display: inline-flex; gap: 7px; align-items: center; cursor: pointer;
}
#event-detail .ev-day:hover { background: var(--sunk); color: var(--ink); }
#event-detail .ev-day svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
#event-detail .ev-confirm { display: flex; flex-direction: column; gap: var(--sp-2); }

/* Move: a clean floating Month, on its own (Ed's note 5). */
#move-dialog {
  --goal: #8a8f98; width: min(420px, calc(100vw - 32px)); padding: 16px 16px 14px; box-sizing: border-box; border: 0;
  border-radius: var(--r-dialog); background: var(--surface); color: var(--ink); box-shadow: var(--shadow-dialog); overflow: visible;
}
#move-dialog .mv-top { display: flex; align-items: center; gap: var(--sp-2); }
#move-dialog h3 { flex: 1; margin: 0; font: var(--fw-heavy) var(--fs-heading)/1.2 var(--font-head); letter-spacing: -0.02em; }
#move-dialog .mv-nav { display: flex; gap: 6px; }
#move-dialog .mv-nav button {
  width: 30px; height: 30px; padding: 0; border: 1px solid var(--line); border-radius: 50%; background: var(--surface);
  display: grid; place-items: center; color: var(--text-2); cursor: pointer;
}
#move-dialog .mv-nav button:hover:not(:disabled) { background: var(--sunk); color: var(--ink); }
#move-dialog .mv-nav button:disabled { opacity: 0.4; cursor: default; } /* Chunk 161: nothing before today's month */
#move-dialog .ev-ic svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
#move-dialog .mv-sub { margin: var(--sp-0-5) 0 10px; color: var(--muted); font-size: var(--fs-md); }
#move-dialog .mv-month { margin: 0 0 var(--sp-2); font: var(--fw-semi) var(--fs-md)/1 var(--font-ui); color: var(--text-2); }
#move-dialog .mv-row { display: grid; grid-template-columns: repeat(7, 1fr); }
#move-dialog .mv-hd { padding: 2px 0 6px; text-align: center; font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--muted); }
#move-dialog .mv-d { position: relative; height: 40px; display: grid; place-items: center; }
#move-dialog .mv-d button {
  position: relative; width: 34px; height: 34px; padding: 0; border: 0; border-radius: 50%; background: none; display: grid; place-items: center;
  font: var(--fw-semi) var(--fs-md)/1 var(--font-ui); font-variant-numeric: tabular-nums; color: var(--ink); cursor: pointer;
}
#move-dialog .mv-d.ok button:hover, #move-dialog .mv-d.ok button:focus-visible { background: var(--ink); color: var(--surface); }
#move-dialog .mv-d button:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
#move-dialog .mv-d.out button { color: var(--faint-text); opacity: 0.55; font-weight: var(--fw-regular); cursor: not-allowed; }
#move-dialog .mv-d.today button { box-shadow: inset 0 0 0 1.5px var(--ink); }
#move-dialog .mv-d.here button::after { content: ""; position: absolute; bottom: 3px; left: 50%; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--goal); }
#move-dialog .mv-d.band { background: color-mix(in srgb, var(--goal) 14%, var(--surface)); }
#move-dialog .mv-d.band.s { border-radius: var(--r-band) 0 0 var(--r-band); }
#move-dialog .mv-d.band.e { border-radius: 0 var(--r-band) var(--r-band) 0; }
#move-dialog .mv-d.band.s.e { border-radius: var(--r-band); }
#move-dialog .mv-tip {
  position: absolute; z-index: 4; bottom: 44px; left: 50%; transform: translateX(-50%); padding: 6px 10px; border-radius: var(--r-input);
  background: var(--ink); color: var(--surface); font-size: var(--fs-sm); font-weight: var(--fw-medium); white-space: nowrap; pointer-events: none;
}
#move-dialog .mv-row > .mv-d:first-child .mv-tip { left: 0; transform: none; }
#move-dialog .mv-row > .mv-d:last-child .mv-tip { left: auto; right: 0; transform: none; }
#move-dialog .mv-rules { margin: var(--sp-3) 0 0; padding: 10px var(--sp-3); border-radius: var(--r-block); background: var(--sunk); color: var(--text-2); font-size: var(--fs-sm); line-height: 1.5; }
#move-dialog .mv-rules strong { color: var(--ink); }
#move-dialog .mv-foot { display: flex; align-items: center; margin-top: var(--sp-3); }
#move-dialog .mv-esc {
  margin-left: auto; padding: var(--sp-1) var(--sp-1-5); border: 0; border-radius: var(--r-pill); background: none;
  color: var(--faint-text); font-size: var(--fs-sm); display: inline-flex; gap: 6px; align-items: center; cursor: pointer;
}
#move-dialog .mv-esc:hover { color: var(--ink); }
#move-dialog .mv-esc:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
#move-dialog kbd {
  font: var(--fw-semi) var(--fs-xs) var(--font-ui); border: 1px solid var(--line); border-bottom-width: 2px; border-radius: var(--r-key); padding: 1px 6px;
  color: var(--text-2); background: var(--surface);
}

/* ===== Chunk 139: Settings and linked calendars (section check 06) ===== */
/* The head stays put while the panel scrolls (bug 5); it covers the panel's own top padding. */
.settings-pop .settings-head {
  position: sticky; top: calc(-1 * var(--sp-4)); z-index: 2;
  margin: calc(-1 * var(--sp-4)) 0 var(--sp-1); padding: var(--sp-4) 0 var(--sp-1);
  background: var(--surface);
}
/* A focused row scrolled into view never sits under the sticky head (WCAG 2.4.11). */
.settings-pop { scroll-padding-top: 64px; }
/* Time zone: one select, as wide as the segments above it. */
.settings-pop .settings-tz { width: 100%; }
.link-btn { padding: 0; border: 0; background: none; font: inherit; color: var(--ink); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.link-btn:hover { text-decoration-thickness: 2px; }
/* A failed sync reads in Ink with a small warning mark - orange is for missed (bug 7). */
.settings-pop .feed-status-error { color: var(--ink); }
.feed-warn {
  display: inline-grid; place-items: center; width: 14px; height: 14px; margin-right: var(--sp-1);
  border: 1.5px solid currentColor; border-radius: 50%;
  font-size: var(--fs-2xs); font-weight: var(--fw-bold); line-height: 1; vertical-align: -2px;
}
.settings-pop .feed-row.has-error { border-color: var(--divider); }
/* A just-added row is pointed out once (bug 5). */
.settings-pop .feed-row.flash { background: var(--state-hover); }
.settings-pop .feed-row { transition: background var(--motion-panel) var(--ease-fade); }
/* Manage sits under its row, like the colour picker. */
.settings-pop .feed-manage { margin: 0 0 var(--sp-2-5); padding-top: var(--sp-2); border-top: 0; }
.settings-pop .feed-manage .feeds-add-row { justify-content: flex-end; }
/* ===== end Chunk 139 ===== */

/* ===== Chunk 140: To place, missed and Week review (sweep 1, check 04) ===== */
/* Focus lands on these headings by script (Tab then starts in the review);
   they aren't controls, so no ring. */
.rv-title:focus, .rv-bar-title:focus, .ck-slipped h2:focus { outline: none; }
.c140-fold { margin: var(--sp-1) 0 0; font-size: var(--fs-md); }

/* "Confirm the rest as missed": one quiet pill under the card's head; asked
   once, in place, as a question with its two answers. */
.ck-slipped .btn.c140-bulk-btn { align-self: flex-start; margin: var(--sp-2) 0 var(--sp-1); min-height: 32px; padding: 0 var(--sp-3);
  border: 1px solid var(--line); border-radius: var(--r-pill); background: none; color: var(--ink); font-size: var(--fs-sm); font-weight: var(--fw-medium); }
.ck-slipped .btn.c140-bulk-btn:hover { border-color: var(--muted); }
.c140-bulk { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-3);
  margin: var(--sp-2) 0 var(--sp-1); padding: var(--sp-2-5) var(--sp-3); border-radius: var(--r-card); background: var(--track); }
.c140-bulk p { margin: 0; font-size: var(--fs-md); font-weight: var(--fw-medium); }
.c140-bulk-actions { display: flex; gap: var(--sp-2); }
.c140-bulk .btn { min-height: 32px; padding: 0 var(--sp-3); border-radius: var(--r-pill); font-size: var(--fs-sm); font-weight: var(--fw-medium); }
.c140-bulk .btn.quiet { border: 1px solid var(--line); background: var(--surface); color: var(--ink); }

/* A skipped week folded in: one heading per week, its groups under it. */
.ck-slipped { display: flex; flex-direction: column; }
.c140-week { display: flex; flex-direction: column; margin-top: var(--sp-3); }
.c140-week + .c140-week { margin-top: var(--sp-5); padding-top: var(--sp-3); border-top: 1px solid var(--line); }
.c140-week-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-3); margin: 0 0 var(--sp-1);
  font-family: var(--font-head); font-size: var(--fs-lg); font-weight: var(--fw-semi); }
.c140-week-head .muted { font-family: var(--font-ui); font-size: var(--fs-md); font-weight: var(--fw-regular); }
.c140-week .ck-slip-group { margin-top: var(--sp-2); }
.ck-slip-group h4 { margin: 0 0 var(--sp-1); font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--muted); }

/* Today's Missed card: the newest five, then a quiet "Show N more". */
.today-missed .btn.c140-missed-more { align-self: flex-start; margin-top: var(--sp-2); padding: var(--sp-0-5) var(--sp-1); border: 0; background: none;
  font-size: var(--fs-md); font-weight: var(--fw-medium); color: var(--muted); }
.today-missed .btn.c140-missed-more:hover { color: var(--ink); }

/* To place: a folded group's heading shows it opens (04 #14), with the tray's own chevron. */
.place-head { align-items: center; }
.place-head .place-head-n { margin-left: auto; }
.place-head .tray-chev { margin-left: var(--sp-1-5); }

/* 04 #17: one grid for the lower cards - Close the week is a card beside
   This week, and Day notes runs the height of what sits beside it. */
.rv-foot { align-items: stretch; }
.rv-foot .ck-close { flex-direction: column; justify-content: center; align-items: flex-start; gap: var(--sp-3); margin: 0;
  padding: var(--sp-5) var(--sp-6); border-radius: var(--r-card); background: var(--surface); box-shadow: var(--shadow-line); }
.rv-foot .ck-close-left { margin: 0; }
.rv-more { align-items: stretch; }
/* ===== end Chunk 140 ===== */

/* ===== Chunk 145: quick add (⌘K) =====
   Mock: docs/brand-identity/mockups/quick-add/ (common.css). One field, one
   preview row, one foot; the only filled thing is Add. Recognised words get
   the ink at 12%; the owner its own colour with an underline; an unread "#"
   an ink underline. No red or orange anywhere, the past-date line included. */
.qa-layer { position: fixed; inset: 0; z-index: 49; } /* under the toast (50), so Show and Undo stay live */
.qa-scrim { position: absolute; inset: 0; background: rgb(0 0 0 / 0.3); animation: qa-fade var(--motion-fast) var(--ease-enter); }
:root[data-theme="dark"] .qa-scrim { background: rgb(0 0 0 / 0.6); }
@keyframes qa-fade { from { opacity: 0; } }
.qa-box {
  --hl: color-mix(in srgb, var(--ink) 12%, transparent);
  position: absolute; left: 0; right: 0; top: 150px; margin: 0 auto; width: min(640px, calc(100vw - 32px)); box-sizing: border-box;
  display: flex; flex-direction: column; gap: var(--sp-3); padding: 14px;
  background: var(--surface); border: 1px solid var(--faint); border-radius: var(--r-card); box-shadow: var(--shadow-dialog);
  animation: fan-in var(--motion-fast) var(--ease-enter);
}
:root[data-theme="dark"] .qa-box:not(.in-sheet) { box-shadow: var(--shadow-dialog), 0 0 0 1px var(--line); }
.qa-line { display: flex; gap: 10px; align-items: center; }
/* The field: a mirror of the words with the read ones tinted, under a
   transparent input carrying the same text, so the caret and selection are
   the input's own. */
.qa-field {
  position: relative; flex: 1; min-width: 0; height: 48px; border: 1px solid var(--field-line); border-radius: var(--r-input); background: var(--surface);
}
.qa-field:focus-within { outline: var(--focus-width) solid var(--focus-color); outline-offset: 1px; }
.qa-mirror, .qa-input {
  position: absolute; inset: 0; box-sizing: border-box; padding: 0 14px; margin: 0;
  font: inherit; font-size: var(--fs-lg); line-height: 46px; letter-spacing: 0; white-space: pre; word-spacing: 0;
}
.qa-mirror { overflow: hidden; color: transparent; pointer-events: none; }
.qa-input { width: 100%; border: 0; background: transparent; color: var(--ink); outline: none; }
.qa-input::placeholder { color: var(--faint-text); }
.qa-tk { background: var(--hl); border-radius: var(--r-key); box-decoration-break: clone; -webkit-box-decoration-break: clone; }
.qa-tk.own { --hl: color-mix(in srgb, var(--goal, var(--muted)) 20%, var(--surface)); box-shadow: inset 0 -2px 0 var(--goal, var(--muted)); }
.qa-tk.unsure { background: none; border-radius: 0; box-shadow: inset 0 -2px 0 var(--ink); }
/* In the field the tint can't take padding (it would push the words off the caret), so a spread stands in for it. */
.qa-mirror .qa-tk:not(.unsure) { box-shadow: 0 0 0 2px var(--hl); }
.qa-mirror .qa-tk.own { box-shadow: 0 0 0 2px var(--hl), inset 0 -2px 0 var(--goal, var(--muted)); }
.qa-box .qa-add { height: 48px; padding: 0 22px; }
.qa-box .qa-add:disabled { opacity: 0.4; cursor: default; }
.qa-error { margin: 0; }
/* The preview row: shared with Chunk 128's One-off form. */
.qa-prev {
  display: flex; align-items: center; gap: 14px; min-height: 62px; box-sizing: border-box; padding: 10px 14px;
  border: 1px dashed var(--field-line); border-left: 6px solid var(--goal); border-radius: var(--r-input);
  background: color-mix(in srgb, var(--goal) 7%, var(--surface));
}
.qa-prev.none { --goal: var(--muted); }
.qa-prev-tx { flex: 1; min-width: 0; }
.qa-prev-title { font-size: var(--fs-lg); font-weight: var(--fw-semi); letter-spacing: -0.01em; color: var(--ink); overflow-wrap: anywhere; }
.qa-prev-meta { margin-top: 3px; display: flex; flex-wrap: wrap; align-items: center; row-gap: 4px; font-size: var(--fs-md); color: var(--text-2); }
.qa-prev-meta .qa-tk { padding: 1px 3px; }
.qa-sep { margin: 0 7px; color: var(--faint-text); }
.qa-dot { display: inline-block; width: 8px; height: 8px; margin-right: 6px; border-radius: 50%; background: var(--goal); }
.qa-prev-why { margin-top: 3px; display: flex; align-items: center; gap: 6px; font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--ink); }
.qa-ic { display: inline-flex; flex: none; }
.qa-ic svg, .qa-sheet-ib svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.qa-prev-ic { color: var(--muted); }
.qa-prev-ic svg { width: 18px; height: 18px; }
.qa-prev-slot:empty { display: none; }
/* The "#" list */
.qa-list { display: flex; flex-direction: column; padding: 6px; border: 1px solid var(--line); border-radius: var(--r-popover); background: var(--surface); }
.qa-list[hidden] { display: none; }
.qa-opt { display: flex; align-items: center; gap: var(--sp-3); min-height: 40px; padding: 0 10px; border-radius: var(--r-small); font-size: var(--fs-body); color: var(--ink); cursor: pointer; }
.qa-opt i { flex: none; width: 4px; height: 18px; border-radius: var(--r-dash); background: var(--goal); }
.qa-opt b { font-weight: var(--fw-semi); }
.qa-opt-kind { margin-left: auto; font-size: var(--fs-sm); color: var(--muted); white-space: nowrap; }
.qa-opt.on, .qa-opt:hover { background: var(--page); }
.qa-hint { margin-top: 4px; padding: 8px 10px 4px; border-top: 1px solid var(--divider); font-size: var(--fs-sm); color: var(--muted); }
/* The foot */
.qa-foot { display: flex; align-items: center; gap: 10px; font-size: var(--fs-sm); color: var(--muted); }
.qa-foot .qa-more { height: 32px; min-height: 32px; padding: 0 var(--sp-3); }
.qa-gap { flex: 1; }
.qa-k { margin-left: var(--sp-3); }
.qa-foot kbd, .topbar-qa kbd {
  font: var(--fw-semi) var(--fs-xs)/1 var(--font-ui); padding: 3px 6px; border: 1px solid var(--line); border-radius: var(--r-key);
  background: var(--page); color: var(--text-2); margin-right: 4px;
}
/* The top bar's pill, in the slot Chunk 82 kept (left of Settings). */
.slot-quickadd { display: flex; justify-content: flex-end; pointer-events: auto; }
.topbar-qa { display: inline-flex; align-items: center; gap: var(--sp-2); color: var(--text-2); white-space: nowrap; }
.topbar-qa kbd { margin: 0; border: 0; background: none; padding: 0; font-size: var(--fs-md); color: var(--text-2); }
.topbar-qa:hover { color: var(--ink); }
@media (max-width: 999.98px) { .topbar-qa { width: 44px; padding: 0; justify-content: center; } .topbar-qa-label { display: none; } .topbar-qa kbd { font-size: var(--fs-xs); } }
@media (max-width: 600px) { .slot-quickadd { display: none; } } /* a phone has the sheet, no pill (Ed's answer 1) */
/* Chunk 128's One-off form gets the row, smaller to fit its 280px. */
/* The phone's + New sheet: quick add on top, then Goal, Routine, Collection, Task. */
.qa-sheet {
  position: absolute; left: 0; right: 0; bottom: 0; top: 62px; overflow-y: auto; padding: 0 18px var(--sp-6);
  background: var(--surface); border-radius: var(--r-sheet) var(--r-sheet) 0 0; box-shadow: 0 -12px 40px -12px rgb(0 0 0 / 0.4);
  animation: qa-rise var(--motion-panel) var(--ease-enter);
}
@keyframes qa-rise { from { transform: translateY(24px); opacity: 0; } }
.qa-grab { width: 36px; height: 5px; margin: 8px auto 4px; border-radius: var(--r-mini); background: var(--line); }
.qa-sheet-head { display: flex; align-items: center; justify-content: space-between; height: 48px; }
.qa-sheet-head h2 { margin: 0; font-size: var(--fs-input); font-weight: var(--fw-semi); color: var(--ink); }
.qa-sheet-cancel { width: 72px; padding: 0; justify-content: flex-start; font-size: var(--fs-input); color: var(--muted); }
.qa-sheet-head .btn.qa-sheet-cancel { background: none; }
.qa-box.in-sheet { position: static; margin: 0; width: auto; padding: 0; border: 0; box-shadow: none; background: none; animation: none; }
.in-sheet .qa-field { height: 52px; }
.in-sheet .qa-mirror, .in-sheet .qa-input { line-height: 50px; }
.in-sheet .qa-add { width: 100%; }
.qa-sheet-links { margin-top: 20px; border-top: 1px solid var(--divider); }
.qa-sheet-link {
  display: flex; align-items: center; gap: 14px; width: 100%; height: 56px; padding: 0; border: 0; border-bottom: 1px solid var(--divider);
  background: none; color: var(--ink); font: inherit; font-size: var(--fs-lg); text-align: left; cursor: pointer;
}
.qa-sheet-ib { display: grid; place-items: center; width: 36px; height: 36px; border-radius: var(--r-small); background: var(--page); color: var(--text-2); }
.qa-sheet-ib svg { width: 18px; height: 18px; }
@media (prefers-reduced-motion: reduce) { .qa-scrim, .qa-box, .qa-sheet { animation: none; } }
/* ===== end Chunk 145 ===== */

/* ===== Chunk 146: week reflections =====
   Mock 144 (docs/brand-identity/mockups/quick-add/): Week review's Looking back
   card, then the Reflections page - a 760 list, newest week first, a pill
   search on the list's right edge, matches tinted and underlined in ink. */
.rv-more > .rv-look { height: calc(100% - var(--sp-4)); box-sizing: border-box; display: flex; flex-direction: column; gap: 14px; }
.rv-look h3 { margin: 0; }
.rv-look h4 { margin: 0 0 var(--sp-1-5); font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--muted); }
.rv-look .ck-note { margin: 0 0 var(--sp-2-5); }
.rv-look .ck-note:last-child { margin-bottom: 0; }
.rv-look .ck-note-day { display: block; font-size: var(--fs-xs); }
.rv-look .ck-note p { margin: 1px 0 0; font-size: var(--fs-body); line-height: 1.45; }
.rv-look-notes { padding-bottom: var(--sp-4); border-bottom: 1px solid var(--divider); }
.rv-look-label { font-size: var(--fs-body); font-weight: var(--fw-semi); color: var(--ink); }
.refl-box { width: 100%; box-sizing: border-box; min-height: 108px; margin: 0; padding: var(--sp-3); resize: vertical;
  border: 1px solid var(--line); border-radius: var(--r-input); background: var(--page); color: var(--ink);
  font: inherit; font-size: var(--fs-body); line-height: 1.5; }
.refl-box::placeholder { color: var(--faint-text); }
.rv-look .refl-box, .rv-look .refl-status { margin-top: calc(-1 * var(--sp-1-5)); } /* tighter than the card's gap */
.refl-box:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.refl-status { margin: var(--sp-1) 0 0; min-height: 14px; font-size: var(--fs-sm); color: var(--muted); }

.refl-search { position: relative; display: flex; align-items: center; width: 300px; max-width: 100%; }
.refl-search-icon { position: absolute; left: var(--sp-3); top: 50%; translate: 0 -50%; width: 16px; height: 16px; color: var(--muted); pointer-events: none; }
.refl-search-icon svg { display: block; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.refl-clear { position: absolute; right: 4px; width: 32px; height: 32px; border: 0; border-radius: 50%; background: none; color: var(--muted); font-size: var(--fs-lead); line-height: 1; cursor: pointer; }
.refl-clear:hover { background: var(--divider); color: var(--ink); }
.refl-clear:focus-visible { outline: 2px solid var(--ink); outline-offset: 0; }
.refl-text { display: block; width: 100%; margin: var(--sp-2-5) 0 0; padding: 0; border: 0; background: none; text-align: left; cursor: text;
  font: inherit; font-size: var(--fs-lg); line-height: 1.5; letter-spacing: -0.005em; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; border-radius: var(--r-mini); }
.refl-text:hover { background: var(--page); }
.refl-text:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.refl-none { margin: var(--sp-4) 0 0; font-size: var(--fs-body); color: var(--text-2); }
/* ===== end Chunk 146 ===== */

/* ===== Chunk 142: Sweep 1 calendar fixes (section-checks/02-calendar.md) ===== */
/* 02 #6: "+N more" is a button that opens the day in Day. It keeps the look
   of the count it was; the hover underline says it goes somewhere. */
#calendar-grid :is(.fold-more, .month-more) {
  appearance: none; background: none; border: 0; margin: 0; font-family: inherit; cursor: pointer;
  border-radius: var(--r-mini);
}
#calendar-grid .fold-more { width: 100%; }
#calendar-grid .month-more { pointer-events: auto; padding: 0; text-align: left; width: max-content; max-width: calc(100% - var(--sp-3)); right: auto; }
#calendar-grid :is(.fold-more, .month-more):hover { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
#calendar-grid .month-day.today .month-more:hover { color: var(--on-feature); }
/* 02 #10: what a Week day folds is hidden whole, not half drawn above its count. */
#calendar-grid .fold-hidden { visibility: hidden; }

/* 02 #4: a "times per week" Task's week or month is outlined in its colour
   (dashed, as the draft is) over a stronger tint - the tint alone sat under
   the blocks and vanished on a full Week. */
#calendar-grid .draft-window {
  box-shadow: inset 0 0 0 999px color-mix(in srgb, var(--draft, var(--ink)) 14%, transparent);
  outline: 2px dashed color-mix(in srgb, var(--draft, var(--ink)) 80%, transparent); outline-offset: -2px;
}
#calendar-grid .draft-window.compose-hover { outline: 2px solid var(--ink); }

/* 02 #12: a click on a day that's gone, while composing, flashes the same
   refused outline a drag over it shows. */
#calendar-grid :is([data-day], [data-year-day]).compose-refused, #calendar-grid [data-day].compose-refused.compose-hover { outline: 2px dashed var(--danger); outline-offset: -2px; }

/* 02 #5: Year marks the days the Task being made falls on. */
#calendar-grid .ym-d.ym-draft .ym-n { box-shadow: 0 0 0 1.5px var(--surface), 0 0 0 3px var(--draft, var(--ink)); }

/* 02 #7: on a Day block at the floor height the duration grip moves to the
   right edge and shows only on hover, focus or the keyboard's pick, so it
   never runs across the block's text. */
.cal-entry.lane-short .lane-edge.lane-handle { left: auto; right: var(--sp-1); margin-left: 0; width: 32px; }
.cal-entry.lane-short .lane-handle .lane-grip { width: 18px; opacity: 0; }
.cal-entry.lane-short:is(:hover, :focus-visible, .selected) .lane-handle .lane-grip,
.dragging .cal-entry.lane-short .lane-handle .lane-grip { opacity: 1; }

/* 02 #13 (Ed's call): while composing the top bar steps back, but the section
   you're in stays at full strength. */
body.adding .topbar .view-switch [data-go].active { opacity: 1; filter: none; }

/* 02 #14 (Ed's call): when six weeks don't fit and Month scrolls inside its
   frame, its foot fades out under a small chevron until the last week is in view. */
.calendar-frame.scrolls-inside::after {
  content: ""; position: sticky; bottom: 0; flex: none; display: block;
  height: 40px; margin-top: -40px; pointer-events: none;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a8f98' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center bottom 2px / 20px 20px no-repeat,
    linear-gradient(to bottom, transparent, var(--page) 80%);
  transition: opacity var(--motion-fast) var(--ease-fade);
}
.calendar-frame.scrolls-inside.at-end::after { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .calendar-frame.scrolls-inside::after { transition: none; } }
/* ===== end Chunk 142 ===== */

/* ---- Chunk 147: WCAG 2.2 AA fixes (contrast, targets, focus). Appended; nothing above reordered. ---- */
/* 1.4.3: "+N more" and quiet text on today's dark column used the page's faint text (3.1:1 on Ink). */
#calendar-grid.week-stack .day.today .muted, #calendar-grid.week-stack .day.today .fold-more,
#calendar-grid .month-day.today .fold-more { color: var(--on-feature-2); }
/* 2.5.8: To place's group headings are at least 24px tall. */
.place-head { min-height: 24px; }
/* 1.4.3: past rows on Today faded the whole row to 0.62 (times 2.6:1, titles under 3:1). The text stays at full
   strength; the fade moves to the colour slice and the dot. Flagged: it is the same signal, less pale. */
.today-slot.is-past { opacity: 1; }
.today-slot.is-past .today-dot { opacity: 0.55; } /* the colour slice fades by its own colour since Chunk 223 */
/* 2.5.8: the "+4 wk" fold is a 24px-tall target (it was 16px); the pill keeps its look, the hit area grows. */
.place-fold { min-height: 24px; min-width: 24px; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; }
/* Chunk 147 (141's low item): how many Goals wait for confirming, on the left panel's Completed entry. */
.nav-count { flex: none; margin-left: auto; min-width: 18px; height: 18px; padding: 0 var(--sp-1); border-radius: var(--r-pill); background: var(--badge-fill); color: var(--on-badge); font-size: var(--fs-2xs); font-weight: var(--fw-bold); line-height: 18px; text-align: center; box-sizing: border-box; }
.nav-count[hidden] { display: none; }
/* ===== Chunk 148: the heavy year =====
   A week with dozens of classes kept growing its key under the grid until the
   week itself had room for two items a day (1100 wide). The key holds three and
   a half rows - the half says there's more - and scrolls the rest; nothing in
   it is dropped. A key row is 20px (its colour dash). */
.week-going:not(.is-key) .going-legend { max-height: calc(3.5 * 20px + 3 * var(--sp-1-5)); overflow-y: auto; }
/* ===== end Chunk 148 ===== */

/* ===== Chunk 149: the key's scroll box takes focus (WCAG 2.1.1) ===== */
.week-going .going-legend[tabindex]:focus-visible { outline: var(--focus-width) solid var(--focus-color); outline-offset: var(--focus-offset); border-radius: var(--r-small); }
/* ===== end Chunk 149 ===== */

/* ===== Chunk 151: History (mock 150, round 2) =====
   Completed and Reflections become one page. An overview - Waiting (a warm
   tray of rows), Weeks (cards with a date rail) and Goals (cards with their
   colour across the top) - in one 760 column, plus See all pages with search.
   The view keeps its old ids (#completed-view, #completed-list). */
#completed-list { max-width: 760px; }
#completed-list .hs-head { display: flex; align-items: flex-end; gap: var(--sp-4); }
#completed-list .hs-head h1 { flex: 1; margin: 0; font: var(--fw-heavy) var(--fs-title)/1 var(--font-head); letter-spacing: -0.04em; color: var(--ink); }
#completed-list .hs-head .completed-pointer { flex: none; }
.hs-empty { margin: 120px 0 0; font-size: var(--fs-lg); color: var(--text-2); }
.hs-ov { margin-top: var(--sp-7); display: flex; flex-direction: column; gap: var(--sp-10); }
.hs-sec-head { display: flex; align-items: flex-end; gap: var(--sp-4); margin-bottom: 14px; }
.hs-sec-head > div { flex: 1; min-width: 0; }
.hs-sec-head h2 { margin: 0; font: var(--fw-heavy) var(--fs-h-lg)/1.1 var(--font-head); letter-spacing: -0.03em; color: var(--ink); }
.hs-sec-head p { margin: var(--sp-1) 0 0; font-size: var(--fs-base); color: var(--muted); }
#completed-list .hs-see-all, #completed-list .hs-tray .fv-btn { min-height: 36px; flex: none; }
.hs-list { display: flex; flex-direction: column; gap: var(--sp-3); }
/* Waiting: the one warm block, a tray of rows - not a card. Orange means waiting. */
.hs-waiting .hs-sec-head h2 { color: var(--missed-ink); }
:root[data-theme="dark"] .hs-waiting .hs-sec-head h2 { color: var(--missed-accent); }
.hs-tray { border-radius: var(--r-card); padding: var(--sp-1-5) var(--sp-5);
  background: color-mix(in srgb, var(--missed-accent) 9%, var(--surface)); border: 1px solid color-mix(in srgb, var(--missed-accent) 35%, var(--line)); }
.hs-tray-row { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3) 0; font-size: var(--fs-body); }
.hs-tray-row + .hs-tray-row { border-top: 1px solid color-mix(in srgb, var(--missed-accent) 22%, var(--divider)); }
.hs-tray-title { padding: 0; border: 0; background: none; font: inherit; font-weight: var(--fw-semi); color: var(--ink); cursor: pointer; text-align: left; }
.hs-tray-title:hover { text-decoration: underline; text-underline-offset: 3px; }
.hs-tray-row small { font-size: var(--fs-md); color: var(--text-2); }
.hs-tray-acts { margin-left: auto; display: flex; align-items: center; gap: var(--sp-2); flex: none; }
#completed-list .hs-tray .fv-quiet { background: none; }
/* Week: a date rail with the big week number, then the week. */
.hs-week { display: grid; grid-template-columns: 112px 1fr; background: var(--surface); border-radius: var(--r-card); box-shadow: var(--shadow-line); overflow: hidden; scroll-margin: 96px; }
.hs-rail { display: flex; flex-direction: column; gap: var(--sp-0-5); padding: 18px var(--sp-4); background: var(--sunk); border-right: 1px solid var(--divider); }
.hs-rail-lbl { font-size: var(--fs-sm); color: var(--muted); }
.hs-rail-n { font: var(--fw-heavy) 38px/1 var(--font-head); letter-spacing: -0.04em; color: var(--ink); }
.hs-rail-d { margin-top: var(--sp-2); font-size: var(--fs-md); line-height: 1.35; color: var(--text-2); }
.hs-week-bd { min-width: 0; padding: 18px var(--sp-6); }
#completed-list .hs-refl { margin: 0; }
#completed-list .hs-refl.none { font-size: var(--fs-body); color: var(--faint-text); }
#completed-list .hs-refl.none:hover { color: var(--ink); }
.hs-week-bd > .refl-box { margin-top: 0; }
.hs-sum { margin-top: var(--sp-3); font-size: var(--fs-base); line-height: 1.5; color: var(--text-2); }
.hs-sum p { margin: 0; }
.hs-sum-line b { font-weight: var(--fw-semi); color: var(--ink); }
.hs-sep { margin: 0 var(--sp-1); color: var(--muted); }
.hs-sum.none { color: var(--muted); }
.hs-sub { font-size: var(--fs-md); color: var(--muted); }
.hs-show { padding: 0 var(--sp-1); margin: 0 calc(-1 * var(--sp-1)); border: 0; border-radius: var(--r-mini); background: none; font: inherit; color: var(--muted);
  cursor: pointer; text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 3px; }
.hs-show:hover { color: var(--ink); text-decoration-color: currentColor; }
.hs-sum-items { margin: var(--sp-1-5) 0 var(--sp-1); display: grid; gap: var(--sp-1); }
.hs-sum-items b { margin-right: var(--sp-2); font-weight: var(--fw-semi); color: var(--ink); }
.hs-notes { margin-top: var(--sp-3); padding-top: var(--sp-2-5); border-top: 1px solid var(--divider); display: grid; gap: var(--sp-1-5); }
.hs-notes p { margin: 0; font-size: var(--fs-base); line-height: 1.45; color: var(--text-2); white-space: pre-wrap; overflow-wrap: anywhere; }
.hs-notes b { margin-right: var(--sp-2); font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--muted); }
/* Goal: its colour across the top, its Milestones as ticks. */
.hs-goal { padding: var(--sp-4) var(--sp-6) 14px; background: var(--surface); border-radius: var(--r-card); box-shadow: var(--shadow-line); border-top: 5px solid var(--c); }
.hs-goal-t { display: flex; align-items: baseline; gap: var(--sp-3); }
.hs-goal-t h3 { flex: 1; min-width: 0; margin: 0; font: var(--fw-semi) 18px/1.2 var(--font-head); color: var(--ink); overflow-wrap: break-word; }
.hs-goal-t span { margin-left: auto; flex: none; font-size: var(--fs-md); color: var(--muted); }
.hs-goal ul { list-style: none; margin: var(--sp-2-5) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-1-5) var(--sp-5); }
.hs-goal li { display: flex; align-items: center; gap: var(--sp-1-5); font-size: var(--fs-base); color: var(--text-2); }
.hs-tick svg { display: block; width: 16px; height: 16px; fill: none; stroke: var(--muted); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* Archived collections (from Completed): quiet rows, Bring back on the right. */
.hs-coll { background: var(--surface); border-radius: var(--r-card); box-shadow: var(--shadow-line); padding: var(--sp-1) var(--sp-5); }
.hs-coll-row { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-2) 0; font-size: var(--fs-body); }
.hs-coll-row + .hs-coll-row { border-top: 1px solid var(--divider); }
.hs-coll-dash { width: 4px; height: 20px; border-radius: var(--r-dash); background: var(--c, var(--line)); flex: none; }
.hs-coll-title { flex: 1; min-width: 0; color: var(--ink); }
/* See all pages */
.hs-back { display: inline-flex; align-items: center; gap: var(--sp-1-5); height: 32px; margin: calc(-1 * var(--sp-1)) 0 14px -10px; padding: 0 var(--sp-3) 0 var(--sp-2);
  border: 0; border-radius: var(--r-pill); background: none; font: inherit; font-size: var(--fs-base); color: var(--text-2); cursor: pointer; }
.hs-back:hover { background: var(--track); color: var(--ink); }
.hs-back svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
#completed-list .hs-search #hs-search { width: 100%; height: 40px; box-sizing: border-box; padding: 0 40px 0 36px; border: 1px solid var(--field-line); border-radius: var(--r-pill);
  background: var(--surface); color: var(--ink); font: inherit; font-size: var(--fs-base); }
#hs-search::placeholder { color: var(--faint-text); }
#hs-search::-webkit-search-cancel-button { display: none; }
.hs-all-line { margin: var(--sp-5) 0 0; font-size: var(--fs-base); color: var(--muted); }
.hs-all { margin-top: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-3); }
.hs-all .hs-month { margin: var(--sp-3) 0 calc(-1 * var(--sp-1)); font: var(--fw-semi) var(--fs-body)/1.2 var(--font-head); color: var(--text-2); }
.hs-all .hs-month:first-child { margin-top: 0; }
.hs-end { margin: var(--sp-2) 0 0; font-size: var(--fs-md); color: var(--muted); }
#completed-list mark { background: color-mix(in srgb, var(--ink) 14%, transparent); color: inherit; border-radius: var(--r-mini); padding: 0 1px; box-shadow: inset 0 -2px 0 var(--ink); }
/* The calendar's link: a quiet pill right of the week's title, only on a closed week. */
.week-history { display: inline-flex; align-items: center; gap: var(--sp-1-5); height: 32px; margin-left: var(--sp-3); padding: 0 var(--sp-3);
  border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--surface); font: inherit; font-size: var(--fs-md); color: var(--text-2); cursor: pointer; vertical-align: middle; }
.week-history[hidden] { display: none; }
.week-history:hover { color: var(--ink); border-color: var(--muted); }
.week-history svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
@media (max-width: 700px) {
  #completed-list .hs-head { flex-wrap: wrap; }
  #completed-list .hs-search { width: 100%; }
  .hs-ov { margin-top: var(--sp-1); gap: var(--sp-7); }
  .hs-sec-head { flex-wrap: wrap; row-gap: var(--sp-2); }
  .hs-sec-head h2 { font-size: var(--fs-section); }
  #completed-list .hs-see-all { width: 100%; min-height: 44px; }
  .hs-tray { padding: var(--sp-1) 14px; }
  .hs-tray-row { flex-wrap: wrap; row-gap: var(--sp-2); }
  .hs-tray-row small { flex-basis: 100%; order: 3; }
  .hs-tray-acts { flex-basis: 100%; order: 4; margin-left: 0; justify-content: flex-end; }
  .hs-goal-t { flex-wrap: wrap; row-gap: var(--sp-1); }
  .hs-goal-t span { margin-left: 0; }
  .hs-week { grid-template-columns: 1fr; }
  .hs-rail { flex-direction: row; align-items: baseline; gap: var(--sp-2-5); padding: var(--sp-3) var(--sp-4); border-right: 0; border-bottom: 1px solid var(--divider); }
  .hs-rail-n { font-size: var(--fs-h-lg); }
  .hs-rail-d { margin: 0 0 0 auto; }
  .hs-week-bd { padding: 14px var(--sp-4); }
  .hs-goal { padding: 14px var(--sp-4); }
}
/* ===== end Chunk 151 ===== */

/* ===== Chunk 155: a confirmed Goal's full record (History) ===== */
/* The card opens its record: the title is a button that reads as the heading. */
.hs-goal.is-openable { cursor: pointer; transition: box-shadow var(--motion-fast) var(--ease-fade); }
.hs-goal.is-openable:hover { box-shadow: var(--shadow-menu); }
.hs-goal-open { all: unset; cursor: pointer; overflow-wrap: break-word; }
.hs-goal-open:focus-visible { outline: var(--focus-width) solid var(--focus-color); outline-offset: var(--focus-offset); border-radius: var(--r-dash); }
.hs-rec-when { margin-left: auto; font-size: var(--fs-md); color: var(--muted); }
.hs-rec { margin-top: var(--sp-4); cursor: auto; }
.hs-rec-desc { margin: 0 0 var(--sp-4); font-size: var(--fs-base); line-height: 1.5; color: var(--text-2); white-space: pre-wrap; }
.hs-rec-sec + .hs-rec-sec { margin-top: var(--sp-5); }
.hs-rec-sec h2 { margin: 0 0 var(--sp-2); font: var(--fw-semi) var(--fs-md)/1.3 var(--font-head); color: var(--ink); }
.hs-goal .hs-rec-list, .hs-goal .hs-rec-nested { display: block; list-style: none; margin: 0; padding: 0; }
.hs-goal .hs-rec-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-0-5) var(--sp-4); align-items: baseline;
  padding: var(--sp-2) 0; border-top: 1px solid var(--line); font-size: var(--fs-base); color: var(--ink); }
.hs-rec-list > .hs-rec-row:first-child { border-top: 0; }
.hs-rec-title { overflow-wrap: break-word; }
.hs-rec-meta { color: var(--muted); font-size: var(--fs-md); text-align: right; }
.hs-goal .hs-rec-nested { grid-column: 1 / -1; margin-left: var(--sp-4); }
.hs-goal .hs-rec-nested .hs-rec-row { color: var(--text-2); }
/* ===== end Chunk 155 ===== */

/* ===== Chunk 157: the date popover inside a modal dialog sits in the top layer (Done on) ===== */
.date-pop[popover] { margin: 0; right: auto; bottom: auto; overflow: visible; }
.tray-wait-h { margin: 0; font: inherit; }

/* ===== Chunk 157 (M7): linked calendars in the left panel ===== */
/* Their heading's "+" (Link a calendar) shows, as the other sections' do not: Linked has no New menu entry. */
.sidebar .nav-linked h2 { display: flex; align-items: center; justify-content: space-between; }
.sidebar .nav-linked h2 .icon-btn { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; min-height: 0; padding: 0; font-size: var(--fs-md); color: var(--muted); }
.sidebar .nav-linked h2 .icon-btn:hover, .sidebar .nav-linked h2 .icon-btn:focus-visible { color: var(--ink); }
/* A row's eye shows while any control in the row has focus, so Tab can reach it (it used to need the pointer). */
.sidebar .nav-row:focus-within .nav-eye { display: inline-flex; }

/* Chunk 157 (L5): a bold lead-in and the words after it ("Wed 11 Nov" + "Mum sounds better") read as one run to a
   screen reader. The generated content has no visible text (nothing moves, innerText is unchanged) and a spoken ". ". */
.hs-notes b::after { content: "" / ". "; }
.hs-sum-items b::after, .fv-day-labels b::after { content: "" / ": "; }

/* ===== Chunk 160 (M14): a word in quick add that looks like a command but wasn't read ===== */
.qa-unread { border-radius: 0; box-shadow: inset 0 -2px 0 0 transparent; text-decoration: underline dotted var(--muted); text-decoration-thickness: 2px; text-underline-offset: 3px; }

/* ===== Chunk 160 (M18): Today's tick is its own button ===== */
.today-card-wrap { position: relative; }
.today-card-task.has-tick .tc-text { inset-inline-end: 124px; }
.today-card-task.has-tick .tc-icons { right: 58px; color: var(--muted); }
.tc-do {
  position: absolute; right: 8px; top: 50%; translate: 0 -50%; z-index: 1;
  width: 38px; height: 38px; padding: 0; display: grid; place-items: center;
  border: 1.5px solid currentColor; border-radius: 50%; background: transparent; color: var(--on); cursor: pointer;
}
.tc-do .entry-icon svg { width: 18px; height: 18px; stroke-width: 1.4; }
.tc-do:hover { background: color-mix(in srgb, var(--on) 22%, transparent); }
.tc-do:active { background: color-mix(in srgb, var(--on) 36%, transparent); }
@media (hover: none) { .tc-do { width: 44px; height: 44px; } }
.fv-pace2 { margin: var(--sp-0-5) 0 0; font-size: var(--fs-sm); }
/* Chunk 159: To place's Snoozed group sits apart at the foot of the list, folded, never counted. */
.place-snoozed-head { margin-top: var(--sp-3); padding-top: var(--sp-1-5); border-top: 1px solid var(--line); }
.place-empty + .place-snoozed-head { margin-top: var(--sp-1); }

/* Chunk 159 (M12): a quiet line over a Goal that only holds a never-ending repeat. */
.fv-hint { margin: 0 0 var(--sp-2); padding: var(--sp-1-5) var(--sp-2); border: 1px solid var(--line); border-radius: var(--r-input); color: var(--muted); font-size: var(--fs-sm); }
/* Chunk 187: the hint's "Make it a Routine" sits at its end, wrapping under on a narrow page */
.fv-hint:has(.fv-hint-btn) { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-1) var(--sp-2); }
.fv-hint-btn { flex: none; }
#limit-dialog [data-limit-out] { margin-top: var(--sp-1-5); } /* Chunk 159: the way out, a beat after what counts */

/* ===== Chunk 164: panels (W4, W8, W13) ===== */
/* A hidden row keeps its tab in the collapsed strip, dimmed, so it can be shown again. */
.peek-item.is-off { background: linear-gradient(to right, color-mix(in srgb, var(--goal, var(--muted)) 35%, var(--surface)) 0 8px, var(--surface) 8px); }
.peek-item.is-off:hover, .peek-item.is-off:focus-within { background: var(--surface); }

/* ===== Chunk 165: the short one-off form, and softer text-field focus ===== */
/* W16: the one-off is the New task form with only a title, a day and a time.
   "+ Repeat…" waits behind More options, which lifts .tf-oneoff. */
#task-form.tf-oneoff [data-lane-go="repeating"] { display: none; }

/* W5: a text field's focus is its own border turning Ink plus a soft halo, both
   following the field's radius - not the square 2px outline. The transparent
   outline is what forced-colors mode draws, so it stays visible there too.
   Ink border against the surface is well over 3:1 (WCAG 2.4.7, 2.4.11). */
:is(input:not([type=checkbox], [type=radio], [type=range], [type=button], [type=submit]), textarea, select, .rename-input, [contenteditable=true]):not(.date-text, .qa-input, .log-stepper input):is(:focus-visible, .is-focus):not(dialog) {
  outline: 2px solid transparent !important;
  outline-offset: 0 !important;
  border-color: var(--ink);
  box-shadow: 0 0 0 1px var(--ink), 0 0 0 4px color-mix(in srgb, var(--ink) 14%, transparent);
}
.rename-input { outline: 0; border: 1px solid var(--line); }
.qa-field:has(:focus-visible), .log-stepper:has(input:focus-visible), .date-field:has(.date-text:focus-visible) {
  outline: 2px solid transparent !important;
  border-color: var(--ink);
  box-shadow: 0 0 0 1px var(--ink), 0 0 0 4px color-mix(in srgb, var(--ink) 14%, transparent);
}
/* ===== end Chunk 165 ===== */
/* ===== Chunk 163: calendar fixes from Ed's walkthrough (W7, W12, W17-W19) ===== */
/* W12: an item whose eye is off leaves Week and Month (Day fades it: Chunk 127's
   .class-faded, above). Year draws only what its eyes turn on. */
#calendar-grid .class-off { display: none !important; }

/* W7: Month's missed bar rule ("Month's missed bar", above) now covers the
   strip a Goal hover swaps it to, which had the old orange stripes. */

/* W19 (Chunk 178 reverts 163's fixed 20px mark, on Ed's word): the done tick is
   bigger than its box and the box's own edge crops it - the look a normal box
   always had. It scales with the box (--h, which also follows a grown box), so
   a tall box gets a tall tick and the edge crops it there too, not an inner clip
   short of the edge. The ::after fills the box and the mask is sized from --h,
   pushed a little past the right edge so the tick's bend stays in view on a tall
   box, so nothing but the box edge ever cuts it. */
.entry.cal-entry:not(.today-entry).state-done:is([data-density="chip"], [data-density="lane"])::after {
  top: 0; bottom: 0; left: 6px; right: 0; width: auto; height: auto; max-width: none; aspect-ratio: auto;
  -webkit-mask-size: calc(var(--h) * 1.8) auto; mask-size: calc(var(--h) * 1.8) auto;
  -webkit-mask-position: calc(100% + var(--h) * 0.3) center; mask-position: calc(100% + var(--h) * 0.3) center;
}

/* W17: a Week title wraps onto the lines its box has room for at rest
   (app.js's measureWeekTitles sets --title-lines), then ends in "...". */
#calendar-grid.week-stack .week-day-events .cal-entry[data-density="chip"] .entry-title {
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--title-lines, 1); line-clamp: var(--title-lines, 1);
  white-space: normal; overflow: hidden; overflow-wrap: break-word; flex: none;
}

/* W18: a box still too small for its title grows down over the boxes below
   while hovered or focused (up too, at a day's foot), then shrinks back. Its
   slot keeps its resting height, so nothing else moves. */
#calendar-grid.week-stack .entry.cal-entry:is(.title-open, .title-closing) { z-index: 4; }
#calendar-grid.week-stack .entry.cal-entry.title-open {
  --h: var(--grown) !important;
  --lift: var(--shadow-lift);
  margin-bottom: calc(var(--rest) - var(--grown));
  translate: 0 var(--rise, 0);
  opacity: 1;
  transition: height var(--motion-move) var(--ease-move), margin-bottom var(--motion-move) var(--ease-move), translate var(--motion-move) var(--ease-move);
}
#calendar-grid.week-stack .entry.cal-entry.title-open .entry-title { -webkit-line-clamp: none; line-clamp: none; }
#calendar-grid.week-stack .entry.cal-entry.title-closing {
  transition: height var(--motion-fast) var(--ease-exit), margin-bottom var(--motion-fast) var(--ease-exit), translate var(--motion-fast) var(--ease-exit);
}
@media (prefers-reduced-motion: reduce) {
  #calendar-grid.week-stack .entry.cal-entry:is(.title-open, .title-closing) { transition: none; }
}
/* ===== end Chunk 163 ===== */

/* ===== Chunk 169: chart labels (W9) and Routine graphs that say what they show (W11) ===== */
/* Goal chart: the two marker labels sit above their markers. Text in text colours. */
.pace-chart text.pc-mark { fill: var(--muted); font-size: var(--fs-xs); }
.pace-chart text.pc-mark .pc-mark-name { fill: var(--ink); font-weight: var(--fw-semi); }

/* Routine graphs: title, one line, one 0-100% scale, counts beside percentages. */
#routine-detail .rs-graph { min-width: 0; }
#routine-detail .rs-title { margin: 0; font-size: var(--fs-body); font-weight: var(--fw-semi); color: var(--ink); }
#routine-detail .rs-desc { margin: var(--sp-1) 0 var(--sp-3); max-width: 38ch; font-size: var(--fs-md); line-height: 1.4; color: var(--text-2); }
#routine-detail .rs-now-label { margin: 0 var(--sp-2-5) var(--sp-1); text-align: right; font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--ink); }
#routine-detail .rs-chart { display: grid; grid-template-columns: 34px 1fr; column-gap: var(--sp-1-5); }
#routine-detail .rs-chart .rs-scale { grid-column: 1; grid-row: 1; display: flex; flex-direction: column; justify-content: space-between; height: 120px; text-align: right; font-size: var(--fs-xs); color: var(--muted); line-height: 1; transform: translateY(0); }
#routine-detail .rs-chart .rs-bars { grid-column: 2; grid-row: 1; margin: 0; background: linear-gradient(var(--divider), var(--divider)) 0 0 / 100% 1px no-repeat, linear-gradient(var(--divider), var(--divider)) 0 50% / 100% 1px no-repeat; }
#routine-detail .rs-chart .rs-axis { grid-column: 2; margin: var(--sp-1-5) 0 0; }
#routine-detail .rs-axis-title { grid-column: 2; margin: var(--sp-1) 0 0; font-size: var(--fs-xs); color: var(--muted); }
#routine-detail .rs-wk div { grid-template-columns: 34px 1fr 96px; }
#routine-detail .rs-wk b small { font-weight: var(--fw-regular, 400); color: var(--muted); font-size: var(--fs-xs); }
#routine-detail .rs-wk-scale { display: grid; grid-template-columns: 34px 1fr 96px; gap: var(--sp-2-5); margin-top: var(--sp-1-5); padding: 0 var(--sp-2-5); font-size: var(--fs-xs); color: var(--muted); }
#routine-detail .rs-wk-scale > span:nth-child(2) { position: relative; height: 1.2em; }
#routine-detail .rs-wk-scale > span:nth-child(2) > span { position: absolute; top: 0; left: 50%; transform: translateX(-50%); }
#routine-detail .rs-wk-scale > span:nth-child(2) > span:first-child { left: 0; transform: none; }
#routine-detail .rs-wk-scale > span:nth-child(2) > span:last-child { left: auto; right: 0; transform: none; }
#routine-detail .rs-lead-count { margin: calc(-1 * var(--sp-1)) 0 0; font-size: var(--fs-md); color: var(--on-feature-2); }
/* ===== end Chunk 169 ===== */
/* ===== Chunk 168: Move task beside the real Month (W14, mock 167) =====
   The Edit task panel's frame, holding only what a move needs. The task being
   moved keeps its colour while the rest greys (Chunk 126's composing-fade),
   ringed in its colour; once a new day is picked it fades dashed where it
   was, and a solid copy and a tinted outline mark where it's going. */
dialog#move-panel.slide-panel:is([open], :not([open])) {
  z-index: 30; width: 100%; margin: 0; box-sizing: border-box; overflow-y: auto;
  border: 0; border-top: 2px solid var(--goal, var(--line)); background: var(--surface);
}
.aside-drawer > dialog#move-panel.slide-panel:is([open], :not([open])) {
  position: static; inset: auto; height: 100%; max-height: 100%; padding: var(--sp-4) var(--sp-5) 0; border-radius: 0; box-shadow: none;
}
#move-panel .task-form { gap: var(--sp-2); min-height: 100%; }
#move-panel .task-form > h2 {
  margin: 0 0 var(--sp-1-5); font-family: var(--font-head); font-weight: var(--fw-heavy); font-size: var(--fs-heading); letter-spacing: -0.02em;
}
#move-panel :is(input[type=text]) { min-height: 34px; height: 34px; padding: 0 var(--sp-2-5); font-size: var(--fs-base); }
#move-panel input[name=title] { min-height: 38px; height: 38px; font-size: var(--fs-body); background: var(--sunk); color: var(--text-2); }
#move-panel .tf-pair { align-items: end; }
#move-panel .tf-field { font-size: var(--fs-md); font-weight: var(--fw-semi); }
#move-panel .tf-field input { font-weight: var(--fw-regular); }
#move-panel .tf-field > .date-field { grid-column: 1 / -1; display: flex; margin-top: var(--sp-1-5); }
#move-panel .tf-field > input.time-input { margin-top: var(--sp-1-5); }
#move-panel .date-field .date-text { flex: 1; width: auto; min-width: 0; margin: 0; }
#move-panel .tf-help { margin: 0; }
.mp-now { margin: var(--sp-1) 0 0; font-size: var(--fs-md); color: var(--text-2); }
.mp-now b { font-weight: var(--fw-semi); color: var(--ink); }
#move-panel .task-form > .actions {
  position: sticky; bottom: 0; z-index: 1; margin: auto calc(-1 * var(--sp-5)) 0; padding: var(--sp-3) var(--sp-5);
  background: var(--surface); border-top: 1px solid var(--divider);
}

/* The Back chip beside the month's name: the quiet pill Week's In History uses. */
.move-back { margin-left: var(--sp-4); }
.move-back svg { width: 15px; height: 15px; }

/* The task in hand: in colour, ringed, on top of its day. */
#calendar-grid .cal-entry.move-held, #calendar-grid .cal-entry.draft-preview.move-copy {
  position: relative; z-index: 2; background: var(--surface); color: var(--ink); box-shadow: 0 0 0 2px var(--goal), var(--shadow-soft);
}
#calendar-grid.composing-fade .cal-entry.move-held { filter: none; }
/* Today's dark cell has its own dark boxes; the one in hand stays light there too. */
#calendar-grid :is(.month-day, .day).today .entry.cal-entry:is(.move-held, .move-copy):not(.today-entry):not(.draft-hover)[data-density] { background: var(--surface); }
#calendar-grid :is(.month-day, .day).today .entry.cal-entry:is(.move-held, .move-copy) .entry-title { color: var(--ink); }
#calendar-grid .cal-entry.move-held.move-origin { opacity: 0.5; box-shadow: none; outline: 1.5px dashed var(--goal); outline-offset: -1.5px; }
#calendar-grid .cal-entry.draft-preview.move-copy { opacity: 1; outline: 0; }
#calendar-grid.composing-fade .cal-entry.move-copy { filter: none; }
#calendar-grid [data-day].move-target { outline: 2px solid var(--ink); outline-offset: -2px; }

/* A phone (Ed's answer 3): a bottom sheet over the lower half, the Month
   above it; a tap sets the day. The page leaves room to scroll above it. */
body > dialog#move-panel.slide-panel:is([open], :not([open])) {
  position: fixed; inset: auto 0 0 0; height: auto; max-height: 52vh; padding: var(--sp-4) var(--sp-4) 0;
  border-radius: var(--r-card) var(--r-card) 0 0; box-shadow: var(--shadow-panel);
}
body > dialog#move-panel.slide-panel[open] { translate: none; }
@starting-style { body > dialog#move-panel.slide-panel[open] { translate: 0 24px; opacity: 0; } }
body.move-sheet #move-panel .task-form { min-height: 0; }
body.move-sheet #move-panel .task-form > .actions { margin-inline: calc(-1 * var(--sp-4)); padding-inline: var(--sp-4); }
body.move-sheet #move-panel .actions .btn { min-height: 44px; }
body.move-sheet .content { padding-bottom: 52vh; }
/* ===== end Chunk 168 ===== */

/* ===== Chunk 171: Move to shows availability (Ed, 5 Nov) =====
   Move draws the free-time marks dragging from To place draws (Chunk 76,
   above) on every day it can go to, in the task's colour. Redraws as the date
   changes don't grow them in again; the day under the pointer and the chosen
   day lift a little, and the panel says the chosen day's figure in words. */
.free-mark.steady :is(.free-fill, .free-track > span), .free-gap.steady { animation: none; }
#calendar-grid .compose-hover .free-bar .free-fill,
#calendar-grid .move-target .free-bar .free-fill { height: 6px; }
#calendar-grid .compose-hover .free-bar.tight .free-fill,
#calendar-grid .move-target .free-bar.tight .free-fill { height: 2px; }
#calendar-grid .compose-hover .free-strip .free-track,
#calendar-grid .move-target .free-strip .free-track { height: 8px; }
#calendar-grid :is(.compose-hover, .move-target) .free-label { color: var(--ink); }
.mp-free { margin: 0; font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--ink); }
.mp-free:empty { display: none; }
/* A phone's days are too narrow for the figure: the bar stays, the sheet says it. */
body.move-sheet .free-bar .free-label { display: none; }
/* ===== end Chunk 171 ===== */
/* ===== Chunk 170: Today and the event look (Ed's answers on mock 166, 5 Nov) ===== */
/* Chunk 180 (Ed on mock 179): W15 reversed - a missed event is grey stripes (the old
   148deg 6px/3px pattern, recoloured to two greys) on Today, Day, Week and Month, Month's
   16px bars too. Year is untouched. It stays apart from an eye-hidden item (faded, plain
   grey, no stripes) by the texture, not the shade, and says "Missed" in words. Text on it
   is Ink (10.7:1 light, 7.9:1 dark on the worse stripe). Full strength, not faded. */
:root { --missed-grey-a: #e0dfd9; --missed-grey-b: #cfcec7; }
:root[data-theme="dark"] { --missed-grey-a: #34363c; --missed-grey-b: #43464d; }
:root { --missed-grey-stripes: repeating-linear-gradient(148deg, var(--missed-grey-a) 0 6px, var(--missed-grey-b) 6px 9px); }
#calendar-grid:not(.year) .entry.cal-entry:not(.today-entry).missed { background-image: var(--missed-grey-stripes) !important; opacity: 1; filter: grayscale(0.9); }
.today-card-task.missed .tc-left { background: var(--missed-grey-stripes); }
#calendar-grid:not(.year) .entry.cal-entry:not(.today-entry).missed:is(:hover, :focus-visible) { filter: none; }
#calendar-grid:not(.year) .cal-entry:not(.today-entry).missed .grid-sub:not(:empty),
#calendar-grid:not(.year) .cal-entry:not(.today-entry).missed .entry-title,
.today-card-task.missed .tc-top { color: var(--ink); }
.key-item i.key-missed, .c127-sw.sw-box.sw-missed { background: var(--missed-grey-stripes); box-shadow: inset 0 0 0 1px var(--line); opacity: 1; filter: none; }

/* Chunk 180 (W2): the owner colour is an 18px band down the card's right edge. The card
   clips to its own radius (overflow hidden, --r-block), so the band's outer corners curve
   with the card; the inner edge is straight. Glass bevel: a light highlight along the top
   and inner edges and a soft inner shade at the outer edge, so it reads curved up. The
   ring (178's round focus ring) sits clear of the band. */
:root { --band: 18px; --band-hi: rgba(255, 255, 255, 0.5); --band-shade: rgba(0, 0, 0, 0.16); }
:root[data-theme="dark"] { --band-hi: rgba(255, 255, 255, 0.28); --band-shade: rgba(0, 0, 0, 0.32); }
.today-card-task .tc-left, .today-card-task.state-done .tc-left { clip-path: none; }
.today-card-task .tc-right, .today-card-task.state-done .tc-right {
  inset: 0 0 0 auto; width: var(--band); clip-path: none; border-radius: 0;
  background-image: linear-gradient(90deg, rgba(255, 255, 255, 0.22) 0, rgba(255, 255, 255, 0) 45%, var(--band-shade) 100%),
    linear-gradient(180deg, var(--band-hi) 0, rgba(255, 255, 255, 0) 38%, rgba(0, 0, 0, 0.08) 100%);
  box-shadow: inset 0 1.5px 0 var(--band-hi), inset 1px 0 0 color-mix(in srgb, var(--band-hi) 55%, transparent), inset -2px 0 3px var(--band-shade), inset 0 -2px 3px rgba(0, 0, 0, 0.1);
}
.today-card-wrap .tc-do { right: calc(var(--band) + 12px); color: var(--ink); }
.today-card-task .tc-icons { color: var(--muted); }
.today-card-task.has-tick .tc-text { inset-inline-end: calc(var(--band) + 12px + 44px + 12px + 46px); }
.today-card-task.has-tick .tc-icons { right: calc(var(--band) + 12px + 44px + 12px); }
.today-card-task:not(.has-tick):not(.state-done) .tc-icons { right: calc(var(--band) + 12px); }
.today-card-task:not(.has-tick):not(.state-done) .tc-text { inset-inline-end: calc(var(--band) + 12px + 46px); }
/* A done card: the text sits on the grey, so it takes Ink, and the logo tick moves left to leave it room. */
.today-card-task.state-done .tc-tick { left: 4px; }
.today-card-task.state-done .tc-text { inset: 0 calc(var(--band) + 12px) 0 96px; }
.today-card-task.state-done .tc-title { color: var(--ink); }
.today-card-task.state-done .tc-top { color: var(--muted); }

/* W3: the one-click tick says what a click does. On hover or keyboard focus the
   ring fills Ink and a "Mark done" chip arrives after --motion-delay (80ms),
   fading in over --motion-fast (160ms). The label is the button's own
   data-label, so Log and Log note read the same way. */
.tc-do {
  transition: background var(--motion-fast) var(--ease-fade), color var(--motion-fast) var(--ease-fade),
    border-color var(--motion-fast) var(--ease-fade), scale var(--motion-press) var(--ease-move);
}
.tc-do:active { scale: 0.96; }
.tc-do .entry-icon { transition: color var(--motion-fast) var(--ease-fade); }
.tc-do::after {
  content: attr(data-label); position: absolute; right: 0; bottom: calc(100% + 4px); translate: 0 4px; /* Chunk 181: above the ring, right-aligned, so it never cuts the title */
  padding: var(--sp-1) var(--sp-2-5); border-radius: var(--r-pill); background: var(--ink); color: var(--surface);
  font-size: var(--fs-sm); font-weight: var(--fw-semi); line-height: 1.2; white-space: nowrap; opacity: 0; pointer-events: none;
  transition: opacity var(--motion-out) var(--ease-exit), translate var(--motion-out) var(--ease-exit);
}
.tc-do:focus-visible { background: var(--ink); color: var(--surface); border-color: var(--ink); }
.tc-do:focus-visible .entry-icon { color: var(--surface); }
.tc-do:focus-visible:not(.chip-off)::after {
  opacity: 1; translate: 0;
  transition: opacity var(--motion-fast) var(--ease-enter) var(--motion-delay), translate var(--motion-fast) var(--ease-enter) var(--motion-delay);
}
@media (hover: hover) {
  .tc-do:hover { background: var(--ink); color: var(--surface); border-color: var(--ink); }
  .tc-do:hover .entry-icon { color: var(--surface); }
  .tc-do:hover:not(.chip-off)::after {
    opacity: 1; translate: 0;
    transition: opacity var(--motion-fast) var(--ease-enter) var(--motion-delay), translate var(--motion-fast) var(--ease-enter) var(--motion-delay);
  }
}
@media (prefers-reduced-motion: reduce) {
  .tc-do { transition: background var(--motion-fast) var(--ease-fade), color var(--motion-fast) var(--ease-fade), border-color var(--motion-fast) var(--ease-fade); }
  .tc-do:active { scale: none; }
  .tc-do::after, .tc-do:hover::after, .tc-do:focus-visible::after { translate: 0; transition: opacity var(--motion-fast) var(--ease-fade); }
}

/* Chunk 181: Esc dismisses the chip until the pointer or focus leaves the tick. */
.tc-do.chip-off::after { opacity: 0 !important; }
/* Chunk 181: Move's allowed-days line and the typed date's own error sit right under the date row. */
#move-panel .mp-allowed { margin-top: var(--sp-1); color: var(--text-2); }
#move-panel .mp-date-error { margin: var(--sp-1) 0 0; font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--ink); }
#move-panel .mp-date-error::before { content: "! "; font-weight: var(--fw-bold); }
#move-panel input[aria-invalid] { border-color: var(--ink); }

/* W1: the Week review row is one line: title and dot left, the status right-aligned by the arrow. */
.today-review-sub { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: right; font-size: var(--fs-sm); }
.today-review-arrow { margin-left: 0; }
/* ===== end Chunk 170 ===== */

/* ===== Chunk 178: round controls get a round focus ring (W5, Ed 5 Nov); the Week done tick (W19) ===== */
/* W5: "I just don't like that I can see this weird square selection box around the
   curved circle thing." Every round control draws its keyboard focus as a ring
   that is its own circle (a box-shadow, so no browser can square it off), in the
   same soft Ink as 165's fields: a 2px Ink ring with a 14% halo outside it, a
   paper gap between ring and control. The transparent outline is what forced-colors
   mode draws. Ink on the paper gap is far over 3:1 (WCAG 2.4.7, 2.4.11); on Ink
   feature cards --focus-color flips to the paper colour, as for every focus ring. */
:is(.tc-do, .swatch, .nav-colour-dot, .feed-colour-dot, .fv-colour-dot, .refl-clear, #move-dialog .mv-nav button, #move-dialog .mv-d button):is(:focus-visible, .is-focus),
.tf-chip input:is(:focus-visible, .is-focus) + span {
  outline: 2px solid transparent !important;
  outline-offset: 0 !important;
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--focus-color), 0 0 0 7px color-mix(in srgb, var(--focus-color) 14%, transparent);
}
/* ===== end Chunk 178 ===== */

/* ===== Chunk 181: missed is grey everywhere (Ed, 5 Nov cards) ===== */
/* The Missed card, What slipped, To place's overdue dates and edge, the Week review's missed
   count and the event dialog's Missed badge take Chunk 180's greys instead of orange, so
   missed is one colour wherever it shows. The words keep saying "Missed". --miss-ink is the
   text grey (light 7.4:1 on paper, dark 9:1); --miss-edge is the stripes' darker grey.
   Orange stays for what else it means: the brand's full stop, the Now dot, errors, History's Waiting. */
:root { --miss-ink: #55544d; --miss-edge: var(--missed-grey-b); }
:root[data-theme="dark"] { --miss-ink: #b9bbc1; }
:is(.today-missed-when, .ck-slip-missed, .ck-slip-confirm, .rv-stat.is-missed strong),
.ck-slipped .ck-slip-missed { color: var(--miss-ink); }
.tray-wait { border-left-color: var(--miss-edge); }
.tray-wait.empty { border-left-color: var(--line); }
#event-detail .ev-state[data-kind="missed"] { color: var(--miss-ink); border-color: var(--miss-edge); background: var(--missed-grey-a); }
#event-detail .ev-when .is-missed { color: var(--miss-ink); }
/* A missed box keeps its owner colour on its edge (event states review, default): the stripes
   fill, the Goal's colour is the left edge so you can tell whose it is. Today's card has its
   owner band already. */
#calendar-grid:not(.year) .entry.cal-entry:not(.today-entry).missed { box-shadow: inset 3px 0 0 var(--goal, var(--muted)); }
/* ===== end Chunk 181 ===== */

/* ===== Chunk 186: sweep 2 fixes - Goals, Routines, Settings ===== */
/* 03 #2: the two Routine graphs stack as soon as a half would be too narrow for 13 bars and their dates (was a fixed 720px viewport). */
#routine-detail .rs-stats { grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); row-gap: var(--sp-6); }
#routine-detail .rs-chart { grid-template-columns: 34px minmax(0, 1fr); }
#routine-detail .rs-axis span { min-width: 0; }
/* 03 #4: the left panel clips an outside ring, so its rows take the ring inside. */
.sidebar :is(.nav-goal, .nav-entry, .nav-row):focus-visible { outline-offset: -2px; }
/* 03 #6: the line under the dark card's projection used the muted grey (2.85:1); the card's own second text colour passes. */
:is(#goal-detail, #routine-detail, #collection-detail, #completed-detail) .fv-summary .fv-pace2 { color: var(--on-feature-2); }
/* 06 #2: "sync failed" in the left panel is Ink, as Settings' row, not the Missed orange at 11px. */
.nav-linked .nav-goal.feed-broken .nav-label::after { content: " · ⚠ sync failed"; color: var(--ink); }
/* 04 #3: the Reschedule row's own date field and its range message. */
.ev-daterow { flex-wrap: wrap; }
.ev-daterow .date-field { flex: 1; min-width: 0; }
.ev-daterow .ev-row-label:empty { display: none; }
.ev-daterow-error { flex-basis: 100%; margin: 0; font-size: var(--fs-sm); color: var(--text-2); }
.hs-back[data-goal-back] { margin-left: 0; }
/* ===== end Chunk 186 ===== */
/* Chunk 186 (03 #16): a very long title stops at three lines instead of pushing the page down (the full text is in Edit). */
.fv-head h2 { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; }

/* ===== Chunk 185: sweep 2 fixes (calendar, Today) ===== */
/* Calendar 3: a lane's meta line ends in an ellipsis (past the 96px floor, lanes fold into "+N more", Chunk 187). */
.cal-entry[data-density="lane"] .entry-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Today 2: under 1000px the chip is a plus (it is named "Quick add"), not a bare keyboard hint. */
.topbar-qa-plus { display: none; font-size: var(--fs-lg); line-height: 1; font-weight: var(--fw-semi); }
@media (max-width: 999.98px) { .topbar-qa-plus { display: inline; } .topbar-qa kbd { display: none; } }
/* Calendar 11: Year's card head reads like Month's and Day's (sentence case, no tracking). */
.year-sofar h3 { font-size: var(--fs-body); letter-spacing: 0; text-transform: none; color: var(--on-feature-2); font-weight: var(--fw-bold); }
/* Calendar 9: a long name in Day's list ends in an ellipsis; the duration never breaks. */
.day-sum-row .day-sum-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.day-sum-row strong { white-space: nowrap; flex: none; }
/* Calendar 14: Month's "+N more" at the 12px Muted text size. */
.month-more, #calendar-grid .month-more { font-size: var(--fs-sm); }
/* Calendar 8 and 10: a scrolling box that has more below fades at its foot (Month's chevron does the same job). */
.week-going .going-legend.scrolls-more { mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent); }
#calendar-grid .day-scroll.scrolls-y { mask-image: linear-gradient(to bottom, #000 calc(100% - 26px), transparent); }
/* Calendar 5: a Week lane that folds hides its overflow items whole and counts them in "+N more", so its last block isn't also faded. */
.week-day-events.folded { mask-image: none; }
/* ===== Chunk 184 (04 #6): Where the week went stays beside a long What slipped ===== */
@media (min-width: 1001px) {
  .rv-two > .rv-went { position: sticky; top: calc(var(--topbar-h) + var(--sp-4)); }
}
/* ===== end Chunk 184 ===== */

/* Chunk 187: the Goal description's count, shown from 450 characters */
.field-count { margin: calc(-1 * var(--sp-1)) 0 0; font-size: var(--fs-sm); text-align: right; }
.field-count.over { color: var(--danger); font-weight: 600; }

/* Chunk 187: Today's quiet line when this device's time zone isn't the account's */
.today-zone { margin: 0; padding-top: var(--sp-1); font-size: var(--fs-sm); color: var(--muted); }
.today-zone .link-btn { font-size: inherit; }

/* Chunk 187: Day's overlaps past the 96px floor fold into a "+N more" chip in the last lane, like Month's */
.day-lane-wrap { position: absolute; z-index: 3; }
.fv-more.day-lane-more { display: block; width: 100%; height: 30px; padding: 0 var(--sp-1); border: 1px dashed var(--muted); border-radius: var(--r-input); background: var(--surface); color: var(--ink); font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-semi); text-align: left; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fv-more.day-lane-more:hover, .fv-more.day-lane-more[aria-expanded="true"] { border-style: solid; background: var(--surface); }
.fv-menu.day-lane-menu { right: 0; left: auto; min-width: 220px; max-height: 320px; overflow-y: auto; }
.day-lane-time { font-variant-numeric: tabular-nums; color: var(--muted); }

/* ===== Chunk 190: first run and words ===== */
/* Today: Anytime and All day stay pinned at the top; only timed cards scroll to now. */
.today-anytime { position: sticky; top: 0; z-index: 2; display: flex; flex-direction: column; gap: var(--sp-2-5); padding-bottom: var(--sp-2); background: var(--surface); }
.today-anytime .today-slot.is-anytime + :not(.is-anytime) { margin-top: 0; }
/* History's week card leads with its dates; the week number sits small under them. */
.hs-rail-range { font-size: var(--fs-h-lg); }
.hs-rail-range + .hs-rail-lbl { margin-top: var(--sp-1); }
/* ===== end Chunk 190 ===== */
/* ===== Chunk 190 (cont.) ===== */
.today-next[hidden], .today-summary:empty { display: none; }
.welcome-tips { margin: 40px 0 0; max-width: 28em; font-size: var(--fs-xl); line-height: 32px; color: var(--text-2); }
/* ===== end Chunk 190 ===== */
/* ===== Chunk 189: gate 2 accessibility (WCAG 2.2 AA) ===== */
/* a11y 1 (1.4.3): past boxes keep full strength - Ink titles, #3a3c42 sub lines (5.2:1), as on Day. */
#calendar-grid :is(.day, .month-day).past .cal-entry:not(.today-entry) .entry-title { color: var(--ink); }
#calendar-grid :is(.day, .month-day).past .cal-entry:not(.today-entry) .grid-sub:not(:empty) { color: var(--text-2); }
/* a11y 4 (1.4.3): a done card's top line sat at 3.3:1 on the grey. */
.today-card-task.state-done .tc-top { color: var(--text-2); }
/* a11y 5 (1.4.3): Move's free-time labels are text in Ink (paper on a today column), the goal colour stays on the bar. */
.free-bar, .free-strip, .free-gap { color: var(--ink); }
#calendar-grid :is(.day.today, .month-day.today) :is(.free-bar, .free-strip, .free-gap) { color: var(--on-feature); }
/* designer 6: code-focused headings and panels take no square box; the logo link gets the round ring of Chunk 178. */
:is(h1, h2, h3, article, section, main, .rv-title, .rv-bar-title)[tabindex="-1"]:focus,
:is(h1, h2, h3, article, section, main, .rv-title, .rv-bar-title)[tabindex="-1"]:focus-visible { outline: none !important; box-shadow: none; }
.brand:focus-visible, .topbar .brand:focus-visible {
  outline: 2px solid transparent !important; outline-offset: 0 !important; border-radius: var(--r-input);
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--focus-color), 0 0 0 7px color-mix(in srgb, var(--focus-color) 14%, transparent);
}
/* designer 10: Day's resize grips show on hover or focus, not at rest (a touch screen has no hover, so it keeps them). */
@media (hover: hover) {
  .cal-entry .lane-handle .lane-grip { opacity: 0; transition: opacity var(--motion-fast) var(--ease-fade), transform var(--motion-fast) var(--ease-fade); }
  .cal-entry:is(:hover, :focus-visible, :focus-within, .selected) .lane-handle .lane-grip,
  .dragging .cal-entry .lane-handle .lane-grip, .cal-entry.dragging .lane-handle .lane-grip { opacity: 1; }
}
/* a11y 2: the toast pauses while hovered or focused; Alt+U lands on it, so its ring shows */
.toast:is(:hover, :focus-within) { box-shadow: var(--shadow-menu), 0 0 0 2px var(--on-primary); }
/* designer 10: where a Week box is too narrow for "07:00 · Missed", the time goes (still read aloud) and the state word stays whole. */
@media (max-width: 1100px) {
  #calendar-grid.week-stack .cal-entry .grid-sub .grid-time {
    position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
}
/* ===== end Chunk 189 ===== */
/* ===== Chunk 191: narrow windows (gate 2: product-designer 1, accessibility 7) =====
   A holding fallback so the app reflows (WCAG 1.4.10) before the designed phone layout (roadmap 3.4).
   Media queries only; 900px and up is untouched. Layout and wording, never colour, type, tokens or motion. */

/* 600-900: Day's heading wraps instead of clipping or scrolling sideways. */
@media (max-width: 899.98px) {
  #calendar-view .calendar-panel .range-title { flex-wrap: wrap; min-width: 0; }
  #calendar-view .calendar-panel #range-label { min-width: 0; overflow-wrap: anywhere; }
  .calendar-panel > .toolbar { min-width: 0; flex-wrap: wrap; row-gap: var(--sp-2); }
  .calendar-main, .calendar-frame { min-width: 0; }
}

/* 600-900: the top bar's centred switch is laid out in the row, so the quick-add pill and Settings never sit on it. */
@media (min-width: 600px) and (max-width: 899.98px) {
  .topbar .view-switch { position: static; transform: none; flex: none; }
  .topbar .topbar-slot.slot-sync, .topbar .topbar-slot.slot-account { display: none; }
}
@media (min-width: 600px) and (max-width: 699.98px) { .topbar .brand { display: none; } }

/* Below 700 the left panel is an overlay (app.js OVERLAY_LEFT): it floats over the page, which stays put. */
@media (max-width: 699.98px) {
  body.left-open .sidebar { box-shadow: 8px 0 24px color-mix(in srgb, var(--ink) 14%, transparent); }
  html body.left-open .content > :not(.topbar):not(.error) { margin-left: var(--sp-12); } /* as closed: the panel floats over it */
  body.left-open .content > :is(#today-view, #goal-view, #routine-view, #collection-view, #completed-view) { margin-left: 36px; }
}

/* Below 600: one column, nothing overlapping, nothing sideways. */
@media (max-width: 599.98px) {
  body { --topbar-h: 94px; --rail-w: 40px; --rail-gap: 8px; }

  /* Top bar: menu and + New on the first row, Settings at the end; Today / Calendar (and the zooms) on the second. */
  .topbar { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; grid-template-rows: 36px 36px; row-gap: var(--sp-2);
    height: auto; min-height: var(--topbar-h); padding: var(--sp-2) var(--sp-2) var(--sp-2); align-items: center; box-sizing: border-box; }
  .topbar > .spacer, .topbar .topbar-slot, .topbar .brand { display: none; }
  .topbar .topbar-left { grid-column: 1; grid-row: 1; margin-right: 92px; } /* room for the + New beside it */
  .topbar .nav-toggle { width: 36px; height: 36px; }
  .topbar #topbar-review { grid-column: 3; grid-row: 1; }
  .topbar .settings-wrap { grid-column: 4; grid-row: 1; }
  .topbar .view-switch { position: static; transform: none; grid-column: 1 / -1; grid-row: 2; justify-self: center; max-width: 100%; box-sizing: border-box; }
  .view-switch button { padding-left: var(--sp-2-5); padding-right: var(--sp-2-5); }
  .view-zooms button { padding-left: var(--sp-2); padding-right: var(--sp-2); }
  .view-zooms .view-zoom-label { display: none; }
  .view-zooms button.is-unavailable { opacity: 0.45; }
  .topbar .view-switch > .calendar-badge { right: 0; }
  .rail-count { right: -2px; }
  .new-float { top: var(--sp-2); left: 52px; z-index: 32; }
  .new-float .global-new { width: auto; min-height: 36px; height: 36px; padding: 0 var(--sp-3); gap: var(--sp-1-5); font-size: var(--fs-base); }
  .new-float .new-fan-menu { top: calc(100% + 8px); left: 0; }
  .sidebar { width: min(var(--left-w), calc(100vw - 48px)); z-index: 40; }
  body.left-open .new-fan { width: 100%; }

  /* The page uses the whole width; the rail keeps its own strip on the right. */
  .content { margin-left: 0; padding-left: 0; padding-right: 0; }
  .topbar { margin: 0; }
  .content > :not(.topbar):not(.error),
  body.left-open .content > :not(.topbar):not(.error) { margin-left: var(--sp-3); margin-right: var(--sp-3); }
  .content > :is(#today-view, #goal-view, #routine-view, #collection-view, #completed-view),
  body.left-open .content > :is(#today-view, #goal-view, #routine-view, #collection-view, #completed-view) { margin-left: 0; margin-right: 0; }
  .today-page { padding-left: var(--sp-3); padding-right: var(--sp-3); }
  .edge-peek { display: none; }
  .calendar-panel { padding-left: 0; padding-right: 0; }
  body[data-view="calendar"].s-cal:not(.cal-composing) .calendar-main { padding-right: calc(var(--rail-w) + var(--sp-1)); }

  /* Day is one column (no neighbours beside it); Month's title and arrows wrap under each other. */
  #calendar-grid.day-stack > .day-view.neighbour { display: none; }
  #calendar-grid.day-stack > .day-view.focused { flex-grow: 1; }
  #calendar-grid.day-stack .day-events { right: var(--sp-2); }
  #calendar-view .calendar-panel .range-title { flex-wrap: wrap; gap: var(--sp-2); max-width: 100%; }
  #calendar-view .calendar-panel #range-label { order: -1; flex: 1 1 100%; font-size: var(--fs-2xl); line-height: 1.1; min-width: 0; }
}

/* ===== Chunk 195: Today's card back to the tick and slant (Ed, 6 Nov) ===== */
/* "I don't like the new today page card coloured bit can we revert back to the exact
   tick/slant look." Everything below restores the pre-Chunk-170 geometry exactly (the
   58-degree cuts, 47/84.5px and 26/63.5px on a planned card; 121.6/86.7px and 142.6/107.7px
   on a done one; the 82.8px logo tick at left 60px; the 38px ring at right 8px; the text
   and icon insets) over 170's rounded cap and 180's band. Kept from later chunks: the grey
   stripes on a missed card's left part (181), 178's round focus ring and the Mark done chip
   on .tc-do, 189's readable top line on a done card, 190's Anytime pinning. */
.today-card-task .tc-left { clip-path: polygon(0 0, calc(100% - 47px) 0, calc(100% - 84.5px) 100%, 0 100%); }
.today-card-task .tc-right, .today-card-task.state-done .tc-right {
  inset: 0; width: auto; border-radius: 0; background-image: none; box-shadow: none;
  clip-path: polygon(calc(100% - 26px) 0, 100% 0, 100% 100%, calc(100% - 63.5px) 100%);
}
.today-card-task.state-done .tc-left { clip-path: polygon(0 0, 121.6px 0, 86.7px 100%, 0 100%); }
.today-card-task.state-done .tc-right { clip-path: polygon(142.6px 0, 100% 0, 100% 100%, 107.7px 100%); }
.today-card-task.state-done .tc-tick { left: 60px; }
.today-card-task .tc-text { inset: 0 96px 0 14px; }
.today-card-task .tc-icons { right: 12px; color: var(--on); }
.today-card-task.has-tick .tc-text { inset-inline-end: 124px; }
.today-card-task.has-tick .tc-icons { right: 58px; color: var(--muted); }
.today-card-task:not(.has-tick):not(.state-done) .tc-icons { right: 12px; color: var(--on); }
.today-card-task:not(.has-tick):not(.state-done) .tc-text { inset-inline-end: 96px; }
.today-card-task.state-done .tc-text { inset: 0 14px 0 154px; }
.today-card-task.state-done .tc-title { color: var(--on); }
/* 189's fix: the top line reads at full on-colour (the grey it was fixed against is no longer behind it). */
.today-card-task.state-done .tc-top { color: var(--on); }
.today-card-wrap .tc-do { right: 8px; color: var(--on); }
/* ===== end Chunk 195 ===== */

/* ===== Chunk 192: Ed's panel calls 2-6 (6 Nov) ===== */

/* 2. Today's "To place" row sits under the Week review row and reads as its sibling. */
.today-place { min-height: 44px; }

/* 4. History's one line: "1 goal waiting in Week review" (warm, as the old tray was), opening Week review. */
#completed-list .hs-waiting-line {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); width: 100%; min-height: 44px;
  padding: 0 var(--sp-5); border: 1px solid var(--line); border-radius: var(--r-card); background: var(--surface);
  font: inherit; font-size: var(--fs-body); font-weight: var(--fw-semi); color: var(--missed-ink); text-align: left; cursor: pointer;
}
#completed-list .hs-waiting-line:hover { background: var(--page); }
.hs-waiting-arrow svg { display: block; width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
:root[data-theme="dark"] #completed-list .hs-waiting-line { color: var(--missed-accent); }

/* (Item 5, Month fills by state, is paused by Ed: Month's bars, past cells and key are untouched.) */

/* 6. Empty Week and Month: full-height columns and rows, one line and a New task pill in today's
   column or cell (the first day still to come when today isn't shown). */
.cal-empty-state { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2); padding: var(--sp-2) var(--sp-2) 0; min-width: 0; }
.cal-empty-line { margin: 0; font-size: var(--fs-sm); line-height: 1.35; color: var(--muted); }
.cal-empty-new { min-height: 32px; padding: 0 var(--sp-3); border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--surface); color: var(--ink); font-size: var(--fs-sm); font-weight: var(--fw-medium); }
.cal-empty-new:hover { background: var(--page); }
#calendar-grid .today .cal-empty-line { color: var(--on-feature); }
#calendar-grid .today .cal-empty-new { background: transparent; border-color: var(--on-feature); color: var(--on-feature); }
#calendar-grid .today .cal-empty-new:hover { background: var(--feature-2); }
#calendar-grid.month .cal-empty-state { padding: var(--sp-1) 0 0; gap: var(--sp-1-5); }
#calendar-grid.month .cal-empty-line { font-size: var(--fs-xs); }
#calendar-grid.month .cal-empty-new { min-height: 26px; padding: 0 var(--sp-2); }
#calendar-grid.month.empty-month .month-week { align-items: stretch; }
/* ===== end Chunk 192 ===== */

/* ===== Chunk 196: the Under row on New task (Ed, mock 193 A) ===== */
.under-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.under-chip {
  display: inline-flex; align-items: center; gap: var(--sp-1-5); min-height: 32px; max-width: 100%; padding: 0 var(--sp-3);
  border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--surface);
  font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--text-2); cursor: pointer;
  transition: background var(--motion-fast), color var(--motion-fast), border-color var(--motion-fast);
}
.under-chip:hover { background: var(--state-hover); color: var(--ink); border-color: var(--faint-text); }
.under-chip[aria-checked="true"] { border-color: var(--ink); background: var(--divider); color: var(--ink); font-weight: var(--fw-semi); }
.under-chip:focus-visible, .under-more:focus-visible { outline: var(--focus-width) solid var(--focus-color); outline-offset: 2px; }
.under-mark { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--c); }
.under-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.under-more { align-self: flex-start; margin-top: var(--sp-1); padding: 0; border: 0; background: none; font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--muted); text-decoration: underline; cursor: pointer; }
.under-more:hover { color: var(--ink); }
@media (max-width: 600px) { .under-chip { min-height: 44px; } .under-more { min-height: 44px; } }
/* The sticky Create/Cancel footer must not cover a focused field the form scrolls to (the taller form makes it likelier). */
#task-dialog, #task-dialog .task-form { scroll-padding-bottom: 88px; }
/* ===== end Chunk 196 ===== */

/* ===== Chunk 200 (gate 2, D10): the Goal, Milestone and Routine form gives way =====
   The page beside it narrows by the panel's width instead of sitting under it, as the
   calendar does for New task. Below 900 wide there's no room, so it overlays as before. */
@media (min-width: 900px) {
  body.goal-form-open .content > :is(#goal-view, #routine-view, #collection-view, #completed-view) { margin-right: var(--side-panel-w); }
}

/* ===== Chunk 201: Ed's review R1-R3 (6 Nov) ===== */
/* R1: a text field's focus is History's "Search weeks" look everywhere: the field's own
   border turns Ink with a 1px Ink ring and a soft 14% halo outside it, following the field's
   radius (Chunk 165's rule). Quick add's field drew that on its wrapper, but the global
   focus ring (2px Ink, !important) was also drawn on the bare input inside it - the "weird
   square thing". A field that lives inside a wrapper hands its focus to the wrapper: the
   input draws no outline of its own (the wrapper's transparent outline still shows in
   forced-colors mode). Contrast, measured: the Ink border on the white surface is 16.8:1 light,
   and the dark theme's Ink on its surface is 13.8:1 (WCAG 2.4.7, 2.4.11, 1.4.11). */
:is(.qa-input, .date-text, .log-stepper input):is(:focus-visible, .is-focus) { outline: 0 !important; box-shadow: none; }

/* R2: no "Mark done" chip on Today's tick. The hover and focus fill (solid Ink ring) stays;
   the button keeps its accessible name (aria-label) and has no tooltip. */
.tc-do::after, .tc-do:hover::after, .tc-do:focus-visible::after { content: none; display: none; }
/* R3: "a little bit wider so there's not the weird overlap with the circle around the mark
   done button ... slightly bigger segment of color." Chunk 195's slant: the colour began 26px
   in from the right at the top and 63.5px at the foot (58 degrees), and the 38px tick ring
   (right 8px) poked 3.9px past its slanted edge. The colour's edge moves 12px further left
   (26 -> 38px and 63.5 -> 75.5px; same angle, same colours), which leaves the ring 6px clear
   of it at its nearest point (3.9px over, now 6.1px of air). The grey's cut moves with it
   (47 -> 59px, 84.5 -> 96.5px) so the seam between them stays the 21px it was. It applies to
   every card that isn't done - planned, missed and Anytime, ticked or not - so slants line
   up down the list; a done card keeps its logo tick's own geometry (it has no ring). */
.today-card-task:not(.state-done) .tc-left { clip-path: polygon(0 0, calc(100% - 59px) 0, calc(100% - 96.5px) 100%, 0 100%); }
.today-card-task:not(.state-done) .tc-right { clip-path: polygon(calc(100% - 38px) 0, 100% 0, 100% 100%, calc(100% - 75.5px) 100%); }
/* ===== end Chunk 201 ===== */

/* ===== Chunk 204: one focus look for every text field (Ed, 6 Nov) ===== */
/* Ed: "make sure that any other applicable spots where there are text boxes are found,
   checked, and fixed." The audit (docs/chunk-204/README.md) drove every text entry in the
   app. The reference is quick add's field as Chunk 201 left it, which Ed called perfect
   (the field's own border turns Ink, a 1px Ink ring, a 14% halo to 4px, all following the
   field's own radius, and a transparent 2px outline that forced-colors mode still draws).
   165's direct fields, 165's wrappers and 201's bare inputs drew it by three separate rules;
   it now comes from two tokens and one rule, so a new field joins by being an input, a
   textarea, a select, a contenteditable, or the wrapper a field hands its focus to
   (.qa-field, .log-stepper, .date-field, .ev-amount). Quick add's look is unchanged, and so
   is History's search field (left to 165's rule: its own #id rule keeps its border at the
   resting grey, with the same ring and halo): neither moved. WCAG 2.4.7, 2.4.11, 1.4.11, measured: the Ink border
   and ring are 16.8:1 on the white surface in light and 13.8:1 on the dark surface (15.2 and
   15.3 on the page-coloured notes boxes). Buttons, chips, the round tick, checkboxes, radios
   and the colour swatch are not text boxes and keep the global 2px Ink ring. */
:root {
  --field-focus-line: var(--ink);        /* the 1px ring and the halo */
  --field-focus-border: var(--field-focus-line); /* quick add's look: the border turns Ink too */
  --field-focus-shadow: 0 0 0 1px var(--field-focus-line), 0 0 0 4px color-mix(in srgb, var(--field-focus-line) 14%, transparent);
}
:is(
  input:not([type=checkbox], [type=radio], [type=range], [type=button], [type=submit], [type=hidden]):not(.date-text, .qa-input, .log-stepper input, .ev-amount input, #hs-search),
  textarea, select, .rename-input, [contenteditable=true]
):is(:focus-visible, .is-focus):not(dialog),
.qa-field:has(:focus-visible), .log-stepper:has(input:focus-visible), .date-field:has(.date-text:focus-visible),
.ev-amount:has(input:focus-visible), #event-detail .ev-amount:has(input:focus-visible) {
  outline: 2px solid transparent !important;
  outline-offset: 0 !important;
  border-color: var(--field-focus-border) !important; /* beats the dialogs' own id-level resting borders, which had left task-form fields on grey */
  box-shadow: var(--field-focus-shadow);
}
/* The Event dialog's amount box is a wrapper too (an Ink border at its own id-level rule, with
   the bare input also drawing a ring inside it: two outlines). Its input hands the focus to it. */
.ev-amount input:is(:focus-visible, .is-focus) { outline: 0 !important; box-shadow: none; }
/* ===== end Chunk 204 ===== */

/* ===== Chunk 224 (Ed's walkthrough, 13 Nov): fixes. Keep this block together. ===== */
/* 1. The Event dialog keeps every line inside its box: a long unbroken word or web address in a linked entry's
   place or description (and a long title, owner or date line) wraps at the edge instead of running past it. */
#event-detail { min-width: 0; max-width: 100%; }
#event-detail :is(.ev-head, .ev-body, .ev-foot, .ev-ro, .ev-when, .ev-when > span, .ev-noteline) { min-width: 0; max-width: 100%; }
#event-detail :is(.ev-ro, .ev-head h2, .ev-owner, .ev-when > span, .ev-noteline, .ev-result, .ev-field-label) { overflow-wrap: anywhere; }
#event-detail .ev-foot { flex-wrap: wrap; }
#event-detail .ev-day { max-width: 100%; height: auto; min-height: 32px; text-align: left; }
/* ===== end Chunk 224 ===== */
/* ==== Chunk 226: the top switch's balance ====
   Drawn to the mark's own geometry: Today's dark pill and the Calendar's dark
   half sit the same 4px inside the ring on every side, ends included, so their
   curves are concentric with it (ring radius 22, pill radius 18). The zoom's
   light pill sits 2px inside the dark half on every side (radius 16), Year's
   end too. Before, Today's pill was 32px tall in a 36px slot: 6px of gap above
   and below but 4px at its end. Every segment is 36px tall; the zooms 32px, so
   their hover and focus rings match the pill. The highlight eases between the
   two heights on the switch's own spring. Widths and position: app.js
   (sizeSwitchParts, snapSwitch). */
.topbar .view-switch > [data-go], .topbar .cal-seg, .topbar .cal-seg > [data-go] { height: 36px; min-height: 0; }
.topbar .view-zooms button { height: 32px; justify-content: center; }
.view-thumb {
  height: 32px;
  transition: background-color var(--switch-ms) var(--switch-ease), opacity var(--dur-140) ease, height var(--switch-ms) var(--switch-ease);
}
.view-thumb:not(.on-dark) { height: 36px; }
@media (prefers-reduced-motion: reduce) { .view-thumb { transition: none; } }
/* ===== end Chunk 226 ===== */
/* ===== Chunk 227: composing polish (Ed, 13 Nov) =====
   Consistency fixes only; the compose structure is as Ed has it. */
/* 1. The parent in the left panel tree reads as the app's selected row (same track fill, radius,
      Ink and medium weight as .nav-goal.active), and the "New task" place in it is drawn as the
      calendar's draft is: a dashed edge in the parent's colour, task-block radius, no italic. */
body.adding .sidebar .nav-row.add-focus .nav-goal { background: var(--track); color: var(--ink); font-weight: var(--fw-medium); }
.nav-tree, .nav-tree-branch { border-left: 1px solid var(--line); }
.nav-tree { margin-left: 10px; } /* its stem under the parent row's colour bar */
.nav-tree-node::before { border-top: 1px solid var(--line); }
.nav-tree-node.selected { font-weight: var(--fw-medium); }
.nav-tree-new {
  font-style: normal; font-weight: var(--fw-medium); color: var(--ink); border-radius: var(--r-block);
  background: color-mix(in srgb, var(--goal) 10%, var(--surface));
  box-shadow: none; outline: 1.5px dashed var(--goal); outline-offset: -1.5px;
}
/* 2. The repeat range line: centred in the gap above what it marks, with even space above and
      below (Week: the 20px gap under the title; Month: the 6px gap between rows; Day: the card's
      top padding), solid in the Task's colour, starting and ending at its dots. A side that runs
      on past what's shown ends in a short dashed tail (the app's "carries on" mark, as the draft's
      dashed edge) rather than a soft fade. */
.range-layer.range-week { top: -11.5px; }
.range-layer.range-month { top: -4.5px; }
.range-layer.range-day { top: 6.5px; }
.range-line { background: var(--range); border-radius: var(--r-dash); }
.range-line.fade-r { mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent calc(100% - 40px)), repeating-linear-gradient(to left, #000 0 6px, transparent 6px 10px); }
.range-line.fade-l { mask-image: linear-gradient(to left, #000 calc(100% - 40px), transparent calc(100% - 40px)), repeating-linear-gradient(to right, #000 0 6px, transparent 6px 10px); }
.range-line.fade-l.fade-r {
  mask-image: linear-gradient(to right, transparent 40px, #000 40px, #000 calc(100% - 40px), transparent calc(100% - 40px)),
    repeating-linear-gradient(to right, #000 0 6px, transparent 6px 10px);
}
/* 3. Its Starts and Ends words: the app's small pill (medium weight, Text 2), knocked out of the
      line on the surface it sits on instead of a hairline box squeezed over it. */
.range-label {
  top: -7.5px; height: 18px; padding: 0 var(--sp-1-5); border: 0;
  font-weight: var(--fw-medium); color: var(--text-2); background: var(--page);
}
.range-layer.range-day .range-label { background: var(--surface); }
.range-label.left { margin-left: -4px; }
.range-label.right { margin-left: 4px; }
.range-handle::before, .range-dot { box-shadow: 0 0 0 2px var(--page); }
.range-layer.range-day .range-handle::before, .range-layer.range-day .range-dot { box-shadow: 0 0 0 2px var(--surface); }
/* 4. The draft: in its parent's colour, as user-structure says (a faint tint, not the grey of a
      planned block), its title at full strength, its dashed edge kept (Week's dark today column keeps
      its own block colour: its rule is more specific). */
#calendar-grid .cal-entry.draft-preview { background: color-mix(in srgb, var(--goal, var(--ink)) 10%, var(--surface)); }
#calendar-grid.composing-fade .cal-entry.draft-preview { opacity: 1; }
/* ===== end Chunk 227 ===== */
/* ===== Chunk 223: seams and edge bleed (Ed, 13 Nov) ===== */
/* "I can see edges of the tick and edges of the slant and edges of the border and white
   sticking through." One rule for every layered shape below: the colour that surrounds a
   shape is the bottom layer, and each visible edge is drawn once, by the shape on top, over
   a layer that runs on underneath it. Two shapes never butt against each other at the same
   line (each edge is anti-aliased against the other's and the background shows through),
   and nothing relies on a box landing on a whole device pixel. The approved look (Chunks
   195 and 201: the slants, the tick, the 1px owner-colour border, the colours) is unchanged.
   Details and before/after crops: docs/chunk-223/README.md. */

/* Today's task card. The card's own background is the owner colour, the same as its 1px border,
   so the sub-pixel strip between the border and the shapes inside (white at 1.25x, 1.5x and most
   zooms) and the inner rounded corners are the owner colour too. Then, bottom to top: .tc-right
   (the colour, faded on a past row), the white seam (the card's ::before, cut at the colour's
   slant), the grey (.tc-left, cut at its own slant), and on a done card the logo tick. Each slant
   is drawn once, by the shape on top; the layer under it runs on past the edge. */
.today-card-task { background: var(--goal); isolation: isolate; }
.today-card-task .tc-right { z-index: -1; }
.today-card-task:not(.state-done) .tc-right { clip-path: polygon(calc(100% - 48px) 0, 100% 0, 100% 100%, calc(100% - 85.5px) 100%); } /* 10px under the white seam */
.today-card-task:not(.state-done)::before {
  content: ""; position: absolute; inset: 0; background: var(--surface);
  clip-path: polygon(0 0, calc(100% - 38px) 0, calc(100% - 75.5px) 100%, 0 100%); /* 201's colour edge */
}
/* Chunk 147's past rows faded the colour slice to 55% over white: the same colour, mixed solid,
   on .tc-right only; the border and the strip inside it keep the full colour, as before. */
.today-slot.is-past .today-card-task .tc-right { background: color-mix(in srgb, var(--goal) 55%, var(--surface)); }
/* A done card: the tick is drawn at the card's full inner height, at its own proportions (it was
   82.8 x 56px, letterboxed in the 58px space, so its long arm ran 2px short at the top and at a
   different angle from the slants: the notch and the jagged edge). At 58px tall it is 85.8px wide,
   the same mark 3.6% larger, from the same left edge. Its long arm is now the slant: the grey runs
   on under it to the arm's middle (134.8/98.6px), and the colour runs on under the grey, so
   the tick draws both slanted edges itself, over grey on one side and colour on the other, and
   grey and colour never butt (not even while the tick pops in). */
.today-card-task.state-done .tc-left { clip-path: polygon(0 0, 134.8px 0, 98.6px 100%, 0 100%); }
.today-card-task.state-done .tc-right { clip-path: polygon(124.8px 0, 100% 0, 100% 100%, 88.6px 100%); }
.today-card-task .tc-tick { top: 0; bottom: 0; height: auto; width: auto; aspect-ratio: 1653 / 1118; }

/* Event dialog. Its 6px owner-colour band was the header's top border, drawn over the dialog's
   own white background with the same 16px rounded corner, so both edges anti-aliased against
   the backdrop and the white showed as a pale rim along the band's top and round its corners.
   Now one layer draws the rounded shape: the dialog itself is transparent, #event-detail paints
   the band and the surface in one background, and the header's tint stops at its padding box
   (its 6px border is still there for spacing, now transparent over the band). The colour runs
   16px down, the corner's depth, so the band still curves into both corners as the border did
   (the header's rounded padding box draws that curve over it). Same look. */
#event-dialog { background: transparent; }
#event-detail { background: linear-gradient(var(--goal) 0 var(--r-dialog), var(--surface) var(--r-dialog)); }
#event-detail .ev-head { border-top-color: transparent; background-clip: padding-box; }
/* Forced colours drop background images: the dialog takes the system's Canvas so it isn't see-through. */
@media (forced-colors: active) { #event-dialog { background: Canvas; } }

/* Focus rings in the left panel's lists. Each list scrolls (overflow-y: auto), which clips what
   draws outside it, so a focused row's 2px ring (2px out) lost its sides, and the first row its
   top: only the corners showed. The lists get 4px of room inside, given back outside, so nothing
   moves and the whole ring shows at every scale. */
#sidebar-goals, #sidebar-routines, #sidebar-collections { padding: var(--sp-1); margin: calc(-1 * var(--sp-1)); }
/* The same clip elsewhere, found by focusing every control on each screen: To place's rows and
   its Waiting button, and Day's Next up card (the side column clips). They join the rows that
   already draw the ring inside themselves (Chunk 147's rule above), so it's whole. (Pennants and
   Year's month names are clipped too but keep their outside ring: inside, it would sit on a
   goal colour or on the letters. Flagged in the build notes.) */
:is(.tray-wait, .place-open, .day-next.side-card) { --focus-offset: calc(-1 * var(--focus-width)); }
/* Drawn inside, the ring sits on the element's own fill: Day's Next up card is Ink in light mode,
   so its ring takes the on-feature colour, as the rings inside it already do (WCAG 1.4.11). */
.day-next.side-card:is(:focus-visible, .is-focus) { --focus-color: var(--on-feature); }
/* ===== end Chunk 223 ===== */

/* ===== Chunk 230: polish pass on the small leftovers (13 Nov) =====
   Look unchanged except the five things below, each Ed's call or a left-over from 223, 226, 227. */
/* 1. Missed is grey in Week review's year heatmap, as everywhere else (Ed, 5 Nov: "Do stripes for
      all grey"; orange is the logo's full stop and nothing else). A cell is too small for stripes,
      so it takes the stripes' darker grey. */
.rv-cell.has-miss { background: var(--missed-grey-b); }
.rv-key.is-miss i { background: var(--missed-grey-b); }
/* Year view's own missed day cell and its key too (same grey, light and dark). */
.year-cell.has-miss, .year-key .key-miss { background: var(--missed-grey-b); }
/* 2. Focus rings that a scrolling or clipping parent cut off (Chunk 223's left for a call).
      Pennants sit flush in a clipped day, so their ring is drawn inside, as the switch's is. Year's
      scroller gets 4px at the sides and 2px at the top, so the first month name's ring (and a day
      at its right edge) has the room the scroller used to clip. */
.pennant { --focus-offset: calc(-1 * var(--focus-width)); }
#calendar-grid.year { padding: var(--sp-0-5) var(--sp-1) 0; }
/* A Year day the keyboard scrolls to keeps its whole ring clear of the scroller's edge. */
#calendar-grid.year { scroll-padding-block: var(--sp-2); }
/* 3. Week titles break at spaces, never inside a word (a word longer than its box is clipped). */
#calendar-grid.week-stack .week-day-events .cal-entry[data-density="chip"] .entry-title { overflow-wrap: normal; word-break: normal; hyphens: manual; }
/* 4. Dark mode: the left panel's selected row is one clear step off the panel, as light mode's is
      (light: Page to Track is a 9-level step; dark's Track is 4, so it takes Divider, 18). */
:root[data-theme="dark"] :is(.sidebar .nav-goal.active, .sidebar.expanded .nav-goal.active, .sidebar .nav-entry.active, body.adding .sidebar .nav-row.add-focus .nav-goal) { background: var(--divider); }
/* ===== end Chunk 230 ===== */

/* ===== Chunk 238: the Calendar's small fixes (section check 02, bugs 3, 5, 6, 8, 9) ===== */
/* Bug 3: Ends before Starts, said under Ends in the Move panel's own look (a "!" and the reason, ink on the panel). */
.tf-date-error { margin: var(--sp-1) 0 0; font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--ink); }
.tf-date-error::before { content: "! "; font-weight: var(--fw-bold); }
.tf-date-error[hidden] { display: none; }
.tf-field .date-text[aria-invalid] { border-color: var(--ink); }
/* Bug 6: the header's words aren't a place to select (a double-click on an entry opens the dialog under the pointer); fields stay selectable. */
#event-detail :is(.ev-head-meta, #event-dialog-title, .ev-when) { user-select: none; }
/* Bug 9: Week's linked entry keeps its length whole; the feed name, then the time, give way first (as on Week's own entries). */
#calendar-grid.week-stack .linked-event .grid-sub:not(:empty) { display: flex; align-items: baseline; }
#calendar-grid.week-stack .linked-event .grid-sub .linked-icon { flex: none; }
#calendar-grid.week-stack .linked-event .grid-lead { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#calendar-grid.week-stack .linked-event .grid-dur { flex: none; white-space: pre; }
/* Bug 8: reduced motion cuts the top switch's labels, icons and fades; nothing slides. */
@media (prefers-reduced-motion: reduce) {
  .view-switch, .view-switch button, .view-switch button > *, .view-zoom-label, .view-zooms svg, .topbar .view-switch { transition: none !important; }
}
/* Bug 5: Day's Starts / Ends chips (24px, on the line 6.5px into the card) sat 4.5px above the card top edge and were cut (the chip itself is 7px above its box); keep them wholly inside. */
.range-layer.range-day .range-edge { top: 3px; }

/* Chunk 246 (Ed, 14 Nov): dark mode's today cell (Month) and column (Week) keep their fill but
   get a thin 2px ring in --muted: 5.4:1 on the --feature fill and 6.7:1 on the page (1.4.11
   needs 3:1). Inset, so it never clips at the cell edge or moves layout; the focus ring is an
   offset outline in --on-feature, so the two read as different things. Light mode unchanged. */
:root[data-theme="dark"] #calendar-grid .month-day.today,
:root[data-theme="dark"] #calendar-grid.week-stack .day.today { box-shadow: inset 0 0 0 2px var(--muted); }
