/* ═══════════════════════════════════════════════════════════════════════
   Ergon · Coda Design System
   Implemented from "Ergon Design Spec" sheet 01 (docs/design/mockups/).
   Rules that govern everything below:
     · surfaces are separated by outline, not shadow — one charcoal outline
       per surface, hairlines inside, never two charcoal outlines nested
     · electric blue does exactly one job per screen (primary action /
       active nav / focus) — never decoration
     · status marks sit on their own pastel; text on pastel is charcoal
     · numerals in data are tabular, always
   ═══════════════════════════════════════════════════════════════════════ */

@font-face { font-family: "Hanken Grotesk";
             src: url("fonts/hankengrotesk-var.woff2") format("woff2");
             font-weight: 300 900; font-display: swap; }
@font-face { font-family: "DM Mono";
             src: url("fonts/dmmono-regular.woff2") format("woff2");
             font-weight: 400; font-display: swap; }

:root {
  /* surfaces */
  --bg:         #F8F9EB;
  --panel:      #FFFFFF;
  --panel-sub:  rgba(32,32,32,.04);
  --panel-dark: #202020;

  /* ink */
  --ink:        #202020;
  --muted:      #5A5A4F;
  --faint:      #626258;   /* ≥4.5:1 on --bg at 12px (was #6E6E62, ~4.3:1) */
  --ink-inverse:#F8F9EB;
  --ink-inverse-muted: rgba(248,249,235,.66);
  --inverse-hover:     rgba(248,249,235,.07);  /* hover/field fill on charcoal */  /* Coda text-inverse-secondary: the ONE muted-on-charcoal */

  /* lines */
  --line:        rgba(32,32,32,.14);
  --line-mid:    rgba(32,32,32,.28);
  --line-strong: #202020;
  --line-inverse:rgba(248,249,235,.32);

  /* accent — one job per screen */
  --accent:      #002EFF;
  --accent-ink:  #F8F9EB;
  --accent-deep: #041668;
  --accent-soft: #B0F4FF;
  --sage:        #C0C2A9;
  --sage-fill:   #DFDFD9;

  /* status — mark on its own pastel */
  --green:       #007C44;
  --green-soft:  #ABF7C0;
  --amber:       #ED7D31;
  --amber-soft:  #FFE8CA;
  --amber-ink:   #A8521A;   /* amber as TEXT: 5.1:1 on cream; --amber is 2.6:1 (health check D11) */
  --red:         #B12F19;
  --red-soft:    #FFE0D3;
  --danger:      #B12F19;
  --red-edge:    rgba(177,47,25,.45);  /* outline of a red mark */
  --green-edge:  rgba(0,124,68,.45);   /* outline of a green mark */

  /* type */
  --font-sans: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "DM Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* focus — 2px halo + 2px ring */
  --focus-ring: 0 0 0 2px #F8F9EB, 0 0 0 4px #002EFF;

  /* motion */
  --dur-1: 120ms;
  --dur-2: 180ms;
  --dur-3: 320ms;
  --ease: cubic-bezier(.16,1,.3,1);

  /* Type ramp — the spec's nine steps. Every font-size reads from these;
     a size that isn't on the ramp is a decision, not a default. */
  --fs-display: 34px; --fs-stat: 40px; --fs-h1: 26px; --fs-h2: 20px;
  --fs-md: 16px; --fs-base: 14px; --fs-sm: 13px; --fs-xs: 12px;
  --fs-label: 11px;
  /* Block-margin scale. Deliberately NOT applied to sub-12px gaps —
     those were tuned optically and re-gridding them is a redesign. */
  /* One control height: a .btn was 32px, a select 39px and a .btn.tiny
     24px, so any toolbar with two kinds of control had three edges. */
  --ctl-h: 34px; --ctl-h-sm: 26px;

  /* Corner scale (Ergon spec, on Coda's): chip 6 · control 8 ·
     field/panel 12 · card 22 · pill. Data marks (chart bars) keep their own. */
  --radius-chip: 6px; --radius-sm: 8px; --radius-md: 12px; --radius-lg: 22px; --radius-pill: 999px;
  /* Four layers, named (design audit): menus/pickers/tooltips; the phone's
     sticky chrome; the phone's More sheet; overlays. 1–8 are local order
     inside a table's frozen pane only. */
  --z-popover: 40; --z-chrome: 60; --z-sheet: 70; --z-overlay: 90;
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
  --space-5: 20px; --space-6: 26px; --space-7: 32px; --space-8: 40px;
  --space-9: 56px; --space-10: 72px; --gutter: 14px;

  --panel-hover: #FDFDF7;   /* off-white lifted one step  */
  --green-band:  #CFEBD4;   /* green-soft, one step down   */
  --sage-hover:  #EFF0DE;   /* bg tinted with sage         */
  --fs-code: 12.5px;   /* mono runs optically larger; all code chrome shares this */

  /* the only two shadows allowed */
  --shadow-popover: 0 6px 20px rgba(32,32,32,.14);
  --shadow-overlay: 0 18px 48px rgba(32,32,32,.22);
}

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
* { box-sizing: border-box; }
[hidden] { display: none !important; }

body { margin: 0; font-weight: 400; font-size: var(--fs-base); line-height: 1.45; font-family: var(--font-sans);
       background: var(--bg); color: var(--ink);
       -webkit-font-smoothing: antialiased; }
a { color: inherit; }
form { margin: 0; }  /* every context was zeroing this locally */

/* ── Type registers ─────────────────────────────────────────────────── */
h1 { font-size: var(--fs-h1); font-weight: 700; letter-spacing: -.015em;
     line-height: 1.15; margin: 0 0 var(--space-3); }
/* A card title, not a section heading — a heading inside a page is
   .section-head. Scoped so a bare <h2> can't quietly become a third
   treatment again. */
.settings-card h2, .card h2, .summary-block h2 {
  font-size: var(--fs-h2); font-weight: 700; letter-spacing: -.01em;
  margin: 0 0 var(--space-3); }
h3 { font-size: var(--fs-md); font-weight: 600; margin: 0 0 var(--space-2); }
.muted { color: var(--muted); font-weight: 400; }
.display { font-weight: 800; letter-spacing: -.02em; line-height: 1; }
/* The mono label register, declared once. Eighteen rules used to
   re-declare these four properties, which is exactly how one of them
   drifts to 12px or .04em tracking without anyone noticing. */
.label, .eyebrow, .brand-sub, .pinned-title, .crumbs, .section-head,
.rail-head, .col-group, .quarter-band, .key-hint,
.week-nav,
.comment-head .muted, table.tasks th, tr.section-band td.band-cell,
.hero-dark .eyebrow-row {
  font-family: var(--font-mono); font-size: var(--fs-label);
  font-weight: 400; letter-spacing: .1em; text-transform: uppercase; }
.label, .eyebrow { color: var(--muted); }
td.due, td.age, .col-value
  { font-variant-numeric: tabular-nums; }

/* ── Shell: charcoal sidebar, off-white main ────────────────────────── */
.shell { display: flex; min-height: 100vh; }
.sidebar { width: 216px; flex-shrink: 0; padding: var(--space-5) var(--gutter);
           background: var(--panel-dark); color: var(--ink-inverse);
           display: flex; flex-direction: column; gap: var(--space-5);
           position: sticky; top: 0; height: 100vh; overflow-y: auto; }
.brand { text-decoration: none; display: flex; flex-direction: column;
         padding: 0 var(--space-2); }
.brand-name { font-weight: 800; font-size: var(--fs-h2); letter-spacing: .01em;
              text-transform: uppercase; color: var(--ink-inverse); }
.brand-sub { font-family: var(--font-mono); font-size: var(--fs-label);
             letter-spacing: .1em; color: var(--ink-inverse-muted); }
.brand.center { align-items: center; margin-bottom: var(--space-4); }
.brand.center .brand-name { color: var(--ink); }
.auth-card .brand-sub { color: var(--muted); }

.nav-search { display: flex; position: relative; }
.nav-search input[type=search] { width: 100%; background: var(--inverse-hover); border: 1px solid var(--line-inverse); border-radius: var(--radius-sm); color: var(--ink-inverse); padding: 7px 10px; font: inherit; font-size: var(--fs-sm); height: 32px; }
.nav-search input[type=search]::placeholder { color: var(--ink-inverse-muted); }

/* Global quick-capture, under the search box. Closed it is one row; open
   it is a three-field form in the same dark chrome. */
.quick-cap > summary { list-style: none; cursor: pointer; display: flex;
  align-items: center; gap: var(--space-2); padding: 7px 10px; border-radius: var(--radius-sm);
  color: var(--ink-inverse-muted); font-size: var(--fs-sm); font-weight: 500; }
.quick-cap > summary::-webkit-details-marker { display: none; }
.quick-cap > summary:hover { background: var(--inverse-hover); }
.quick-cap > summary .key-hint { margin-left: auto; position: static; transform: none; } /* in line, not the search box's float-and-centre (health check D2) */
.quick-cap-form { display: flex; flex-direction: column; gap: 6px;
  padding: 6px var(--space-1) 2px; }
.quick-cap-form input[type=text], .quick-cap-form select { width: 100%;
  background: var(--inverse-hover); border: 1px solid var(--line-inverse);
  border-radius: var(--radius-sm); color: var(--ink-inverse); padding: 7px 10px;
  font: inherit; font-size: var(--fs-sm); }
.quick-cap-form input[type=text]::placeholder { color: var(--ink-inverse-muted); }
.quick-cap-form select option { color: var(--ink); }
@media (max-width: 900px) {
  .quick-cap { position: relative; }
  .quick-cap > summary { padding: 6px; }
  .quick-cap > summary span, .quick-cap > summary .key-hint { display: none; }
  .quick-cap[open] .quick-cap-form { position: absolute; top: 100%; right: 0;
    z-index: var(--z-overlay); width: min(320px, 88vw); padding: 10px;
    background: var(--panel-dark); border: 1px solid var(--line-inverse);
    border-radius: var(--radius-md); box-shadow: var(--shadow-overlay); }
}

.nav { display: flex; flex-direction: column; gap: 2px; }
.nav a { display: flex; align-items: center; gap: 10px; position: relative;
         padding: var(--space-2) 10px; border-radius: var(--radius-sm); text-decoration: none;
         font-size: var(--fs-base); font-weight: 500;
         color: var(--ink-inverse-muted); border: 1px solid transparent;
         transition: color var(--dur-2) var(--ease); }
.nav a:hover { color: var(--ink-inverse); }
.nav a.active { color: var(--ink-inverse);
                background: var(--inverse-hover);
                border-color: var(--line-inverse); }
.nav .ico { opacity: .85; display: block; width: 20px; height: 20px; }
.nav a > span:not(.badge) { line-height: 1.4; }
.nav-app-title { display: flex; flex-direction: column; gap: var(--space-1);
  padding: 0 10px var(--space-4); margin-bottom: var(--space-2);
  border-bottom: 1px solid var(--line-inverse); }
.nav-app-title strong { font-size: var(--fs-base); font-weight: 600; }
.nav-app-title > span { font-family: var(--font-mono); font-size: var(--fs-label);
  color: var(--ink-inverse-muted); letter-spacing: .1em; text-transform: uppercase; }
/* The More tab and its sheet are phone furniture; on a desktop the full
   sidebar IS the menu, so both stay out of the tree entirely. */
.nav-more, .more-sheet { display: none; }
.badge { background: var(--accent); color: var(--accent-ink);
         border-radius: var(--radius-pill); font-size: var(--fs-label); font-weight: 700;
         padding: 1px 7px; margin-left: auto;
         font-variant-numeric: tabular-nums; }

.pinned-nav { display: flex; flex-direction: column; gap: var(--space-1);
              border-top: 1px solid var(--line-inverse); padding-top: var(--gutter); }
.pinned-title { font-family: var(--font-mono); font-size: var(--fs-label);
                letter-spacing: .1em; text-transform: uppercase;
                color: var(--ink-inverse-muted); margin-bottom: var(--space-1); }
.pinned-nav a { color: var(--ink-inverse-muted); text-decoration: none; font-size: var(--fs-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 3px 0; display: flex; align-items: center; gap: var(--space-2); }

.pinned-nav a span { overflow: hidden; text-overflow: ellipsis;
                     white-space: nowrap; }
.pinned-nav .ico { flex: 0 0 auto; opacity: .55; }
.pinned-nav a[data-pin] { cursor: grab; }
.pinned-nav a.dragging { opacity: .4; }
.pinned-nav a:hover { color: var(--ink-inverse); }

.sidebar-foot { margin-top: auto; display: flex; border-top: 1px solid var(--line-inverse); padding-top: var(--gutter); flex-direction: column; align-items: stretch; gap: 6px; }
.sidebar-foot a { color: var(--ink-inverse-muted); text-decoration: none;
                  display: flex; align-items: center; gap: var(--space-2); font-size: var(--fs-sm); }
.sidebar-foot a:hover { color: var(--ink-inverse); }
.linkish { background: none; border: none; padding: 0; font: inherit;
           font-size: var(--fs-sm); color: var(--ink-inverse-muted); cursor: pointer;
           text-align: left; }
.linkish:hover { color: var(--ink-inverse); }
.main .linkish { color: var(--muted); }
.main .linkish:hover { color: var(--ink); }
/* Foot: who you are on one row, then the two utilities flush to the same
   left edge as the nav above them. Indenting them under the name made them
   read as properties of it rather than as their own controls. */

.foot-me { font-size: var(--fs-sm); }
.sidebar-foot .foot-link { color: var(--ink-inverse-muted); text-decoration: none;
                           font-size: var(--fs-sm); display: block; }
.sidebar-foot .foot-link:hover, .sidebar-foot .foot-link.active
  { color: var(--ink-inverse); }

/* Tables have columns to anchor the eye, so they earn the whole screen;
   PROSE is capped where it's read (.doc-grid 1240, .summary-rich below,
   .form-col 560) rather than by squeezing every page. 2400 keeps the
   layout anchored on an ultrawide without binding on a normal monitor. */
.main { flex: 1; padding: var(--space-6) var(--space-7) var(--space-10); max-width: var(--main-max);
        min-width: 0; }

/* ── Buttons — 32px tall, 8px radius, 14px label ────────────────────── */
.btn { display: inline-flex; align-items: center; gap: 7px;
       height: var(--ctl-h); padding: 0 var(--gutter);
       font-weight: 500; font-size: var(--fs-base); line-height: 1; font-family: var(--font-sans); color: var(--ink);
       background: var(--panel); border: 1px solid var(--line-strong);
       border-radius: var(--radius-sm); padding: var(--space-2) var(--gutter); cursor: pointer;
       text-decoration: none;
       transition: background var(--dur-2) var(--ease),
                   filter var(--dur-2) var(--ease); }
.btn:hover { background: var(--panel-sub); }
.btn:active { transform: translateY(1px); }
.btn.primary { font-weight: 600; background: var(--accent);
               border-color: var(--accent); color: var(--accent-ink); }
.btn.primary:hover { filter: brightness(1.12); background: var(--accent); }
.btn.danger { color: var(--danger); border-color: var(--red-edge); }
.btn.danger:hover { background: var(--red-soft); }
.btn.tiny { font-size: var(--fs-xs); border-radius: var(--radius-chip);
            height: var(--ctl-h-sm); padding: 0 10px;
            border-color: var(--line-mid); }
.btn.block { width: 100%; justify-content: center; }
.btn[disabled] { opacity: .38; pointer-events: none; }
/* two-step confirm: armed = the only filled red in the app */
.btn.confirming { background: var(--danger); border-color: var(--danger);
                  color: var(--accent-ink); font-weight: 600; }
/* Size too, not just family: a bare <button> otherwise renders at the
   browser's 13.33px, off the ramp (design audit, 2026-09-26). */
button { font: inherit; }

:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-sm); }
.sidebar :focus-visible { box-shadow: 0 0 0 2px var(--panel-dark), 0 0 0 4px var(--accent); }

/* ── Status pills — four shapes of attention ────────────────────────── */
/* Not a status. .pill carries the task vocabulary (Open/Doing/Blocked/…)
   and nothing else — a role, a field type or an audit action wearing a
   status dot erodes the one vocabulary in Ergon that is settled. */
.tag { display: inline-flex; align-items: center; font-weight: 500;
  font-size: var(--fs-xs); line-height: 1; border-radius: var(--radius-pill);
  padding: var(--space-1) 10px; background: var(--sage-fill); color: var(--ink);
  white-space: nowrap; }
/* Tag moods: a status mark on its own pastel, charcoal text (never
   coloured text on pastel). */
.tag.positive { background: var(--green-soft); }
.tag.warn { background: var(--amber-soft); }
.tag.negative { background: var(--red-soft); }

.pill { display: inline-flex; align-items: center; gap: 6px;
        font-weight: 500; font-size: var(--fs-xs); line-height: 1; font-family: var(--font-sans); border-radius: var(--radius-pill);
        padding: var(--space-1) 10px; border: 1px solid var(--line-mid);
        color: var(--muted); white-space: nowrap; }
.pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%;
                background: var(--muted); flex: 0 0 auto; }
.pill.doing { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.pill.doing::before { background: var(--accent); }
.pill.blocked { background: var(--amber-soft); border-color: var(--amber);
                color: var(--ink); font-weight: 600; }
.pill.blocked::before { width: 11px; height: 11px; border-radius: 0;
  background: no-repeat center / contain
  url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%23ED7D31" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="m21.7 18-8-14a2 2 0 0 0-3.5 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.7-3Z"/><path d="M12 9v4.5M12 17.2v.1"/></svg>'); }
.pill.done { border-color: var(--green-edge); color: var(--green); }
.pill.done::before { width: 11px; height: 11px; border-radius: 0;
  background: no-repeat center / contain
  url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%23007C44" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>'); }

/* RAG health dot — 9px; contradicted = amber halo, never a colour change */
.rag { display: inline-block; width: 9px; height: 9px; border-radius: 50%;
       vertical-align: baseline; }
.rag.green { background: var(--green); }
.rag.amber { background: var(--amber); }
.rag.red { background: var(--red); }
.rag.needs-review { box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--amber);
                    margin: 0 5px 0 3px; }

/* ── Chips (field values read as data, not buttons) ─────────────────── */
.chip-tag, .chip { display: inline-flex; align-items: center; gap: 5px;
  font-weight: 500; font-size: var(--fs-xs); line-height: 1; font-family: var(--font-sans); background: var(--sage-fill);
  color: var(--ink); border-radius: var(--radius-chip); padding: 5px 9px; }
.chip-x { border: none; background: none; cursor: pointer; font-size: var(--fs-sm);
          line-height: 1; padding: 0 1px; color: var(--muted); }
.chip-x:hover { color: var(--danger); }
/* Was blue on blue. Blue marks one interactive thing per screen; twelve
   outlined chips in the Key Wins table are data, not the screen's action. */
.project-chip { background: var(--sage-fill); border: 1px solid transparent;
  color: var(--ink); text-decoration: none; }
.check-progress { background: var(--panel); border: 1px solid var(--line-mid);
  color: var(--muted); }

/* ── Avatars — hashed hue, fixed S/L, off-white text ────────────────── */
.avatar { display: inline-flex; align-items: center; justify-content: center;
          flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%;
          background: hsl(var(--h, 100) 32% 38%); color: var(--ink-inverse);
          font-weight: 700; font-size: var(--fs-xs); line-height: 1; font-family: var(--font-sans); vertical-align: middle; }
.avatar.tiny { width: 24px; height: 24px; font-size: var(--fs-label); /* the smallest step on the scale, not a one-off 10px */ margin-right: 5px; }

/* ── Forms — 12px radius, 28% border ────────────────────────────────── */
/* Full-height fields take --radius-md. Inline editors (a ghost box that
   becomes a field on hover) and compact fields under 34px take --radius-sm,
   like buttons of that size (health check D17). */
input[type=text], input[type=search], input[type=email], input[type=url],
input[type=password], input[type=date], select, textarea {
  font-weight: 400; font-size: var(--fs-base); line-height: 1.45; font-family: var(--font-sans); color: var(--ink);
  background: var(--panel); border: 1px solid var(--line-mid);
  border-radius: var(--radius-md); padding: var(--space-2) var(--space-3); max-width: 100%; }
/* Height stated, not inherited from font metrics — see --ctl-h. */
input[type=text], input[type=search], input[type=email], input[type=url],
input[type=password], input[type=date], select {
  height: var(--ctl-h); padding-top: 0; padding-bottom: 0; }
textarea { height: auto; padding: var(--space-2) var(--space-3); }
input:focus, select:focus, textarea:focus { outline: none;
  border-color: var(--accent); box-shadow: var(--focus-ring); }
label { display: flex; flex-direction: column; gap: 5px; font-size: var(--fs-sm);
        color: var(--muted); }
label > input, label > select, label > textarea { color: var(--ink); }
input[type=checkbox] { appearance: none;
  width: var(--check-size); height: var(--check-size);
  border-radius: var(--radius-chip); border: 1.5px solid var(--line-mid);
  background: var(--panel); cursor: pointer; flex: 0 0 auto;
  display: inline-grid; place-content: center; padding: 0;
  /* margin: 0 — the browser's own 4px/3px around a checkbox is invisible
     until something tries to align to it (the digest help text sat 6px
     off). Spacing is the layout's job, via --check-gap. */
  margin: 0; }
input[type=checkbox]:checked { background: var(--accent); border-color: var(--accent); }
input[type=checkbox]:checked::before { content: "";
  width: 12px; height: 12px;
  background: no-repeat center / contain
  url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%23F8F9EB" stroke-width="3.2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>'); }
.checkline { flex-direction: row; align-items: center;
             gap: var(--check-gap);
             font-size: var(--fs-base); color: var(--ink); }

/* segmented control — the density switch */

/* ── Cards — 22px, one charcoal outline, no shadow ──────────────────── */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
         gap: var(--gutter); }
.card, .settings-card, .auth-card {
  background: var(--panel); border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg); padding: var(--space-5); }
.card { text-decoration: none; display: block;
        transition: background var(--dur-2) var(--ease); }
a.card:hover, .project-card:hover { background: var(--panel-hover); }
.card-title { font-size: var(--fs-md); font-weight: 600; display: flex;
              align-items: center; gap: var(--space-2); margin-bottom: 6px; }
.card-stats { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); font-size: var(--fs-sm);
              color: var(--muted); }
.stat-blocked { color: var(--amber-ink); font-weight: 600; }
.stat-overdue { color: var(--red); font-weight: 600; }
.card-desc { font-size: var(--fs-sm); color: var(--muted); margin-top: 6px; }
.card-owner { display: flex; align-items: center; gap: 6px; margin-top: 10px;
              font-size: var(--fs-sm); color: var(--muted); }
/* not overflow:hidden — it clipped the name tooltip off the avatars */
.card-members { margin-top: var(--space-2); display: flex; flex-wrap: wrap;
                align-items: center; gap: 3px; }
.card-members .avatar.tiny { margin-right: 3px; }
.note { font-size: var(--fs-sm); background: var(--panel-sub); border-radius: var(--radius-sm);
        padding: 6px 10px; margin-top: 10px; }
.project-card { position: relative; display: flex; flex-direction: column; }
.project-card .card-main { flex: 1; color: inherit; text-decoration: none; display: block; }
.project-card .card-title { padding-right: 64px; }
.card-join { position: absolute; top: 14px; right: 14px; margin: 0; }
.faded { opacity: .55; }

.settings-grid { display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: var(--gutter); align-items: start; }
.settings-card h2 { margin: 0 0 var(--space-3); font-size: var(--fs-h2); }
.danger-zone { border-color: var(--red-edge); }

/* ── Tabs — blue underline, never a filled tab ──────────────────────── */
.tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--line);
        margin-bottom: var(--space-5); }
.tabs a { text-decoration: none; padding: var(--space-2) var(--space-3) 10px; font-size: var(--fs-base);
          font-weight: 500; color: var(--muted);
          border-bottom: 2px solid transparent; margin-bottom: -1px; }
.tabs a:hover { color: var(--ink); }
.tabs a.active { color: var(--ink); border-bottom-color: var(--accent); }

/* ── Breadcrumbs — mono, uppercase ──────────────────────────────────── */
.crumbs { font-family: var(--font-mono); font-size: var(--fs-label);
          letter-spacing: .1em; text-transform: uppercase;
          color: var(--muted); margin: 0 0 var(--space-4); }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--ink); }

/* ── Callouts — one component, four moods ───────────────────────────── */
/* One banner, three moods. Five names diverged only by fill and two of
   them were byte-identical. .empty-well and .note stay out: a dashed well
   marks absence and a note annotates inside a card — different objects. */
.callout, .flash, .rag-nudge, .blocked-banner, .project-banner {
  display: flex; align-items: flex-start; gap: var(--space-3);
  border-radius: var(--radius-md); padding: 10px var(--space-4); margin: 0 0 var(--space-4);
  font-size: var(--fs-base); border: 1px solid var(--line-strong);
  background: var(--panel); }
.callout.warn, .rag-nudge, .blocked-banner { background: var(--amber-soft);
  border-color: var(--amber); }
.callout.quiet { background: var(--sage-fill); border-color: var(--line-mid); }
/* Moods for status messages (Worldpay's data checks brought them in). */
.callout.positive { background: var(--green-soft); border-color: var(--green); }
.callout.negative { background: var(--red-soft); border-color: var(--red); }
/* Title over body — Coda's own callout shape; used for explanations. */
.callout.titled { flex-direction: column; gap: var(--space-1); }
.callout.titled > strong { font-weight: 600; }
.callout.titled > p { margin: 0; }
.callout.split { flex-wrap: wrap; gap: var(--space-2) var(--space-5);
  align-items: baseline; justify-content: space-between; }
.undo-flash { display: flex; justify-content: space-between;
              align-items: center; gap: var(--gutter); }

/* ── Page head ──────────────────────────────────────────────────────── */
/* Actions sit on the title's baseline, and every page gives the same gap
   (--space-6) to its first block of content — whatever that block is, and
   in every app (design audit, 2026-09-26: it ranged 6–32px). The title
   block itself is .head-left. */
.page-head { display: flex; flex-wrap: wrap; justify-content: space-between;
             align-items: flex-end; gap: var(--space-3) var(--space-6); margin: 0 0 var(--space-6); }
/* 'main' lifts specificity over later block rules (.section-head etc.);
   a section that opens with a heading counts as the first block too. */
main .page-head + *, main .page-head + * > .section-head:first-child { margin-top: 0; }
.page-head h1 { margin: 0; display: flex; align-items: center; gap: 10px; }
.page-head h2 { margin: 0; }
/* The eyebrow and breadcrumb belong to the head, not to a wrapper div and
   not to the page above it — they stack full-width inside it. */
.page-head > .crumbs, .page-head > .eyebrow { flex-basis: 100%; margin: 0 0 var(--space-1); }
.page-head .crumbs { margin: 0; }
/* The one exception: a task's meta line belongs to its header. */
.page-head.task-head { margin-bottom: 6px; }
.head-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.filter-bar, .member-line { align-items: center; }

/* ── Audience line — contract rule 4: who can see this page ────────── */
.audience { display: flex; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-5);
  font-size: var(--fs-xs); color: var(--muted); }
.audience .ico { flex: none; }

/* ── AI record: the meter beside AI buttons and the weekly chart ───── */
.ai-meter { margin: var(--space-2) 0 0; font-size: var(--fs-xs); color: var(--muted);
  font-variant-numeric: tabular-nums; }
/* Bar chart — ONE component (AI cost, Worldpay fees and periods).
   Row = label · track · value. Series colours in a fixed order; bars are
   data marks and keep their own 3px ends. */
.bars { display: grid; gap: var(--space-3); max-width: 720px; }
.bar-row { display: grid; grid-template-columns: minmax(7rem, 30%) 1fr auto; align-items: center;
  gap: var(--space-3); font-size: var(--fs-sm); }
.bar-label { color: var(--muted); min-width: 0; overflow-wrap: anywhere; }
.bar-track { display: flex; height: 10px; background: var(--panel-sub); border-radius: 3px; overflow: hidden; }
.bar-seg { display: block; height: 100%; }
.bar-value { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.bar-value .muted { font-weight: 400; }
.seg-1 { background: var(--ink); } .seg-2 { background: var(--accent); } .seg-3 { background: var(--amber); }
.seg-4 { background: var(--sage); } .seg-5 { background: var(--muted); } .seg-6 { background: var(--green-band); }
.seg-7 { background: var(--red-soft); }
.bar-legend { display: flex; gap: var(--space-4); margin: var(--space-2) 0 0; font-size: var(--fs-xs); color: var(--muted); }
.bar-legend > span { display: inline-flex; align-items: center; gap: var(--space-1); }
.bar-legend .bar-seg { width: 10px; height: 10px; border-radius: 2px; }

/* ── Small layout helpers (replace one-off inline styles) ──────────── */
/* Shared by every app (Worldpay's parallel names retired, 2026-09-26). */
.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
form.cluster { align-items: end; }
.cluster-fill { flex: 1; min-width: 12rem; }
.card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  gap: var(--space-4); margin-bottom: var(--space-5); }
.card-grid > .card { margin-bottom: 0; }
.footnote { font-size: var(--fs-xs); color: var(--muted); margin: var(--space-4) 0; max-width: 100ch; }
/* In-page jump links look like links, never like tabs (tabs switch views). */
.jump-links { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5);
  margin: 0 0 var(--space-5); font-size: var(--fs-sm); }
.jump-links a { color: var(--muted); text-underline-offset: .2em; }
.jump-links a:hover { color: var(--ink); }
/* A table scroll box with a height cap, for long reference lists. */
.tbl-scroll.capped { max-height: 24rem; overflow: auto; }
.tbl-scroll:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
/* An action on the right of a section heading */
.section-head .section-action { margin-left: auto; }
/* The explanatory note at the end of a filter bar */
.filter-bar .filter-note { margin-left: auto; font-size: var(--fs-xs); color: var(--muted); }
.filter-bar label { display: inline-flex; flex-direction: row; align-items: center; gap: var(--space-2); }
.small { font-size: var(--fs-xs); }
.grow { flex: 1; margin: 0; }
.tight-block { margin: var(--space-2) 0; }
.sub-head { margin: var(--space-5) 0 var(--space-2); }
.spaced { margin-top: var(--space-4); }
.brand-name-lg { font-size: var(--fs-h1); }

/* ── Filter bar ─────────────────────────────────────────────────────── */
.filter-bar { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center;
              margin: 0 0 var(--space-4); }
.filter-bar input[type=search] { min-width: 200px; }
.filter-bar select { max-width: 170px; }        /* matches .allt-row */
/* A view control, not a filter: it was inside the form and wrapped onto
   a second row with the submit button at laptop width. */

/* ── Quick-add — quiet: grows a border on focus ─────────────────────── */
.quick-add { display: flex; margin: 6px 0 var(--gutter); }
.quick-add input[type=text] { width: 100%; background: transparent;
  border: 1px dashed var(--line-mid); border-radius: var(--radius-sm);
  transition: background var(--dur-2) var(--ease); }
.quick-add input[type=text]:focus { background: var(--panel);
  border-style: solid; }
.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; }

/* ── Task tables — the extension component ──────────────────────────── */
.tbl-scroll { overflow-x: auto; overflow-y: clip;
              border: 1px solid var(--line-strong); border-radius: var(--radius-md);
              background: var(--panel); margin-bottom: var(--space-5); }
table.tasks { width: 100%; border-collapse: separate; border-spacing: 0;
              background: var(--panel); }
table.tasks.wide { table-layout: auto; width: max-content; min-width: 100%; }
table.tasks td { padding: 11px var(--space-3); border-bottom: 1px solid var(--line);
                 vertical-align: top; font-size: var(--fs-base); }
table.tasks tbody:last-child tr:last-child td,
table.tasks > tr:last-child td { border-bottom: none; }
table.tasks th { text-align: left; font-family: var(--font-mono);
  font-size: var(--fs-label); font-weight: 400; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted);
  background: var(--bg); padding: 9px var(--space-3);
  border-bottom: 1px solid var(--line-strong); white-space: nowrap;
  position: sticky; top: 0; z-index: 6; }
table.tasks a { text-decoration: none; }
table.tasks a:hover { text-decoration: underline; }
td.due, td.age, td.col-due, td.col-age, td.col-created, td.col-done
  { font-variant-numeric: tabular-nums; font-size: var(--fs-sm); color: var(--muted); }
td.col-age { font-size: var(--fs-xs); color: var(--faint); }

/* column sizing — ONE width per shared column, everywhere. Jumping from
   page to page must not reflow the same column to a new width; only the
   task/name column flexes. Report tables (wins/values) keep their own
   documented percentage layouts. */
:root {
  --colw-status: 104px; --colw-due: 128px; --colw-assignee: 140px;
  --colw-project: 190px; --colw-age: 64px; --colw-date: 96px;
  --colw-tick: 40px; --colw-act: 92px;
  /* the checkbox control: size + the gap to its label. Anything that
     needs to line up UNDER a label reads these, never re-guesses. */
  --check-size: 18px; --check-gap: 9px;
  /* the form column: wide enough to use the page, bounded so prose stays
     readable instead of running the full 1600px main */
  --form-w: 560px;
  --main-max: 2400px;
}
.col-status { width: var(--colw-status); }
.col-assignee { width: var(--colw-assignee); }
.col-due { width: var(--colw-due); } .col-age { width: var(--colw-age); }
.col-created { width: var(--colw-date); } .col-done { width: var(--colw-date); }
.col-tick { width: var(--colw-tick); }
.col-project { width: var(--colw-project); }
.col-field { width: 8%; }
table.tasks.wide td, table.tasks.wide th { white-space: nowrap; }
table.tasks.wide td.col-task, table.tasks.wide th.col-task {
  white-space: normal; min-width: 300px; max-width: 520px; }
