/* Horizon — "The Great Wave off Kanagawa" (Hokusai, c. 1831).
 *
 * The print works because it is disciplined: four or five colours, enormous
 * flat fields, and one bright mass — the foam — that the eye cannot avoid.
 * A dashboard wants exactly the same behaviour, so the mapping is literal:
 *
 *   deep Prussian blue (bero-ai) ... the page and its cards, banded darker
 *                                    towards the bottom like the trough
 *   unbleached paper cream ....... all type, and the urgent strip itself
 *   the foam crest ............... the urgent strip: the one light mass on a
 *                                  dark page, edged with scallops
 *   ochre sky band ............... "needs Sam" accents
 *   faded rose ................... errors (the print has no red; it has this)
 *   Mount Fuji ................... the brand mark, small and far away
 *
 * Nothing here uses a colour that is not in the woodblock. Old variable names
 * are kept and repointed so no markup depends on the palette's history.
 */

:root {
  /* Prussian blue, in the dilutions the printer would have mixed */
  --deep: #04121f;
  --sea: #072437;
  --night: #061d2e;      /* page ground */
  --night-2: #0a2c45;    /* raised sheet (the event drawer) */
  --card: #0b2a42;
  --card-2: #113c58;
  --swell: #1d5a7a;
  --shallow: #6fa8c4;
  --pale: #a8c3d6;
  --sky: #0b3350;        /* the band at the very top of the page */
  --scroll-ground: #0d2c44;

  /* the paper itself */
  --foam: #f2ead6;
  --paper: #e2d6b8;
  --ink: #f2ead6;
  --ink-2: #c3d0da;
  --muted: #8fa6ba;
  --ink-rgb: 242, 234, 214;   /* every hairline and overlay is this, thinned */

  /* the sky, and the one warm note */
  --ochre: #d9af63;
  --rose: #c98e88;
  --jade: #86ad98;
  --on-accent: #241505;  /* type on ochre, rose or jade */

  /* The one bright mass — the foam. It is the page inverted, whichever way the
     page is running: cream on a dark ground, ink on a pale one. Everything
     sitting on it reads --on-mass, so the strip, the chips and the primary
     buttons all turn over together when the theme does. */
  --mass: #f2ead6;
  --mass-2: #e2d6b8;
  --on-mass: #0a2a44;
  --on-mass-strong: #0e3350;
  --on-mass-muted: #1d5a7a;
  --on-mass-soft: #40708c;
  --on-mass-rgb: 10, 42, 68;
  --on-mass-field: rgba(255, 255, 255, 0.6);
  --mass-sheen: linear-gradient(90deg, #ded1b2, #eee3c8, #ded1b2);

  --shadow: #000;
  --shadow-soft: rgba(0, 0, 0, 0.4);

  /* the key block: a hairline, never a heavy border */
  --line: rgba(var(--ink-rgb), 0.14);
  --line-strong: rgba(var(--ink-rgb), 0.28);

  /* legacy names, repointed */
  --amber: var(--ochre);
  --teal: var(--shallow);
  --lilac: var(--pale);
  --coral: var(--rose);
  --green: var(--jade);

  --radius: 16px;
  --gap: 14px;
  --capture-h: 76px;
  --font: "Inter", ui-sans-serif, -apple-system, "SF Pro Text", system-ui, sans-serif;

  /* the foam edge, and the seigaiha wave-scale pattern */
  /* Hokusai's crest is not a scallop border — the drops vary, and a few reach
     down as claws. Uneven depths across a long tile keep it from reading as
     lace. */
  --foam-edge: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 14' preserveAspectRatio='none'%3E%3Cpath d='M0 0 H120 V4 C114 14 110 12 106 4 C101 13 97 11 92 4 C88 9 84 9 80 4 C74 15 70 12 66 4 C61 11 57 11 53 4 C48 14 44 12 40 4 C35 9 31 9 27 4 C22 15 18 12 14 4 C9 11 5 11 0 4 Z' fill='%23f2ead6'/%3E%3C/svg%3E");
  --seigaiha: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='20' viewBox='0 0 40 20'%3E%3Cg fill='none' stroke='%23f2ead6' stroke-width='1'%3E%3Cpath d='M0 20 A20 20 0 0 1 40 20'/%3E%3Cpath d='M6 20 A14 14 0 0 1 34 20'/%3E%3Cpath d='M12 20 A8 8 0 0 1 28 20'/%3E%3Cpath d='M17 20 A3 3 0 0 1 23 20'/%3E%3C/g%3E%3C/svg%3E");
}

/* ------------------------------------------------------------ light mode
 *
 * The same woodblock, printed the way it actually exists: ink on paper. Nothing
 * new is introduced — the blues become type, the paper becomes ground, and the
 * accents move to their deeper dilutions so they still carry on cream.
 *
 * The foam is the part that has to think. On a dark page it is the one light
 * mass; on a pale page a light mass is invisible, so it inverts and becomes the
 * one *dark* mass. That keeps Hokusai's actual discipline — a single field the
 * eye cannot avoid — rather than the literal colour it happened to be.
 */
:root[data-theme="light"] {
  --deep: #d8cdb0;
  --sea: #e8dfc7;
  --night: #f4eeda;
  --night-2: #fffbef;
  --card: #fbf6e6;
  --card-2: #efe7d1;
  --swell: #2d6f92;
  --shallow: #1d5a7a;
  --pale: #345f7d;
  --sky: #fffdf2;
  --scroll-ground: #f6f0dd;

  --foam: #f2ead6;
  --paper: #e2d6b8;
  --ink: #0a2a44;
  --ink-2: #234b66;
  --muted: #4e6e85;
  --ink-rgb: 10, 42, 68;

  /* Deeper dilutions than the dark theme's: the sky ochre straight off the
     block is 3.5:1 on cream, which is a caption nobody over forty can read. */
  --ochre: #8a5f1e;
  --rose: #a35550;
  --jade: #3f7361;
  --on-accent: #f7f2e2;

  --mass: #0b2a42;
  --mass-2: #061d2e;
  --on-mass: #f2ead6;
  --on-mass-strong: #fbf5e3;
  --on-mass-muted: #a8c3d6;
  --on-mass-soft: #8fa6ba;
  --on-mass-rgb: 242, 234, 214;
  --on-mass-field: rgba(10, 42, 68, 0.35);
  --mass-sheen: linear-gradient(90deg, #0a2740, #14405f, #0a2740);

  --shadow: rgba(10, 42, 68, 0.38);
  --shadow-soft: rgba(10, 42, 68, 0.22);

  /* The crest breaks downward out of the strip, so it is the strip's colour. */
  --foam-edge: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 14' preserveAspectRatio='none'%3E%3Cpath d='M0 0 H120 V4 C114 14 110 12 106 4 C101 13 97 11 92 4 C88 9 84 9 80 4 C74 15 70 12 66 4 C61 11 57 11 53 4 C48 14 44 12 40 4 C35 9 31 9 27 4 C22 15 18 12 14 4 C9 11 5 11 0 4 Z' fill='%230b2a42'/%3E%3C/svg%3E");
  --seigaiha: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='20' viewBox='0 0 40 20'%3E%3Cg fill='none' stroke='%230a2a44' stroke-width='1'%3E%3Cpath d='M0 20 A20 20 0 0 1 40 20'/%3E%3Cpath d='M6 20 A14 14 0 0 1 34 20'/%3E%3Cpath d='M12 20 A8 8 0 0 1 28 20'/%3E%3Cpath d='M17 20 A3 3 0 0 1 23 20'/%3E%3C/g%3E%3C/svg%3E");
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* The print's vertical gradation: pale-ish sky at the top, the trough below. */
body {
  font-family: var(--font);
  background:
    linear-gradient(180deg, var(--sky) 0%, var(--night) 34%, var(--sea) 72%, var(--deep) 100%) fixed;
  color: var(--ink);
  min-height: 100dvh;
  padding: max(env(safe-area-inset-top), 12px) 14px calc(var(--capture-h) + env(safe-area-inset-bottom) + 18px);
  font-size: 15px;
  line-height: 1.45;
}

[hidden] { display: none !important; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
a { color: inherit; }
h1, h2, h3 { font-weight: 650; letter-spacing: -0.015em; }

/* ------------------------------------------------------------------ topbar */
.topbar {
  position: relative;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 2px 16px;
}
/* Wave scales, barely there — texture, not decoration. */
.topbar::before {
  content: ""; position: absolute; inset: -8px -14px 8px;
  background-image: var(--seigaiha), var(--seigaiha);
  background-position: 0 0, 20px 10px;
  opacity: 0.07;
  pointer-events: none;
  mask-image: linear-gradient(180deg, #000, transparent);
  -webkit-mask-image: linear-gradient(180deg, #000, transparent);
}
.brand { display: flex; align-items: center; gap: 11px; position: relative; }
.brand h1 { font-size: 19px; }

/* Fuji: small, distant, snow-capped — the calm thing behind the wave. */
.fuji {
  position: relative;
  width: 30px; height: 21px; flex: none;
  background: linear-gradient(180deg, #2c5f7e 0%, #14405f 55%, #0e3350 100%);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
.fuji::after {
  content: ""; position: absolute; inset: 0;
  background: var(--foam);
  clip-path: polygon(50% 0, 74% 46%, 62% 38%, 52% 52%, 42% 36%, 30% 48%);
}

.clock { font-size: 12px; color: var(--muted); white-space: nowrap; }
.topbar-actions { display: flex; align-items: center; gap: 8px; position: relative; }
.freshness { font-size: 11px; color: var(--muted); text-align: right; max-width: 68px; line-height: 1.25; }
.icon-btn {
  width: 36px; height: 36px; border-radius: 11px;
  background: rgba(var(--ink-rgb), 0.06);
  border: 1px solid var(--line);
  display: grid; place-items: center;
  font-size: 16px; color: var(--ink-2); text-decoration: none;
}
.icon-btn:active { transform: scale(0.94); }
.icon-btn.spinning { animation: spin 0.9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.text-btn { font-size: 12px; text-decoration: underline; text-underline-offset: 3px; }

/* ------------------------------------------------ urgent strip = the foam */
/* The one light mass on a dark page. Inverted on purpose: in the print the
   foam is the paper, and it is the only thing that stops your eye. */
.urgent {
  position: sticky; top: 0; z-index: 20;
  background: linear-gradient(180deg, var(--mass) 0%, var(--mass-2) 100%);
  color: var(--on-mass);
  border-radius: var(--radius) var(--radius) 4px 4px;
  padding: 13px 16px 15px;
  margin-bottom: calc(var(--gap) + 6px);
  box-shadow: 0 16px 34px -20px var(--shadow);
}
/* the scalloped crest, breaking below the strip */
.urgent::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -11px; height: 14px;
  background-image: var(--foam-edge);
  background-size: 120px 14px;
  background-repeat: repeat-x;
  filter: drop-shadow(0 4px 6px var(--shadow-soft));
}
.urgent-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 9px; }
.urgent-head h2 { font-size: 11px; text-transform: uppercase; letter-spacing: 0.16em; color: var(--on-mass-muted); }
.urgent .text-btn { color: var(--on-mass-soft); }
.urgent-list { list-style: none; display: grid; gap: 10px; }
.urgent-list li { display: grid; grid-template-columns: 18px 1fr; gap: 10px; align-items: start; }
.urgent-list .rank {
  color: var(--on-mass-strong); font-weight: 800; font-variant-numeric: tabular-nums;
  font-size: 15px; line-height: 1.35;
}
.urgent-list .u-title { font-weight: 640; color: var(--on-mass); }
.urgent-list .u-why { font-size: 12.5px; color: var(--on-mass-soft); }
/* Two ways out of every urgent item: go deal with it, or say it's handled. */
.urgent-actions { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.u-btn {
  font-size: 12px; font-weight: 600; padding: 4px 11px; border-radius: 999px;
  /* Light ink by default: .u-btn started life inside the cream urgent strip and
     kept that strip's near-black navy everywhere else, where it is dark on
     dark. The strip keeps its own colours a few rules further down. */
  border: 1px solid var(--line-strong); color: var(--ink); text-decoration: none;
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  background: none; font-family: inherit;
}
.u-btn.go { background: var(--on-mass-strong); color: var(--mass); border-color: var(--on-mass-strong); }
.u-btn:active { opacity: 0.65; }
.skeleton {
  height: 34px; border-radius: 8px;
  background: var(--mass-sheen);
  background-size: 200% 100%; animation: shimmer 1.4s ease infinite;
}
@keyframes shimmer { to { background-position: -200% 0; } }

/* -------------------------------------------------------------------- grid */
/* align-items: start keeps every card its own natural height — otherwise the
   tallest in a row stretches its neighbours and the page balloons. */
.grid { display: grid; gap: var(--gap); align-items: start; }

/* Two columns on desktop: the left one is the narrative (what happened, what's
   moving, life, money), the right one the two live feeds. On a phone the
   columns dissolve and cards reorder — Calendar and Inbox must not end up below
   Money on the one screen Sam actually reads in the morning. */
.col { display: contents; }
.grid.columns .card { order: var(--order, 99); }

@media (min-width: 900px) {
  .grid.columns { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }
  .col { display: flex; flex-direction: column; gap: var(--gap); min-width: 0; }
  .grid.columns .card { order: 0; }
}
.card {
  background: linear-gradient(180deg, rgba(var(--ink-rgb), 0.045), rgba(var(--ink-rgb), 0.012)), var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
  min-width: 0;
}
.card > header {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-bottom: 10px; padding-bottom: 9px;
  border-bottom: 1px solid var(--line);
}
.card > header h2 { font-size: 14px; }

/* The whole header is the collapse target — a small caret would be a poor tap
   target on a phone. Collapsed state is remembered per panel. */
.card-toggle { display: flex; align-items: center; gap: 8px; flex: 1; text-align: left; padding: 2px 0; }
.card-toggle .caret { font-size: 10px; color: var(--muted); transition: transform 0.18s ease; }
.card-toggle[aria-expanded="false"] .caret { transform: rotate(-90deg); }
.card.collapsed > header { margin-bottom: 0; padding-bottom: 0; border-bottom: 0; }
.card.collapsed .card-body,
.card.collapsed .filters { display: none; }

/* A section is its own band of the page, titled like a chapter. */
.section-head {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.18em;
  color: var(--shallow); margin: 26px 2px 12px;
  display: flex; align-items: center; gap: 10px;
}
.section-head::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* --------------------------------------------------------------- pickers */
.filters { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px; margin-bottom: 10px; }
.picker { position: relative; }
.picker > summary {
  list-style: none; cursor: pointer;
  font-size: 12px; padding: 5px 11px; border-radius: 999px;
  border: 1px solid var(--line-strong); background: rgba(var(--ink-rgb), 0.05); color: var(--ink-2);
  white-space: nowrap;
}
.picker > summary::-webkit-details-marker { display: none; }
.picker > summary::after { content: " ▾"; color: var(--muted); }
.picker[open] > summary { background: var(--mass); color: var(--on-mass); border-color: var(--mass); }
.picker-menu {
  position: absolute; z-index: 15; top: calc(100% + 6px); left: 0; min-width: 190px;
  background: var(--night-2); border: 1px solid var(--line-strong); border-radius: 12px;
  padding: 6px; box-shadow: 0 18px 34px -20px var(--shadow);
}
.picker-menu label {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 9px; border-radius: 8px; font-size: 13px; cursor: pointer;
}
.picker-menu label:hover { background: rgba(var(--ink-rgb), 0.06); }
.picker-menu input { accent-color: var(--ochre); width: 15px; height: 15px; }
.picker-menu .count { margin-left: auto; color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.picker-menu .group-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--muted); padding: 8px 9px 4px;
}
.picker-menu .hint { font-size: 11.5px; color: var(--muted); padding: 6px 9px 8px; line-height: 1.35; }

/* Segmented control: three states, one tap, no dropdown to open first. */
.segmented { display: inline-flex; border: 1px solid var(--line-strong); border-radius: 999px; padding: 2px; gap: 2px; }
.segmented button { font-size: 12px; padding: 4px 12px; border-radius: 999px; color: var(--ink-2); }
.segmented button[aria-selected="true"] { background: var(--mass); color: var(--on-mass); font-weight: 640; }

.stepper { display: inline-flex; align-items: center; gap: 2px; border: 1px solid var(--line-strong); border-radius: 999px; padding: 2px; }
.stepper button { font-size: 13px; padding: 4px 10px; border-radius: 999px; color: var(--ink-2); line-height: 1.2; }
.stepper button:active { background: rgba(var(--ink-rgb), 0.1); }
.stepper .today-btn { font-size: 12px; }

/* --------------------------------------------------------- calendar views */
.cal-title { font-size: 13px; font-weight: 640; margin-bottom: 2px; }
.cal-next {
  display: flex; align-items: baseline; gap: 8px;
  background: rgba(217, 175, 99, 0.1); border: 1px solid rgba(217, 175, 99, 0.3);
  border-radius: 12px; padding: 9px 12px; margin-bottom: 4px;
}
.cal-next .lead { font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ochre); }
.cal-next .what { font-size: 13.5px; font-weight: 600; }
.cal-next .in { margin-left: auto; font-size: 12px; color: var(--ochre); white-space: nowrap; }

/* ------------------------------------------------------------- month view */
/* Each week is its own grid: row 1 is the date numbers, the rows under it are
   lanes. A multi-day event claims a lane across the columns it covers, so a
   trip reads as one continuous bar the way it does in Outlook — the previous
   grid bucketed everything by start day and a five-day trip appeared once. */
.month { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
.month .dow {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--muted); padding: 0 0 5px 3px;
}
.mweek {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  grid-template-rows: 18px repeat(var(--rows, 1), 17px);
  gap: 2px 2px;
  min-height: 74px;
  align-content: start;
}
/* The cell is only a background — it spans every lane so the day reads as one
   block, and sits behind the bars that cross it. */
.mcell {
  grid-row: 1 / -1;
  border-radius: 8px;
  background: rgba(var(--ink-rgb), 0.035);
}
.mcell.other { background: rgba(var(--ink-rgb), 0.015); }
.mcell.today { background: rgba(217, 175, 99, 0.08); box-shadow: inset 0 0 0 1px var(--ochre); }

.mday-num {
  justify-self: start; align-self: start;
  font: inherit; font-size: 11px; font-variant-numeric: tabular-nums;
  color: var(--muted); background: none; border: 0; cursor: pointer;
  padding: 1px 5px; border-radius: 5px; line-height: 1.35;
}
.mday-num.other { opacity: 0.45; }
.mday-num.is-today { color: var(--ochre); font-weight: 700; }
.mday-num:hover { background: rgba(var(--ink-rgb), 0.1); color: var(--ink); }

.mevent {
  display: flex; align-items: center; gap: 4px; min-width: 0;
  font: inherit; font-size: 10.5px; text-align: left; cursor: pointer;
  padding: 0 5px; border-radius: 4px; height: 17px;
  border: 0; border-left: 2px solid var(--shallow);
  background: rgba(111, 168, 196, 0.14); color: var(--ink-2);
  overflow: hidden;
}
.mevent:hover { background: rgba(111, 168, 196, 0.26); color: var(--ink); }
.mevent.is-span { font-weight: 560; }
.mevent.is-allday.is-span { border-left-width: 3px; }
/* A bar that began last week or runs into the next loses the cap on that side,
   so a trip does not look like it restarts every Monday. */
.mevent.from-before { border-left-width: 0; border-top-left-radius: 0; border-bottom-left-radius: 0; }
.mevent.into-next { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.mtime { font-size: 9.5px; color: var(--muted); font-variant-numeric: tabular-nums; flex: none; }
.mtitle { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

.mmore {
  font: inherit; font-size: 9.5px; text-align: left; cursor: pointer;
  background: none; border: 0; color: var(--shallow); padding: 0 5px;
  align-self: center;
}
.mmore:hover { color: var(--ink); }

.mevent.acct-shallow { border-left-color: var(--shallow); background: rgba(111, 168, 196, 0.14); }
.mevent.acct-ochre   { border-left-color: var(--ochre);   background: rgba(217, 175, 99, 0.14); }
.mevent.acct-jade    { border-left-color: var(--jade);    background: rgba(134, 173, 152, 0.14); }
.mevent.acct-rose    { border-left-color: var(--rose);    background: rgba(201, 142, 136, 0.14); }
.mevent.acct-pale    { border-left-color: var(--pale);    background: rgba(168, 195, 214, 0.14); }
.mevent.acct-slate   { border-left-color: var(--pale);    background: rgba(29, 90, 122, 0.24); }
.mevent.acct-muted   { border-left-color: var(--muted);   background: rgba(var(--ink-rgb), 0.07); }

/* A phone cannot read three titles across a seventh of the screen, so the bars
   become bands. A trip still spans its days — that is the shape worth keeping. */
@media (max-width: 700px) {
  .mweek { grid-template-rows: 15px repeat(var(--rows, 1), 6px); min-height: 46px; gap: 1px; }
  .mevent { height: 6px; padding: 0; border-left-width: 0; border-radius: 2px; }
  .mtime, .mtitle, .mmore { display: none; }
}

.merged { font-size: 10px; color: var(--muted); }
.hidden-note { font-size: 11.5px; color: var(--muted); padding-top: 6px; }

/* -------------------------------------------------------------- inbox groups */
.mail-group summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 8px;
  padding: 7px 0; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--ink-2);
}
.mail-group summary::-webkit-details-marker { display: none; }
.mail-group summary::before { content: "▸"; font-size: 9px; color: var(--muted); transition: transform 0.15s ease; }
.mail-group[open] summary::before { transform: rotate(90deg); }
.mail-group summary .count { margin-left: auto; color: var(--muted); font-variant-numeric: tabular-nums; }
/* Used in the inbox groups, the tag picker and the tag editor. */
.kind-dot { width: 6px; height: 6px; border-radius: 50%; flex: none; display: inline-block; }
.kind-person { background: var(--ochre); }
.kind-invite { background: var(--shallow); }
.kind-newsletter { background: var(--pale); }
.kind-notification { background: var(--muted); }
.kind-security { background: var(--rose); }
/* Finances is the sea itself: in-palette, clearly not one of the other five,
   and deliberately not jade — jade means done/good everywhere else. */
.kind-finances { background: var(--swell); }

/* A newsletter that is only selling is still listed — just visibly demoted. */
.row.dim { opacity: 0.55; }
.value { font-size: 10px; padding: 2px 7px; border-radius: 999px; white-space: nowrap; }
.value-useful { background: rgba(134, 173, 152, 0.16); color: var(--jade); }
.value-skim { background: rgba(var(--ink-rgb), 0.07); color: var(--muted); }
.value-selling { background: rgba(201, 142, 136, 0.14); color: var(--rose); }
.value-replied { background: rgba(134, 173, 152, 0.16); color: var(--jade); }
.value-rsvp-open { background: rgba(217, 175, 99, 0.18); color: var(--ochre); }
/* Sam's own words on the Activity feed — quoted, wrapped, never truncated to one line. */
.activity-verbatim { white-space: normal; font-style: italic; }

/* --------------------------------------------------- inbox: the two axes */
/* Account is position (the rail, shared with the calendar); kind is mark (this
   strip). Both were nested lists before, which is why a full inbox read as one
   undifferentiated column. */
.kind-strip {
  display: flex; flex-wrap: wrap; gap: 5px;
  padding-bottom: 10px; margin-bottom: 2px;
  border-bottom: 1px solid var(--line);
}
.kind-chip {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 5px 10px; border-radius: 999px;
  background: transparent; border: 1px solid var(--line);
  color: var(--ink-2); font-family: inherit; font-size: 12px;
  cursor: pointer; transition: background 0.12s ease, border-color 0.12s ease;
}
.kind-chip .kind-glyph { font-size: 12px; line-height: 1; }
.kind-chip .count { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.kind-chip:hover { border-color: var(--line-strong); }
.kind-chip.is-on { background: rgba(var(--ink-rgb), 0.09); border-color: var(--line-strong); color: var(--ink); }
/* Empty kinds stay on the strip rather than vanishing: the shape of the inbox
   should not change just because a filter is on. */
.kind-chip.is-quiet { opacity: 0.4; }
.kind-chip.kind-tint-person .kind-glyph { color: var(--ochre); }
.kind-chip.kind-tint-invite .kind-glyph { color: var(--shallow); }
.kind-chip.kind-tint-newsletter .kind-glyph { color: var(--pale); }
.kind-chip.kind-tint-notification .kind-glyph { color: var(--muted); }
.kind-chip.kind-tint-security .kind-glyph { color: var(--rose); }
.kind-chip.kind-tint-finances .kind-glyph { color: var(--shallow); }

/* The row is a three-column grid, and the two action buttons were its fourth
   and fifth children — so they wrapped onto a second line under the sender and
   Sam could barely find them. They belong inside the right-hand cell. */
.mail-right { display: inline-flex; align-items: center; gap: 4px; }

/* Two row actions that used to look identical. Archive is the one that moves
   mail, so it carries the colour that already means "handled" everywhere else;
   snooze stays quiet because it only defers. */
.row-x.archive { color: var(--jade); }
.row-x.snooze { color: var(--muted); }
.highlights { margin: 4px 0 2px; padding-left: 15px; }
.highlights li { font-size: 12px; color: var(--ink-2); line-height: 1.4; }
.row .main:has(.highlights) .sub { white-space: normal; }
.badge { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.badge.alert { color: var(--ochre); }
.badge.bad { color: var(--rose); }
.card-body { display: grid; gap: 9px; }
.empty { color: var(--muted); font-size: 13px; }
.error-note { color: var(--rose); font-size: 12px; line-height: 1.4; }

/* The calendar is unbounded by nature; it scrolls inside its own card rather
   than pushing everything below it off the screen. */
/* Flat fill, not the gradient — a sticky day header has to match its backdrop
   exactly or it reads as a band sliding over the list. */
.card.scroll { background: var(--scroll-ground); }
/* `overscroll-behavior: contain` swallowed the wheel here even when the box
   had nothing left to scroll — and the Inbox usually does not, since only the
   people group opens by default. So scrolling over the card did nothing and
   Sam had to aim at the margins beside it (9 Aug 2026). Chaining is restored,
   and the cap is generous enough that the inner scrollbar is the exception
   rather than the everyday case. */
.card.scroll .card-body {
  max-height: 70dvh;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--swell) transparent;
}
.card.scroll .card-body .day-head {
  position: sticky; top: 0; z-index: 1;
  background: var(--scroll-ground); padding-bottom: 4px;
}

/* --------------------------------------------------------------- list rows */
.row { display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: baseline; padding: 7px 0; border-top: 1px solid var(--line); }
.row:first-child { border-top: 0; }
.row .when { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.row .main { min-width: 0; }
.row .title { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row .sub { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row .right { font-size: 12px; color: var(--muted); white-space: nowrap; }
.clickable { cursor: pointer; }
.clickable:active { opacity: 0.6; }

.day-head { font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--shallow); padding-top: 10px; }

/* ------------------------------------------------------------------- chips */
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.chip {
  font-size: 12px; padding: 5px 11px; border-radius: 999px;
  border: 1px solid var(--line); background: rgba(var(--ink-rgb), 0.05); color: var(--ink-2);
}
.chip[aria-pressed="true"] { background: var(--mass); color: var(--on-mass); border-color: var(--mass); font-weight: 640; }
.chip .count { opacity: 0.55; margin-left: 5px; font-variant-numeric: tabular-nums; }

/* Categories drawn only from the print: two blues, the ochre sky, the rose
   horizon, the paper, and the grey of the boats. */
.tag { font-size: 10.5px; padding: 2px 8px; border-radius: 999px; white-space: nowrap; border: 1px solid transparent; }
.tag-client_meeting { background: rgba(111, 168, 196, 0.16); color: var(--shallow); }
.tag-leave { background: rgba(201, 142, 136, 0.16); color: var(--rose); }
.tag-team_note { background: rgba(168, 195, 214, 0.14); color: var(--pale); }
.tag-blocked { background: rgba(217, 175, 99, 0.16); color: var(--ochre); }
.tag-personal { background: rgba(134, 173, 152, 0.16); color: var(--jade); }
.tag-other, .tag-untagged { background: rgba(var(--ink-rgb), 0.06); color: var(--muted); }
.tag.sam::after { content: " ✓"; }

.ctx { font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); }

/* ------------------------------------------------------------------ today */
.brief { font-size: 14px; color: var(--ink-2); line-height: 1.55; }
.brief h3 {
  font-size: 13px; color: var(--ink);
  margin: 16px 0 6px; display: flex; align-items: baseline;
}
.brief h3:first-child { margin-top: 0; }
.brief ul { list-style: none; display: grid; gap: 3px; }
.brief li { padding-left: 14px; position: relative; }
.brief li::before { content: '·'; position: absolute; left: 4px; color: var(--shallow); }
.brief p { margin: 6px 0; }
.brief strong { color: var(--ink); }

/* ---------------------------------------------------------------- capture */
.capture {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  display: flex; gap: 8px; align-items: center;
  padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, rgba(4, 18, 31, 0.55), var(--deep) 60%);
  backdrop-filter: blur(12px);
}
.capture input {
  flex: 1; min-width: 0; font: inherit; color: var(--ink);
  background: rgba(var(--ink-rgb), 0.07); border: 1px solid var(--line); border-radius: 999px;
  padding: 12px 16px; outline: none;
}
.capture input:focus { border-color: var(--ink); background: rgba(var(--ink-rgb), 0.1); }
.capture input::placeholder { color: var(--muted); }
.capture button {
  width: 44px; height: 44px; border-radius: 50%; flex: none;
  background: var(--mass); color: var(--on-mass); font-size: 19px; font-weight: 700;
  display: grid; place-items: center;
}
.capture button:disabled { opacity: 0.5; }

/* ------------------------------------------------------------------ sheet */
.sheet-backdrop { position: fixed; inset: 0; background: rgba(4, 18, 31, 0.68); z-index: 40; }
.sheet {
  /* Centred with inset + auto margins rather than a 50% translate. The translate
     version shared an animation name with the mobile rule below, and a second
     @keyframes of the same name wins globally — so the panel settled wherever
     the wrong animation left it, small and off to one side. Auto margins have
     no such coupling and need no transform at all. */
  position: fixed; inset: 0; margin: auto; z-index: 50;
  width: min(1200px, calc(100vw - 64px));
  height: fit-content; max-height: 90dvh;
  overflow-y: auto;
  background: var(--night-2);
  border: 1px solid var(--line-strong); border-radius: 18px;
  padding: 26px 30px 30px;
  box-shadow: 0 30px 80px rgba(3, 14, 24, 0.6);
  animation: sheet-in 0.2s ease;
}
@keyframes sheet-in { from { opacity: 0; transform: translateY(10px); } }

/* A phone has nothing to centre — it goes back to a bottom sheet. */
@media (max-width: 640px) {
  .sheet-grip { display: block; }
  .sheet {
    inset: auto 0 0; margin: 0;
    width: auto; max-height: 90dvh;
    border-radius: 20px 20px 0 0; border-width: 1px 0 0;
    padding: 14px 18px calc(24px + env(safe-area-inset-bottom));
    animation: sheet-up 0.22s ease;
  }
}
@keyframes sheet-up { from { transform: translateY(16px); opacity: 0; } }

.sheet-grip { display: none; width: 40px; height: 4px; border-radius: 2px; background: var(--line-strong); margin: 2px auto 14px; }
.sheet-close {
  position: absolute; top: 12px; right: 12px; width: 36px; height: 36px;
  display: grid; place-items: center; border-radius: 10px; color: var(--muted);
  background: rgba(var(--ink-rgb), 0.06); border: 1px solid var(--line);
  font-size: 20px; line-height: 1;
}
.sheet-close:hover { color: var(--ink); background: rgba(var(--ink-rgb), 0.1); }
.sheet h3 { font-size: 17px; margin-bottom: 4px; }
.sheet .meta { font-size: 13px; color: var(--muted); margin-bottom: 14px; }
.sheet .label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--shallow); margin: 14px 0 8px; }
.cat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.cat-btn { padding: 11px; border-radius: 11px; border: 1px solid var(--line); background: rgba(var(--ink-rgb), 0.05); font-size: 13px; text-align: left; }
.cat-btn[aria-pressed="true"] { border-color: var(--ink); background: rgba(var(--ink-rgb), 0.13); font-weight: 640; }
.sheet .link { display: inline-block; margin-top: 14px; font-size: 13px; color: var(--shallow); }

/* ------------------------------------------------------------------ toast */
.toast {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--capture-h) + env(safe-area-inset-bottom) + 12px);
  z-index: 60; background: var(--mass); color: var(--on-mass);
  border-radius: 999px; padding: 9px 16px; font-size: 13px; font-weight: 560;
  box-shadow: 0 14px 30px -16px var(--shadow);
  animation: rise 0.2s ease;
}
.toast.bad { background: var(--rose); color: var(--on-accent); }
.toast.good { background: var(--jade); color: var(--on-accent); }

/* --------------------------------------------------------------- desktop */
@media (min-width: 760px) {
  body { max-width: none; margin: 0; padding-left: 24px; padding-right: 24px; }
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .card.wide { grid-column: span 2; }
  .urgent-list { grid-auto-flow: column; grid-auto-columns: 1fr; gap: 26px; }
}
@media (min-width: 1080px) {
  .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .card.wide { grid-column: span 2; }
  .capture { left: 50%; transform: translateX(-50%); max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

/* ---------------------------------------------------------- tag management */
/* Tag colours are named, not hardcoded per key, so a tag Sam invents gets a
   real colour instead of falling through to grey. */
.tagdot-shallow, .tag.tagdot-shallow { background: rgba(111, 168, 196, 0.16); color: var(--shallow); }
.tagdot-pale,    .tag.tagdot-pale    { background: rgba(168, 195, 214, 0.14); color: var(--pale); }
.tagdot-ochre,   .tag.tagdot-ochre   { background: rgba(217, 175, 99, 0.16);  color: var(--ochre); }
.tagdot-rose,    .tag.tagdot-rose    { background: rgba(201, 142, 136, 0.16); color: var(--rose); }
.tagdot-jade,    .tag.tagdot-jade    { background: rgba(134, 173, 152, 0.16); color: var(--jade); }
.tagdot-slate,   .tag.tagdot-slate   { background: rgba(29, 90, 122, 0.28);   color: var(--pale); }
.tagdot-muted,   .tag.tagdot-muted   { background: rgba(var(--ink-rgb), 0.06); color: var(--muted); }
.kind-dot.tagdot-shallow { background: var(--shallow); }
.kind-dot.tagdot-pale { background: var(--pale); }
.kind-dot.tagdot-ochre { background: var(--ochre); }
.kind-dot.tagdot-rose { background: var(--rose); }
.kind-dot.tagdot-jade { background: var(--jade); }
.kind-dot.tagdot-slate { background: var(--swell); }
.kind-dot.tagdot-muted { background: var(--muted); }

.cat-btn { display: flex; align-items: center; gap: 8px; }
.picker-actions { display: flex; gap: 6px; padding: 4px 5px 8px; border-bottom: 1px solid var(--line); margin-bottom: 4px; }
.picker-actions button {
  font-size: 11.5px; padding: 5px 10px; border-radius: 999px;
  border: 1px solid var(--line-strong); color: var(--ink-2);
}
.tag-admin { display: flex; gap: 8px; margin-top: 12px; }
.u-btn.ghost { border-color: var(--line-strong); color: var(--ink-2); background: none; }
#tag-editor { margin-top: 6px; }
.tag-row { display: flex; align-items: center; gap: 9px; padding: 6px 0; border-top: 1px solid var(--line); }
.tag-row input {
  flex: 1; min-width: 0; font: inherit; font-size: 13px; color: var(--ink);
  background: rgba(var(--ink-rgb), 0.05); border: 1px solid var(--line);
  border-radius: 9px; padding: 7px 10px; outline: none;
}
.tag-row input:focus { border-color: var(--ochre); }
.tag-row button { font-size: 11.5px; color: var(--rose); }
.tag-row .built-in { font-size: 11px; color: var(--muted); }
#tag-new { display: flex; gap: 8px; margin-top: 10px; }
#tag-new input {
  flex: 1; min-width: 0; font: inherit; font-size: 13px; color: var(--ink);
  background: rgba(var(--ink-rgb), 0.05); border: 1px solid var(--line);
  border-radius: 9px; padding: 9px 11px; outline: none;
}
#tag-new input:focus { border-color: var(--ochre); }
#tag-new button {
  font-size: 12.5px; font-weight: 640; padding: 0 14px; border-radius: 9px;
  background: var(--mass); color: var(--on-mass);
}

/* A whole row as a link — the inbox exists to get Sam into Gmail, not to
   re-implement it. */
.link-row { text-decoration: none; }
.link-row:hover { background: rgba(var(--ink-rgb), 0.04); }
.link-row .go-arrow { color: var(--muted); opacity: 0; transition: opacity 0.15s ease; }
.link-row:hover .go-arrow { opacity: 1; }
.sheet .people { font-size: 12px; color: var(--muted); margin-top: 10px; overflow-wrap: anywhere; }
/* flex: none, or the card-toggle's flex: 1 squeezes this to a few pixels —
   which is what made the Today panel's "dry run" button look like it had
   vanished. It was there, 19px wide, with the text wrapped to a sliver. */
.head-actions { display: flex; align-items: center; gap: 10px; flex: none; }
.head-actions .text-btn { white-space: nowrap; }

/* Capture follow-up: sits just above the capture bar, dies after 30s. */
#capture-followup {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--capture-h) + env(safe-area-inset-bottom) + 8px);
  z-index: 31; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  max-width: min(560px, calc(100vw - 28px));
  background: var(--mass); color: var(--on-mass);
  border-radius: 14px; padding: 10px 14px; font-size: 13px;
  box-shadow: 0 16px 34px -18px var(--shadow);
  animation: rise 0.2s ease;
}

/* Quick add: words to a prefilled Google Calendar screen. No write. */
.quick-add { display: flex; gap: 8px; margin-bottom: 10px; }
.quick-add input {
  flex: 1; min-width: 0; font: inherit; font-size: 13px; color: var(--ink);
  background: rgba(var(--ink-rgb), 0.05); border: 1px solid var(--line);
  border-radius: 10px; padding: 9px 12px; outline: none;
}
.quick-add input:focus { border-color: var(--ochre); }
.quick-add input::placeholder { color: var(--muted); }
.quick-add button {
  font-size: 12.5px; font-weight: 640; padding: 0 14px; border-radius: 10px;
  background: rgba(var(--ink-rgb), 0.1); border: 1px solid var(--line-strong); color: var(--ink);
}
.quick-add-hit {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  background: rgba(217, 175, 99, 0.1); border: 1px solid rgba(217, 175, 99, 0.3);
  border-radius: 12px; padding: 10px 12px; margin-bottom: 10px; font-size: 13px;
}

/* ------------------------------------------------------------------- rail */
/* Desktop: a left rail with live counts, so a section Sam is not looking at
   still announces itself. Mobile: a bottom bar, because the top of a phone
   screen is the hardest place to reach. */
.rail {
  position: fixed; z-index: 40;
  display: flex; background: rgba(4, 18, 31, 0.92); backdrop-filter: blur(14px);
}
.rail-item {
  display: flex; align-items: center; gap: 10px;
  color: var(--muted); text-decoration: none; font-size: 13px;
  border-radius: 10px; padding: 9px 11px; white-space: nowrap;
}
.rail-item[aria-current="page"] { background: rgba(var(--ink-rgb), 0.1); color: var(--ink); font-weight: 620; }
.rail-icon { font-size: 15px; width: 18px; text-align: center; }
.rail-count {
  margin-left: auto; font-size: 11px; font-variant-numeric: tabular-nums;
  background: var(--ochre); color: var(--on-accent); border-radius: 999px;
  min-width: 18px; text-align: center; padding: 1px 5px; font-weight: 700;
}
.rail-count:empty { display: none; }

@media (max-width: 899px) {
  .rail {
    left: 0; right: 0; bottom: 0;
    padding: 6px 8px calc(6px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--line);
    overflow-x: auto; gap: 2px;
  }
  .rail-item { flex-direction: column; gap: 2px; padding: 6px 10px; font-size: 10px; }
  .rail-label { font-size: 10px; }
  .rail-count { position: absolute; margin: 0; transform: translate(14px, -4px); }
  .rail-item { position: relative; }
  /* Capture bar sits above the rail rather than under it. The rail measures
     ~64px with its labels, so 58px left a 5px overlap. */
  .capture { bottom: calc(68px + env(safe-area-inset-bottom)); }
  #capture-followup { bottom: calc(68px + var(--capture-h) + env(safe-area-inset-bottom)); }
  .toast { bottom: calc(68px + var(--capture-h) + env(safe-area-inset-bottom) + 10px); }
  body { padding-bottom: calc(var(--capture-h) + 90px + env(safe-area-inset-bottom)); }
}

@media (min-width: 900px) {
  .rail {
    top: 0; bottom: 0; left: 0; width: 176px;
    flex-direction: column; gap: 3px;
    padding: 18px 12px; border-right: 1px solid var(--line);
    /* The rail is taller than the window on a laptop, and without this its tail
       is simply unreachable -- Sam lost the nightly cleanup entry that way.
       Consolidating the mail screens (1 Sep) shortened the list; being able to
       reach the bottom of it is the part that must not depend on the list
       staying short. */
    overflow-y: auto; overscroll-behavior: contain;
    scrollbar-width: thin;
  }
  .shell { padding-left: 176px; }
  .capture { left: 176px; transform: none; }
  #capture-followup { left: calc(176px + 14px); transform: none; }
}

/* A single-panel page has nothing to sit beside, so let it use the width. */
body.single .grid.columns { grid-template-columns: minmax(0, 1fr); }
body.single .card.scroll .card-body { max-height: none; }
/* Work has two panels, but they are consecutive full-width sections rather
   than peers in a three-column dashboard grid. */
body.work-view .grid { grid-template-columns: minmax(0, 1fr); }
body.work-view #panel-docs { grid-column: 1 / -1; }

/* ----------------------------------------------------------------- search */
.search-bar { display: flex; gap: 8px; margin-bottom: 10px; }
.search-bar input {
  flex: 1; min-width: 0; font: inherit; color: var(--ink);
  background: rgba(var(--ink-rgb), 0.06); border: 1px solid var(--line);
  border-radius: 12px; padding: 12px 15px; outline: none;
}
.search-bar input:focus { border-color: var(--ochre); }
.search-bar button {
  font-size: 13px; font-weight: 640; padding: 0 18px; border-radius: 12px;
  background: var(--mass); color: var(--on-mass);
}
#search-results { display: grid; gap: var(--gap); margin-top: var(--gap); }
@media (min-width: 900px) { #search-results { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; } }
.row.failed .title { color: var(--rose); }
.row.failed .right { color: var(--rose); }

/* ------------------------------------------------------------- needs you */
.needs-head { margin-bottom: var(--gap); }
.needs-head h2 { font-size: 17px; }
#needs-list { display: grid; gap: var(--gap); align-items: start; }
@media (min-width: 900px) {
  #needs-list { grid-template-columns: repeat(auto-fit, minmax(min(440px, 100%), 1fr)); }
}
.need-broken { border-color: rgba(201, 142, 136, 0.4); }
.need-soon { border-color: rgba(217, 175, 99, 0.4); }
.card.need-broken > header h2 { color: var(--rose); }
.card.need-soon > header h2 { color: var(--ochre); }

/* -------------------------------------------------------------- proposals */
#proposal-list, #proposal-scoreboard { display: grid; gap: var(--gap); }
#proposal-scoreboard { margin-bottom: var(--gap); }
@media (min-width: 900px) { #proposal-list { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; } }
.card.proposal-proposed { border-color: rgba(217, 175, 99, 0.4); }
.card.proposal-executed > header h2 { color: var(--jade); }
.card.proposal-rejected, .card.proposal-flagged { opacity: 0.6; }
.card.proposal-failed { border-color: rgba(201, 142, 136, 0.4); }
.card.proposal-failed > header h2 { color: var(--rose); }
.proposal-edit { margin-top: 10px; }
.edit-row { display: flex; gap: 8px; margin-top: 6px; }
.edit-row select, .edit-row input {
  flex: 1; min-width: 0; font: inherit; font-size: 13px; color: var(--ink);
  background: rgba(var(--ink-rgb), 0.06); border: 1px solid var(--line);
  border-radius: 9px; padding: 8px 10px; outline: none;
}
.edit-row select:focus, .edit-row input:focus { border-color: var(--ochre); }
.edit-row option { background: var(--night-2); color: var(--ink); }

/* Proposing from wherever the thing is, not from a separate page. */
.proposer { margin-top: 12px; }
.urgent .proposer { background: rgba(var(--on-mass-rgb), 0.06); border-radius: 12px; padding: 10px 12px; margin-top: 8px; }
.urgent .proposer .label { color: var(--on-mass-muted); }
.urgent .proposer input { background: var(--on-mass-field); border-color: rgba(var(--on-mass-rgb), 0.2); color: var(--on-mass); }
.urgent .proposer button[type="submit"] { background: var(--on-mass-strong); color: var(--mass); border: 0; }
.inline-proposal { margin-top: 10px; }
.context-proposals { display: grid; gap: 8px; margin: 10px 0; }
.context-proposal {
  display: grid;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid rgba(217, 175, 99, 0.4);
  border-radius: 10px;
  background: rgba(217, 175, 99, 0.08);
}
.context-proposal .tag-admin { margin-top: 0; }
/* Blocked cards read as inactive, not as damaged. The flat ochre field is
   dropped to a quarter strength rather than dimmed with opacity: a blanket
   opacity multiplies the title too, and the action's name is the one thing
   Sam still needs to read here. */
.context-proposal.blocked {
  border-color: rgba(217, 175, 99, 0.2);
  background: rgba(217, 175, 99, 0.03);
}
.context-proposal.blocked .title { color: var(--ink-2); }
.context-proposal .blocked-reason { color: var(--ink-2); font-size: 0.85em; }
.proposals-blocked-header {
  margin-top: 8px;
  padding: 0 2px;
  font-size: 0.85em;
  font-weight: 500;
  color: var(--ink-2);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.source-with-proposals { border-bottom: 1px solid var(--line); }
.source-with-proposals > .row { border-bottom: 0; }
.proposal-bulk {
  /* Spans the list's two columns. Without this it takes a single grid cell and
     sits beside the first card, which is how it shipped in #39 — the bug was
     invisible while the list was one long column of waiting cards. */
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
}
.card > header [data-select-proposal] { flex: 0 0 auto; }
.inline-proposal .title { font-size: 14px; font-weight: 640; }
.agenda-row { cursor: pointer; }
.agenda-row:hover { background: rgba(var(--ink-rgb), 0.04); }
.agenda-row .u-btn.go { background: var(--mass); color: var(--on-mass); border-color: var(--mass); }

/* ------------------------------------------------------------ mail reader */
.mail-body {
  white-space: pre-wrap; font-size: 14px; line-height: 1.6; color: var(--ink-2);
  background: rgba(var(--ink-rgb), 0.04); border: 1px solid var(--line);
  border-radius: 12px; padding: 12px 14px; margin: 12px 0;
  max-height: 46dvh; overflow-y: auto; overflow-wrap: anywhere;
}
/* Which account a message belongs to, at a glance rather than by reading. */
.acct { border-left: 3px solid transparent; padding-left: 7px; }
.acct-shallow { border-left-color: var(--shallow); }
.acct-ochre { border-left-color: var(--ochre); }
.acct-jade { border-left-color: var(--jade); }
.acct-pale { border-left-color: var(--pale); }
.acct-rose { border-left-color: var(--rose); }
.acct-slate { border-left-color: var(--swell); }
.acct-muted { border-left-color: var(--muted); }
.acct-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.acct-email { font-size: 10.5px; color: var(--muted); text-transform: none; letter-spacing: 0; }
.acct-count { margin-left: auto; font-size: 10.5px; color: var(--muted); text-transform: none; letter-spacing: 0; }

/* Fields in the event-details sheet. Full width so a thumb can hit them, and
   the same ink as the rest of the drawer — a form here is still the drawer. */
.sheet-field {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--night);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
}
.sheet-field:focus { outline: none; border-color: var(--shallow); }
.sheet .edit-row { display: flex; gap: 8px; }
.sheet .edit-row .sheet-field { min-width: 0; }
.sheet textarea.sheet-field { resize: vertical; }

/* Reply composer inside the mail reader. Boxed off from the message above it,
   because the difference between "what they said" and "what you are about to
   say" should never be a matter of squinting. */
.reply-box { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.reply-box .edit-row { gap: 8px; }
.reply-box .edit-row .sheet-field { flex: 1; }
.reply-box textarea.sheet-field { margin-top: 10px; line-height: 1.55; }
.reply-box .sub { margin-top: 8px; }

/* The last gate before something leaves. Warm ochre, not the calm blue of the
   rest of Horizon — this is the one card that should make her pause. */
.confirm-card {
  margin-top: 12px;
  padding: 12px 14px;
  border: 1px solid var(--ochre);
  border-radius: 10px;
  background: rgba(196, 141, 62, 0.1);
}
.confirm-card p { margin: 0 0 6px; }
.confirm-card .sub { line-height: 1.5; }

/* ------------------------------------------------------- watchers (Stage 6) */

/* Ochre edge, like the send-confirm card: both are Horizon acting rather than
   reporting, and that difference should be visible before it is read. */
.need-watch { border-left: 3px solid var(--ochre); }
.watch-row .right { display: flex; gap: 6px; align-items: center; }
.watch-row .u-btn { font-size: 11px; padding: 3px 8px; }

.watcher-settings { margin-top: 18px; }
.watcher-settings summary {
  cursor: pointer; font-size: 12px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--shallow); padding: 4px 0;
}
.watch-setting .right { display: flex; align-items: center; }
.switch {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted);
}
.switch input { accent-color: var(--shallow); width: 15px; height: 15px; }

/* The urgent strip is the one light surface in a dark app, so anything dropped
   into it inherits colours built for the opposite background. Approve/Reject/
   Wrong were pale ink on cream — technically rendered, practically invisible. */
.urgent .u-btn { color: var(--on-mass); border-color: rgba(var(--on-mass-rgb), 0.28); }
.urgent .u-btn.ghost { color: var(--on-mass-muted); border-color: rgba(var(--on-mass-rgb), 0.28); background: none; }
.urgent .u-btn.go { background: var(--on-mass-strong); color: var(--mass); border-color: var(--on-mass-strong); }
.urgent .proposer .sub,
.urgent .proposer .label,
.urgent .proposal-why { color: var(--on-mass-soft); }
.urgent .proposer .title,
.urgent .proposer strong { color: var(--on-mass); }
.urgent .proposal-edit .sheet-field,
.urgent .proposer select,
.urgent .proposer textarea {
  background: var(--on-mass-field);
  border-color: rgba(var(--on-mass-rgb), 0.2);
  color: var(--on-mass);
}

/* ------------------------------- deadline urgency (Grimoire #53, pattern 4) */
/* The urgency was already computed and then spent on prose. A colour is read
   at a glance; "due Thursday" has to be read. Four states, no manual tagging,
   and the formula cannot forget to apply one. */
.due-over  { color: var(--rose); font-weight: 640; }
.due-today { color: var(--ochre); font-weight: 640; }
.due-soon  { color: var(--shallow); }
.due-later { color: var(--muted); }

/* --------------------------------------------- weekly review (Grimoire #70) */
/*
 * The one place in Horizon that is a ritual rather than a readout, so it is the
 * one place allowed a signature. That signature is the budget: thirty minutes
 * laid out as five segments, each as wide as it is long, draining as she goes.
 * It is the only element here doing anything; every other rule below exists to
 * keep the rest quiet enough that it reads.
 *
 * The order of the steps carries real information — emptying the inbox is what
 * surfaces the commitments step four asks about, and deleting is last because
 * it cannot be undone — so the numbering is structural, not decoration.
 */
.review-head { display: flex; align-items: center; gap: 18px; margin-bottom: 14px; }
.review-intro h2 { font-size: 20px; }

/* The clock is the thesis: a number that gets smaller, not a bar that fills. */
.review-clock {
  display: flex; align-items: baseline; gap: 6px;
  padding: 10px 16px 12px;
  border: 1px solid var(--line-strong); border-radius: 14px;
  background: linear-gradient(180deg, rgba(93, 158, 191, 0.13), transparent 70%);
  flex: none;
}
.review-remaining {
  font-size: 40px; font-weight: 300; line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--ink);
  letter-spacing: -0.03em;
}
.review-unit {
  font-size: 10px; line-height: 1.15; text-transform: uppercase;
  letter-spacing: 0.14em; color: var(--shallow);
}

.review-budget { display: flex; gap: 3px; margin-bottom: 22px; height: 5px; }
.budget-seg { border-radius: 3px; background: rgba(93, 158, 191, 0.2); overflow: hidden; }
.budget-seg i { display: block; height: 100%; width: 0; background: var(--shallow); transition: width 420ms cubic-bezier(0.16, 1, 0.3, 1); }
.budget-seg.spent i { width: 100%; }

.review-step {
  border-top: 1px solid var(--line);
  padding: 14px 0;
}
.review-step header { display: flex; align-items: center; gap: 11px; }
.review-step h3 { font-size: 15px; font-weight: 560; flex: 1; }
.step-n {
  display: inline-grid; place-items: center; flex: none;
  width: 24px; height: 24px; border-radius: 50%;
  border: 1px solid var(--line-strong); background: var(--night-2);
  font-size: 11px; font-variant-numeric: tabular-nums; color: var(--shallow);
}
.step-min { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* Steps not yet reached recede rather than disappear: she should be able to see
   what is coming without being able to start it. */
.review-step:not(.is-open):not(.is-done) h3,
.review-step:not(.is-open):not(.is-done) .step-min { opacity: 0.45; }
.review-step.is-done h3 { color: var(--muted); text-decoration: line-through; text-decoration-color: var(--line-strong); }
.review-step.is-done .step-n { background: var(--shallow); color: var(--night); border-color: var(--shallow); }
.review-step.is-open .step-n { border-color: var(--ink); color: var(--ink); }

.step-open { padding: 12px 0 0 35px; }
.step-ask { font-size: 13px; color: var(--ink-2); margin-bottom: 10px; line-height: 1.55; }
.step-open .card-body { margin-bottom: 14px; }
.review-reset { margin-top: 18px; }

@media (max-width: 640px) {
  .review-head { gap: 13px; }
  .review-remaining { font-size: 32px; }
  .step-open { padding-left: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .budget-seg i { transition: none; }
}

/* ------------------------------------------- accessibility floor (audit fix) */
/*
 * Two failures the ui-ux-pro-max checklist caught, both of which predate the
 * review page and affect every screen.
 *
 * 1. Nothing had a visible focus ring. Horizon is keyboard-reachable and always
 *    was, but a keyboard user could not see where they were, which makes that
 *    reachability theoretical.
 * 2. .u-btn renders about 24px tall. That is fine to look at and too small to
 *    hit — the target is 44px. Rather than inflate every control and wreck the
 *    density the dashboard depends on, the hit area is extended past the paint
 *    with a pseudo-element, and only where the pointer is actually coarse.
 */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  border-radius: 6px;
}
.urgent :where(a, button, input, select):focus-visible { outline-color: var(--on-mass-strong); }

:where(button, .u-btn, .text-btn, summary, .rail-item, .link-row) { cursor: pointer; }

@media (pointer: coarse) {
  .u-btn, .text-btn { position: relative; }
  .u-btn::after,
  .text-btn::after {
    content: '';
    position: absolute;
    inset: 50% 0 auto;
    height: 44px;
    transform: translateY(-50%);
    /* Wider than the button where there is room to be, never narrower. */
    left: -6px;
    right: -6px;
  }
}

/* Keep/Bin sit at the end of a review row. Bin is the quieter of the two on
   purpose: binning is the irreversible-feeling one, so it should not be the
   button the eye lands on first. */
.review-step .row .right { display: flex; gap: 6px; align-items: center; }
.review-step .row { align-items: center; }
.u-btn[disabled] { opacity: 0.4; pointer-events: none; }
.u-btn.ghost { border-color: var(--line); color: var(--muted); }
.u-btn:not(.go):hover { border-color: var(--shallow); color: var(--ink); transition: border-color 160ms, color 160ms; }

/* --------------------------------------------- acting on a project in place */
/*
 * The review asks "what do you want to do with this" and then has to be able to
 * accept the answer. Chips for the five answers Sam gives most often, and a
 * field for everything else. The chips skip the model entirely — she already
 * knows what she wants it to say, so a guess would be slower and less certain.
 */
/* .row is a three-column grid, so flex-basis did nothing here and the whole
   action block became a fourth column pinned to the right of the title. It
   belongs underneath, spanning the lot. */
.row-actions { grid-column: 1 / -1; padding: 9px 0 2px; display: grid; gap: 8px; max-width: 620px; }
.status-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.chip {
  font-size: 11px; padding: 3px 10px; border-radius: 999px;
  border: 1px solid var(--line); background: none; color: var(--muted);
  font-family: inherit; cursor: pointer;
  transition: border-color 160ms, color 160ms;
}
.chip:hover { border-color: var(--shallow); color: var(--ink); }
.chip[disabled] { opacity: 0.35; pointer-events: none; }
.next-action { display: flex; gap: 6px; }
.next-action .sheet-field { flex: 1; font-size: 13px; padding: 6px 10px; }
.row-out:empty { display: none; }
.row-out .sub { color: var(--shallow); }
.proposal-inline { padding: 8px 10px; border: 1px solid var(--line); border-radius: 9px; display: grid; gap: 5px; justify-items: start; }
.proposal-inline .u-btn { margin-top: 3px; }
/* The chip that is now true. Marked rather than removed: she should be able to
   see what she just set, and change it again without reloading. */
.chip.is-set {
  border-color: var(--shallow); color: var(--night);
  background: var(--shallow); font-weight: 600;
}

/* Tag management in the calendar's own picker. It lived only inside an event
   detail sheet — findable if you already knew, invisible otherwise. */
#cal-manage .picker-menu { min-width: 260px; padding: 10px; display: grid; gap: 8px; }
#tag-list-main .tag-row,
#tag-list .tag-row { display: flex; align-items: center; gap: 7px; padding: 3px 0; }
#tag-list-main .tag-row input,
#tag-list .tag-row input {
  flex: 1; min-width: 0; padding: 4px 8px; font: inherit; font-size: 13px;
  background: var(--night); color: var(--ink);
  border: 1px solid var(--line); border-radius: 7px;
}
#tag-list-main .tag-row button,
#tag-list .tag-row button {
  font-size: 11px; padding: 3px 8px; border-radius: 999px; cursor: pointer;
  background: none; color: var(--muted); border: 1px solid var(--line); font-family: inherit;
}
#tag-list-main .tag-row button:hover,
#tag-list .tag-row button:hover { border-color: var(--rose); color: var(--rose); }
#tag-list-main .built-in,
#tag-list .built-in { font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); }
#tag-new-main { display: flex; gap: 6px; padding-top: 8px; border-top: 1px solid var(--line); }
#tag-new-main input {
  flex: 1; min-width: 0; padding: 5px 9px; font: inherit; font-size: 13px;
  background: var(--night); color: var(--ink);
  border: 1px solid var(--line); border-radius: 7px;
}
#tag-new-main button {
  font-size: 12px; font-weight: 600; padding: 4px 12px; border-radius: 999px; cursor: pointer;
  background: var(--shallow); color: var(--night); border: 0; font-family: inherit;
}

