/* Hand-written, no framework. Colours are tokens on :root; dark mode follows
   the OS. No inline styles anywhere (CSP style-src 'self'). */
/* COLOURS ARE THE MAC'S `memoratu` THEME, read from ThemeCatalog in
   mac/Memoratu/Design/Theme.swift rather than re-picked here, so the two
   clients cannot drift. Only the default theme is carried: the Mac's picker
   has six and nothing on the server stores a choice, so offering one here
   would be a preference with nowhere to live. */
:root {
  --bg: #f7f6fb; --surface: #ffffff; --ink: #111827; --muted: #6b7280; --line: #e4e2ef;
  --accent: #4f46e5; --accent-ink: #ffffff; --success: #ff7a59; --list-accent: #0f766e;
  --danger: #c62828; --warn-bg: #fff3d6; --warn-ink: #6a4a00;
  --info-bg: #e8f0fe; --info-ink: #17407f; --radius: 10px; --gap: 12px; --touch: 44px;
  /* Pane widths. The ONLY place a width lives — see js/views/shell.js.
     Starting values are the Mac's Tokens.Metrics ideals. */
  --sb-w: 236px; --lp-w: 360px;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #12111a; --surface: #1c1b27; --ink: #f3f2fa; --muted: #9a98ad; --line: #2d2b3d;
    --accent: #8b85ff; --accent-ink: #0b1a38; --success: #ff7a59; --list-accent: #0f766e;
    --danger: #ff7b72; --warn-bg: #3a2e0a; --warn-ink: #ffd98a;
    --info-bg: #14233f; --info-ink: #a9c6ff;
  }
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 16px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
  padding-bottom: env(safe-area-inset-bottom);
}
#app { min-height: 100vh; display: flex; flex-direction: column; }
main { flex: 1; width: 100%; max-width: 720px; margin: 0 auto; padding: 0 16px 96px; }
h1, h2, h3 { margin: 0; line-height: 1.2; }
h2 { font-size: 1.4rem; margin: 20px 0 14px; }
.section { font-size: .8rem; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); margin: 24px 0 8px; }
a { color: var(--accent); }
.muted { color: var(--muted); }
.mono { font-family: ui-monospace, Menlo, monospace; font-size: .75rem; word-break: break-all; }

/* top bar */
.top { display: flex; align-items: center; gap: var(--gap); padding: 10px 16px; padding-top: calc(10px + env(safe-area-inset-top));
  border-bottom: 1px solid var(--line); background: var(--surface); position: sticky; top: 0; z-index: 5; }
.top .who { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: .85rem; text-align: right; }
.brand { font-weight: 700; letter-spacing: -.02em; }
.brand.small { font-size: 1rem; }
.tag { color: var(--muted); font-weight: 400; }

/* nav: bottom tab bar on phones, top tabs on wide screens */
.nav { position: fixed; left: 0; right: 0; bottom: 0; display: flex; background: var(--surface);
  border-top: 1px solid var(--line); padding-bottom: env(safe-area-inset-bottom); z-index: 5; }
.nav a { flex: 1; text-align: center; padding: 12px 0; min-height: var(--touch); text-decoration: none; color: var(--muted); font-weight: 600; }
.nav a.on { color: var(--accent); }
@media (min-width: 720px) {
  .nav { position: static; border: 0; max-width: 720px; margin: 0 auto; width: 100%; order: 1; background: transparent; }
  .nav a { flex: 0 0 auto; padding: 8px 18px; }
  #app { display: flex; flex-direction: column; }
  .top { order: 0; } .banners { order: 0; } main { order: 2; padding-bottom: 48px; }
}

/* banners */
.banners:empty { display: none; }
.banner { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 10px 16px; font-size: .9rem; }
.banner.warn { background: var(--warn-bg); color: var(--warn-ink); }
.banner.info { background: var(--info-bg); color: var(--info-ink); }
.banner > span:first-child { flex: 1 1 220px; }

/* buttons + inputs (16px font: iOS Safari will not zoom on focus) */
.btn { font: inherit; font-weight: 600; min-height: var(--touch); padding: 0 16px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--surface); color: var(--ink); cursor: pointer; }
.btn.small { min-height: 36px; padding: 0 12px; font-size: .9rem; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn.ghost { background: transparent; }
.btn.danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn.wide { width: 100%; }
.btn:disabled { opacity: .5; cursor: default; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
input[type=text], input[type=email], input[type=password] { font: inherit; width: 100%; min-height: var(--touch); padding: 0 12px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); color: var(--ink); }

/* composer */
.composer { display: flex; gap: 8px; margin-bottom: 16px; }
.composer-input { flex: 1; }

/* todos */
.todos { list-style: none; margin: 0; padding: 0; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); }
.todos:empty { display: none; }
.todo { border-bottom: 1px solid var(--line); padding: 4px 8px; }
.todo:last-child { border-bottom: 0; }
.todo.unsaved { opacity: .75; }
.row-main { display: flex; align-items: center; gap: 4px; }
.check { flex: 0 0 var(--touch); height: var(--touch); background: none; border: 0; cursor: pointer; position: relative; font-size: 1rem; color: var(--accent-ink); }
.check::before { content: ""; position: absolute; inset: 11px; border: 2px solid var(--muted); border-radius: 50%; }
.check.on::before { background: var(--accent); border-color: var(--accent); }
.check span, .check.on { z-index: 1; }
.check:disabled { cursor: default; opacity: .5; }
.title { flex: 1; min-width: 0; text-align: left; font: inherit; background: none; border: 0; color: var(--ink);
  padding: 10px 4px; min-height: var(--touch); cursor: pointer; overflow-wrap: anywhere; }