table.tasks.wide td.col-field, table.tasks.wide th.col-field {
  width: auto; min-width: 110px; max-width: 200px;
  overflow: hidden; text-overflow: ellipsis; }
table.tasks.wide td.col-assignee, table.tasks.wide th.col-assignee
  { width: auto; min-width: 96px; }
td.col-status, td.col-assignee, td.col-due, td.col-age,
td.col-created, td.col-done { white-space: nowrap; overflow: hidden;
                              text-overflow: ellipsis; }
/* tick/checkbox cells hold widgets, not text: no ellipsis (a checkbox one
   pixel over the line painted as a stray "." on the values workbench) */
td.col-tick, td.col-sel { white-space: nowrap; overflow: hidden; }

/* frozen pane */
table.tasks.wide th.col-status, table.tasks.wide td.col-status {
  position: sticky; left: 0; z-index: 4; width: var(--colw-status); }
table.tasks.wide th.col-task, table.tasks.wide td.col-task {
  position: sticky; left: 104px; z-index: 4; }
table.tasks.wide thead th.col-status, table.tasks.wide thead th.col-task { z-index: 8; }
table.tasks.wide td.col-status, table.tasks.wide td.col-task
  { background: var(--panel); }

/* row state lives on the edge of the frozen pane, not the whole row */
td.col-status { border-left: 3px solid transparent; }
tr.overdue td.col-status { border-left-color: var(--red); }
tr.overdue td.due, tr.overdue td.col-due { color: var(--red); font-weight: 600; }
tr.blocked-row td.col-status { border-left-color: var(--amber); }
/* Only the edge (and the status tag) says it — in every list. Wide project
   lists also tinted the two frozen cells, which read as a row half painted
   (health check D10). */
tr.done-row { opacity: .55; }
/* A deactivated person reads as past tense — but NOT via opacity. Opacity
   makes a stacking context, and the row's Edit popover is then trapped
   inside it: every row BELOW paints over the panel (and it inherits the
   fade). Colour says the same thing and traps nothing. */
tr.inactive-row td { color: var(--faint); }
tr.inactive-row td strong { font-weight: 500; }
tr.inactive-row .avatar { opacity: .55; }  /* a leaf: contains no popover */
tr.done-row td.col-task > a { text-decoration: line-through;
  text-decoration-color: var(--line-mid); }
tr.done-row td.col-status, tr.done-row td.col-task { background: var(--panel); }
/* New, not complete — green is the delivered colour everywhere else.
   The row already carries bold text, so the edge alone does the work. */
tr.unread-row td:first-child { border-left: 3px solid var(--accent); }

/* section band rows inside a single table */
/* The band IS the progress bar: done-share tints the row left-to-right
   across every column, so completion is legible at a glance. */
tr.section-band td.band-cell {
  font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink); padding: 7px var(--space-3);
  border-bottom: 1px solid var(--line);
  background: linear-gradient(to right,
    var(--green-band) var(--pct, 0%), var(--sage-fill) var(--pct, 0%)); }
.band-inner { position: sticky; left: 12px; display: inline-flex;
              align-items: center; gap: var(--space-2); }
tr.section-band .band-name { font-weight: 700; }
tr.section-band .band-count { color: var(--muted); font-weight: 400; }
tbody.collapsed tr:not(.section-band) { display: none; }
tr.quickadd-row td { padding: var(--space-1) var(--space-2); }
tr.quickadd-row .quick-add { margin: 0; align-items: center; gap: 2px; }
tr.quickadd-row input[type=text] { border-color: transparent; }
tr.quickadd-row input[type=text]:hover,
tr.quickadd-row input[type=text]:focus { border-color: var(--line-mid); }

/* density */
/* Compact row height — set once on <html>, so every list agrees */
html.dense table.tasks td:not(.band-cell) { padding: 5px 10px; font-size: var(--fs-sm); }
html.dense table.tasks th { padding: 6px 10px; }
html.dense .pill { padding: 3px var(--space-2); }
html.dense tr.section-band td { padding: 5px 10px; }
html.dense tr.quickadd-row td { padding: 2px var(--space-2); }
/* Avatars keep one size in both densities. Compact is about fitting more
   rows, and a person is the same person either way — resizing their face
   between views just made the two modes look like different products. */

/* metadata tables (summaries list, admin) — natural layout */
table.tasks.meta { table-layout: auto; }
table.tasks.meta td.shrink { width: 1%; white-space: nowrap; }
td.shrink { width: 1%; white-space: nowrap; }
/* Admin/summary tables sit in .tbl-scroll like every other list. A sibling
   selector used to supply the card look without the scrolling, so those
   tables pushed the whole page sideways and its overflow:hidden clipped
   the settings panel that opens inside them. */
.tbl-scroll td.shrink { white-space: nowrap; width: 1%; }
.tbl-scroll td.muted { white-space: normal; }

/* wins table */
/* Percent widths only bind under fixed layout; without this the Key Win
   column collapsed to 15% and titles wrapped to seven lines. */
table.tasks.wins-table,
table.tasks.values-table { table-layout: fixed; width: 100%; }
.wins-table .col-task { width: 42%; min-width: 0; }
.wins-table .col-winproject { width: 15%; }
.wins-table .col-assignee { width: 11%; }
.wins-table .col-value { width: 12%; text-align: right; }
.wins-table .col-due { width: 13%; }
td.col-winproject { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Full width, like every other table on the site — but proportioned so
   no column is a prairie: the value, then where it's used (which is what
   tells you whether a spelling is real vocabulary or a stray typo). */
.values-table .col-task { width: 24%; }
.values-table .col-projects { width: 36%; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.values-table .col-value { width: 11%; text-align: right; }

/* ── Sections / group heads outside tables ──────────────────────────── */
.section-head { display: flex; align-items: baseline; gap: 10px;
  color: var(--ink); margin: var(--space-7) 0 var(--space-2); }
.section-head .muted { font-size: var(--fs-label); text-transform: none;
  letter-spacing: .02em; font-family: var(--font-sans); }
.section-head.urgent { color: var(--red); }

/* ── Feed / activity ────────────────────────────────────────────────── */
.feed { list-style: none; padding: 0; margin: 0; max-width: 1100px; }
.feed > li { padding: var(--space-2) 0; border-bottom: 1px solid var(--line);
             font-size: var(--fs-sm); }
.feed .muted { font-variant-numeric: tabular-nums; margin-right: 6px; }

/* ── Comments ───────────────────────────────────────────────────────── */
.comments { list-style: none; padding: 0; margin: 0 0 var(--gutter); }
.comments > li { padding: var(--space-3) 0; border-bottom: 1px solid var(--line); scroll-margin-top: 84px; }
.comment-head { font-size: var(--fs-sm); margin-bottom: var(--space-1); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.comment-actions { margin-left: auto; display: flex; gap: 6px;
                   align-items: center; }

/* Editing a comment takes over the row. The edit form lives inside the
   right-aligned actions (that is where its <details> toggle sits), so
   without this the editor renders in a narrow right-hand column with the
   unedited copy still shown underneath — the same text twice. Opening it
   gives the actions the full width, drops the rendered copy, and steps
   Delete aside until you are done. */

.comment-actions:has(details[open]) { width: 100%; margin: var(--space-2) 0 0; }
.comment-actions:has(details[open]) > details { flex: 1 1 100%; }
.comment-actions:has(details[open]) > form[data-confirm] { display: none; }
.comment-edit { width: 100%; margin-top: 6px; }
.comments li:has(.comment-actions details[open]) .comment-body { display: none; }
.comment-body { font-size: var(--fs-base); line-height: 1.55; }
.mention { background: var(--accent-soft); border-radius: var(--radius-chip);
           padding: 0 var(--space-1); font-weight: 600; }

/* ── Rich text ──────────────────────────────────────────────────────── */
.rich-text { line-height: 1.55; }
.rich-text p { margin: 0 0 10px; }
.rich-text p:last-child { margin-bottom: 0; }
.rich-text ul, .rich-text ol { margin: 6px 0; padding-left: 22px; }
.rich-text strong { font-weight: 600; }
.rich-text table { border-collapse: collapse; margin: 6px 0 var(--space-3); }
.rich-text th, .rich-text td { border: 1px solid var(--line-mid);
  padding: 5px 10px; font-size: var(--fs-sm); }
.rich-text th { background: var(--bg); font-weight: 600; }
.rich-text pre { background: var(--panel-sub); border-radius: var(--radius-sm); padding: 10px var(--space-3); overflow-x: auto; font-family: var(--font-mono); font-size: var(--fs-code); white-space: pre-wrap; overflow-wrap: anywhere; }
.rich-text code { background: var(--panel-sub); border-radius: var(--radius-chip);
  padding: 0 var(--space-1); font-family: var(--font-mono); font-size: .92em; }
.rich-text pre code { background: none; padding: 0; }
.rich-text blockquote { border-left: 3px solid var(--accent);
  margin: 6px 0 10px; padding: 2px 0 2px var(--space-3); color: var(--muted); }

/* WYSIWYG editor — the area IS the document */
.rich-editor { position: relative; }
.re-area { background: var(--panel); border: 1px solid var(--line-mid);
           border-radius: var(--radius-md); padding: 10px var(--space-3); min-height: 52px;
           outline: none; }
.re-area:focus { border-color: var(--accent); box-shadow: var(--focus-ring); }
.re-area:empty::before { content: attr(data-placeholder); color: var(--faint); }
.re-area p:first-child { margin-top: 0; }

/* toolbar in a sage well; active mark = charcoal, never blue */
.re-toolbar { display: flex; gap: 2px; align-items: center;
  border: 1px solid var(--line-mid); border-radius: var(--radius-md); padding: var(--space-1);
  background: var(--bg); width: fit-content; margin-bottom: 6px; }
.re-toolbar button { width: 28px; display: inline-flex; align-items: center; justify-content: center; border: none; background: none; border-radius: var(--radius-chip); font-weight: 500; font-size: var(--fs-sm); line-height: 1; font-family: var(--font-sans); color: var(--ink); cursor: pointer; padding: 0; height: 28px; }
.re-toolbar button:hover { background: var(--sage-fill); }
.re-toolbar button.on { background: var(--panel-dark); color: var(--ink-inverse); }

/* ── Popovers (mention, chips suggestions) ──────────────────────────── */
.mention-anchor { position: relative; }
.mention-popup { position: absolute; left: 6px; bottom: calc(100% + 4px);
  z-index: var(--z-popover); background: var(--panel); border: 1px solid var(--line-mid);
  border-radius: var(--radius-md); box-shadow: var(--shadow-popover); min-width: 220px;
  overflow: hidden; }
.mention-item { padding: 7px var(--space-3); cursor: pointer; font-size: var(--fs-sm); }
.mention-item.active, .mention-item:hover { background: var(--accent-soft); }

/* chips input */
.chips { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; background: var(--panel); border: 1px solid var(--line-mid); border-radius: var(--radius-md); cursor: text; height: auto; padding: var(--space-1) 7px; min-height: var(--ctl-h); }
.chips:focus-within { border-color: var(--accent); }
.chips-entry { border: none !important; outline: none; box-shadow: none !important; width: 100%; min-width: 0; padding: var(--space-1) var(--space-1); background: transparent; text-align: left; height: auto; }
.chips-entry::placeholder { color: var(--muted); }
/* the typing slot fills the rest of the row, so its placeholder sits where
   text will actually appear instead of floating in the middle of the box */
.chips-entry-wrap { flex: 1 1 90px; min-width: 90px; display: block; }
.rail-field-tall .chips { align-items: stretch; width: 100%; }
#add-follower-search { width: 100%; }

/* ── Checklist ──────────────────────────────────────────────────────── */
.checklist { list-style: none; padding: 0; margin: 0 0 var(--space-2); }
.checklist li { display: flex; align-items: center; gap: 10px;
                padding: 7px 0; border-bottom: 1px solid var(--line); }
.checklist form { display: flex; }
.checkbox { width: var(--check-size); height: var(--check-size);
  border-radius: var(--radius-chip);
  border: 1.5px solid var(--line-mid); background: var(--panel);
  cursor: pointer; padding: 0; font-size: var(--fs-label); line-height: 1;
  color: var(--accent-ink); }
.checkbox.checked { background: var(--accent); border-color: var(--accent); }
.checked-text { text-decoration: line-through;
  text-decoration-color: var(--line-mid); color: var(--muted); }
.checklist-actions { margin-left: auto; display: flex; gap: 6px; }

/* ── File links ─────────────────────────────────────────────────────── */
.file-links { list-style: none; padding: 0; margin: 0 0 var(--space-2); }
.file-links li { display: flex; align-items: center; gap: var(--space-2);
                 padding: 6px 0; }
.file-links a { display: inline-flex; align-items: center; gap: 6px;
  background: var(--panel); border: 1px solid var(--line-mid);
  border-radius: var(--radius-sm); padding: 6px var(--space-3); font-size: var(--fs-sm);
  text-decoration: none; }
.file-links a:hover { border-color: var(--line-strong); }
.grow-input { min-width: min(260px, 100%); flex: 1 1 200px; }

/* ── Inline forms / rows ────────────────────────────────────────────── */
/* Wraps at every width, not just under 900px — the Add-person form is
   754px of controls and was pushing the page sideways on a laptop, the
   same defect as an unwrapped table. */
.inline-form { display: inline-flex; flex-wrap: wrap; gap: var(--space-2);
               align-items: flex-end; margin-bottom: var(--space-2); }
.stack { display: flex; flex-direction: column; gap: 10px; margin-bottom: var(--space-4); }
.doc-rail .stack { margin-bottom: 0; }  /* rail spacing comes from rail-heads */
.row { display: flex; gap: var(--space-3); }
.row label { flex: 1; }
.two-col { display: grid; grid-template-columns: 1fr 280px; gap: var(--space-7); }
.two-col > * { min-width: 0; }
.two-col select, .two-col input[type=url] { max-width: 100%; min-width: 0; }
.side-panel { border: 1px solid var(--line-strong); border-radius: var(--radius-lg);
              padding: var(--space-5); align-self: start; background: var(--panel);
              display: flex; flex-direction: column; gap: 10px; }
.side-panel h3 { font-family: var(--font-mono); font-size: var(--fs-label);
  font-weight: 400; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); margin: var(--space-2) 0 2px; }
.label-row { display: flex; gap: 10px; align-items: baseline;
  font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); }
.save-state { font-family: var(--font-mono); font-size: var(--fs-label); }
.save-state.save-error { color: var(--red); }

.field-row { display: flex; justify-content: space-between; gap: var(--space-2);
             align-items: center; }
.hint { font-size: var(--fs-xs); margin: 2px 0 0; }
.col-group { font-family: var(--font-mono); font-size: var(--fs-label);
  letter-spacing: .1em; text-transform: uppercase; margin-top: var(--space-2); }

/* ── Settings odds ──────────────────────────────────────────────────── */
.settings { position: relative; }
details.settings:not([open]) .settings-panel { display: none; }
.settings summary { list-style: none; }
.settings summary::-webkit-details-marker { display: none; }
.settings-panel { position: absolute; right: 0; z-index: var(--z-popover);
  background: var(--panel); border: 1px solid var(--line-mid);
  border-radius: var(--radius-md); padding: var(--gutter); width: 320px; display: flex;
  flex-direction: column; gap: var(--space-3); box-shadow: var(--shadow-popover); }
.settings-panel form { display: flex; flex-direction: column; gap: var(--space-2); }
.section-admin-row { display: flex; gap: 6px; align-items: center;
                     margin-bottom: 6px; }
.section-admin-row .inline-form { margin: 0; flex: 1; min-width: 0; }
.member-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 var(--space-3); }
.member-chips .chip-tag { gap: 5px; padding: var(--space-1) var(--space-2); }
.member-chips form { display: inline; }
.member-line { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center;
               margin-bottom: var(--gutter); color: var(--muted); }
.follower-names { font-size: var(--fs-sm); margin: 2px 0 var(--space-2); }
.follower-note { font-size: var(--fs-xs); margin: 0 0 6px; }

/* ── Stat block — ONE component (design audit, 2026-09-26) ────────────
   Number first, then its mono label, then an optional note. Sizes:
   .stat (26px, 700) in strips and panels · .stat.lg (display, 800) for
   page counters · .stat.xl (stat size, 800) for hero figures. */