/* Editing lives inside the tag filter, not beside it. Two pickers called "All
   tags" and "Edit tags" was one dropdown too many for one concept. */
#cal-manage { margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--line); }
#cal-manage > summary {
  cursor: pointer; font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.09em; color: var(--shallow); padding: 2px 0;
}

/* ------------------------------------------------------------- tag rules */
/* A rule reads as a sentence — condition, account, arrow, tag — so the row
   says what it does without a legend. */
.rule-new { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; }
.rule-new select,
.rule-new input {
  padding: 6px 10px; font: inherit; font-size: 13px;
  background: var(--night); color: var(--ink);
  border: 1px solid var(--line); border-radius: 8px; min-width: 0;
}
.rule-new input { flex: 1; min-width: 120px; }
.rule-new select { cursor: pointer; }
.rule-new option { background: var(--night-2); color: var(--ink); }
.rule-arrow { color: var(--shallow); font-size: 15px; }
.rule-row .right { display: flex; align-items: center; gap: 9px; }
.rule-row .title { white-space: normal; }
/* An off rule stays legible — she needs to read it to decide whether to bin it. */
.rule-off { opacity: 0.5; }
#rule-hint { margin-top: 8px; }
#rules-preview:empty { display: none; }
#rules-preview { margin-top: 10px; }