.title.clamp { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.title.done { text-decoration: line-through; color: var(--muted); }
.title-edit { flex: 1; display: flex; gap: 6px; padding: 4px 0; flex-wrap: wrap; }
.title-edit .edit { flex: 1 1 200px; }
.row-state { font-size: .85rem; padding: 0 8px 8px var(--touch); }
.row-state.failed { color: var(--danger); }
.row-state.saving { color: var(--muted); }
.row-actions { display: inline-flex; gap: 8px; margin-left: 8px; flex-wrap: wrap; }
.detail { padding: 0 8px 12px var(--touch); }
.notes { white-space: pre-wrap; overflow-wrap: anywhere; font: inherit; margin: 0 0 8px; }
.meta { font-size: .85rem; color: var(--muted); margin: 2px 0; }
.confirm { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.empty { color: var(--muted); padding: 24px 0; }
.note { color: var(--muted); font-size: .85rem; margin-top: 24px; }
.crumb { margin: 16px 0 -8px; font-size: .9rem; }

/* projects */
.group { margin-bottom: 20px; }
.group-head { display: block; font-weight: 700; margin-bottom: 8px; text-decoration: none; color: var(--ink); font-size: 1.05rem; }
.group-head.plain { color: var(--muted); font-size: .85rem; text-transform: uppercase; letter-spacing: .06em; }
.cards { display: grid; gap: 8px; }
.card { display: flex; justify-content: space-between; align-items: center; min-height: var(--touch); padding: 10px 14px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); text-decoration: none; color: var(--ink); margin-bottom: 8px; }
.cards .card { margin-bottom: 0; }
.badge { color: var(--muted); font-variant-numeric: tabular-nums; }

/* sign-in */
.auth-page { max-width: 380px; padding-top: 12vh; }
.auth-page .brand { font-size: 2rem; }
.auth { display: flex; flex-direction: column; gap: 6px; margin-top: 24px; }
.auth label { font-size: .85rem; color: var(--muted); margin-top: 8px; }
.auth .btn { margin-top: 16px; }
.error { color: var(--danger); margin: 8px 0 0; }
.notice { background: var(--info-bg); color: var(--info-ink); padding: 10px 12px; border-radius: var(--radius); margin-top: 16px; }
[hidden] { display: none !important; }

.zone { color: var(--muted); font-size: .9rem; margin: -6px 0 12px; }
.row-due { font-size: .8rem; color: var(--muted); padding: 0 8px 8px var(--touch); margin-top: -8px; }
.field { display: block; font-size: .85rem; color: var(--muted); margin: 16px 0 4px; }
select { font: inherit; width: 100%; min-height: var(--touch); padding: 0 12px; border: 1px solid var(--line);
  border-radius: var(--radius); background: var(--surface); color: var(--ink); }
.form-actions { margin: 16px 0 8px; }
.ok { color: var(--accent); margin: 8px 0 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   THE THREE-PANE SHELL
   ═══════════════════════════════════════════════════════════════════════════
   One CSS grid. Widths are --sb-w and --lp-w, written by js/views/shell.js and
   nowhere else; the dividers are grid items, so a drag is one property write
   and the browser does every layout calculation.

   Collapsing is a CLASS on the grid (.no-sb / .no-dt) which sets that track to
   0. There is no JS measurement anywhere, and no pane can be collapsed by
   dragging — the setter clamps at the Mac's minimum width instead. The only
   way to collapse is the labelled button in the top bar, which is always
   present and always says what it will do. (Mac REQ-001058: a collapsed pane
   with no way back is indistinguishable from a broken app.)
   ═════════════════════════════════════════════════════════════════════════ */
.shell { display: flex; flex-direction: column; height: 100vh; height: 100dvh; }
.shell .top { flex: 0 0 auto; }
.shell .banners { flex: 0 0 auto; }
.top-tools { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.top .prefix { margin-left: auto; font-family: ui-monospace, Menlo, monospace;
  background: var(--accent); color: var(--accent-ink); border-radius: 6px; padding: 2px 8px; font-size: .8rem; }

.grid {
  flex: 1 1 auto; min-height: 0;
  display: grid;
  grid-template-columns: var(--sb-w) 6px var(--lp-w) 6px minmax(0, 1fr);
  background: var(--bg);
}
.grid.no-sb { grid-template-columns: 0 0 var(--lp-w) 6px minmax(0, 1fr); }
.grid.no-dt { grid-template-columns: var(--sb-w) 6px var(--lp-w) 0 0; }
.grid.no-sb.no-dt { grid-template-columns: 0 0 minmax(0, 1fr) 0 0; }
.pane { min-width: 0; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }
.grid.no-sb .sb-pane, .grid.no-dt .dt-pane { display: none; }
.sb-pane { background: var(--bg); border-right: 1px solid var(--line); }
.lp-pane { background: var(--surface); }
.dt-pane { background: var(--bg); border-left: 1px solid var(--line); }

.divider { cursor: col-resize; background: var(--line); opacity: .5; }
.divider:hover, .divider:focus-visible { opacity: 1; background: var(--accent); }
.grid.no-sb > .divider:first-of-type, .grid.no-dt > .divider:last-of-type { display: none; }
body.dragging { cursor: col-resize; user-select: none; }

/* ---- sidebar ------------------------------------------------------------- */
.sb { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.sb-scroll { flex: 1 1 auto; overflow-y: auto; padding: 8px 6px 12px; }
.sb-head { font-size: .7rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); padding: 14px 10px 4px; font-weight: 700; }
.sb-row { display: flex; align-items: center; gap: 8px; width: 100%;
  font: inherit; font-size: .92rem; text-align: left; background: none; border: 0;
  color: var(--ink); padding: 6px 10px; border-radius: 7px; cursor: pointer; min-height: 30px; }
.sb-row:hover { background: var(--line); }
.sb-row.on { background: var(--accent); color: var(--accent-ink); }
.sb-row.on .sb-count, .sb-row.on .sb-ico { color: inherit; opacity: .85; }
.sb-row.d1 { padding-left: 30px; }
.sb-row.project { flex: 1; color: var(--success); font-weight: 600; }
.sb-row.project.on { color: var(--accent-ink); }
.sb-row.permanent .sb-label { font-weight: 600; }
.sb-ico { flex: 0 0 16px; text-align: center; color: var(--muted); font-size: .85rem; }
.sb-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sb-count { color: var(--muted); font-variant-numeric: tabular-nums; font-size: .8rem; }
.sb-proj { display: flex; align-items: center; }
.sb-twist { flex: 0 0 18px; background: none; border: 0; color: var(--muted); cursor: pointer;
  font-size: .7rem; padding: 0; transition: transform .12s; }
.sb-twist.open { transform: rotate(90deg); }
.sb-twist.blank { cursor: default; }
.sb-note { color: var(--muted); font-size: .8rem; padding: 4px 10px; margin: 0; }
/* Pinned, outside the scroller, never scrolls away — Mac REQ-001061. */
.sb-profile { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; margin: 0 6px 8px;
  padding: 8px 10px; font: inherit; font-size: .85rem; text-align: left; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line); border-radius: 7px; color: var(--ink); }
.sb-profile.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* ---- list pane ---------------------------------------------------------- */
.lp { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.lp-head { flex: 0 0 auto; padding: 14px 16px 10px; border-bottom: 1px solid var(--line); }
.lp-title { font-size: 1.25rem; }
.lp-sub, .lp-zone { color: var(--muted); font-size: .82rem; margin: 2px 0 0; }
.lp-scroll { flex: 1 1 auto; overflow-y: auto; }
.lp-rows { list-style: none; margin: 0; padding: 0; }
.lp-row { display: flex; align-items: center; border-bottom: 1px solid var(--line); }
.lp-row.on { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.lp-row.unsaved { opacity: .7; }
.lp-pick { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 10px;
  font: inherit; text-align: left; background: none; border: 0; color: var(--ink);
  padding: 11px 14px 11px 0; cursor: pointer; }
/* §3.7: the list truncates for the eye, the detail pane shows it in full. */
.lp-row-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--accent); }
.lp-row-title.done { text-decoration: line-through; color: var(--muted); }
.lp-row-due, .lp-row-state { flex: 0 0 auto; font-size: .76rem; color: var(--muted); }
.lp-row-state.failed { color: var(--danger); }
.lp-empty { color: var(--muted); padding: 28px 16px; margin: 0; }
.lp-add { flex: 0 0 auto; display: flex; gap: 8px; padding: 10px 14px;
  border-top: 1px solid var(--line); background: var(--surface); }
.lp-add-in { flex: 1; min-height: 36px; }
.lp-add-note { flex: 0 0 auto; padding: 12px 16px; margin: 0; font-size: .8rem;
  border-top: 1px solid var(--line); }

/* ---- detail pane -------------------------------------------------------- */
.dt { height: 100%; overflow-y: auto; }
.dt-pad { padding: 16px; display: flex; flex-direction: column; gap: 4px; }
.dt-top { display: flex; align-items: center; gap: 4px; margin-bottom: 4px; }
.dt-cap { font-size: .7rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); margin: 14px 0 4px; font-weight: 700; }
.dt-title-in { font-size: 1.2rem; font-weight: 600; color: var(--accent);
  background: var(--surface); width: 100%; }
.dt-notes-in { font: inherit; width: 100%; padding: 10px 12px; color: var(--muted);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); resize: vertical; }
.dt-due-in { font: inherit; min-height: 36px; padding: 0 10px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); }
.dt-zone { color: var(--muted); font-size: .78rem; margin: 4px 0 0; }
.dt-where { margin: 0; }
.dt-bar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 18px; }
.dt-hint { font-size: .8rem; }
.dt-empty { padding: 40px 20px; text-align: center; }
.dt-empty-head { font-weight: 600; margin: 0 0 4px; }
.dt-gone { color: var(--danger); font-weight: 600; margin: 0 0 6px; }
.danger-text { color: var(--danger); }
/* The leave-guard's sheet. Inside the pane, NOT a modal over the whole app:
   it is about the thing in this pane, and a window-wide overlay for it would
   be the discourtesy the Mac's gate-001 R2 argued against. */