.stat { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.stat .n { font-size: var(--fs-h1); font-weight: 700; letter-spacing: -.02em;
  line-height: 1.1; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.stat.lg .n { font-size: var(--fs-display); font-weight: 800; line-height: 1; }
.stat.xl .n { font-size: var(--fs-stat); font-weight: 800; line-height: 1; }
.stat .n small { font-size: var(--fs-md); font-weight: 400; color: var(--muted); }
.stat .n.red { color: var(--red); }
.stat .n.amber { color: var(--amber-ink); }
.stat .label { color: var(--muted); }
.stat .stat-note { font-size: var(--fs-xs); color: var(--muted); }
/* A row of counters (My Tasks, Review) */
.stat-row { display: flex; gap: var(--space-7); }
/* A bordered strip of figures (Worldpay); tracks line up across the row */
.stat-strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  background: var(--panel); border: 1px solid var(--line-strong); border-radius: var(--radius-lg);
  margin-bottom: var(--space-5); overflow: hidden; }
.stat-strip > .stat { padding: var(--space-5); display: grid; grid-template-rows: subgrid;
  grid-row: span 3; align-content: start; gap: var(--space-1); }
.stat-strip > .stat + .stat { border-left: 1px solid var(--line); }

/* ── Charcoal hero — ONE component: Key Wins, and Worldpay's headline
   figure (.hero-split). Stats inside it read inverse. */
.hero-dark { background: var(--panel-dark); color: var(--ink-inverse);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0; padding: var(--space-6) var(--space-7); }
.hero-dark .eyebrow-row { display: flex; justify-content: space-between;
  gap: var(--space-4); font-family: var(--font-mono); font-size: var(--fs-label);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-inverse-muted); margin-bottom: var(--space-5); }
.hero-dark .hero-title { font-size: var(--fs-display); font-weight: 800;
  text-transform: uppercase; letter-spacing: -.02em; line-height: .95;
  margin: 0 0 var(--space-6); }
.hero-stats { display: flex; flex-wrap: wrap; gap: var(--space-6) var(--space-9);
  border-top: 1px solid var(--line-inverse); padding-top: var(--space-5); }
.hero-dark .stat .n small, .hero-dark .stat .label, .hero-dark .stat .stat-note { color: var(--ink-inverse-muted); }
.hero-dark.hero-split { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: var(--space-7); border-radius: var(--radius-lg); padding: var(--space-7); margin-bottom: var(--space-5); }
.hero-split .eyebrow-row { margin-bottom: var(--space-3); }
.hero-split p { max-width: 54ch; margin: var(--space-4) 0; }
.hero-split a { text-underline-offset: .2em; font-size: var(--fs-sm); }
.hero-side { border-left: 1px solid var(--line-inverse); padding-left: var(--space-6);
  display: grid; gap: var(--space-4); align-content: start; }
.hero-side .stat .n { font-size: var(--fs-h2); }
.hero-body { border: 1px solid var(--line-strong); border-top: none;
  border-radius: 0 0 var(--radius-lg) var(--radius-lg); background: var(--panel);
  padding: var(--space-2) var(--space-6) var(--space-5); margin-bottom: var(--space-5); }
.quarter-band { display: flex; align-items: baseline; gap: var(--space-3);
  margin: var(--space-5) 0 var(--space-2); }
.quarter-band .muted { font-family: var(--font-sans); font-size: var(--fs-sm);
  text-transform: none; letter-spacing: 0; }

/* ── Empty state — a dashed well, one fact, no illustration ─────────── */
.empty-well { border: 1px dashed var(--line-mid); border-radius: var(--radius-md);
  padding: var(--space-7) var(--space-6); text-align: center; background: var(--bg); }
.empty-well .ico-ring { width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid var(--line-strong); display: inline-flex;
  align-items: center; justify-content: center; margin-bottom: var(--space-3); }
.empty-well .fact { font-size: var(--fs-md); font-weight: 600; margin-bottom: 2px; }
.empty-well .muted { font-size: var(--fs-sm); }
/* Six screens open with an explanatory paragraph that had no rule at all,
   so it took the user-agent 1em margin — the one measurement nobody chose —
   and ran 200 characters wide on a big monitor. */
.page-lede { margin: 0 0 var(--space-4); font-size: var(--fs-base); color: var(--muted); text-wrap: pretty; max-width: 760px; }
.btn.claim { color: var(--accent); border-color: var(--accent); }

/* ── Inbox list ─────────────────────────────────────────────────────── */
.inbox-table .col-inbox-project { width: var(--colw-project); }
.inbox-table td.col-inbox-project { white-space: nowrap; overflow: hidden;
                                    text-overflow: ellipsis; }
.inbox-quote { display: block; color: var(--muted); font-size: var(--fs-sm);
  margin-top: 3px; border-left: 2px solid var(--line-mid); padding-left: var(--space-2); }

/* ── Landing/auth ───────────────────────────────────────────────────── */
.auth-main { min-height: 100vh; display: flex; flex-direction: column;
             align-items: center; justify-content: flex-start; padding: var(--space-6);
             background: var(--bg); }
/* The public landing page (ergonbench.com). Its own classes: it used to
   borrow .app-card from the Apps page and carry a private <style> block,
   and the wordmark kept the sidebar's white-on-charcoal colour — invisible
   on cream (health check D1). */
.landing { max-width: 640px; margin: 10vh auto 0; padding: 0 var(--gutter); }
.landing .brand { padding: 0; }
.landing .brand-name { color: var(--ink); }
.landing .brand-sub { color: var(--muted); }
.landing h1 { font-size: var(--fs-display); margin: var(--space-5) 0 0; }
.landing p { line-height: 1.6; }
.landing-apps { margin: var(--space-6) 0; display: flex; flex-direction: column; gap: var(--space-3); }
.landing-app { display: flex; justify-content: space-between; align-items: center; gap: var(--space-4);
               flex-wrap: wrap; background: var(--panel); border: 1px solid var(--line);
               border-radius: var(--radius-lg); padding: var(--space-4) var(--space-5); }
.landing footer { color: var(--muted); font-size: var(--fs-sm); margin: var(--space-7) 0 var(--space-6); }
/* The card (and any message about it) centres in the space the staging
   banner leaves, so the banner sits at the top instead of floating
   mid-screen above the card. */
.auth-stack { margin-block: auto; width: 100%; max-width: 400px;
              display: flex; flex-direction: column; gap: var(--space-3); }
.auth-card { width: 100%; max-width: 400px; padding: var(--space-7); }
.auth-title { font-size: var(--fs-h2); margin: 0 0 var(--space-2); text-align: center; }
.auth-card > .muted { text-align: center; }
.env-banner { align-self: stretch; background: var(--amber-soft); border: 1px solid var(--amber);
              border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3);
              font-size: var(--fs-sm); margin-bottom: var(--space-5); }
.auth-card form { display: flex; flex-direction: column; gap: var(--space-3); }
.center { text-align: center; align-items: center; }
.plain-link { text-decoration: none; }

/* icons */
.ico { flex: 0 0 auto; vertical-align: -.15em; }

/* ── Mobile — tab bar, not a wrapped sidebar ────────────────────────── */
@media (max-width: 900px) {
  .shell { flex-direction: column; }
  .sidebar { position: sticky; top: 0; z-index: var(--z-chrome); width: auto;
    height: auto; overflow: visible; flex-direction: row; flex-wrap: wrap;
    align-items: center; gap: var(--space-2) var(--space-3); padding: 10px var(--gutter); }
  /* The top bar's wordmark only: sign-in cards and the landing page keep
     theirs whole and centred on a phone (health check D1). */
  .sidebar .brand { padding: 0; flex-direction: row; align-items: baseline; gap: 6px; }
  .sidebar .brand-sub { display: none; }
  .nav-search { flex: 1 1 140px; min-width: 0; }
  /* the nav leaves the top bar and becomes a bottom tab bar */
  .nav { position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-chrome);
    flex-direction: row; background: var(--panel-dark);
    border-top: 1px solid var(--line-inverse); height: 56px;
    padding: 0 var(--space-1) calc(env(safe-area-inset-bottom, 0px)); }
  .nav a, .nav-more { flex: 1; flex-direction: column; justify-content: center;
    gap: 3px; font-size: 10px; border: none; border-radius: 0;
    border-top: 2px solid transparent; padding: 6px 2px; }
  .nav a.active { background: none; border-top-color: var(--accent); }
  .nav a .badge { position: absolute; transform: translate(12px, -14px);
                  margin: 0; }
  .nav a[data-mobile-overflow] { display: none; }
  .nav .nav-app-title { display: none; }
  /* The fourth tab: shares the .nav a rule above for its anatomy, so the
     two can never drift; this adds only what a button doesn't inherit. */
  .nav-more { display: flex; align-items: center;
    font-family: inherit; font-weight: 500;
    color: var(--ink-inverse-muted); background: none; cursor: pointer; }
  .nav-more[aria-expanded="true"] { color: var(--ink-inverse);
    border-top-color: var(--accent); }
  .nav-more .ico { opacity: .85; }
  /* The sheet docks just above the bar it came from, same dark chrome. */
  .more-sheet:not([hidden]) { display: flex; flex-direction: column; }
  .more-sheet { position: fixed; left: 10px; right: 10px;
    bottom: calc(64px + env(safe-area-inset-bottom, 0px)); z-index: var(--z-sheet);
    background: var(--panel-dark); border: 1px solid var(--line-inverse);
    border-radius: var(--radius-md); padding: var(--space-2); max-height: calc(100dvh - 11rem); overflow-y: auto;
    box-shadow: var(--shadow-overlay); }
  .more-sheet a, .more-sheet .linkish { display: flex; align-items: center;
    gap: 10px; width: 100%; padding: 10px var(--space-3); border-radius: var(--radius-sm);
    font-size: var(--fs-base); font-weight: 500; text-decoration: none;
    color: var(--ink-inverse-muted); }
  .more-sheet a.active { color: var(--ink-inverse);
    background: var(--inverse-hover); }
  .more-sheet .ico { opacity: .85; }
  .more-sheet .more-sep { border-top: 1px solid var(--line-inverse);
    margin: 6px var(--space-1); }
  .more-sheet form { display: contents; }
  .pinned-nav { display: none; }
  .sidebar-foot { margin: 0; border: none; padding: 0; flex-direction: row;
                  align-items: center; gap: 10px; }
  /* Admin and Sign out ride in the More sheet on a phone; the top bar
     keeps just the search and who you are. */
  .sidebar-foot .foot-link, .sidebar-foot form { display: none; }

  .main { padding: var(--space-4) var(--gutter) 84px; }
  .two-col { grid-template-columns: 1fr; }
  .row { flex-direction: column; gap: var(--space-2); }

  .col-created, .col-done, .col-age, .col-field { display: none; }
  .hero-dark { padding: var(--space-5); }
  .hero-dark .hero-title { font-size: var(--fs-h1); }
  .hero-stats { gap: var(--space-4) var(--space-6); }
  .hero-stats .n { font-size: var(--fs-h1); }
  .stat-row { gap: var(--space-5); }
  .page-head, .head-actions, .inline-form, .filter-bar { flex-wrap: wrap; }
  .tabs { overflow-x: auto; }
  /* Shrink cells may reflow on small screens — but never dates, which
     wrap one word per line and turn the audit log into a ransom note. */
  .tbl-scroll td.shrink { white-space: normal; width: auto; }
  .tbl-scroll td.shrink[title] { white-space: nowrap; }
  .tbl-scroll .inline-form { flex-wrap: wrap; margin-bottom: var(--space-1); }
  .tbl-scroll input[type=text] { min-width: 90px; }
}
@media (max-width: 560px) {
  .col-assignee, .col-due { display: none; }
  .wins-table .col-task { width: 62%; }
  .wins-table .col-value { width: 19%; }
  .wins-table .col-winproject { display: none; }
}

/* ── Task document layout ───────────────────────────────────────────── */
.doc-pills { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center;
             margin: 6px 0 10px; }
/* Everything on the pill row shares one height and one baseline. The
   status pill is 22px in table rows (padding-set, correct there); here it
   sits beside two 26px buttons, so it matches them. The nested forms'
   8px form margin was lifting the buttons off the row. */
.doc-pills .pill { height: var(--ctl-h-sm); padding-top: 0; padding-bottom: 0; }
.doc-pills .inline-form { margin: 0; align-items: center; }
.doc-grid { grid-template-columns: minmax(0, 1fr) 320px;
            gap: var(--space-8); max-width: 1240px; align-items: start; }
textarea.title-input, h1.title-read { font-family: var(--font-sans); font-size: var(--fs-h1); font-weight: 700; /* an h1 like any other; 800 is the display register */ letter-spacing: -.02em; line-height: 1.12; width: 100%; border: 1px solid transparent; border-radius: var(--radius-sm); background: transparent; padding: var(--space-1) var(--space-2); margin: 0 -8px 10px; resize: none; overflow: hidden; display: block; height: auto; }
textarea.title-input:hover { border-color: var(--line); }
textarea.title-input:focus { background: var(--panel); }
/* the notes editor IS the document — no box, no ring, just a caret */
.doc-notes .re-area { min-height: 96px; font-size: var(--fs-md); line-height: 1.6; }
.doc-label { margin: var(--space-6) 0 var(--space-2); border-bottom: 1px solid var(--line);
             padding-bottom: 6px; }
.doc-rail .status-grid { display: grid; grid-template-columns: 1fr 1fr;
                         gap: 6px; }
.status-grid form { display: flex; }
.status-grid .btn { width: 100%; justify-content: center;
                    border-color: var(--line-mid); }
.status-now { justify-content: center; font-weight: 600; cursor: default; }
.status-now.done { background: var(--green-soft); border-color: var(--green); }
.status-now.doing { background: var(--accent); border-color: var(--accent);
                    color: var(--accent-ink); }
.status-now.blocked { background: var(--amber-soft); border-color: var(--amber); }
.status-now.todo { background: var(--sage-fill); }
.rail-fields { display: flex; flex-direction: column; }
.rail-field { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 6px 0; border-bottom: 1px solid var(--line);
  min-height: 38px; }
.rail-field:last-child { border-bottom: none; }
.rf-label { font-size: var(--fs-sm); color: var(--muted); flex: 0 0 auto; }
.rf-value { font-size: var(--fs-sm); font-weight: 600;
             font-variant-numeric: tabular-nums; }
.rail-field select, .rail-field input { font-weight: 500; }
/* rail controls read as values until touched */
.rail-field select, .rail-field input[type=text],
.rail-field input[type=date] { border-color: transparent; background: transparent;
  text-align: right; font-size: var(--fs-sm); padding: 5px 6px; border-radius: var(--radius-sm);
  flex: 1 1 auto; min-width: 0; max-width: 170px; }
.rail-field select:hover, .rail-field input:hover { border-color: var(--line-mid); }
.rail-field select:focus, .rail-field input:focus { background: var(--panel);
  border-color: var(--accent); }
.rail-field-tall { flex-direction: column; align-items: stretch; }

.rail-actions { display: flex; flex-direction: column; gap: var(--space-2);
  border-top: 1px solid var(--line); padding-top: var(--space-3); margin-top: var(--space-1); }
.rail-actions .linkish { display: inline-flex; align-items: center; gap: 6px; }
.rail-move { display: flex; gap: 6px; }
.rail-move select { flex: 1; min-width: 0; font-size: var(--fs-sm); }

@media (max-width: 900px) {
  .doc-grid { grid-template-columns: 1fr; }
}

/* PSP hub cards + win marker */
.psp-card { display: flex; flex-direction: column; gap: var(--space-1); }
.psp-stats { display: flex; font-size: var(--fs-sm); color: var(--muted); gap: 10px; }
.psp-stats b { font-family: var(--font-mono); font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; font-size: var(--fs-base); }
.psp-stats .stat-blocked b { color: var(--amber-ink); }
.win-mark { color: var(--ink);  /* amber is the blocked signal; the star already says win */ display: inline-flex; vertical-align: -.1em; }

/* comment button sits under the box, not across it */
.stack > .btn { align-self: flex-start; }
@media (max-width: 900px) { textarea.title-input, h1.title-read { font-size: var(--fs-h2); } }

/* Pasted meeting notes are prose in a code fence, not code — wrap them
   rather than hiding the tail behind a scrollbar. */

.rich-text a { overflow-wrap: anywhere; }

/* PSP hub: many small providers — pack more per row, less air inside */
.cards.tight { grid-template-columns: repeat(auto-fill, minmax(236px, 1fr));
               gap: var(--space-3); }
/* The ONE compact card variant (lookup directories): same corner, tighter padding. */
.cards.tight .card { padding: var(--gutter) var(--space-4); border-radius: var(--radius-lg); }
.cards.tight .card-title { font-size: var(--fs-base); margin-bottom: 2px; }

/* ── Design polish: icons, weight, and one colour per state ─────────── */
.rail-head { font-family: var(--font-mono); font-size: var(--fs-label); font-weight: 400;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
  margin: var(--space-5) 0 var(--space-2); }
.doc-rail > .rail-head:first-child { margin-top: 0; }

/* a status pill that carries an icon doesn't also need the dot */
.pill.has-ico::before { display: none; }
.pill.has-ico { padding-left: var(--space-2); }