/* The way from the calendar to the rules that tag it. */
.picker-link {
  display: block; margin-top: 9px; padding-top: 9px;
  border-top: 1px solid var(--line);
  font-size: 12px; color: var(--shallow); text-decoration: none;
}
.picker-link:hover { color: var(--ink); }

/* Panel tools: a small icon row at the right of a panel's own toolbar, for
   settings that belong to that panel rather than to the app. The main rail is
   for places Sam goes; this is for adjusting where she already is. */
.panel-tools { margin-left: auto; display: flex; gap: 4px; align-items: center; }
.tool-btn {
  display: inline-grid; place-items: center;
  width: 30px; height: 30px; border-radius: 9px;
  border: 1px solid var(--line); color: var(--shallow);
  text-decoration: none; font-size: 14px; line-height: 1;
  transition: border-color 160ms, color 160ms;
}
.tool-btn:hover { border-color: var(--shallow); color: var(--ink); }
/* A calendar with nothing in this window still has to look connected. */
.empty-account { opacity: 0.62; }
.empty-account .count { font-size: 10px; text-transform: uppercase; letter-spacing: 0.07em; }

/* The rail sits outside the card, running down its left edge — a control for
   the panel rather than a control inside it. */
.railed { display: flex; gap: 9px; align-items: flex-start; min-width: 0; }
.railed > .card { flex: 1; min-width: 0; }
/* The mail screens are not one card but a stack of them, so the rail sits
   beside a column rather than beside a panel. */