.dt-sheet { margin: 12px; padding: 14px; background: var(--warn-bg); color: var(--warn-ink);
  border: 1px solid var(--line); border-radius: var(--radius); }
.dt-sheet-head { font-weight: 700; margin: 0 0 4px; }
.dt-sheet .muted { color: inherit; opacity: .85; }

/* ---- the shortcut sheet ------------------------------------------------- */
.ks-back { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 50;
  display: flex; align-items: center; justify-content: center; padding: 20px; }
.ks { background: var(--surface); color: var(--ink); border-radius: 14px; border: 1px solid var(--line);
  max-width: 680px; width: 100%; max-height: 86vh; overflow-y: auto; padding: 20px; }
.ks-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.ks-intro { font-size: .84rem; margin: 8px 0 0; }
.ks-group { margin-top: 18px; }
.ks-group .section { margin: 0 0 6px; }
.ks-row { display: grid; grid-template-columns: 110px 1fr; gap: 4px 12px; padding: 5px 0;
  border-bottom: 1px solid var(--line); }
.ks-key { font-family: ui-monospace, Menlo, monospace; font-size: .85rem; background: var(--bg);
  border: 1px solid var(--line); border-radius: 6px; padding: 1px 6px; justify-self: start; }
.ks-label { font-size: .92rem; }
.ks-note { grid-column: 2; color: var(--muted); font-size: .76rem; }
.ks-dead { opacity: .55; }
.ks-dead .ks-key { text-decoration: line-through; }