/* the line under the title: who · when · where · what it's tagged with */
.doc-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-5);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  padding: 10px 0; margin: var(--space-1) 0 var(--space-5); font-size: var(--fs-sm); color: var(--muted); }
.doc-meta .dm { display: inline-flex; align-items: center; gap: 6px; }
.doc-meta .dm strong { color: var(--ink); font-weight: 600; }
.doc-meta .dm-late strong { color: var(--red); }
.doc-meta .chip { margin: 0; }

/* rail actions all read the same: mark, label, one line each */
.rail-actions .linkish, .rail-disclosure > summary {
  display: inline-flex; align-items: center; gap: var(--space-2); padding: 3px 0;
  list-style: none; cursor: pointer; }
.rail-disclosure > summary::-webkit-details-marker { display: none; }
.rail-disclosure[open] > summary { color: var(--ink); }
.rail-disclosure .rail-move { margin: var(--space-2) 0 var(--space-1); }

/* search mark inside the field, matching the sidebar */
.search-field { position: relative; display: inline-flex; align-items: center; }
.search-field .ico { position: absolute; left: 11px; color: var(--muted);
                     pointer-events: none; }
.search-field input[type=search] { padding-left: var(--space-7); }

/* banners lead with a mark and end with the way to act on them */

.banner-ico { flex: 0 0 auto; color: var(--amber-ink); display: flex;
              padding-top: 1px; }
.banner-text { flex: 1; }
.banner-text strong { font-weight: 600; }
.rag-nudge .btn { flex: 0 0 auto; align-self: center; }

.qa-plus { display: inline-flex; align-items: center; color: var(--muted);
           padding-left: var(--space-1); }

/* ── Mobile: one calm type scale, not the desktop one shrunk ────────── */
@media (max-width: 900px) {
  h1 { font-size: var(--fs-h2); margin-bottom: var(--space-2); }
  h2 { font-size: var(--fs-md); margin: var(--space-5) 0 var(--space-2); }
  h3 { font-size: var(--fs-base); }
  .display { font-size: var(--fs-h1); }
  .btn { font-size: var(--fs-sm); padding: 7px 11px; }
  .btn.tiny { font-size: var(--fs-xs); }
  .flash, .rag-nudge, .blocked-banner, .project-banner,
  .note, .muted, .member-line { font-size: var(--fs-sm); }
  table.tasks td { font-size: var(--fs-sm); padding: 9px 10px; }
  .doc-meta { font-size: var(--fs-xs); gap: 6px var(--gutter); }
  .doc-rail { border-radius: var(--radius-lg); }
  .stat-row .n { font-size: var(--fs-h1); }
}

/* the separator belongs to the line, not to the wrapped fragment */

@media (max-width: 900px) {
  .member-line { gap: 6px var(--space-2); }

  
}

@media (max-width: 900px) {
  /* the document body was the one thing still set at desktop reading size */
  .doc-notes .re-area, .rich-text { font-size: var(--fs-base); line-height: 1.55; }
  .re-toolbar { gap: 2px; }
  .doc-label { margin: var(--space-5) 0 6px; }
}

/* consistency sweep */
h1.display { font-size: var(--fs-display); }
.search-field.grow-input { flex: 1; max-width: 480px; }
.search-field.grow-input input[type=search] { width: 100%; }
@media (max-width: 900px) { h1.display { font-size: var(--fs-h1); } }

/* Stateful toggles (Pin, Key Win, Follow) show "on" ONE way: sage fill,
   charcoal outline, heavier label — never blue, which keeps its one job. */
.btn.on { background: var(--sage-fill); border-color: var(--line-strong);
          color: var(--ink); font-weight: 600; }

/* ── Band collapse ──────────────────────────────────────────────────── */
tr.section-band { cursor: pointer; }
tr.section-band:hover td { background: var(--sage-hover); }
.band-toggle { background: none; border: none; padding: 0; margin: 0;
  display: flex; align-items: center; color: var(--muted); cursor: pointer; }
.band-toggle .ico { transition: transform var(--dur-2) var(--ease); }
tbody.collapsed .band-toggle .ico { transform: rotate(-90deg); }
.band-toggle:focus-visible { outline: none; box-shadow: var(--focus-ring);
                             border-radius: var(--radius-chip); }

/* ── Density switch — a segmented control, not two buttons ──────────── */
.density { display: inline-flex; margin-left: auto; border-radius: var(--radius-sm);
  border: 1px solid var(--line-strong); overflow: hidden; }
.density button { font-weight: 500; font-size: var(--fs-xs); line-height: 1; font-family: var(--font-sans); color: var(--muted);
  background: var(--panel); border: none; padding: 7px var(--space-3); cursor: pointer; }
.density button + button { border-left: 1px solid var(--line); }
.density button.on { background: var(--panel-dark); color: var(--ink-inverse); }
.density button:focus-visible { outline: none; box-shadow: var(--focus-ring); }

/* ── The "/" hint the sidebar search advertises ─────────────────────── */

.key-hint { position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  font-weight: 400; font-size: var(--fs-label); line-height: 1; font-family: var(--font-mono); color: var(--ink-inverse-muted);
  border: 1px solid var(--line-inverse); border-radius: var(--radius-chip); padding: 3px 5px;
  pointer-events: none; }
.nav-search input[type=search]:focus + .key-hint { display: none; }

@media (max-width: 900px) {
  .density { margin-left: 0; }
  .key-hint { display: none; }
}

/* ── Screen 4: who is that avatar? ──────────────────────────────────── */
.avatar[data-tip] { position: relative; }
.avatar[data-tip]:hover::after, .avatar[data-tip]:focus-visible::after {
  content: attr(data-tip); position: absolute; bottom: calc(100% + 6px);
  left: 50%; transform: translateX(-50%); white-space: nowrap; z-index: var(--z-popover);
  font-weight: 400; font-size: var(--fs-xs); line-height: 1; font-family: var(--font-sans); text-transform: none; letter-spacing: 0;
  color: var(--ink-inverse); background: var(--panel-dark);
  padding: 6px 9px; border-radius: var(--radius-chip); box-shadow: var(--shadow-popover);
  pointer-events: none; }

/* ── Screen 9: an invite link is a thing you copy, not a wall of text ── */
/* A row's buttons stay side by side: stacked, "Reset password" pushed the
   People table past its frame at laptop width (health check D6). */
.row-actions { display: flex; gap: var(--space-2); justify-content: flex-end; align-items: center; white-space: nowrap; }
.row-actions .inline-form { margin: 0; flex-wrap: nowrap; }
.invite-row { display: flex; align-items: center; gap: var(--space-2); max-width: 420px; }
.invite-row code { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-xs); background: var(--panel-sub); border-radius: var(--radius-chip); padding: 5px var(--space-2); height: var(--ctl-h-sm); display: inline-flex; align-items: center; }

/* ── Screen 10: the usage line is one line ──────────────────────────── */
.tbl-scroll td.usage { white-space: nowrap; width: 1%;
                       font-size: var(--fs-sm); }
.tbl-scroll td { vertical-align: middle; }

/* Fields list: whether a field restricts what can be typed reads under its
   editor. Saving a list is what restricts it — there is no lock button —
   so the state has to be stated rather than inferred from a full box. */
.field-lock { display: block; margin: var(--space-1) 0 2px; font-size: var(--fs-xs); }

/* ── All Tasks: one panel, three labelled rows ───────────────────────────
   Search + sort on top; then Scope / Dates / Fields, each row led by a
   mono label so ten controls read as a form, not a junk drawer. */
.allt-panel { border: 1px solid var(--line-strong); border-radius: var(--radius-md);
              background: var(--panel); padding: var(--space-3) var(--gutter) 6px;
              margin-bottom: var(--gutter); }
.allt-row { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center;
            padding-bottom: 10px; border-bottom: 1px solid var(--line); }
.allt-row .search-field { flex: 1; min-width: 220px; }
.allt-row select { max-width: 170px; }
.allt-grid { display: flex; flex-direction: column; }
.allt-group { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center;
              padding: 10px 0; }
.allt-group + .allt-group { border-top: 1px solid var(--line); }
.allt-group > .label { flex: 0 0 52px; }
.allt-group select { max-width: 180px; text-overflow: ellipsis; }
.date-pair { display: inline-flex; align-items: center; gap: 6px; }
.date-pair input[type=date] { padding: 6px var(--space-2); font-size: var(--fs-sm); height: var(--ctl-h-sm); border-radius: var(--radius-sm); }
.allt-count { margin: 0 0 var(--space-3); font-size: var(--fs-sm); }

/* Checkbox dropdown — a select that allows several. */
.fpick { position: relative; }
.fpick summary { list-style: none; cursor: pointer; display: inline-flex;
  align-items: center; gap: 6px; font-weight: 400; font-size: var(--fs-base); line-height: 1.45; font-family: var(--font-sans);
  color: var(--ink); background: var(--panel);
  border: 1px solid var(--line-mid); border-radius: var(--radius-md); padding: var(--space-2) var(--space-3);
  user-select: none; }
.fpick summary::-webkit-details-marker { display: none; }
.fpick summary strong { font-weight: 600; }
.fpick-caret { display: inline-flex; color: var(--muted); }
.fpick[open] summary { border-color: var(--accent); }
.fpick-pop { position: absolute; z-index: var(--z-popover); top: calc(100% + 4px); left: 0;
  min-width: 210px; max-width: 300px; max-height: 260px; overflow-y: auto;
  background: var(--panel); border: 1px solid var(--line-strong);
  border-radius: var(--radius-md); box-shadow: var(--shadow-popover); padding: 6px; }
.fpick-pop label { display: flex; flex-direction: row; align-items: center;
  gap: var(--space-2); padding: 5px var(--space-2); border-radius: var(--radius-chip); font-size: var(--fs-sm);
  cursor: pointer; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }  /* row beats the global stacked-label rule */
.fpick-pop label:hover { background: var(--panel-sub); }

/* ── Screen 7: the PSP filter is part of the toolbar, not loose text ── */

/* the fold chevron matches the section bands */
.quarter-fold > summary { cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: var(--space-2); }
.quarter-fold > summary::-webkit-details-marker { display: none; }
.quarter-fold > summary .band-toggle .ico { transform: rotate(-90deg); }
.quarter-fold[open] > summary .band-toggle .ico { transform: none; }

/* The rail right-aligns its value inputs, but a chip box is a place you
   TYPE — its entry stays left, full width, so "+ add" reads as a prompt
   at the end of the chips instead of floating mid-box. */
.rail-field input.chips-entry { text-align: left; max-width: none;
                                flex: 1 1 auto; }
.rail-field .chips { justify-content: flex-start; }

/* ── Sortable column headers ────────────────────────────────────────── */
.sort-link { color: inherit; text-decoration: none; display: inline-flex;
             align-items: center; gap: var(--space-1); white-space: nowrap; }
.sort-link:hover { color: var(--ink); text-decoration: none; }
.sort-link.on { color: var(--ink); font-weight: 500; }
.sort-mark { font-size: 8px; /* glyph, sized to the arrow */ line-height: 1; }
table.tasks th:has(.sort-link:hover) { background: var(--panel-sub); }

/* ── Closed-but-not-delivered: cancelled and deprioritized ──────────── */
/* Neither is a failure state, so neither gets red. They read as "off the
   list": struck through like done, but in the neutral sage rather than the
   green of delivered work. */
.pill.cancelled, .pill.deprioritized {
  background: var(--sage-fill); border-color: var(--line-mid);
  color: var(--muted); }
.pill.cancelled::before, .pill.deprioritized::before { background: var(--muted); }
.status-now.cancelled { background: var(--red-soft); border-color: var(--red); }
.status-now.deprioritized { background: var(--sage-fill);
  border-color: var(--line-strong); color: var(--ink); }
/* Set aside (deprioritized): parked, not dead. Dimmed like the closed
   rows but never struck — a strike says "will not happen", and the whole
   point of the status is that it might. (.abandoned-row retired with it.) */
tr.aside-row { opacity: .65; }
tr.aside-row td.col-status, tr.aside-row td.col-task { background: var(--panel); }

/* Cancelled/Deprioritized explain themselves in the neutral tone — they
   are decisions, not alarms. Blocked keeps the amber. */
.blocked-banner.stopped-banner { background: var(--sage-fill);
  border-color: var(--line-mid); }
.blocked-banner.stopped-banner .banner-ico { color: var(--muted); }

/* ── Composer: toolbar, typing area and its action in ONE outlined box ──
   A borderless editor reads as a page of text, not a place to type (Ivan:
   "I can't tell it's meant for me to type"). One outline around the whole
   thing, the way every chat composer does it, plus the usual field states:
   the border firms up on hover and takes the focus ring while you write. */
/* No overflow:hidden here. It was clipping the corners of the toolbar, but
   it also clipped the @mention popup — which sits ABOVE the box — out of
   existence, so mentions silently stopped working. The toolbar rounds its
   own top corners instead, and popovers can escape the frame. */
.rich-editor.composer { border: 1px solid var(--line-mid); border-radius: var(--radius-md);
  background: var(--panel);
  transition: border-color var(--dur-2) var(--ease); }
.rich-editor.composer:hover { border-color: var(--line-strong); }
.rich-editor.composer:focus-within { border-color: var(--accent);
  box-shadow: var(--focus-ring); }

.composer .re-toolbar { border: none; border-bottom: 1px solid var(--line);
  border-radius: 11px 11px 0 0; width: auto; margin: 0; background: var(--bg);
  padding: 5px 6px; position: static; }
.composer .re-area { border: none; border-radius: 0 0 11px 11px;
  background: transparent; min-height: 64px; padding: 10px var(--space-3); }
.composer .re-area:focus { box-shadow: none; border: none; }
/* a contenteditable the browser has seeded with <br> is still "empty" to a
   reader, so the prompt has to survive that too */
.composer .re-area:has(> br:only-child)::before {
  content: attr(data-placeholder); color: var(--faint); }

/* 11px, not 12: the frame's 12px radius is measured on its border box, so
   a child inside a 1px border needs one less to sit concentric with it. */
.composer-foot { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: var(--space-2) 10px; border-top: 1px solid var(--line);
  background: var(--panel); border-radius: 0 0 11px 11px; }
.composer-hint { font-size: var(--fs-xs); color: var(--faint); }
.composer-foot .btn { flex: 0 0 auto; }
@media (max-width: 560px) { .composer-hint { display: none; } }

/* Each status wears its own colour on the picker, so you aim at a colour
   rather than read six near-identical buttons. The one you're on is filled;
   the others are only tinted, and firm up as you go to press them. */
.status-pick { border-color: var(--line-mid); }
.status-pick::before { content: ""; width: 7px; height: 7px; border-radius: 50%;
  flex: 0 0 auto; margin-right: 1px; }
.status-pick.todo::before          { background: var(--muted); }
.status-pick.doing::before         { background: var(--accent); }
.status-pick.done::before          { background: var(--green); }
.status-pick.blocked::before       { background: var(--amber); }
.status-pick.cancelled::before     { background: var(--red); }
.status-pick.deprioritized::before { background: var(--faint); }
.status-pick.doing:hover     { background: var(--accent-soft); border-color: var(--accent); }
.status-pick.done:hover      { background: var(--green-soft); border-color: var(--green); }
.status-pick.blocked:hover   { background: var(--amber-soft); border-color: var(--amber); }
.status-pick.cancelled:hover { background: var(--red-soft); border-color: var(--red); }
.status-pick.todo:hover,
.status-pick.deprioritized:hover { background: var(--sage-fill);
                                   border-color: var(--line-strong); }
/* the current status keeps the dot too, so the set reads as one family */
.status-now::before { content: ""; width: 7px; height: 7px; border-radius: 50%;
  flex: 0 0 auto; margin-right: 1px; background: currentColor; opacity: .8; }

/* Cancelled reads as a stop in the lists as well; deprioritized stays quiet
   because it is a "not now", not a "no". */
.pill.cancelled { background: var(--red-soft); border-color: var(--red-edge);
                  color: var(--red); }
.pill.cancelled::before { background: var(--red); }
.pill.deprioritized { background: var(--sage-fill); border-color: var(--line-mid);
                      color: var(--muted); }

/* ── File links ─────────────────────────────────────────────────────── */
.file-row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.file-name { display: inline-flex; align-items: center; gap: 6px;
             font-weight: 500; }
.file-meta { font-size: var(--fs-xs); }
/* A Drive link pasted into notes or a comment reads as the file it is,
   not as a wall of URL. */
.rich-text a.file-chip { display: inline-flex; align-items: center; gap: 5px;
  background: var(--sage-fill); border: 1px solid var(--line-mid);
  border-radius: var(--radius-pill); padding: 1px 9px; font-size: var(--fs-code); font-weight: 500;
  text-decoration: none; color: var(--ink); vertical-align: baseline; }
.rich-text a.file-chip:hover { border-color: var(--line-strong);
                               text-decoration: none; }