.railed > .railed-body { flex: 1; min-width: 0; display: grid; gap: var(--gap); align-content: start; }
.acct-rail {
  display: flex; flex-direction: column; gap: 6px;
  position: sticky; top: 12px; flex: none; padding-top: 15px;
}

/* No gutter to spare on a phone: the rail lies down above the card instead. */
@media (max-width: 900px) {
  .railed { flex-direction: column; gap: 7px; }
  .acct-rail { flex-direction: row; position: static; padding-top: 0; }
}

/* --------------------------------------- one-tap account filter (calendar) */
/* Monogram chips, left of the calendar's own controls. Each carries the colour
   that account already has everywhere else in Horizon, so the chip teaches the
   colour once and the colour then reads on its own in the agenda. */
.acct-chip {
  width: 28px; height: 28px; border-radius: 50%;
  display: inline-grid; place-items: center;
  font-family: inherit; font-size: 12px; font-weight: 700;
  letter-spacing: 0; cursor: pointer;
  border: 1px solid transparent;
  transition: border-color 150ms, opacity 150ms, transform 120ms;
}
.acct-chip.all { background: none; border-color: var(--line-strong); color: var(--shallow); font-weight: 400; }
/* Unselected chips recede without disappearing — she has to be able to read the
   set to know what she is choosing between. */