/* ═══════════════════════════════════════════════════════════════════════════
   NARROW SCREENS
   The grid collapses to the middle pane alone, and the two side panes become
   overlays. shell.js starts them collapsed below 900px and resets on crossing
   the breakpoint, so the state is a function of the viewport rather than a
   remembered desktop choice applied to a phone. The buttons that bring them
   back are in the top bar at every width.
   ═════════════════════════════════════════════════════════════════════════ */
@media (max-width: 900px) {
  .grid, .grid.no-sb, .grid.no-dt, .grid.no-sb.no-dt { grid-template-columns: minmax(0, 1fr); }
  .divider { display: none; }
  .sb-pane, .dt-pane {
    position: fixed; top: 0; bottom: 0; width: min(88vw, 360px); z-index: 40;
    box-shadow: 0 0 40px rgba(0,0,0,.35); border: 0;
  }
  .sb-pane { left: 0; background: var(--surface); }
  .dt-pane { right: 0; background: var(--surface); }
  .grid.no-sb .sb-pane, .grid.no-dt .dt-pane { display: none; }
  .lp-pane { grid-column: 1; }
}

/* THE COMPLETION TICK WAS INVISIBLE, and had been since before this round.
   `.check::before` is an ABSOLUTELY POSITIONED pseudo-element, and a
   positioned box paints above its parent's in-flow text — so the filled circle
   covered the ✓ it was supposed to sit behind. The existing
   `.check span, .check.on { z-index: 1 }` could not help: the ✓ is a bare text
   node, not a span, so there was no element for that rule to lift.
   Pushing the circle BEHIND needs the parent to make its own stacking context,
   or z-index:-1 would drop it behind the row as well. */
.check { display: inline-flex; align-items: center; justify-content: center; isolation: isolate; }
.check::before { z-index: -1; }