.rich-text a.file-chip::before { content: ""; width: 6px; height: 6px;
  border-radius: 2px; background: var(--muted); flex: 0 0 auto; }
.rich-text a.file-chip[data-kind=doc]::before    { background: var(--accent); }
.rich-text a.file-chip[data-kind=sheet]::before  { background: var(--green); }
.rich-text a.file-chip[data-kind=slides]::before { background: var(--amber); }
.rich-text a.file-chip[data-kind=folder]::before { background: var(--faint);
                                                   border-radius: 50%; }
.steps { padding-left: var(--space-5); font-size: var(--fs-base); line-height: 1.7; }
.steps code { font-size: var(--fs-xs); }

/* A URI you are meant to copy verbatim — never transformed, always exact.
   (.crumbs uppercases, which silently produced a redirect URI that would
   not match the one registered with Google.) */
code.copyable { display: inline-block; text-transform: none;
  font-family: var(--font-mono); font-size: var(--fs-code); letter-spacing: 0;
  background: var(--panel-sub); border: 1px solid var(--line);
  border-radius: var(--radius-chip); padding: 3px var(--space-2); user-select: all; }

/* A folder shows what's in it, indented under the folder itself. */
.folder-contents { list-style: none; margin: 6px 0 2px; padding: 0 0 0 22px;
  border-left: 1px solid var(--line); flex-basis: 100%; }
.folder-contents li { display: flex; align-items: baseline; gap: var(--space-2);
                      flex-wrap: wrap; padding: 3px 0; }
.folder-contents a { display: inline-flex; align-items: center; gap: 6px;
                     text-decoration: none; }
.folder-contents a:hover { text-decoration: underline; }
.folder-empty { flex-basis: 100%; font-size: var(--fs-xs); margin: var(--space-1) 0 0 var(--space-5); }

.drive-panel { border: 1px solid var(--line); border-radius: var(--radius-md);
  padding: 10px var(--gutter); margin: 0 0 var(--gutter); background: var(--panel); }
.drive-panel > summary { cursor: pointer; display: flex; align-items: center;
  gap: var(--space-2); font-weight: 500; list-style: none; }
.drive-panel > summary::-webkit-details-marker { display: none; }
.drive-panel .folder-contents { border-left: none; padding-left: 22px; }

/* ── Review ─────────────────────────────────────────────────────────── */
.review-stats { justify-content: flex-start; gap: var(--space-7); margin: var(--space-5) 0 6px; }
.col-num { width: 96px; text-align: right; font-variant-numeric: tabular-nums; }
th.col-num { text-align: right; }

/* the scope switch reuses the density control, as links rather than buttons */
.density a { font-weight: 500; font-size: var(--fs-xs); line-height: 1; font-family: var(--font-sans); color: var(--muted);
  background: var(--panel); padding: 7px var(--space-3); text-decoration: none; }
.density a + a { border-left: 1px solid var(--line); }
.density a.on { background: var(--panel-dark); color: var(--ink-inverse); }

/* A rendered narrative reads like prose; the rollup stays a literal digest. */
.summary-rich { font-size: var(--fs-md); line-height: 1.6;
                max-width: 900px; }
.summary-rich > *:first-child { margin-top: 0; }
.summary-rich > *:last-child { margin-bottom: 0; }
.summary-rich ul { margin: 10px 0; padding-left: var(--space-5); }
.summary-rich li { margin: 6px 0; }
.summary-rich p { margin: 10px 0; }

/* AI output sits above the data it describes, visibly derived from it. */
.ai-ask { align-items: center; gap: var(--space-3); margin: 0 0 var(--space-5); }
.ai-panel { border: 1px solid var(--line); border-left: 3px solid var(--accent);
  background: var(--panel); padding: var(--space-4) var(--space-5); margin: 0 0 var(--space-5); }
.ai-panel.err { border-left-color: var(--line); }
.ai-head { display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); margin-bottom: 10px; }
.ai-foot { margin: var(--space-3) 0 0; font-size: var(--fs-xs); }

/* Whose week you're reading, stated in the heading rather than as a tab. */
.page-head h1 .avatar { width: 30px; height: 30px; font-size: var(--fs-xs);
  vertical-align: -5px; margin-right: var(--space-2); }

/* Presets are the common path; the custom range folds away beneath them. */
.gen-form { margin: 0 0 var(--space-6); }
.gen-row { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); }
fieldset.gen-row { border: 0; padding: 0; margin: 0; min-width: 0; }
fieldset.gen-row legend { float: left; margin-right: var(--space-2); padding: 0; }
/* A radio dressed as a button: the chosen one wears the one "on" style. */
.btn.choice { cursor: pointer; }
.btn.choice input { position: absolute; opacity: 0; pointer-events: none; }
.btn.choice:has(input:checked) { background: var(--sage-fill); border-color: var(--line-strong);
  color: var(--ink); font-weight: 600; }
.btn.choice:has(input:focus-visible) { box-shadow: var(--focus-ring); }
.gen-dates { display: none; gap: var(--space-3); margin-top: var(--space-3); }
.gen-form:has(input[value=custom]:checked) .gen-dates { display: flex; }
.gen-go { display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-4); }

/* The rollup is a digest: dense, scannable, one project per block. */
.rollup-rich h1 { font-size: var(--fs-h2); margin: 0 0 6px; }
.rollup-rich h2 { font-size: var(--fs-md); margin: var(--space-5) 0 6px;
  padding-top: var(--gutter); border-top: 1px solid var(--line); }
.rollup-rich ul { margin: 6px 0; padding-left: 18px; }
.rollup-rich li { margin: 3px 0; }
.rollup-rich ul ul { margin: 3px 0; }

/* Stepping between weeks. The chevrons sit either side of the week label
   so the date range reads as the control, rather than as a caption with a
   row of links parked next to it. */
/* The 20px chevron boxes make this row taller than a plain eyebrow, so it
   needs real clearance — otherwise the 30px avatar in the title below rises
   into it and the two collide. */
.week-nav { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2);
            margin: 0; }
.week-nav .step { display: inline-flex; align-items: center; justify-content: center;
  /* 24px: the minimum pointer target, and no longer a fiddly tap on a phone */
  width: 24px; height: 24px; border: 1px solid var(--line); border-radius: var(--radius-chip);
  color: var(--muted); text-decoration: none; font-family: var(--font-sans);
  font-size: var(--fs-base); letter-spacing: 0; }
.week-nav a.step:hover { border-color: var(--ink); color: var(--ink); }
.week-nav .step.off { opacity: .3; }
.step-now { letter-spacing: .1em; color: var(--muted); text-decoration: none;
  border-bottom: 1px solid var(--line); }
.step-now:hover { color: var(--ink); border-bottom-color: var(--ink); }

/* ═══════════════════════════════════════════════════════════════════════
   Consistency pass — Claude Design handoff, Aug 26. Four defects that were
   inconsistent ACROSS screens rather than wrong on one, so each is fixed
   once here. Position matters: these supersede earlier rules at equal
   specificity. (.seg is absent — it was deleted as dead in the previous
   round; .lede in the handoff is this codebase's .page-lede.)
   ═══════════════════════════════════════════════════════════════════════ */

/* ── 1. One control height ──────────────────────────────────────────────
   A .btn was 32px, a select 39px and a .btn.tiny 24px, so any toolbar
   holding two kinds of control had three different edges. Height is now
   explicit rather than a consequence of font metrics. */
/* controls deliberately sized otherwise restate their own height */

.density button, .density a, .fpick summary {
  height: var(--ctl-h); padding-top: 0; padding-bottom: 0; }

.rail-field select, .rail-field input[type=text], .rail-field input[type=date],
.rail-field input[type=search] { height: 30px; }

/* A toolbar is a row of controls, so it centres them. .inline-form keeps
   flex-end globally — elsewhere it holds labelled fields whose baselines
   must line up — and its 8px bottom margin was lifting its controls a
   row-height above their neighbours. */
.page-head .inline-form, .head-actions .inline-form,
.member-line .inline-form, .filter-bar .inline-form,
.allt-row .inline-form,
/* the Sections rows and their Add row: an input beside tiny buttons, no
   labels, so flex-end sank Save below the arrows (Ivan, 2026-09-04) */
.section-admin-row .inline-form,
.settings-card > .inline-form { margin: 0; align-items: center; }
.settings-card > .inline-form { margin-bottom: var(--space-2); }
.member-line .btn.tiny, .section-admin-row .btn.tiny,
.settings-card > .inline-form .btn.tiny { height: var(--ctl-h-sm); }

/* ── 2. Select: the caret belongs inside the field ──────────────────────
   The native indicator sits flush to the border, which reads as a control
   that has run out of room. One drawn caret, inset on the same 12px as
   the text — the Lucide chevron at 14px, matching the icon set. */
select { appearance: none; -webkit-appearance: none;
  padding-right: 34px;
  background-color: var(--panel);
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%235A5A4F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>');
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 14px 14px; }
select::-ms-expand { display: none; }
.rail-field select { background-color: transparent; padding-right: 24px;
                     background-position: right 5px center; }
.rail-field select:focus { background-color: var(--panel); }
.rail-move select, .allt-group select { padding-right: 30px; }

/* ── 3. One page head ───────────────────────────────────────────────────
   Every screen opens the same way: an optional crumb or eyebrow, the title
   at one size, an optional single line of explanation — stacked in
   .head-left — with the actions on the right, on the title's baseline. */
.head-left { display: flex; flex-direction: column; gap: 5px; min-width: 0;
             flex: 1 1 340px; }
.head-left > .crumbs, .head-left > .eyebrow { margin: 0; }
.page-head h1, .page-head h2 { font-size: var(--fs-h1); font-weight: 700;
  letter-spacing: -.015em; line-height: 1.15; margin: 0;
  display: flex; align-items: center; gap: 10px; }
.page-head h1.display { font-size: var(--fs-h1); font-weight: 800; }
.page-head h2 .muted { font-size: var(--fs-sm); font-weight: 400; }
.head-left > .page-lede { margin: 1px 0 0; font-size: var(--fs-sm);
  max-width: 70ch; line-height: 1.5; }
.page-head .stat-row { flex: 0 0 auto; }
@media (max-width: 900px) {
  .page-head { align-items: flex-start; margin-bottom: var(--space-5); }
  .head-left { flex-basis: 100%; }
}

/* ── 4. My Tasks: one column grid for all three sections ────────────────
   Three tables only line up if they are told to. Fixed layout plus a
   shared colgroup gives Status / Task / Project / Due / action the same x
   in every section. Fixed layout divides what it is given, so the table
   states the width the five columns need — below that .tbl-scroll scrolls
   rather than crushing task titles into a column one word wide. */
table.tasks.list-cols { table-layout: fixed; min-width: 760px; }
.list-cols .c-status  { width: var(--colw-status); }
.list-cols .c-project { width: var(--colw-project); }
.list-cols .c-due     { width: var(--colw-due); }
.list-cols .c-act     { width: var(--colw-act); }
.list-cols td.col-project, .list-cols th.col-project { white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.list-cols td.col-task { white-space: normal; }
th.col-act, td.col-act { text-align: right; }
td.col-act form { display: inline-flex; }
.list-cols td.col-due .due-rel { display: block; }
.list-cols td.col-due .due-on { display: block; font-size: var(--fs-xs);
                                color: var(--faint); }
@media (max-width: 900px) {
  /* the narrower columns are what makes the list fit — the floor has to
     come off with them, or the table just scrolls at its desktop width */
  table.tasks.list-cols { min-width: 0; }
  .list-cols .c-project { width: 130px; }
  .list-cols .c-due { width: 104px; }
}
@media (max-width: 560px) {
  /* Phone: three columns, full width. The recipe that survives Chrome's
     table model (measured, not theorised): keep fixed layout, KEEP the
     hidden cells (display:none shifts survivors onto the wrong <col>s),
     collapse them to zero, neutralise every <col> width — by the same
     .c-* class selectors that set them, or specificity keeps the desktop
     widths — and state the status/action widths on the CELLS. Anything
     less leaves a phantom strip where the browser parks the leftover
     column space. */
  .list-cols .c-status, .list-cols .c-task, .list-cols .c-project,
  .list-cols .c-due, .list-cols .c-act { width: auto; }
  .list-cols th.col-status, .list-cols td.col-status { width: 96px; }
  .list-cols th.col-act, .list-cols td.col-act { width: 56px; }
  .list-cols th.col-project, .list-cols td.col-project,
  .list-cols th.col-due, .list-cols td.col-due {
    width: 0; padding: 0; border: none;
    overflow: hidden; white-space: nowrap;
    /* the generic phone rule below display:nones .col-due — which is the
       cell-removal trap all over again. Stay a cell; zero width hides. */
    display: table-cell; }
}

/* ── 5. Sidebar: four pairs, not eight links ────────────────────────────
   Eight equal items read as a list to be searched. Grouped in twos under
   mono labels the nav reads as a map. The labels are plain children of
   .nav so the mobile tab bar can simply drop them. */
.nav-group { font-family: var(--font-mono); font-size: var(--fs-label);
  letter-spacing: .1em; text-transform: uppercase;
  /* .62 clears AA on the charcoal; .4 sat around 3:1 at 11px */
  color: var(--ink-inverse-muted); padding: 0 10px; margin: var(--gutter) 0 3px; }
.nav-group:first-child { margin-top: 0; }
@media (max-width: 900px) { .nav .nav-group { display: none; } }

/* ── Round C: reactions, linked value chips, bulk bar, comment targets ── */
/* Arriving from an inbox deep-link: the comment lights up so the eye
   lands. scroll-margin clears the sticky chrome. */

.comments > li:target { background: var(--amber-soft); border-radius: var(--radius-md);
                        padding: var(--space-2) 10px; margin: 0 -10px; }

.reactions { display: flex; align-items: center; flex-wrap: wrap;
             gap: 6px; margin-top: 6px; }
.react-btn { border: 1px solid var(--line); background: var(--panel);
  border-radius: var(--radius-pill); padding: 1px var(--space-2); font-size: var(--fs-sm);
  line-height: 1.7; cursor: pointer; }
.react-btn:hover { border-color: var(--line-mid); }
.react-btn.on { background: var(--sage-fill); border-color: var(--line-strong); }
.react-pick { position: relative; }
.react-pick > summary { list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border: 1px dashed var(--line-mid);
  border-radius: var(--radius-pill); color: var(--muted); }
.react-pick > summary::-webkit-details-marker { display: none; }
.react-pick[open] > summary { border-style: solid; color: var(--ink); }
.react-menu { display: flex; position: absolute; left: 0; bottom: 26px;
  gap: var(--space-1); background: var(--panel); border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill); padding: var(--space-1) 6px; box-shadow: var(--shadow-popover);
  z-index: var(--z-popover); white-space: nowrap; }

/* A field value that leads somewhere reads as text until you hover. */
.val-link { color: inherit; text-decoration: none; }
.val-link:hover { text-decoration: underline; }

/* Bulk bar: appears with the first ticked row on All Tasks. */
.bulk-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  margin: 0 0 10px; padding: var(--space-2) var(--space-3); background: var(--panel);
  border: 1px solid var(--line-strong); border-radius: var(--radius-md); }
.col-sel { width: 30px; }
.col-sel input { accent-color: var(--accent); }

/* ── #project references + checklist item edit ─────────────────────── */
/* Siblings of .mention: same pill anatomy, sage instead of accent-soft
   — places and work items, not people. */
.project-ref, .task-ref { background: var(--sage-fill); border-radius: var(--radius-chip);
               padding: 0 var(--space-1); color: inherit; text-decoration: none;
               font-weight: 600; }
.project-ref:hover, .task-ref:hover { text-decoration: underline; }
/* The checklist Edit disclosure opens its little form inline, in the
   same row voice as the comment editor. */
.check-edit { display: inline-flex; }
.check-edit > summary { list-style: none; cursor: pointer; }
.check-edit > summary::-webkit-details-marker { display: none; }
.check-edit[open] { flex-wrap: wrap; }
.check-edit .inline-form { margin-left: 6px; }
.check-edit input[type=text] { min-width: 220px; }

/* ── Admin values workbench: bounded width + floating row editor ─────── */
/* Four short columns don't earn the full 1600px main — the Value column
   was a prairie. Same bound the auth card and doc column use: content
   width, not viewport width. */
.values-table .col-act { width: 10%; text-align: right; }
.val-edit { position: relative; display: inline-block; }
.val-edit > summary { list-style: none; cursor: pointer; }
.val-edit > summary::-webkit-details-marker { display: none; }
.val-edit-pop { display: flex; gap: 6px; position: absolute; right: 0;
  top: calc(100% + 4px); z-index: var(--z-popover); background: var(--panel);
  border: 1px solid var(--line-strong); border-radius: var(--radius-md); padding: var(--space-2);
  box-shadow: var(--shadow-popover); }

/* ── Mini-apps: the Bench switcher, and the 1-1 app ─────────────────── */
/* One login, more than one tool. The strip sits under the brand and flips
   the whole sidebar; the lit segment is the app you're in. */