.acct-chip:not(.is-on) { opacity: 0.55; }
.acct-chip:hover { opacity: 1; }
.acct-chip.is-on { border-color: currentColor; opacity: 1; }
.acct-chip.is-quiet { opacity: 0.3; }
.acct-chip.is-quiet.is-on { opacity: 0.8; }
.acct-chip:active { transform: scale(0.93); }

@media (max-width: 640px) {
  .acct-chip { width: 26px; height: 26px; font-size: 11px; }
}

/* Back out of a full-page view. Every view that replaces the dashboard needs
   one — the browser's back button is not a control people see. */
.back-link {
  display: inline-block; margin-bottom: 8px;
  font-size: 12px; color: var(--shallow); text-decoration: none;
}
.back-link:hover { color: var(--ink); }

/* The how-to sheet reuses the event drawer; its rows are prose, not data. */
#sheet-body .row .sub { white-space: normal; overflow: visible; line-height: 1.5; }
#sheet-body .row .title { white-space: normal; overflow: visible; }

/* The stepper's middle button now says where you are, so it needs room to grow
   and a signal when you are not on today. */
#cal-steps .today-btn { min-width: 74px; }
#cal-steps .today-btn.is-away { color: var(--ink); font-weight: 620; }
/* The date input is only ever open for the moment it takes to pick. */
.date-jump {
  position: absolute; opacity: 0; width: 1px; height: 1px;
  border: 0; padding: 0; pointer-events: none;
}
#cal-steps { position: relative; }