.app-switch { display: flex; gap: 3px; padding: 3px;
  background: var(--inverse-hover); border: 1px solid var(--line-inverse);
  border-radius: 9px; /* concentric: the 6px segments + 3px padding */ }
.app-switch a { flex: 1 1 0; min-width: 0; display: flex; align-items: center;
  justify-content: center; white-space: nowrap; text-align: center; text-decoration: none;
  font-family: var(--font-mono); font-size: var(--fs-label);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-inverse-muted); padding: 5px 0; border-radius: var(--radius-chip); }
.app-switch a:hover { color: var(--ink-inverse); }
.app-switch a.on { background: var(--panel); color: var(--ink); }
@media (max-width: 900px) {
  .app-switch { order: 1; flex-basis: 100%; }
  .app-switch a { min-height: var(--ctl-h); }
}
.apps-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 28rem)); gap: var(--space-5); }
.app-card { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-4);
  padding: var(--space-5); border: 1px solid var(--line-strong); border-radius: var(--radius-lg);
  background: var(--panel); color: var(--ink); text-decoration: none; }
.app-card:hover { background: var(--panel-hover); }
.app-card-icon { display: grid; place-items: center; width: 2.5rem; height: 2.5rem;
  border-radius: var(--radius-md); background: var(--sage-fill); }
.app-card h2 { margin: 0; font-size: var(--fs-h2); line-height: 1.25; }
.app-card p { margin: 0; color: var(--muted); }
.app-card-open { display: inline-flex; align-items: center; gap: var(--space-2);
  margin-top: auto; font-size: var(--fs-sm); font-weight: 600; }
.app-card-open .ico { transform: rotate(-90deg); }

/* 1-1 agenda. Discussed rows dim by COLOR, never opacity (stacking-context
   trap), and never strike the title — the task itself isn't done, the
   conversation is. */
.oo-agenda tr.oo-done td, .oo-agenda tr.oo-done td a { color: var(--muted); }
.oo-agenda td.col-oo-note { width: 30%; min-width: 220px; }
.oo-note-form input { width: 100%; border: 1px solid transparent;
  background: transparent; border-radius: var(--radius-sm); padding: var(--space-1) 6px;
  font: inherit; font-size: var(--fs-sm); }
.oo-note-form input:hover { border-color: var(--line); }
.oo-note-form input:focus { border-color: var(--line-strong);
  background: var(--panel); outline: none; }

/* The add panel: suggestions first, search for everything else. */
.oo-add { margin: var(--space-5) 0; padding: var(--gutter) var(--space-4); background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--radius-md); }
.oo-add-hint { margin: 6px 0 0; }
.oo-pick { list-style: none; margin: 6px 0 var(--space-1); padding: 0;
  display: flex; flex-direction: column; gap: 6px; }
.oo-pick li { display: flex; align-items: baseline; gap: var(--space-2);
  flex-wrap: wrap; }
.oo-search { display: flex; gap: var(--space-2); margin-top: 10px; max-width: 480px; }
.oo-search input[type=search] { flex: 1; }

/* Notes are prose — same reading cap as the other rich columns. */
.oo-notes { max-width: 900px; }

/* Series settings (rename / leave): a small disclosure beside the week
   stepper, popping the same way the values editor does. */
.oo-settings { position: relative; display: inline-block; }
.oo-settings > summary { list-style: none; cursor: pointer; }
.oo-settings > summary::-webkit-details-marker { display: none; }
.oo-settings-pop { position: absolute; right: 0; top: calc(100% + 4px);
  z-index: var(--z-popover); display: flex; flex-direction: column; gap: var(--space-2);
  min-width: 300px; background: var(--panel); border: 1px solid var(--line-strong);
  border-radius: var(--radius-md); padding: 10px; box-shadow: var(--shadow-popover); }
.oo-settings-pop .inline-form { display: flex; gap: 6px; }
.oo-settings-pop input[type=text] { flex: 1; }

/* Week jump beside the stepper: only weeks that hold something. */
.week-jump { display: inline-flex; margin-left: 6px; }
.week-jump select { font-size: var(--fs-sm); padding: 3px 6px; }

/* Saved views on All Tasks: named filter sets as chips; the lit one is
   what's on screen. */
.views-bar { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2);
  margin: 0 0 10px; }
.view-chip { display: inline-flex; align-items: center; gap: var(--space-1);
  border: 1px solid var(--line); border-radius: var(--radius-pill); padding: 2px var(--space-1) 2px 10px;
  background: var(--panel); font-size: var(--fs-sm); }
.view-chip a { text-decoration: none; color: inherit; }
.view-chip.on { background: var(--sage-fill); border-color: var(--line-strong);
  font-weight: 600; }
.view-chip form { display: inline; }
.view-save { display: inline-flex; gap: 6px; }
.view-save input[type=text] { min-width: 200px; }

/* The task rail's 1-1 block: a different errand than following, so it
   sits below the follower tools behind the same rule-off line the
   actions block uses. */
.rail-oo { display: flex; flex-direction: column; gap: var(--space-2);
  border-top: 1px solid var(--line); padding-top: var(--space-3); margin-top: var(--space-3); }
.val-edit-pop input[type=text] { min-width: 240px; }

/* Preferences: a toggle and its explanation are one block — the label
   stays short, the sentence sits under it instead of trailing sideways. */
/* Settings forms share ONE column width — /me was 360px while the project
   form was 560px, which is exactly the inconsistency that reads as sloppy
   when you move between them. */
.form-col { max-width: var(--form-w); }
.pref-block { display: flex; flex-direction: column; gap: var(--space-1); }
.pref-block .pref-help { margin: 0; font-size: var(--fs-sm); }
.pref-block:has(> .checkline) .pref-help {
  margin-left: calc(var(--check-size) + var(--check-gap)); }

/* ── Viewer (read-only) task page ───────────────────────────────────── */
/* The title as a block of text, wearing the same type as the textarea. */
.title-read { display: block; }
.doc-notes-read { margin: 6px 0 var(--space-5); }
/* A static checkbox is a fact, not a control. */
span.checkbox { display: inline-grid; place-content: center; cursor: default; }

/* Lists inside rich text are prose: bullets and numbers, no rules between
   them (the comment separator used to reach in and stripe every item). */

.rich-text li { padding: 0; border: none; margin: 2px 0; }
/* A comment's <ul> sits inside the comments list, so the browser counts it
   as a SECOND-level list and hands it a hollow circle — the same bullet
   reads solid in notes, which aren't nested in anything. State the marker
   ourselves so a list looks the same wherever it's written, and keep real
   nesting distinguishable. */
.rich-text ul { list-style-type: disc; }
.rich-text ul ul { list-style-type: circle; }
.rich-text ul ul ul { list-style-type: square; }
.rich-text ol { list-style-type: decimal; }
.rich-text li::marker { color: var(--ink); }

/* Reading measure on the surfaces that are prose, now that the shell no
   longer caps the page for them. */

.rollup-rich { max-width: 900px; }

/* Worldpay mini-app. Shared shell, controls and type; scoped analysis layouts. */
.wp-page { max-width: 1440px; margin-inline: auto; min-width: 0; padding-bottom: var(--space-7); }
.wp-page .head-left { min-width: 0; }
.wp-page h1 { overflow-wrap: anywhere; }
.wp-page section[id] { scroll-margin-top: var(--space-5); }

.wp-report-link { display: grid; gap: var(--space-1); padding-block: var(--space-3); border-bottom: 1px solid var(--line); overflow-wrap: anywhere; }
.wp-report-link .muted { font-size: var(--fs-xs); }
.wp-report-link + .btn { margin-top: var(--space-4); }
.wp-report-search { margin-block: var(--space-4); }
.wp-report-pages { justify-content: space-between; margin-block: var(--space-4); }
.wp-card p { margin: 0 0 var(--space-4); }
.wp-card p:last-child { margin-bottom: 0; }
.wp-card .tbl-scroll:last-child { margin-bottom: 0; }
.wp-card h2 { font-size: var(--fs-h2); }
.wp-card > label { margin-bottom: var(--space-4); }
.wp-section { margin-top: var(--space-7); margin-bottom: var(--space-5); }

.wp-table th, .wp-table td { white-space: nowrap; }
/* Headers wrap; figures don't. Nowrap headers pushed Cost by region to
   1,336px in a 1,158px column on a wide screen (health check D14). */
.wp-table thead th { white-space: normal; min-width: 5.5rem; vertical-align: bottom; }
.wp-table .wp-wrap { white-space: normal; min-width: 10rem; max-width: 22rem; overflow-wrap: anywhere; }
.wp-table .wp-wrap:first-child, table.wp-prose-table th:first-child, table.wp-prose-table td:first-child { position: static; }
.wp-table th.wp-num, .wp-table td.wp-num { text-align: right; font-variant-numeric: tabular-nums; }
.wp-table td.wp-num { font-family: var(--font-mono); font-size: var(--fs-code); }
/* Row labels are data cells, not the sticky, tinted column-heading register. */
table.wp-table tbody th { position: static; z-index: auto; background: var(--panel); color: var(--ink);
  font-family: var(--font-sans); font-size: var(--fs-base); font-weight: 600;
  letter-spacing: normal; text-transform: none; padding: var(--space-3);
  border-bottom: 1px solid var(--line); vertical-align: middle; }
table.wp-table tbody:last-child tr:last-child th { border-bottom: none; }
.wp-table th:first-child, .wp-table td:first-child { position: sticky; left: 0; background: var(--panel); }
.wp-table thead th:first-child { background: var(--bg); }
.wp-upload { padding: var(--space-6); border-style: dashed; }
.wp-upload h2, .wp-upload p { margin: 0; }
.wp-upload > .cluster { display: grid; grid-template-columns: auto minmax(0,1fr);
  align-items: center; margin-bottom: var(--space-5); }
.wp-upload > .cluster .ico-ring { display: grid; place-items: center; flex: 0 0 auto;
  width: 2.5rem; height: 2.5rem; border-radius: var(--radius-md); background: var(--sage-fill); }
.wp-upload .footnote { margin-top: var(--space-4); }
.wp-file { border: 1px solid var(--line-strong); background: var(--panel); border-radius: var(--radius-lg);
  margin-bottom: var(--space-3); padding: var(--space-5); }
.wp-file-muted { background: var(--panel-sub); border-color: var(--line-mid); }
.wp-file-head { display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: center; gap: var(--space-3); }
.wp-file h3 { margin: 0; overflow-wrap: anywhere; line-height: 1.4; }
.wp-file p { margin: 0; font-size: var(--fs-sm); }
.wp-file .wp-file-byline { margin-top: var(--space-2); }
.wp-file .wp-file-facts + p { margin-top: var(--space-3); }
.wp-file:target { outline: 2px solid var(--accent); outline-offset: 3px; scroll-margin-block: var(--space-5); }
.wp-file .callout { margin: var(--space-3) 0; }
.wp-file-facts, .wp-file-actions { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
  margin-top: var(--space-3); font-size: var(--fs-xs); }
.wp-file-facts > span { display: inline-flex; align-items: center; gap: var(--space-1); }
.wp-file-actions { gap: var(--space-2); padding-top: var(--space-3); border-top: 1px solid var(--line); }
/* Forms must occupy the same control row as their adjacent links. The
   buttons are all .tiny, and now render tiny (they were forced to 34px). */
.wp-file-actions .inline-form { display: flex; align-items: center; margin: 0; }
.wp-file-actions:empty { display: none; }
.wp-fieldset { margin: 0; padding: 0; border: 0; min-width: 0; }
.wp-fieldset:disabled { opacity: .85; }
.wp-page input[type=number], .wp-page input:not([type]) { height: var(--ctl-h); border: 1px solid var(--line-mid);
  border-radius: var(--radius-md); padding: 0 var(--space-3); background: var(--panel); color: var(--ink);
  font-family: var(--font-sans); font-size: var(--fs-base); max-width: 100%; }
.wp-page input[type=number] { font-variant-numeric: tabular-nums; }
.wp-page textarea { width: 100%; resize: vertical; }
.wp-settings-form .tbl-scroll th { position: static; }
.wp-settings-form .tbl-scroll td input { width: 100%; min-width: 8rem; }
.wp-settings-form .tbl-scroll tbody th label { color: var(--ink); font-family: var(--font-mono); font-size: var(--fs-xs); }
.wp-currency-input { width: 6rem; text-transform: uppercase; }

.wp-save-bar { display: flex; align-items: center; flex-wrap: wrap; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-4) 0; border-top: 1px solid var(--line); }
.wp-method-list { padding-left: var(--space-5); margin: 0; }.wp-method-list li + li { margin-top: var(--space-3); }
.wp-submit-status { font-size: var(--fs-sm); }
.wp-insight > h3 { margin: 0 0 var(--space-4); }
.wp-insight > p { white-space: pre-wrap; }
.wp-sources { border-top: 1px solid var(--line); padding-top: var(--space-3); font-size: var(--fs-sm); }
.wp-sources summary { cursor: pointer; font-weight: 600; }
details.wp-card > summary { cursor: pointer; font-size: var(--fs-h2); font-weight: 600; line-height: 1.3; }
details.wp-card[open] > summary { margin-bottom: var(--space-5); }
.wp-page summary:focus-visible, .wp-page .tbl-scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.wp-sources dl { margin: var(--space-3) 0; }
.wp-sources dl > div { display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--space-3); padding-block: var(--space-2); border-bottom: 1px solid var(--line); }
.wp-sources dd { margin: 0; max-width: 55%; overflow-wrap: anywhere; flex-shrink: 0; font-variant-numeric: tabular-nums; }
.wp-sources ul { padding-left: var(--space-5); }
.wp-chat-panel { position: fixed; right: 24px; bottom: 24px; z-index: var(--z-overlay);
  width: min(440px, calc(100vw - 28px)); height: min(680px, calc(100dvh - 48px));
  display: flex; flex-direction: column; overflow: hidden; background: var(--panel);
  border: 1px solid var(--line-strong); border-radius: var(--radius-lg); box-shadow: var(--shadow-overlay); }
.wp-chat-panel[hidden] { display: none; }
.wp-chat-heading { display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); padding: var(--space-4); border-bottom: 1px solid var(--line); }
.wp-chat-heading h2 { margin: 0; font-size: var(--fs-md); }
.wp-chat-heading, .wp-chat-toolbar, .wp-chat-composer { flex-shrink: 0; }
.wp-chat-icon { flex-shrink: 0; display: grid; place-items: center; width: 34px; height: 34px; padding: 0; border: 0; border-radius: var(--radius-sm); background: var(--panel-sub); color: var(--ink); cursor: pointer; }
.wp-chat-icon:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.wp-chat-heading span { color: var(--muted); font-size: var(--fs-xs); }

.wp-chat-toolbar { display: flex; gap: var(--space-2); padding: var(--space-3) var(--space-4); }
.wp-chat-toolbar select { flex: 1; min-width: 0; width: 100%; }
.wp-chat-toolbar .btn { height: var(--ctl-h); flex-shrink: 0; }
.wp-chat-context { padding: 0 var(--space-4) var(--space-3); color: var(--muted); font-size: var(--fs-xs);
  border-bottom: 1px solid var(--line); }
.wp-chat-messages { flex: 1; overflow-y: auto; overscroll-behavior: contain;
  padding: var(--space-4); min-height: 0; font-size: var(--fs-sm); }
.wp-chat-message { padding: var(--space-3); margin-bottom: var(--space-3); border-radius: var(--radius-md);
  border: 1px solid var(--line); overflow-wrap: anywhere; }
.wp-chat-user { background: var(--panel-sub); margin-left: var(--space-5); }
.wp-chat-message > p { white-space: pre-wrap; margin: var(--space-2) 0; }
.wp-chat-message small { color: var(--muted); font-size: var(--fs-label); }
.wp-chat-message .wp-sources { margin-top: var(--space-3); font-size: var(--fs-xs); }
.wp-chat-message .wp-sources dl > div { display: block; }
.wp-chat-message .wp-sources dd { margin-top: var(--space-1); max-width: none; font-weight: 600; }
.wp-chat-error { color: var(--danger); }
.wp-chat-version { color: var(--muted); font-size: var(--fs-xs); }
.wp-chat-notice { margin: 0; padding: 0 var(--space-4); color: var(--muted); font-size: var(--fs-xs); }
.wp-chat-notice:not(:empty) { padding-block: var(--space-2); }
.wp-chat-composer { display: grid; grid-template-columns: minmax(0,1fr) auto; align-items: end;
  gap: var(--space-2); padding: var(--space-3) var(--space-4); border-top: 1px solid var(--line); }