/* Guest suggestions. Sits under the field and dies on blur — a list that
   lingers over the next control reads as a stuck menu. */
.suggest { display: grid; gap: 2px; margin-top: 4px; }
.suggest:empty { display: none; }
.suggest-item {
  display: flex; align-items: baseline; gap: 7px; width: 100%;
  padding: 5px 9px; border-radius: 7px; cursor: pointer; text-align: left;
  background: var(--night); border: 1px solid var(--line);
  font: inherit; font-size: 12.5px; color: var(--ink);
}
.suggest-item:hover { border-color: var(--shallow); background: var(--night-2); }
.suggest-name { font-weight: 560; }
.suggest-mail { color: var(--muted); font-size: 11px; overflow: hidden; text-overflow: ellipsis; }
.suggest-src {
  margin-left: auto; flex: none; font-size: 9.5px; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--shallow);
}

/* ------------------------------------------------------- event drawer */
/* Read in the order a calendar entry is read: what, when, where, who, how to
   join. Horizon's own controls come after — they are Horizon's business, not
   the meeting's. */
.ev-head { display: flex; align-items: flex-start; gap: 10px; }
.ev-head h3 { flex: 1; min-width: 0; }
.ev-acct {
  flex: none; font-size: 10px; text-transform: uppercase; letter-spacing: 0.09em;
  padding: 3px 8px; border-radius: 999px; font-weight: 640;
}
.ev-when { font-size: 13.5px; color: var(--ink); margin-top: 4px; }
.ev-where { font-size: 12.5px; color: var(--muted); margin-top: 3px; line-height: 1.45; }
.ev-people { margin-top: 8px; }
.ev-people > summary {
  cursor: pointer; font-size: 12px; color: var(--shallow); padding: 2px 0;
}
.ev-guests { display: grid; gap: 2px; padding: 5px 0 0 2px; }
.ev-guests span { font-size: 12px; color: var(--muted); }
/* The one action most event drawers are opened for. */
.ev-join { display: inline-flex; margin: 12px 0 4px; font-size: 13px; padding: 7px 16px; }
.ev-desc {
  font-size: 12.5px; color: var(--ink-2); line-height: 1.55;
  margin-top: 10px; white-space: pre-wrap;
}
.ev-note { font-size: 11px; color: var(--muted); margin-top: 12px; font-style: italic; }
.ev-row { display: flex; align-items: center; gap: 9px; margin-top: 16px; }
.ev-row .label { margin: 0; }
/* The tag grid was seven buttons open by default, above the meeting itself.
   Behind its own chip now. */
.tag-chip {
  font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
  padding: 3px 11px; border-radius: 999px; border: 1px solid transparent;
}
.tag-chip.is-none { background: none; border-color: var(--line); color: var(--muted); }
#tag-picker { margin-top: 9px; }

/* The next event is marked in place rather than repeated in a card above. */
.row.is-next { box-shadow: inset 2px 0 0 var(--ochre); }
.row.is-next .title { color: var(--ochre); }
.ev-hint { font-size: 10.5px; color: var(--muted); margin: 2px 0 0 2px; }

/* A count that cannot be cleared should not look like one that can. The ochre
   pill means "waiting on you"; a plain number means "this is how much is
   there". They were identical, so the whole rail read as an unfinishable
   to-do list. */
.rail-count.is-info {
  background: none; color: var(--muted);
  font-weight: 500; padding: 1px 3px;
}

/* "Take me there" on a brief heading. The brief is prose with no links in it;
   the heading is enough to route on, and the underlying things all live on
   pages Horizon already has. */
.brief-goto {
  margin-left: auto; font-size: 11px; font-weight: 500;
  color: var(--shallow); text-decoration: none; text-transform: none;
  letter-spacing: 0; margin-left: 10px;
}
.brief-goto:hover { color: var(--ink); }
.ev-where a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--line); }
.ev-where a:hover { color: var(--ink); }

/* ------------------------------------------------------------- text size */
/* Set per role rather than by zooming the page: zoom takes the layout with it,
   and Horizon's density — the account rail, the month grid — is doing work.
   This moves the type Sam reads and leaves the furniture alone. */
:root[data-text='large'] .card > header h2 { font-size: 16px; }
:root[data-text='large'] .row .title,
:root[data-text='large'] .brief { font-size: 15px; }
:root[data-text='large'] .row .sub,
:root[data-text='large'] .brief h3 { font-size: 14px; }
:root[data-text='large'] .sheet h3 { font-size: 19px; }
:root[data-text='large'] .ev-when { font-size: 15px; }

:root[data-text='xlarge'] .card > header h2 { font-size: 18px; }
:root[data-text='xlarge'] .row .title,
:root[data-text='xlarge'] .brief { font-size: 16.5px; }
:root[data-text='xlarge'] .row .sub,
:root[data-text='xlarge'] .brief h3 { font-size: 15px; }
:root[data-text='xlarge'] .sheet h3 { font-size: 21px; }
:root[data-text='xlarge'] .ev-when { font-size: 16.5px; }

/* Titles wrap rather than truncate once the type is bigger — a longer line is
   the reason for choosing a bigger size in the first place. */
:root[data-text='large'] .row .title,
:root[data-text='xlarge'] .row .title { white-space: normal; }
.seg-text { display: inline-flex; margin-bottom: 4px; }
/* The per-line destination sits at the end of the line it belongs to. */
.brief li .brief-goto { margin-left: 8px; float: none; }
.brief li { display: flex; align-items: baseline; gap: 0; flex-wrap: wrap; }

/* ------------------------------------------------------- inbox legibility */
/* The Inbox was set three points below everything else — the group headers,
   the account lines and the counts were all in small-print sizes that made
   the one panel Sam reads most the hardest to read. */
#panel-email .mail-group summary { font-size: 15px; }
#panel-email .acct-email,
#panel-email .acct-count { font-size: 13.5px; }
#panel-email .row .title { font-size: 15px; }
#panel-email .row .sub,
#panel-email .row .when { font-size: 13.5px; }
#panel-email .acct-head { font-size: 13.5px; }

/* Weekly review header, with rescan beside the title. */
.review-title { display: flex; align-items: baseline; gap: 12px; }
.review-title h2 { flex: none; }

/* A brief line offers the item and a way to be rid of it. */
.brief li { position: relative; padding-right: 22px; }
.brief-dismiss {
  position: absolute; right: 0; top: 1px;
  background: none; border: 0; cursor: pointer; padding: 0 4px;
  color: var(--muted); font-size: 14px; line-height: 1;
  opacity: 0; transition: opacity 140ms, color 140ms;
}
.brief li:hover .brief-dismiss,
.brief-dismiss:focus-visible { opacity: 1; }
.brief-dismiss:hover { color: var(--rose); }
button.brief-goto { background: none; border: 0; cursor: pointer; font-family: inherit; }

/* Two doors and a dismiss, on one row of actions. Dismiss sits at the end of
   the same row rather than pinned to the far edge — it is one of the choices,
   not a different kind of thing. */
.row-actions-inline { display: flex; align-items: center; gap: 5px; flex: none; }
.row-actions-inline .u-btn { font-size: 11px; padding: 3px 9px; }
.row-dismiss,
.brief-dismiss {
  background: none; border: 0; cursor: pointer; padding: 0 3px;
  color: var(--muted); font-size: 15px; line-height: 1;
  opacity: 0.45; transition: opacity 140ms, color 140ms;
}
.row:hover .row-dismiss,
.brief li:hover .brief-dismiss { opacity: 1; }
.row-dismiss:hover,
.brief-dismiss:hover { color: var(--rose); }

/* Brief lines: text, then its actions, then the dismiss — all inline. */
.brief li { display: flex; align-items: baseline; gap: 8px; padding-right: 0; position: static; }
.brief-text { flex: 1; min-width: 0; }
.brief-actions { display: flex; align-items: center; gap: 8px; flex: none; }
.brief-dismiss { position: static; }

/* The reader is the one sheet that is mostly prose, so it gets the room. */
/* One scrollbar. The body had its own scroll area inside a sheet that also
   scrolled, so a long thread gave Sam two bars side by side and neither moved
   the thing she was looking at. */
#sheet-body .mail-body {
  padding: 16px 18px; border-radius: 10px;
  background: rgba(4, 18, 31, 0.45); border: 1px solid var(--line);
}
.sheet h3 { font-size: 19px; line-height: 1.3; }
.sheet .meta { font-size: 13px; }
.sheet .people { font-size: 12.5px; line-height: 1.5; }

/* Two lists in one card need a divider that is not another card. Small, spaced,
   and quiet — it labels a group rather than announcing a section. */
.sub-head {
  margin: 16px 0 6px; font-size: 11px; font-weight: 600;
  letter-spacing: 0.09em; text-transform: uppercase; color: var(--muted);
}
.card-body > .sub-head:first-child { margin-top: 2px; }

/* A document shared and not yet opened from Horizon. A left edge rather than a
   dot or a pill: it marks the row without competing with the Open button, and
   it disappears the moment she reads it. */
.row.is-new { box-shadow: inset 2px 0 0 var(--ochre); padding-left: 10px; }

/* Band heading: what separates a screen into questions rather than a pile of
   cards. Sits above a grid, spans it, and stays quiet — the cards are the
   content, this only says which question they answer. */
.band-head {
  margin: 26px 0 10px; font-size: 12px; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--shallow);
  display: flex; align-items: baseline; gap: 10px;
}
.band-head:first-of-type { margin-top: 12px; }
.band-note {
  font-size: 11px; font-weight: 400; letter-spacing: 0.02em;
  text-transform: none; color: var(--muted);
}

/* ---- Work: the map and the evidence -------------------------------------- */
/* Two columns because they are two different kinds of thing. The left is
   durable and hierarchical; the right changes completely when a different
   client is opened, which is why one open at a time matters — the right column
   always has exactly one subject. */
.work-split {
  display: grid; grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: 0; padding: 0; overflow: hidden;
}
/* Spanning is the default here, and the two columns opt in.
 *
 * The other way round, a child that forgets `grid-column` silently claims the
 * 320px client column floor-to-ceiling and pushes everything after it into a
 * new row — which is how the unlinked-engagements strip shipped, filling the
 * left column with four lines of text and putting the client detail below the
 * fold. Inverted, the cost of forgetting is a full-width band, which is what a
 * banner wanted anyway. The failure mode is benign instead of structural. */
.work-split > * { grid-column: 1 / -1; }
.work-map { grid-column: 1; }
.work-evidence { grid-column: 2; }
.work-onboarding {
  grid-column: 1 / -1; display: flex; align-items: center; justify-content: flex-end;
  gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--line);
}
.work-onboarding #work-onboarding-resume { flex: 1; min-width: 0; }
.onboarding-form { display: grid; gap: 16px; padding: 10px 2px; }
.onboarding-form label { display: grid; gap: 6px; font-size: 12px; color: var(--muted); }
.onboarding-form input,
.onboarding-form select {
  width: 100%; font: inherit; color: var(--ink); background: var(--sea);
  border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px;
}
.form-error { min-height: 1.4em; margin: 0; color: var(--rose); font-size: 12px; }
.onboarding-systems { display: grid; gap: 8px; }
.onboarding-system { display: flex; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.onboarding-confirm { border: 1px solid var(--ochre); border-radius: 12px; padding: 14px; }
.onboarding-confirm dl { display: grid; grid-template-columns: auto 1fr; gap: 6px 12px; }
.onboarding-confirm dt { color: var(--muted); }
.onboarding-confirm dd { margin: 0; }
.work-failures {
  grid-column: 1 / -1; padding: 14px 18px;
  color: var(--rose); background: rgba(187, 103, 101, 0.08);
  border-bottom: 1px solid rgba(187, 103, 101, 0.28);
}
.work-map { border-right: 1px solid var(--line); max-height: 70dvh; overflow-y: auto; }
.work-evidence { padding: 20px 22px 22px; min-width: 0; }

.crow {
  display: block; width: 100%; text-align: left; font: inherit; color: inherit;
  background: none; border: 0; border-bottom: 1px solid var(--line);
  padding: 12px 15px; cursor: pointer;
}
.crow:last-child { border-bottom: 0; }
.crow:hover { background: rgba(111, 168, 196, 0.06); }
.crow.on { background: var(--card-2); }
.crow-top { display: flex; align-items: baseline; gap: 8px; }
.cname { font-weight: 600; font-size: 14px; }
.cstat { font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
/* Only a real debt gets the ochre. A dash for zero keeps the column aligned
   without adding a second thing to read. */
.owed {
  margin-left: auto; font-size: 11px; font-weight: 600; color: var(--deep);
  background: var(--ochre); border-radius: 999px; padding: 1px 7px; min-width: 20px; text-align: center;
}
.owed.zero { background: none; color: var(--muted); font-weight: 400; }
.rlabel { display: block; font-size: 10.5px; color: var(--muted); margin-top: 5px; }

.evhead {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding-bottom: 12px; border-bottom: 1px solid var(--line);
}
.evhead h2 { font-size: 18px; }
.evhead .evsub { margin-left: auto; font-size: 12px; color: var(--shallow); }
.work-evidence .sec { margin-top: 18px; }
.work-evidence .sechead {
  font-size: 11px; font-weight: 600; letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--shallow); margin-bottom: 6px;
}
.work-evidence .secn { color: var(--muted); font-weight: 400; letter-spacing: 0.02em; }
.row.owe { box-shadow: inset 2px 0 0 var(--ochre); padding-left: 11px; }

.client-note { display: flex; gap: 8px; margin-top: 18px; align-items: flex-end; }
.client-note textarea {
  flex: 1; font: inherit; font-size: 13px; color: var(--ink); resize: vertical;
  background: var(--sea); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px;
}
.client-note textarea::placeholder { color: var(--muted); }
.note-out:not(:empty) { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 10px; }

@media (max-width: 900px) {
  .work-split { grid-template-columns: 1fr; }
  /* One column, so both panes span it — the opt-ins above name a track that
     does not exist at this width. */
  .work-map, .work-evidence { grid-column: 1 / -1; }
  .work-map { border-right: 0; border-bottom: 1px solid var(--line); max-height: 40dvh; }
}

/* An approval card has to show what is being approved, and let her change it
   before she says yes. */
.prop-edit {
  width: 100%; font: inherit; font-size: 14px; color: var(--ink);
  background: var(--sea); border: 1px solid var(--line);
  border-radius: 8px; padding: 6px 10px;
}
.prop-edit:focus { border-color: var(--swell); outline: none; }

/* The view switch sits inside the map, above the clients — it changes what the
   list is, so it belongs to the list rather than to the page. */
.work-views:not(:empty) {
  display: flex; gap: 2px; margin: 10px 12px; padding: 2px;
  background: var(--sea); border: 1px solid var(--line); border-radius: 9px;
}
.work-views button {
  flex: 1; font: inherit; font-size: 12px; color: var(--muted);
  background: none; border: 0; padding: 5px 10px; border-radius: 7px; cursor: pointer;
}
.work-views button.on { background: var(--card-2); color: var(--ink); }

/* Small, quiet row controls. They sit at the end of the row so the thing itself
   is what you read first. */
.row-x {
  font: inherit; font-size: 13px; line-height: 1; color: var(--muted);
  background: none; border: 0; padding: 4px 6px; cursor: pointer; border-radius: 6px;
}
.row-x:hover { color: var(--ink); background: rgba(111, 168, 196, 0.1); }
[data-edit-action] { cursor: text; }
[data-edit-action]:hover { text-decoration: underline dotted var(--line-strong); }
.chip-btn { cursor: pointer; }
.chip-btn:hover { border-color: var(--swell); color: var(--ink); }
.hidden-docs summary {
  font-size: 11px; font-weight: 600; letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--muted); cursor: pointer; margin-bottom: 6px;
}

/* Pointing a client at its folder. Collapsed by default — it is setup, not
   something she reads every time she opens a client. */
.folders summary {
  font-size: 11px; font-weight: 600; letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--shallow); cursor: pointer; margin-bottom: 8px;
}
.folder-add { display: flex; gap: 8px; margin: 8px 0; }
.folder-add input {
  flex: 1; font: inherit; font-size: 13px; color: var(--ink);
  background: var(--sea); border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px;
}
.folder-add input::placeholder { color: var(--muted); }

/* Row controls sit on one line with the row, not wrapped underneath it.
   The buttons were laid out as if they were content — Done and the dismiss fell
   to a second line and read as belonging to the next item down. */
.work-evidence .row { flex-wrap: nowrap; gap: 8px; }
.work-evidence .row .main { flex: 1; min-width: 0; }
.work-evidence .row .u-btn,
.work-evidence .row .row-x,
.work-evidence .row .chip-select { flex: none; }

/* A status is one of a known set, so it is a select — typing invites a value
   the database will reject. */
.chip-select {
  font: inherit; font-size: 11px; color: var(--ink-2);
  background: var(--sea); border: 1px solid var(--line-strong);
  border-radius: 999px; padding: 3px 8px; cursor: pointer;
}
.chip-select:hover { border-color: var(--swell); color: var(--ink); }

.evhead .gear { margin-left: 4px; font-size: 14px; }
.sechead .add { float: right; font-size: 15px; line-height: 1; }
.work-evidence details.sec > summary { cursor: pointer; list-style: none; }
.work-evidence details.sec > summary::-webkit-details-marker { display: none; }
.work-evidence details.sec > summary::before {
  content: '▾'; display: inline-block; width: 12px; font-size: 9px;
  color: var(--muted); transition: transform 0.15s ease;
}
.work-evidence details.sec:not([open]) > summary::before { transform: rotate(-90deg); }

/* Spend: the number first, then the same money split by what spent it. */
.spend-heads { display: flex; gap: 28px; margin-bottom: 14px; }
.spend-heads .sub { display: block; margin-top: 2px; }
.spend-n { font-size: 26px; font-weight: 650; letter-spacing: -0.02em; }
/* Fourteen bars, no axes. Enough to see a step change; not a chart. */
.spend-bars { display: flex; align-items: flex-end; gap: 3px; height: 36px; margin: 6px 0 2px; }
.spend-bar { flex: 1; background: var(--swell); border-radius: 2px 2px 0 0; min-height: 2px; }
.spend-bar:last-child { background: var(--ochre); }

/* Undo toast. Bottom centre, above the capture bar, gone in six seconds. */
.toast {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 84px; z-index: 60;
  display: flex; align-items: center; gap: 14px;
  background: var(--card-2); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: 10px;
  padding: 10px 16px; font-size: 13px;
  box-shadow: 0 12px 32px rgba(3, 14, 24, 0.5);
}
.toast .text-btn { color: var(--ochre); font-weight: 600; }

/* Row actions: present but quiet until the row is under the pointer, so
   fourteen rows do not read as fourteen buttons. Snooze belongs to the same
   rule as archive — separating them left one permanently visible and the other
   permanently hidden, which is how the archive tick became a mystery. */
.row-x.archive,
.row-x.snooze { opacity: 0; transition: opacity 0.12s ease; }
.link-row:hover .row-x.archive,
.link-row:hover .row-x.snooze,
.row-x.archive:focus-visible,
.row-x.snooze:focus-visible { opacity: 1; }
@media (pointer: coarse) {
  .row-x.archive,
  .row-x.snooze {
    opacity: 0.78; width: 44px; height: 44px; margin-block: -10px;
    display: inline-grid; place-items: center;
  }
}
.mail-group summary .sweep { margin-left: auto; padding-left: 12px; }

/* Cmd+K. */
.palette {
  position: fixed; inset: 0; z-index: 70;
  background: rgba(4, 18, 31, 0.6); display: flex; justify-content: center; padding-top: 14vh;
}
.palette-box {
  position: relative;
  width: min(560px, calc(100vw - 40px)); height: fit-content;
  background: var(--night-2); border: 1px solid var(--line-strong);
  border-radius: 14px; overflow: hidden;
  box-shadow: 0 30px 80px rgba(3, 14, 24, 0.6);
}
#palette-input {
  width: 100%; font: inherit; font-size: 15px; color: var(--ink);
  background: none; border: 0; border-bottom: 1px solid var(--line); padding: 15px 54px 15px 18px;
}
.palette-close {
  position: absolute; z-index: 1; top: 7px; right: 8px; width: 36px; height: 36px;
  display: grid; place-items: center; border: 0; border-radius: 9px;
  color: var(--muted); background: transparent; font-size: 20px; line-height: 1;
}
.palette-close:hover { color: var(--ink); background: var(--card-2); }
@media (pointer: coarse) {
  .sheet-close, .palette-close { width: 44px; height: 44px; }
}
#palette-input:focus { outline: none; }
#palette-input::placeholder { color: var(--muted); }
.palette-list { max-height: 46vh; overflow-y: auto; padding: 6px; }
.palette-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  width: 100%; font: inherit; font-size: 14px; color: var(--ink); text-align: left;
  background: none; border: 0; padding: 9px 12px; border-radius: 8px; cursor: pointer;
}
.palette-row.on, .palette-row:hover { background: var(--card-2); }
.palette-row .sub { font-size: 11px; color: var(--muted); }

/* Keyboard cursor. A left edge rather than a fill: the row still reads as a
   row, and the marker survives whatever colouring the triage chip applies. */
.link-row.cursor { background: rgba(111, 168, 196, 0.09); box-shadow: inset 3px 0 0 var(--shallow); }

.snooze-menu {
  position: absolute; right: 12px; top: 100%; z-index: 40;
  display: flex; flex-direction: column; min-width: 150px;
  background: var(--night-2); border: 1px solid var(--line-strong);
  border-radius: 10px; padding: 4px; box-shadow: 0 14px 34px rgba(3, 14, 24, 0.5);
}
.snooze-menu button {
  font: inherit; font-size: 13px; color: var(--ink); text-align: left;
  background: none; border: 0; padding: 8px 10px; border-radius: 7px; cursor: pointer;
}
.snooze-menu button:hover { background: var(--card-2); }
.link-row { position: relative; }

/* A proposal Horizon could not resolve. Rose rather than ochre: ochre means
   "needs you", this means "nobody knows what happened", and they should not
   look the same. */
.proposal-unknown { box-shadow: inset 2px 0 0 var(--rose); padding-left: 11px; }
.proposal-unknown .sub { color: var(--rose); }
.note-failure { margin-top: 8px; }
.note-failure .title { color: var(--ink); }

/* ---------------------------------------------------------------- triage */
/* Where Sam corrects what Horizon believed. Ochre is "needs Sam" everywhere
   in this palette, so an unsure belief wears it — nothing new is invented. */

.triage-agreement { display: flex; flex-wrap: wrap; gap: 12px; margin: 0 0 16px; }
.triage-score { font-size: 12px; color: var(--ink-2); }
.triage-score strong { color: var(--ink); font-variant-numeric: tabular-nums; }
.triage-score.muted { color: var(--muted); }