.wp-chat-composer textarea { min-width: 0; width: 100%; resize: vertical; max-height: 8rem; font-size: var(--fs-sm); }
.wp-chat-composer .footnote { grid-column: 1 / -1; margin: 0; font-size: var(--fs-label); }
@media (max-width: 900px) {
  .wp-page section[id], .wp-file:target { scroll-margin-top: calc(var(--space-10) + var(--space-8)); }
  .wp-chat-panel { right: 14px; bottom: calc(76px + env(safe-area-inset-bottom, 0px));
    height: min(680px, calc(100dvh - 92px - env(safe-area-inset-bottom, 0px))); }
}
@media (max-width: 1150px) {
  .stat-strip { grid-template-columns: repeat(2,minmax(0,1fr)); }
  .stat-strip > .stat:nth-child(3) { border-left: 0; }
  .stat-strip > .stat:nth-child(n+3) { border-top: 1px solid var(--line); }

}
@media (max-width: 700px) {
  .card-grid, .hero-dark.hero-split { grid-template-columns: minmax(0,1fr); }
  .hero-dark.hero-split { padding: var(--space-5); gap: var(--space-5); }
  .hero-side { border-left: 0; border-top: 1px solid var(--line-inverse); padding: var(--space-5) 0 0;
    grid-template-columns: repeat(3,minmax(0,1fr)); gap: var(--space-3); }
  .hero-side .stat .n { font-size: var(--fs-md); }
  .stat-strip > .stat { padding: var(--space-4); } .stat-strip .stat .n { font-size: var(--fs-h2); }

  .wp-file { padding: var(--space-4); }
  .facts > div { grid-template-columns: minmax(0, 1fr); gap: var(--space-1); }
  .facts.figures dd { text-align: left; }
}
@media (max-width: 420px) {

  /* Each labelled field gets its own row. Sharing one squeezed "Statement
     period from" into three lines and both dates to ~40px (health check D3). */
  .filter-bar > label { flex: 1 1 100%; min-width: 0; white-space: nowrap; }
  .filter-bar > label > input, .filter-bar > label > select { flex: 1; width: auto; min-width: 0; }
  .filter-bar > .btn { flex-basis: 100%; justify-content: center; }
  .wp-file-head { grid-template-columns: minmax(0,1fr); gap: var(--space-2); }
  .wp-file-head > .tag { justify-self: start; }
  .wp-save-bar { align-items: stretch; flex-direction: column; }
  .wp-save-bar .btn { justify-content: center; }
  .wp-file-actions { display: grid; grid-template-columns: minmax(0,1fr); }
  .wp-file-actions .btn { width: 100%; justify-content: center; min-height: 44px; height: auto; }
}
table.wp-fx-table { min-width: 44rem; }
table.wp-fx-table tbody td, table.wp-fx-table tbody th { vertical-align: middle; padding: var(--space-3); }
table.wp-fx-table .wp-fx-select { text-align: center; width: 4rem; }
.wp-fx-select input[type="checkbox"] { display: block; margin: 0 auto; }
.wp-fx-providers { max-width: 20rem; white-space: normal; }
.wp-fx-providers > summary { white-space: nowrap; cursor: pointer; }
.wp-fx-providers > p { margin: var(--space-3) 0 0; }
.wp-fx-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-4); }
.wp-fx-head h2, .wp-fx-head form { margin: 0; }
#wp-reference-rates .wp-save-bar { justify-content: flex-start; }

/* Read-only DART explorer: native controls and the shared table register. */
.wp-explorer-search { display: grid; grid-template-columns: minmax(0,2fr) minmax(0,1fr); gap: var(--space-4); }
.wp-explorer-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: var(--space-4); }
.wp-explorer-filters { display: grid; gap: var(--space-4); }
.wp-explorer-filters label { display: flex; flex-direction: column; justify-content: end; gap: var(--space-2); min-width: 0; }
.wp-explorer-filters input, .wp-explorer-filters select { width: 100%; min-width: 0; max-width: 100%; }
.wp-explorer-filters .muted { font-size: var(--fs-xs); }
.wp-explorer-more { border-top: 1px solid var(--line); padding-top: var(--space-4); }
.wp-explorer-more summary { cursor: pointer; font-weight: 600; }
.wp-explorer-more[open] summary { margin-bottom: var(--space-4); }

.wp-record-secondary { display: block; font-family: var(--font-sans); font-size: var(--fs-xs); color: var(--muted); margin-top: var(--space-1); }
.wp-record-secondary:first-child { margin-top: 0; }
.wp-page #wp-explorer-results { scroll-margin-top: var(--space-5); }
.wp-page #wp-explorer-results h2 { margin: 0; }
.wp-page .card h2 { overflow-wrap: anywhere; }
@media (max-width: 900px) {
  .wp-page #wp-explorer-results { scroll-margin-top: calc(var(--space-10) + var(--space-8)); }
}
@media (max-width: 600px) {
  .wp-explorer-search, .wp-explorer-grid { grid-template-columns: minmax(0,1fr); }
}

/* A compact scan of the same page, above the more detailed record list. */
.wp-quick-browse { margin-bottom: var(--space-6); }
.wp-quick-browse > .section-head { margin-bottom: var(--space-2); }
.wp-quick-browse > .footnote { margin-top: 0; }
table.wp-scan-table { table-layout: fixed; min-width: 44rem; }
.wp-scan-record { width: 22%; }
.wp-scan-period { width: 14%; }
.wp-scan-status { width: 13%; }
.wp-scan-brand { width: 15%; }
.wp-scan-amount { width: 18%; }
table.wp-scan-table th, table.wp-scan-table td { padding: var(--space-2) var(--space-3); vertical-align: middle; }
table.wp-scan-table th { z-index: 2; }
table.wp-scan-table th:first-child { z-index: 3; }
table.wp-scan-table td { font-size: var(--fs-xs); }
table.wp-scan-table td:first-child { z-index: 1; }
table.wp-scan-table td.wp-num { font-size: var(--fs-xs); white-space: normal; overflow-wrap: anywhere; }
.wp-scan-table tbody tr:hover td, .wp-scan-table tbody tr:focus-within td { background: var(--panel-sub); }
.wp-scan-link { display: flex; align-items: baseline; gap: var(--space-2); min-width: 0; }
.wp-scan-ordinal { flex: 0 0 auto; color: var(--muted); font-family: var(--font-mono); }
.wp-scan-order, .wp-scan-text { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wp-scan-order { font-weight: 600; }
.wp-scan-currency { color: var(--muted); font-family: var(--font-sans); }

/* Keep the explorer's fields readable within an embedded browser as well as a full window. */
.wp-explorer-data { container-type: inline-size; margin-bottom: var(--space-4); }
table.wp-explorer-table { table-layout: fixed; border: 1px solid var(--line-strong); border-radius: var(--radius-md); overflow: hidden; }
.wp-explorer-table .wp-col-record { width: 18%; }
.wp-explorer-table .wp-col-period { width: 11%; }
.wp-explorer-table .wp-col-brand { width: 12%; }
.wp-explorer-table .wp-col-value { width: 13%; }
.wp-explorer-table .wp-col-upload { width: 23%; }
.wp-explorer-table .wp-col-state { width: 10%; }
table.wp-explorer-table th, table.wp-explorer-table td { position: static; white-space: normal; overflow-wrap: anywhere;
  padding: var(--space-3); vertical-align: top; }
table.wp-explorer-table thead th { vertical-align: middle; }
.wp-explorer-table .wp-record-state .tag { max-width: 100%; white-space: normal; }
.wp-record-label { display: none; }
.wp-record-source-meta { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3);
  color: var(--muted); font-family: var(--font-sans); font-size: var(--fs-xs); margin-top: var(--space-1); }
.wp-record-source-meta > * { min-width: 0; }
.wp-record-value { overflow-wrap: anywhere; }
.wp-page .wp-explorer-note { margin-top: var(--space-2); }
.wp-row-summary { overflow-wrap: anywhere; }
.wp-row-summary .wp-report-pages { margin-top: 0; }
.wp-row-summary .wp-report-pages h2 { margin: 0; }
.wp-row-summary .tag { flex-shrink: 1; max-width: 100%; }
.wp-row-amounts { border: 1px solid var(--line); border-radius: var(--radius-md); overflow: hidden; }
.wp-row-amounts table { table-layout: fixed; }
.wp-row-amounts table th, .wp-row-amounts table td { position: static; white-space: normal; overflow-wrap: anywhere; }
.wp-row-amounts table th:first-child { width: 55%; }
.wp-row-amounts .wp-record-value { display: block; }
@container (max-width: 56rem) {
  table.wp-explorer-table { display: block; border: 0; border-radius: 0; background: transparent; overflow: visible; }
  .wp-explorer-table colgroup { display: none; }
  .wp-explorer-table thead { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); }
  .wp-explorer-table tbody { display: grid; gap: var(--space-3); }
  .wp-explorer-table tbody tr { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: var(--space-4);
    border: 1px solid var(--line-mid); border-radius: var(--radius-md); background: var(--panel); padding: var(--space-4); }
  table.wp-explorer-table td { display: block; padding: 0; border: 0; min-width: 0; max-width: none; }
  .wp-explorer-table .wp-record-main { grid-area: 1 / 1; }
  .wp-explorer-table .wp-record-main a { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--space-3); }
  .wp-explorer-table .wp-record-state { grid-area: 1 / 2; justify-self: end; text-align: right; }
  .wp-explorer-table .wp-record-period { grid-area: 2 / 1; }
  .wp-explorer-table .wp-record-brand { grid-area: 2 / 2; }
  .wp-explorer-table .wp-record-transaction { grid-area: 3 / 1; }
  .wp-explorer-table .wp-record-charges { grid-area: 3 / 2; }
  table.wp-explorer-table .wp-record-upload { grid-area: 4 / 1 / auto / -1; padding-top: var(--space-3); border-top: 1px solid var(--line); }
  table.wp-explorer-table td.wp-num { text-align: left; }
  .wp-explorer-table .wp-record-label { display: block; font-family: var(--font-sans); font-size: var(--fs-xs);
    color: var(--muted); margin-bottom: var(--space-1); }
}
@container (min-width: 40rem) and (max-width: 56rem) {
  .wp-explorer-table tbody tr { grid-template-columns: repeat(4,minmax(0,1fr)); }
  .wp-explorer-table .wp-record-main { grid-area: 1 / 1 / auto / 4; }
  .wp-explorer-table .wp-record-state { grid-area: 1 / 4; }
  .wp-explorer-table .wp-record-period { grid-area: 2 / 1; }
  .wp-explorer-table .wp-record-brand { grid-area: 2 / 2; }
  .wp-explorer-table .wp-record-transaction { grid-area: 2 / 3; }
  .wp-explorer-table .wp-record-charges { grid-area: 2 / 4; }
  table.wp-explorer-table .wp-record-upload { grid-area: 3 / 1 / auto / -1; }
}

/* ── Personal items on My Tasks (private, per person) ──────────────── */
.personal-add { gap: var(--space-2); align-items: center; max-width: 760px; }
.personal-add input[type=text] { flex: 1; min-width: 0; }
/* On a phone the text gets the whole row and the date and Add go under it;
   side by side the text box shrank to ~90px (health check D8). */
@media (max-width: 600px) {
  .personal-add { flex-wrap: wrap; }
  .personal-add input[type=text] { flex: 1 1 calc(100% - 30px); }
  .personal-add input[type=date] { flex: 1; }
}
.personal-mark { display: inline-flex; align-items: center; gap: var(--space-1); }
.personal-title { margin-right: var(--space-2); }
/* Edit / move / delete for a personal row. It opens INSIDE the row, not
   as a floating pop-up: task tables sit in a scroll box that clips
   anything positioned outside it. */
.row-menu { display: inline-block; vertical-align: middle; }
.row-menu[open] { display: block; }
.row-menu > summary { list-style: none; cursor: pointer; display: inline-flex; }
.row-menu > summary::-webkit-details-marker { display: none; }
.row-menu-pop { margin-top: var(--space-2); padding: var(--space-3);
  background: var(--panel); border: 1px solid var(--line-strong); border-radius: var(--radius-md); }
.row-menu-pop .inline-form { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.row-menu-pop input[type=text] { flex: 1; min-width: 160px; }
.personal-done-list { list-style: none; padding: 0; margin: 0 0 var(--space-5); }
.personal-done-list li { display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-2) var(--space-1); border-bottom: 1px solid var(--line); }
.personal-done-list form { display: flex; margin: 0; }

/* ── Admin → Access grid ────────────────────────────────────────────── */
.access-cell { text-align: center; }
.access-yes { color: var(--green); display: inline-flex; }

/* ── Account ────────────────────────────────────────────────────────── */
.account-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--space-4); align-items: start; }
.account-save { grid-column: 1 / -1; }
.account-grid .row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.account-grid .row input, .account-grid select { width: 100%; min-width: 0; }
.account-block { margin-top: var(--space-5); max-width: 760px; }
/* Label-and-value list — ONE component (Account, Worldpay panels).
   .figures right-aligns numeric values. */
.facts { margin: var(--space-3) 0 var(--space-4); }
.facts > div { display: grid; grid-template-columns: minmax(8rem, 40%) 1fr; gap: var(--space-3);
  align-items: baseline; padding: var(--space-2) 0; border-bottom: 1px solid var(--line); }
.facts > div:last-child { border-bottom: none; }
.facts dt { color: var(--muted); font-size: var(--fs-sm); min-width: 0; }
.facts dd { margin: 0; overflow-wrap: anywhere; }
.facts.figures dd { text-align: right; font-variant-numeric: tabular-nums; }
.account-row { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  margin-top: var(--space-4); }
.account-private { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--space-3); }
.account-private li { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.account-block section[id], .settings-card[id] { scroll-margin-top: var(--space-5); }

/* ── Connected apps (Preferences) + OAuth consent ───────────────────── */
.connected-apps { margin-top: var(--space-6); }
.connected-list { list-style: none; padding: 0; margin: var(--space-2) 0 0; }
.connected-list li { align-items: center; padding: var(--space-2) 0; border-bottom: 1px solid var(--line); }
.connected-list form { margin: 0; }
.connected-apps code, .oauth-consent code { font-family: var(--font-mono);
  font-size: var(--fs-sm); overflow-wrap: anywhere; }
.oauth-host { font-family: var(--font-mono); }

/* ── Floating menus and inline editors — two patterns, one look each
   (design audit, 2026-09-26). Floating: panel, charcoal outline, field
   corner, popover shadow; option lists pad tighter than form panels.
   Inline editors open inside the row: panel, mid outline, field corner. */
.settings-panel, .oo-settings-pop, .fpick-pop, .mention-popup {
  background: var(--panel); border: 1px solid var(--line-strong);
  border-radius: var(--radius-md); box-shadow: var(--shadow-popover); }
.settings-panel, .oo-settings-pop { padding: var(--space-3); gap: var(--space-2); }
.fpick-pop, .mention-popup { padding: var(--space-1); }
.row-menu-pop, .check-edit[open] > .inline-form {
  background: var(--panel); border: 1px solid var(--line-mid); border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3); margin: var(--space-2) 0 0; }

/* Touch screens: every checkbox gets a 24px tap target without looking any
   bigger — an invisible box around it, which the browser counts as the
   checkbox (design audit, 2026-09-26). */
@media (pointer: coarse) {
  input[type=checkbox] { position: relative; }
  input[type=checkbox]::after { content: ""; position: absolute;
    inset: calc((var(--check-size) - 24px) / 2); }
}

/* File pickers: a field-height box whose button is Ergon's regular button,
   not the browser's (design audit, 2026-09-26). */
input[type=file] { height: var(--ctl-h); padding: 0 var(--space-3) 0 0; border: 1px solid var(--line-mid);
  border-radius: var(--radius-md); background: var(--panel); font: inherit; font-size: var(--fs-sm);
  color: var(--muted); display: flex; align-items: center; width: 100%; }
input[type=file]::file-selector-button { height: 100%; margin: 0 var(--space-3) 0 0; padding: 0 var(--space-4);
  border: none; border-right: 1px solid var(--line-mid); background: var(--panel-sub);
  font: inherit; font-weight: 500; color: var(--ink); cursor: pointer; }
input[type=file]::file-selector-button:hover { background: var(--sage-fill); }

/* ── Payments SoT ───────────────────────────────────────────────────── */
.faint { color: var(--faint); }
.pre-line { white-space: pre-line; }
.sot-section { margin-bottom: var(--space-5); }
.sot-section .section-head { margin-top: 0; }
.sot-form textarea { width: 100%; }
.sot-new, .sot-import { max-width: 640px; }
.suffix-field { display: flex; align-items: center; gap: var(--space-2); }
.suffix-field input { flex: 1; min-width: 0; }
.sot-term { border: 1px solid var(--line); border-radius: var(--radius-md); padding: var(--space-4); }
.sot-term h3 { margin: 0; font-size: var(--fs-md); display: flex; gap: var(--space-2); align-items: center; }
.sot-term .facts { margin-bottom: 0; }
.sot-all-terms { margin-top: var(--space-4); }
.sot-siblings, .sot-history { margin-top: var(--space-6); }