.triage-item {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px 16px;
  margin-bottom: 12px;
}
.triage-item header { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.triage-item h3 { margin: 0; font-size: 15px; font-weight: 600; }
.triage-item .meta { flex-basis: 100%; margin: 2px 0 0; font-size: 12px; color: var(--muted); }

/* A message whose metadata predates the index, or aged out. Shown rather than
   hidden: an item Sam cannot review is worse when it is also invisible. */
.triage-item.is-unknown h3 { color: var(--muted); font-style: italic; }

.triage-beliefs { list-style: none; margin: 10px 0; padding: 0; }
.triage-beliefs li { font-size: 13px; color: var(--ink-2); padding: 2px 0; }
.triage-beliefs li.is-unsure { color: var(--ochre); }

.triage-controls { display: flex; flex-wrap: wrap; gap: 14px; margin: 10px 0; }
.triage-choice { display: flex; flex-direction: column; gap: 4px; }
.triage-dim { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.triage-choice select {
  background: var(--night-2);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 6px 8px;
  font: inherit;
  font-size: 13px;
  min-height: 40px; /* thumb-reachable */
}
.triage-actions { display: flex; flex-wrap: wrap; gap: 8px; }

/* ------------------------------------------------------------ mail rules */

.rules-actions { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.mailrule {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 16px;
  margin-bottom: 8px;
}
.mailrule-body { flex: 1; min-width: 0; }
.mailrule-claim { margin: 0; font-size: 14px; }
.mailrule .meta { margin: 2px 0 0; font-size: 12px; color: var(--muted); }
.mailrule.is-retired { opacity: 0.5; }
.mailrule-actions { display: flex; gap: 6px; flex-wrap: wrap; flex: none; }

/* The ambiguity marker on an Inbox row.
   A stored `ambiguous` belief means Horizon does not know, while the row still
   shows the header heuristic's guess. Presenting that guess unqualified is
   false certainty, so the row carries a small ochre ring — the same colour
   that means "needs Sam" everywhere else. */
.mail-unsure {
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  border: 1.5px solid var(--ochre);
  flex: none;
  margin-left: 6px;
  vertical-align: middle;
}

@media (max-width: 640px) {
  .triage-controls { flex-direction: column; gap: 10px; }
  .triage-choice select { width: 100%; }
}

/* -------------------------------------------------------------- settings */
/* Its own screen, with its own nav. It used to be a slide-out sheet holding a
   text-size control and a link to Connections, which put the largest surface in
   the app behind a footnote in the smallest one. */

.settings-shell { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 28px; align-items: start; }

.settings-nav { display: flex; flex-direction: column; gap: 2px; position: sticky; top: 16px; }
.settings-nav button {
  text-align: left;
  background: none;
  border: 0;
  color: var(--ink-2);
  font: inherit;
  font-size: 14px;
  padding: 9px 12px;
  border-radius: 8px;
  cursor: pointer;
  min-height: 40px; /* thumb-reachable */
}
.settings-nav button:hover { background: rgba(var(--ink-rgb), 0.06); color: var(--ink); }
.settings-nav button[aria-current='page'] {
  background: rgba(var(--ink-rgb), 0.09);
  color: var(--ink);
  font-weight: 600;
}

/* The way back, where a way back belongs. */
.settings-back {
  display: block;
  color: var(--muted);
  text-decoration: none;
  font-size: 13px;
  padding: 9px 12px;
  margin-bottom: 10px;
  border-radius: 8px;
}
.settings-back:hover { color: var(--ink); background: rgba(var(--ink-rgb), 0.06); }
/* In a topbar the link sits above the title rather than in the nav column, so
   it loses the nav's padding and keeps only its own line. */
.settings-back-inline { padding: 0; margin: 0 0 1px; font-size: 12px; }

.settings-body h2 { margin: 0 0 6px; font-size: 18px; }
.settings-body .label { margin-top: 18px; }
/* Detail lines in Settings wrap. The dashboard truncates them because density
   is doing work there; an explanation that stops mid-sentence is just wrong. */
.settings-body .sub-wrap { white-space: normal; overflow: visible; }

.changelog { max-width: 68ch; }
.changelog h2 { margin: 26px 0 4px; font-size: 16px; }
.changelog h3 { margin: 22px 0 4px; font-size: 15px; color: var(--ochre); }
.changelog h4 { margin: 16px 0 2px; font-size: 13px; color: var(--ink-2); }
.changelog p { margin: 0 0 10px; font-size: 13px; line-height: 1.6; color: var(--ink-2); }
.changelog code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  background: rgba(var(--ink-rgb), 0.07);
  padding: 1px 4px;
  border-radius: 4px;
}
.changelog a { color: var(--shallow); }

@media (max-width: 720px) {
  .settings-shell { grid-template-columns: 1fr; gap: 16px; }
  .settings-nav { position: static; flex-direction: row; flex-wrap: wrap; }
}

/* The morning-brief preview: plain text as written, wrapped rather than
   scrolled sideways, in the same ink as everything else. */
.brief-preview {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font: inherit;
  color: var(--ink-2);
  line-height: 1.6;
}

/* The connections panel — Google accounts, calendars, other sources.
   Shared, because it renders both on /connect (which must work signed out,
   being the sign-in page) and inside Settings. These lived only in
   connect.html's inline <style>, so lifting the panel into Settings without
   lifting these would have rendered it unstyled. */
.conn {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 12px 0; border-top: 1px solid var(--line);
}
.conn:first-of-type { border-top: 0; }
.conn .who { min-width: 0; }
.conn .who strong { display: block; font-size: 14px; }
.conn .who span { font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
.pill {
  font-size: 12px; padding: 7px 13px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card-2); white-space: nowrap;
}
.pill.go { background: var(--amber); color: var(--on-mass); border-color: var(--amber); font-weight: 600; text-decoration: none; }
.state-connected { color: var(--green); }
.state-error { color: var(--coral); }
.state-unconfigured, .state-unknown { color: var(--muted); }
.lead { color: var(--ink-2); font-size: 14px; margin-bottom: 18px; }

/* Proposals: the Track Record and the cards are two different things and used
   to run together as one undifferentiated column. The listing is now its own
   region with a rule above it — the summary of how Horizon has done, then the
   work itself. */
.proposal-listing { margin-top: 26px; border-top: 1px solid var(--line-strong); padding-top: 18px; }
.proposal-listing-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 12px;
}
.proposal-listing-head h2 { font-size: 15px; margin: 0; }
.proposal-controls { display: flex; gap: 8px; align-items: center; }
.proposal-filters { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }

/* What the card is about. The one line that was missing: a card naming its
   verb but not its subject cannot be acted on. */
.proposal-source {
  display: inline-block; margin: 2px 0 4px;
  font-size: 12px; color: var(--teal); text-decoration: none;
  overflow-wrap: anywhere;
}
a.proposal-source:hover { text-decoration: underline; }
.proposal-source.lost { color: var(--muted); font-style: italic; }

/* The refusal that names what is possible instead of stopping at "no". */
.can-do { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.u-btn.tiny { font-size: 11px; padding: 4px 9px; }
.bulk-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* What Horizon read. The verdict sits right, the extracted notes below the
   summary, so the page can be scanned for the things worth keeping. */
.learning .highlights { margin: 6px 0 0; padding-left: 18px; }
.learning .highlights li { font-size: 12px; color: var(--ink-2); line-height: 1.5; }
.learning-summary { margin-top: 4px; }
.learning-selling { opacity: 0.72; }

/* The sweep offer. Ochre, because it is a thing waiting on Sam. */
.sweep-offer { border-color: rgba(217, 175, 99, 0.4); background: rgba(217, 175, 99, 0.07); }
.sweep-offer.confirming { border-color: var(--amber); }
.sweep-offer .title { font-size: 15px; }
.sweep-senders { display: grid; gap: 2px; margin-top: 10px; }
.sweep-sender { padding: 8px 0; border-top: 1px solid var(--line); }
.sweep-sender .right { display: flex; gap: 6px; }
.sweep-subjects { margin: 6px 0 0; max-height: 220px; overflow-y: auto; }
.sweep-confirm { padding: 10px 0; }
.sweep-tagger { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.sweep-group { margin-top: 14px; }
.sweep-group-head {
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--ink-2); display: flex; align-items: center; gap: 8px;
}
.sweep-group-head { justify-content: space-between; }
.sweep-group-toggle {
  display: flex; align-items: center; gap: 8px;
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: inherit; text-transform: inherit; letter-spacing: inherit;
}
.sweep-caret { font-size: 10px; opacity: 0.7; }

/* The group confirm renders inside the group header, which is small, uppercase
   and letter-spaced. Without this reset the card inherits all three and reads
   as a shout: "ARCHIVE 7 FROM 2 SENDERS? THEY LEAVE YOUR GMAIL INBOX." */
.sweep-group-head .sweep-confirm {
  text-transform: none;
  letter-spacing: normal;
  font-size: 14px;
  color: var(--ink);
  width: 100%;
}
.sweep-group-head .sweep-confirm .sub { font-size: 12px; color: var(--ink-2); }
.sweep-group-head .sweep-confirm .title { font-size: 15px; }
.older-note { margin-top: 8px; color: var(--amber); }
.older-list { margin-top: 4px; }
.search-note { margin-top: 6px; color: var(--ink-2); font-size: 11px; }
.learning-fix { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 8px; }
.linkish {
  background: none; border: 0; padding: 0; font: inherit; color: var(--teal);
  cursor: pointer; text-align: left;
}
.linkish:hover { text-decoration: underline; }
.learning-tag { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 8px; }
.learning-tagger { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.tag-scope { color: var(--amber); }

/* The read. A digest is scanned for the one thing worth catching, so the
   subject is the link and everything else sits under it quietly. */
.digest-section { margin-top: 18px; }
.digest-item { padding: 10px 0; border-top: 1px solid var(--line); }
.digest-item:first-of-type { border-top: 0; }
.digest-subject { font-size: 14px; color: var(--ink); text-decoration: none; }
.digest-subject:hover { text-decoration: underline; }
.digest-summary { margin-top: 4px; }

/* ------------------------------------------------------------- mail tabs */
/* One rail entry, five screens. The strip sits where a section head would and
   reads as part of the page rather than as a second navigation. */
.mail-tabs {
  display: flex; flex-wrap: wrap; gap: 4px;
  margin-bottom: var(--gap); padding: 4px;
  background: rgba(var(--ink-rgb), 0.04);
  border: 1px solid var(--line); border-radius: 12px;
}
.mail-tab {
  display: flex; align-items: center; gap: 6px;
  padding: 7px 13px; border-radius: 9px;
  color: var(--muted); text-decoration: none;
  font-size: 13px; font-weight: 560; white-space: nowrap;
}
.mail-tab:hover { color: var(--ink); }
.mail-tab[aria-current="page"] {
  background: rgba(var(--ink-rgb), 0.1); color: var(--ink); font-weight: 660;
}
.tab-count {
  font-size: 11px; font-variant-numeric: tabular-nums; font-weight: 700;
  background: var(--ochre); color: var(--on-accent);
  border-radius: 999px; min-width: 17px; text-align: center; padding: 1px 5px;
}
.tab-count:empty { display: none; }

/* Engagements Notion holds that no client on this screen can show.
 *
 * Spans by inheriting `.work-split > *`; see the note there for why that is the
 * default rather than something each child declares.
 *
 * Ochre inset rule rather than a filled panel, matching `.row.owe`: this is the
 * "needs Sam" colour, and the fix is hers to make in Notion. The Great Wave has
 * one bright mass and it is the urgent strip — a housekeeping note about two
 * unlinked rows does not get to compete with it. Its first version used
 * `--card-2`, lighter than the page ground, and read as the loudest thing on
 * the screen.
 */
.work-unlinked {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px;
  padding: 9px 15px;
  border-bottom: 1px solid var(--line);
  box-shadow: inset 2px 0 0 var(--ochre);
  font-size: 13px; line-height: 1.45;
}
.work-unlinked strong { font-weight: 600; color: var(--ink); }
.work-unlinked .sub { color: var(--muted); font-size: 12px; }
/* Links run inline on the same baseline. Stacked block anchors turned four
   words of advice into a column six lines tall. */
.work-unlinked a { color: var(--shallow); font-size: 12px; white-space: nowrap; }
.work-unlinked a + a::before {
  content: "·"; color: var(--muted); margin-right: 10px; text-decoration: none;
}

/* Engagement rows reuse `.row`'s three tracks. The Notion link lives in the
   third and stays quiet until hovered — it is an exit, not the point of the row. */
.work-evidence .row.engagement .when { font-size: 11px; color: var(--muted); }
.work-evidence .row.engagement .right { color: var(--muted); text-decoration: none; }
.work-evidence .row.engagement:hover .right { color: var(--shallow); }
.work-evidence .row.engagement .sub {
  font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--shallow);
}

/* What a Notion token can reach. Indented under its integration row so the
   list reads as an answer to that row rather than a new section. */
.probe-out { padding: 4px 0 10px 12px; border-left: 2px solid var(--line); margin: 0 0 8px; }
.probe-out .lead { font-size: 12px; color: var(--muted); margin: 6px 0; }
.probe-out .conn .who span { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; }

/* -------------------------------------------------------------- to do list */
/* A dense table, because it replaces a spreadsheet and the density was the
   point: nine columns Sam scans across, not nine lines she scrolls through. */
.todo-add {
  display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px;
}
.todo-add input {
  flex: 1 1 130px; min-width: 0;
  background: rgba(var(--ink-rgb), 0.06);
  border: 1px solid var(--line); border-radius: 10px;
  padding: 9px 11px; color: var(--ink); font: inherit; font-size: 13px;
}
.todo-add input::placeholder { color: var(--muted); }
.todo-add input:focus { outline: none; border-color: var(--shallow); }
.todo-add button[type="submit"] {
  flex: none; padding: 9px 18px; border-radius: 10px;
  background: var(--mass); color: var(--on-mass); font-weight: 640; font-size: 13px;
}
.todo-date { flex: 1 1 130px; display: flex; }
.todo-date input { width: 100%; }

.todo-toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }

.todo-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.todo-table th { text-align: left; font-weight: 600; white-space: nowrap; }
.todo-table th button {
  display: flex; align-items: center; gap: 4px;
  padding: 7px 8px; width: 100%;
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--muted);
}
.todo-table th button:hover { color: var(--ink); }
.todo-table th[aria-sort] button { color: var(--ink); }
.todo-arrow { font-size: 10px; }
.todo-table td { padding: 9px 8px; border-top: 1px solid var(--line); vertical-align: top; }
.todo-table tbody tr:hover { background: rgba(var(--ink-rgb), 0.04); }
.todo-overdue { color: var(--rose); font-weight: 620; white-space: nowrap; }
.todo-today { color: var(--ochre); font-weight: 620; white-space: nowrap; }
.todo-table tr.is-done td { opacity: 0.45; text-decoration: line-through; }
.todo-actions { white-space: nowrap; text-align: right; }
.todo-actions button {
  padding: 3px 7px; border-radius: 7px; color: var(--muted);
  border: 1px solid transparent;
}
.todo-actions button:hover { color: var(--ink); border-color: var(--line); }

/* Nine columns do not fit a phone, so the card scrolls sideways rather than
   wrapping each row into an unreadable block. */
@media (max-width: 760px) {
  .todo-table { min-width: 720px; }
  #view-todo .card.scroll { overflow-x: auto; }
}
