/* Cabana design system, the mineral direction (Steven's selection of 2026-09-24; HANDOFF §2). A flat, mid-light
   mineral canvas; reading surfaces a little lighter (--paper and its family); clear dark ink; regions told apart
   by shape, space and small tonal steps rather than rules and borders. One muted sage accent for marks, the
   identity and primary actions. Every screen speaks it since the second pass of 2026-09-24: a page is regions on
   the canvas, a region is rows told apart by a hairline, a control is a pill. Tokens first, then primitives (type,
   buttons, inputs, badges), then components. */

:root{
  --font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,monospace;
  --rounded:ui-rounded,"SF Pro Rounded",-apple-system,BlinkMacSystemFont,sans-serif;  /* the type fallback (.wordmark) for an instance not named Cabana */
  /* the canvas and the mineral surfaces: regions, lists and cards on --paper (a row's hover and a control's ground on
     --paper-hi), an inner well (a field, a comment, a quoted change) on --well, the drawer on --pane (a child pane on
     --pane-deep), menus and popovers on --popover, the search field at rest and engaged,
     and three sage steps for hover, current and pressed */
  --bg:#c5ccca;--paper:#d9deda;--paper-hi:#e0e5de;--pane:#dce1dc;--pane-deep:#d2d9d4;--popover:#dde2dc;--well:#c9d3cb;--well-hover:#bcc7bf;  /* a greyed row, and its hover: a full step, in both palettes */
  --field:#d0d7d2;--field-on:#dce2dc;--sage:#c3d0c9;--sage-2:#bdcdc3;--switch:#bdc7c3;--track:#9fb0ad;
  /* --muted is the reference's secondary (#4c6166) a step darker, so small text clears AA on the canvas, the
     shelf and the sage steps too (4.58 to 5.5, tests/test_tickets_page.py); --late is a slipped target date's
     words, never red */
  /* the ink and its steps: the strong pair the reference offered (#20343b / #3a5058), since Steven's third look
     (2026-09-24: the softer pair read worse on his display); the switch in the header is for the dark palette below */
  --ink:#20343b;--ink-2:#233a41;--muted:#3a5058;--faint:#56696c;--late:#664632;--disabled:#84948d;
  --av-bg:#b5c6c0;--av-ink:#20343b;  /* a person's disc: initials in the ink on a mineral step, the same for everyone (the reference's .cw-person) */
  --line:#8da0a2;--line-strong:#788e91;  /* the few visible lines: a bar's track edge, a trace's spine, an underline */
  --separator:color-mix(in srgb,var(--ink) 24%,transparent);--edge:color-mix(in srgb,var(--ink) 30%,transparent);  /* the hairline between rows; a region's edge */
  --accent:#426d67;--accent-hover:#365b56;--accent-fg:#ffffff;--accent-soft:#cad8ce;  /* --accent-fg is the text on the accent: white by day, the deep slate by night */--accent-soft-hover:#bfcdc5;--accent-ink:#294740;--accent-line:#8aa597;--accent-line-strong:#4f7466;
  --ok:#146247;--ok-hover:#125a41;--ok-soft:#dcf1e5;--ok-ink:#155b40;  /* --ok deepened from #1f8a62 so white on it clears AA (7.3; the trace's done dot 4.6 on the sage) (F32) */
  --warn:#d69a2e;--warn-soft:#fbf3e1;--warn-ink:#714a10;--warn-line:#e2bd58;
  --bad-soft:#fbe8e6;--bad-ink:#852d2a;--bad-line:#e78f8a;
  --violet:#7357c4;--violet-soft:#ece6f9;--violet-ink:#4a3592;--violet-line:#b09ae6;
  --orange-ink:#814010;--orange-soft:#fbe8d6;
  --teal-ink:#155b63;
  --blue-ink:#22489a;--blue-soft:#e2e9f7;
  --code-bg:#132330;--code-ink:#dfe7ea;
  --ring:color-mix(in srgb,var(--accent) 20%,transparent);--focus:var(--accent);
  --scrim:rgb(47 63 67 / .11);--backdrop:rgb(32 52 59 / .42);
  --fs-xs:11.5px;--fs-sm:12.5px;--fs-md:13px;--fs:14px;--fs-lg:17px;--fs-xl:22px;
  --r:12px;--r-sm:9px;--r-xs:5px;--r-pill:999px;
  --r-region:19px;--r-card:15px;--r-pane:17px;--r-drawer:24px;--r-field:20px;--r-ctl:13px;
  /* motion: the search widens (Steven asked twice for slower, 2026-09-24) and the drawer slides in and grows by these; the one
     reduced-motion block below stops them */
  --ease-settle:cubic-bezier(.2,.75,.25,1);--t-expand:680ms;--t-drawer:260ms;
  /* the page's frame: its widest, the side gutter the chrome shares with the content, the chrome's height */
  --page-max:1440px;--gutter:25px;--chrome-h:69px;
  --pencil:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3 21v-6L15 3l6 6L9 21z'/%3E%3C/svg%3E");
  color-scheme:light;
  --sh-lg:0 12px 32px rgba(19,35,48,.16);
  --sh-region:0 4px 18px rgb(37 58 63 / .035);--sh-soft:0 3px 12px rgb(37 58 63 / .05);--sh-control:0 2px 7px rgb(44 66 72 / .045);
  --sh-card:0 3px 8px rgb(44 66 72 / .025);--sh-lift:0 3px 13px rgb(44 66 72 / .06);
  --sh-pop:0 16px 40px rgb(32 52 57 / .17),0 1px 4px rgb(32 52 57 / .07);--sh-drawer:0 16px 42px rgb(32 52 57 / .2),0 1px 4px rgb(32 52 57 / .08);
}
/* The dark palette (the switch in the header, remembered per browser; the system's preference when nothing is remembered):
   the same mineral family at night. The canvas is the deepest slate, the paper a step up, the well a step down from the
   paper, the ink a pale mineral white, the accent lightened so it reads on the dark grounds, and every pastel of the
   stamps turned into a deep tint with a pale ink (measured: each pair clears 4.5 as in the light palette;
   tests/test_components.py and test_tickets_page.py). */
html.dark{color-scheme:dark;
  --bg:#1e2829;--paper:#293536;--paper-hi:#303d3e;--pane:#2b3738;--pane-deep:#242f30;--popover:#2f3c3d;--well:#212c2d;--well-hover:#3a4b4a;
  --field:#233031;--field-on:#2c3a3b;--sage:#3a4b4a;--sage-2:#3e4f4e;--switch:#232e2f;--track:#4d605f;
  --ink:#e4ece9;--ink-2:#d2ddd9;--muted:#b6c5c1;--faint:#8a9d9b;--late:#e5bb92;--disabled:#6f827f;--av-bg:#3f5250;--av-ink:#e4ece9;
  --line:#4e6261;--line-strong:#617573;--separator:color-mix(in srgb,var(--ink) 16%,transparent);--edge:color-mix(in srgb,var(--ink) 20%,transparent);
  --accent:#8fbdb2;--accent-hover:#a3ccc2;--accent-fg:#132022;--accent-soft:#2e4744;--accent-soft-hover:#37524e;--accent-ink:#d3e6e0;--accent-line:#4c6d67;--accent-line-strong:#6f938c;
  --ok:#4cba8c;--ok-hover:#62c99b;--ok-soft:#1e3a2f;--ok-ink:#a4e0c6;
  --warn:#d9a94a;--warn-soft:#3a3222;--warn-ink:#efc77f;--warn-line:#6a5526;
  --bad-soft:#40292a;--bad-ink:#f2a8a1;--bad-line:#7b403c;
  --violet:#ad98ee;--violet-soft:#302b46;--violet-ink:#d0c3f6;--violet-line:#5a4a8f;
  --orange-ink:#f3b78f;--orange-soft:#3d2d22;--teal-ink:#9adbe3;--blue-ink:#aec8f7;--blue-soft:#26334b;
  --code-bg:#0e171b;--code-ink:#dfe7ea;--scrim:rgb(0 0 0 / .35);--backdrop:rgb(0 0 0 / .55);
  --sh-region:0 4px 18px rgb(0 0 0 / .18);--sh-soft:0 3px 12px rgb(0 0 0 / .2);--sh-control:0 2px 7px rgb(0 0 0 / .22);--sh-card:0 3px 8px rgb(0 0 0 / .18);--sh-lift:0 3px 13px rgb(0 0 0 / .25);
  --sh-pop:0 16px 40px rgb(0 0 0 / .45),0 1px 4px rgb(0 0 0 / .3);--sh-drawer:0 16px 42px rgb(0 0 0 / .5),0 1px 4px rgb(0 0 0 / .3);--sh-lg:0 12px 32px rgb(0 0 0 / .4)}
*{box-sizing:border-box}
[hidden]{display:none!important}
html{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
body{margin:0;font:var(--fs)/1.5 var(--font);color:var(--ink);background:var(--bg)}
a{color:var(--accent-ink);text-decoration:none}a:hover{text-decoration:underline}  /* the accent-ink, not the accent: a bare link is small text and clears AA on every ground (F12); the accent stays on marks and primary actions */
h1,h2,h3{margin:0;font-weight:500;letter-spacing:-.01em}
h1{font-size:27px;line-height:1.2;letter-spacing:-.7px}
code{font-family:var(--mono);font-size:var(--fs-sm);background:var(--well);padding:1px 5px;border-radius:4px}
.mono{font-family:var(--mono);font-size:var(--fs-sm);word-break:break-all}
.muted{color:var(--muted)}.small{font-size:var(--fs-sm)}.nowrap{white-space:nowrap}
.key{font-family:var(--mono);font-weight:500;font-size:var(--fs-sm);letter-spacing:.01em}
/* text for a screen reader alone: a control's name where the design shows only its icon */
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
/* the icons are inline SVG strokes in the text's colour, one weight everywhere */
svg.i{width:16px;height:16px;flex:none;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}

/* ---------------------------------------------------------------- the chrome: menu, identity, tools */
/* The header is the canvas itself, no bar and no rule: the Menu that opens the drawer, the identity beside
   it, and the palette switch and the signed-in person at the right. A page with no principal (sign-in) has
   the identity and the switch alone. */
header.top{display:flex;align-items:center;gap:16px;max-width:var(--page-max);min-height:var(--chrome-h);margin:0 auto;padding:21px 29px 8px}
.brand{display:flex;align-items:center;gap:10px;color:var(--ink);border-radius:var(--r-sm)}
.brand:hover{text-decoration:none}
/* The identity (Astra's package of 2026-09-24, static/brand/): the symbol in the accent, the wordmark in the ink, both drawn
   inline by base.html from the files, so the palette colours them; an instance named something else gets its name in type. */
.brand-symbol{display:block;flex:none;height:28px;color:var(--accent)}
.brand-wordmark{display:block;flex:none;height:19px;color:var(--ink)}
.brand-symbol svg,.brand-wordmark svg{display:block;height:100%;width:auto}
.wordmark{font:500 23px/1 var(--rounded);letter-spacing:-.9px;text-transform:lowercase}
.top-tools{display:flex;align-items:center;gap:8px;margin-left:auto}
.round-btn{display:grid;place-items:center;flex:none;width:34px;height:34px;padding:0;border:0;border-radius:50%;background:color-mix(in srgb,var(--paper) 65%,transparent);color:var(--ink);font:inherit;cursor:pointer;box-shadow:var(--sh-soft)}
.round-btn:hover{background:var(--sage)}
html.dark .round-btn.toggle{background:var(--ink);color:var(--bg)}  /* the palette switch's pressed look, from theme.js's class on the first paint; its aria-pressed waits for app.js */
.top-tools .me{display:inline-flex;border-radius:50%}
.top-tools .me .av{width:34px;height:34px;font-size:11px}
.pill{display:inline-grid;place-items:center;min-width:18px;height:18px;padding:0 6px;border-radius:var(--r);background:var(--accent);color:var(--accent-fg);font-size:var(--fs-xs);font-weight:600;line-height:1}
a.pill:hover{text-decoration:none;background:var(--accent-hover)}
.icon-btn{display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 10px;border:0;border-radius:var(--r-pill);background:var(--paper-hi);color:var(--ink-2);font:inherit;font-size:var(--fs-sm);font-weight:500;cursor:pointer;box-shadow:var(--sh-control)}
.icon-btn:hover{background:var(--sage)}
.icon-btn svg{width:14px;height:14px}
:is(.brand,.round-btn,.menu-trigger,.drawer-item,.drawer-link,.drawer-back,.drawer-person):focus-visible{outline:2px solid var(--focus);outline-offset:2px}

/* ---------------------------------------------------------------- the drawer
   The destinations, behind Menu. Without the script it is a plain disclosure that drops the panel under the
   button, every entry a link. The script makes it a modal drawer at the left (data-enhanced): the page behind
   is inert and cannot scroll, focus stays inside, Escape backs out of a child pane and then closes, and
   Projects and Settings open their child pane beside the primary one, which keeps its place. */
.drawer>summary{list-style:none}
.drawer>summary::-webkit-details-marker{display:none}
.menu-trigger{position:relative;display:flex;align-items:center;gap:12px;padding:10px 16px;border-radius:22px;background:color-mix(in srgb,var(--paper) 65%,transparent);box-shadow:var(--sh-soft);color:var(--ink);font-size:var(--fs-md);cursor:pointer;user-select:none}
.menu-trigger:hover{background:var(--sage)}
.drawer-panel{position:absolute;z-index:40;top:calc(100% + 8px);left:0;display:flex;width:290px;max-width:calc(100vw - 16px);padding:22px 16px;border-radius:var(--r-drawer);background:var(--pane);color:var(--ink);box-shadow:var(--sh-drawer)}
.drawer{position:relative}
/* Menu floats (Steven, 2026-09-25): once the page scrolls past the header the pill holds where it was, at the top-left, on the
   paper with the region's shadow so it reads over rows; the drawer slides in from the edge over it as always. app.js sets data-floating from the scroll
   position and the pill's resting place (--menu-x, --menu-w); nothing else in the header follows. */
.drawer[data-floating]{width:var(--menu-w)}
.drawer[data-floating]>summary{position:fixed;top:12px;left:var(--menu-x);z-index:41;background:color-mix(in srgb,var(--paper) 65%,var(--bg));box-shadow:0 0 0 1px var(--edge),var(--sh-pop)}  /* the resting pill's colour made solid (65% paper over the canvas), with a hairline of the region's edge and the popover's shadow so it reads over paper and canvas alike (Steven, 2026-09-25) */
/* with the script the panel slides in from the left edge and out again (data-shown, set a frame after it opens and taken off
   before it closes, app.js), and the scrim fades with it */
.drawer[data-enhanced] .drawer-panel{position:fixed;top:8px;left:8px;bottom:8px;overflow:auto;overscroll-behavior:contain;transform:translateX(calc(-100% - 12px));transition:width var(--t-drawer) ease,transform var(--t-drawer) var(--ease-settle)}
.drawer[data-shown] .drawer-panel{transform:none}
.drawer-panel[data-depth]{width:604px}
.drawer-scrim{position:fixed;inset:0;z-index:39;background:var(--scrim);opacity:0;transition:opacity var(--t-drawer) ease}
html:has(.drawer[data-shown]) .drawer-scrim{opacity:1}
html:not(:has(.drawer[data-shown])) .drawer-scrim{pointer-events:none}  /* the close lets the page go at once: while the scrim fades out it must not swallow a click meant for a control under it */
html:has(.drawer[data-enhanced][open]){overflow:hidden}
.drawer-body{display:flex;flex:1;min-width:0}
.drawer-main{display:flex;flex-direction:column;flex:none;width:258px}
.drawer-head{display:flex;align-items:center;justify-content:space-between;gap:15px;min-height:30px;margin-bottom:25px;padding-left:10px;font-weight:500}
.drawer-head .round-btn{width:30px;height:30px;box-shadow:none;background:color-mix(in srgb,var(--ink) 7%,transparent)}
.drawer-wordmark{height:16px}  /* the wordmark at the drawer's head, a step smaller than the header's */
.drawer-nav{display:flex;flex-direction:column;gap:4px}
.drawer-item{display:flex;align-items:center;gap:12px;min-height:46px;padding:11px 10px;border-radius:14px;color:var(--ink);font-size:var(--fs);line-height:1.35}
.drawer-item:hover,.drawer-link:hover,.drawer-back:hover{background:var(--sage);text-decoration:none}
.drawer-item[aria-current=page],.drawer-item[aria-expanded=true]{background:var(--sage);color:var(--accent-ink)}
/* while a child pane is open its entry alone is highlighted; the page's own entry keeps its ink and its Current mark (Steven, 2026-09-24) */
.drawer-panel[data-depth] .drawer-item[aria-current=page]:not([aria-expanded=true]){background:transparent}
/* a destination that is not built yet (Calls, Connections): shown in its place, locked, never a link (Steven, 2026-09-24) */
.drawer-item.locked,.drawer-link.locked{color:var(--muted);cursor:default}
.drawer-item.locked:hover,.drawer-link.locked:hover{background:transparent}
.drawer-item.locked>svg:first-child,.drawer-link.locked>svg:first-child{color:var(--faint)}
.drawer-item .lock,.drawer-link .lock{margin-left:auto;width:14px;height:14px;color:var(--faint)}
.drawer-link small,.drawer-person small{display:block;margin-top:2px;font-size:11px;line-height:1.4;color:var(--muted)}
.drawer-item>svg:first-child{width:18px;height:18px;color:var(--ink-2)}
.drawer-here,.drawer-item .chev{margin-left:auto}
.drawer-here{font-size:11px;color:var(--accent-ink)}
.drawer-foot{display:flex;align-items:center;gap:10px;margin:17px 5px 1px;margin-top:auto;padding-top:16px;border-top:1px solid var(--separator);font-size:var(--fs-sm)}
.drawer-person{display:flex;align-items:center;gap:10px;flex:1;min-width:0;padding:4px;border-radius:12px;color:var(--ink)}
.drawer-person:hover{text-decoration:none;background:var(--sage)}
.drawer-person>span:last-child{min-width:0;overflow-wrap:anywhere}
.drawer-foot .signout{display:inline-flex;margin:0}
.drawer-pane{flex:1;min-width:0;margin-left:12px;padding:15px 12px;border-radius:var(--r-pane);background:var(--pane-deep)}
.drawer-pane h2{margin:17px 8px 16px;font-size:var(--fs-lg);font-weight:500;line-height:1.3;letter-spacing:-.2px}
.drawer-back{display:flex;align-items:center;gap:7px;padding:5px 8px;border:0;border-radius:10px;background:none;color:var(--ink);font:inherit;font-size:11px;cursor:pointer}
.drawer-back svg{width:14px;height:14px}
.drawer-links{display:flex;flex-direction:column}
.drawer-note{margin:0 0 5px;padding:0 10px;font-size:11px;color:var(--muted)}
.drawer-note+.drawer-link{margin-top:0}
.drawer-link{display:flex;align-items:center;gap:10px;min-height:44px;padding:11px 10px;border-radius:12px;color:var(--ink);font-size:var(--fs-md);line-height:1.35}
.drawer-link:hover{background:var(--sage);text-decoration:none}
.drawer-link[aria-current=page]{background:var(--sage);color:var(--accent-ink)}
.drawer-link>svg{color:var(--ink-2)}
.drawer-link.see-all{justify-content:space-between;margin-top:14px;background:var(--sage)}
.drawer-link.see-all:hover{background:var(--sage-2)}
.drawer-links .drawer-note:not(:first-child){margin-top:12px}

/* ---------------------------------------------------------------- page scaffold */
main{max-width:var(--page-max);margin:0 auto;padding:22px var(--gutter) 72px}
main.tk-page{padding-bottom:22px}  /* the lists run to the foot of the window; the footer is below it */
footer.bottom{max-width:var(--page-max);margin:0 auto;padding:0 29px 28px;color:var(--muted);font-size:var(--fs-sm);display:flex;gap:14px;flex-wrap:wrap;align-items:center}
footer.bottom a{color:var(--muted);text-decoration:underline;text-decoration-color:var(--line)}
footer.bottom b{color:var(--muted);font-weight:500}
/* A page's head: the context line above the title (the crumbs, or a page's place), the title itself, its one line of
   explanation, and the page's actions at the right; the same rhythm as the Tickets page. */
.page-head{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;margin-bottom:23px}
.page-head>div:last-child:not(:first-child){flex:none;display:flex;gap:8px;align-items:center;padding-top:6px}
.page-head h1{margin-bottom:4px}
.crumb{color:var(--muted)}.crumb:hover{color:var(--ink)}
.crumbs{display:flex;gap:6px;align-items:center;color:var(--muted);font-size:12px;margin-bottom:6px}
.back{display:inline-flex;align-items:center;gap:4px;margin-bottom:8px;color:var(--muted);font-size:var(--fs-sm)}.back:hover{color:var(--ink);text-decoration:none}.back .i{width:16px;height:16px}  /* "Back to Team" over a person's name (Steven, 2026-09-25): the page is one person's, not the Team's */
/* A region: paper on the canvas, rounded as the lists are, no edge but the tonal step (a visible one in higher contrast). */
/* the edge (visible in higher contrast) is a border, so a row's hover never paints over it */
.card{background:var(--paper);border:1px solid var(--edge);border-radius:var(--r-region);padding:18px 20px;margin-bottom:16px;box-shadow:var(--sh-region)}
.card h2{font-size:var(--fs);font-weight:500;letter-spacing:-.15px;color:var(--ink);margin:0 0 12px;display:flex;align-items:center;gap:8px}
.card h2 .muted{font-weight:400;font-size:12px}
.two-col{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:16px;align-items:start}
.two-col>*{min-width:0}
/* A table wider than the page scrolls inside its holder rather than pushing the document sideways:
   the two-column pages have .main-col, a live list its #results, a settings page its body, and a card
   whose own child is the table. The menus app.js opens hang off <body>, so no holder clips them. */
.main-col,#results,.settings-body,.card:has(>table.grid){overflow-x:auto}
/* a switch between sibling pages (Calls and Extracted items), the view switch's shape */
.subnav{display:inline-flex;gap:3px;margin:0 0 19px;padding:4px;border-radius:var(--r-pane);background:var(--switch)}
.subnav a{padding:8px 13px;border-radius:var(--r-ctl);color:var(--ink);font-size:12px}
.subnav a.on{background:var(--paper-hi);box-shadow:var(--sh-control);color:var(--accent-ink)}
.subnav a:hover{text-decoration:none}
.subnav a:not(.on):hover{background:color-mix(in srgb,var(--paper) 55%,transparent)}
.help{background:var(--accent-soft);border-left:3px solid var(--accent);border-radius:var(--r-sm);padding:12px 16px;margin-bottom:16px;color:var(--accent-ink)}
.help b{color:var(--ink)}
details.help summary{cursor:pointer;font-weight:500;color:var(--ink)}
.flash{background:var(--accent-soft);color:var(--accent-ink);padding:10px 14px;border-radius:var(--r);margin-bottom:16px;font-weight:500}
.flash.error{background:var(--bad-soft);color:var(--bad-ink)}
.flash.js{position:fixed;top:68px;right:28px;z-index:30;box-shadow:var(--sh-pop);max-width:420px}
.empty{text-align:center;color:var(--muted);padding:32px 16px}
/* a figure and its word, on paper */
.stat-row{display:flex;gap:12px;flex-wrap:wrap;margin:0 0 20px}
.stat{background:var(--paper);border:1px solid var(--edge);border-radius:var(--r-card);padding:12px 16px;min-width:120px;box-shadow:var(--sh-card)}
.stat .v{font-size:22px;font-weight:500;letter-spacing:-.02em}.stat .l{font-size:var(--fs-xs);color:var(--muted);margin-top:2px}
.steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px;margin:0 0 20px}
.step{background:var(--paper);border:1px solid var(--edge);border-radius:var(--r-card);padding:14px 16px;box-shadow:var(--sh-card)}
.step .n{display:inline-grid;place-items:center;width:22px;height:22px;border-radius:11px;background:var(--accent-soft);color:var(--accent-ink);font-size:var(--fs-sm);font-weight:600;margin-right:8px}
.step h3{font-size:var(--fs);margin-bottom:6px;display:flex;align-items:center}.step p{margin:0;color:var(--muted);font-size:var(--fs-md)}
.legend{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:8px 20px;margin-top:10px;font-size:var(--fs-md);color:var(--muted)}
.legend b{display:block;color:var(--ink);font-weight:500}

/* ---------------------------------------------------------------- tables */
/* A table is a region of rows: a quiet heading line, a hairline between rows, the row lifting a step on hover. Inside a
   card it is the card's rows (no region of its own). No zebra and no status wash: a status is its stamp or its mark. */
table.grid{width:100%;border-collapse:separate;border-spacing:0;background:var(--paper);border:1px solid var(--edge);border-radius:var(--r-region);overflow:hidden;box-shadow:var(--sh-region)}
.card>table.grid,.card table.grid{background:transparent;border:0;border-radius:0;box-shadow:none}
table.grid th{font-size:11px;font-weight:500;color:var(--muted);text-align:left;padding:14px 16px 8px;border-bottom:1px solid var(--separator);white-space:nowrap}
.card table.grid th{padding-top:4px}
table.grid td{padding:12px 16px;border-bottom:1px solid var(--separator);vertical-align:top;font-size:var(--fs-md)}
table.grid th[data-col="key"],table.grid td:has(> .key:only-child){width:1%;white-space:nowrap}
table.grid td .key{white-space:nowrap}
table.grid th[data-col="assignee"],table.grid th[data-col="owner"],table.grid td.col-av{width:1%;text-align:center;white-space:nowrap}
table.grid th[data-col="assignee"]>span,table.grid th[data-col="owner"]>span{justify-content:center}
table.grid tbody tr:last-child td{border-bottom:0}
table.grid tbody tr:hover td{background:var(--paper-hi)}
table.grid tr.clickable,table.grid tr[data-quick-row],table.grid tr[data-href]{cursor:pointer}
table.grid tr[data-quick-row]:focus-visible,table.grid tr[data-href]:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
.btn.xs{height:20px;padding:0 6px;font-size:var(--fs-xs);border-radius:var(--r-xs)}
.btn.archive{color:var(--muted)}.btn.archive:hover{color:var(--ink)}
.btn.armed{box-shadow:inset 0 0 0 1px var(--warn);background:var(--warn-soft);color:var(--warn-ink)}
table.grid tbody tr.inactive td{background:var(--well);color:var(--muted)}  /* a person who is no longer active */
table.grid tbody tr.inactive:hover td{background:var(--well-hover)}
table.grid th[draggable=true]{cursor:grab;user-select:none}
table.grid th[draggable=true]::before{content:"";display:inline-block;width:6px;height:10px;margin-right:7px;vertical-align:-1px;opacity:.35;background:radial-gradient(circle,var(--faint) 1px,transparent 1.2px) 0 0/3px 3px}
table.grid th.dragging{opacity:.4}
table.grid th.drop-target{box-shadow:inset 3px 0 0 var(--accent)}
.col-reset{color:var(--muted)}
.table-tools{display:flex;justify-content:flex-end;margin:0 2px 6px}
/* a button that looks like a link: an in-page action that is not a navigation */
button.link{border:0;background:none;padding:0;font:inherit;color:var(--accent);text-decoration:underline;cursor:pointer}
.kv-table{width:100%;border-collapse:collapse;font-size:var(--fs-sm)}
.kv-table td{padding:5px 8px;border-bottom:1px solid var(--separator);vertical-align:top}
.kv-table td:first-child{color:var(--muted);white-space:nowrap;width:190px;font-family:var(--mono);font-size:var(--fs-sm)}
.kv-table td.redacted{color:var(--warn-ink);font-style:italic}
.kv{display:grid;grid-template-columns:150px 1fr;gap:6px 14px;font-size:var(--fs-md)}.kv dt{color:var(--muted)}.kv dd{margin:0}

/* ---------------------------------------------------------------- badges */
/* Badges are stamps: the word set as a small uppercase label inside a hairline of its own colour, the
   hairline softened on the mineral grounds. No pastel ground for most; the colour is the ink (a status, a
   priority, a source). A ticket's status in a list is the status mark instead (the Tickets page); the stamp
   stays where a word carries a state on its own: a suggestion, a request, a person. (Steven, 2026-09-21.) */
.badge{display:inline-block;padding:1px 6px;border:1px solid color-mix(in srgb,currentColor 55%,transparent);border-radius:4px;font-size:var(--fs-xs);font-weight:600;letter-spacing:.07em;text-transform:uppercase;line-height:1.5;color:var(--muted);background:transparent;white-space:nowrap;vertical-align:middle}
.badge.st-todo{color:var(--ink)}.badge.st-in_progress{color:var(--warn-ink)}.badge.st-in_review{color:var(--violet-ink)}.badge.st-done{color:var(--ok-ink)}.badge.st-canceled{color:var(--bad-ink)}
.pr-none{color:var(--muted)}.pr-low{color:var(--muted)}.pr-medium{color:var(--blue-ink)}.pr-high{color:var(--orange-ink)}.pr-urgent{color:var(--bad-ink)}
/* A priority is a filled chip and a source a bare word, so the status stamp (the word in its ink inside a hairline) is the one
   thing on a row wearing a border (Steven, 2026-09-22). The inks above are what the contrast test reads. */
.pr-none,.pr-low,.pr-medium,.pr-high,.pr-urgent,.src-internal,.src-client,.src-pipeline,.src-human{border-color:transparent}
.pr-none,.pr-low{background:var(--well)}.pr-medium{background:var(--blue-soft)}.pr-high{background:var(--orange-soft)}.pr-urgent{background:var(--bad-soft)}
.src-internal{color:var(--ok-ink)}.src-client{color:var(--bad-ink)}.src-pipeline{color:var(--violet-ink)}.src-human{color:var(--muted)}
.act-update{color:var(--blue-ink)}.act-create{color:var(--ok-ink)}.act-status_change{color:var(--warn-ink)}.act-reassign{color:var(--violet-ink)}
.ps-queued{color:var(--warn-ink)}.ps-approved{color:var(--blue-ink)}.ps-rejected{color:var(--muted)}.ps-applied{color:var(--ok-ink)}.ps-failed{color:var(--bad-ink)}.ps-reverted{color:var(--muted)}
.kind-decision{color:var(--blue-ink)}.kind-action_item{color:var(--ok-ink)}.kind-blocker{color:var(--bad-ink)}.kind-status_signal{color:var(--warn-ink)}.kind-owner_mention{color:var(--violet-ink)}
.cat-source,.cat-auth{color:var(--blue-ink)}.cat-model{color:var(--violet-ink)}.cat-embedding{color:var(--teal-ink)}.cat-ticket_system{color:var(--ok-ink)}.cat-escalation{color:var(--orange-ink)}.cat-other{color:var(--muted)}
.out-ok{color:var(--ok-ink)}.out-error{color:var(--bad-ink)}.out-pending{color:var(--warn-ink)}
.cs-done{background:var(--ok-soft);color:var(--ok-ink)}.cs-failed{background:var(--bad-soft);color:var(--bad-ink)}
/* The -ink members carry the text: the base --ok and --warn are ground and border colours (there is no base --bad); --warn reads 1.81 on the paper, and --ok, deepened for the Accept button (F32), carries no text but the trace's done dot. */
.conf-word{font-weight:600;font-size:var(--fs-sm)}.conf-word.high{color:var(--ok-ink)}.conf-word.medium{color:var(--warn-ink)}.conf-word.low{color:var(--bad-ink)}

/* ---------------------------------------------------------------- buttons, inputs, filters */
/* A button is a pill on the next lighter step (the Tickets page's controls); the primary one wears the accent. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:34px;padding:0 14px;border:0;border-radius:17px;background:var(--paper-hi);color:var(--ink);cursor:pointer;font:inherit;font-size:var(--fs-md);font-weight:500;line-height:1;white-space:nowrap;flex:none;box-shadow:var(--sh-control);transition:background .12s,box-shadow .12s}
.btn:hover{background:var(--sage);text-decoration:none}
.btn:active{transform:translateY(.5px)}
.btn:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.btn.primary{background:var(--accent);color:var(--accent-fg)}.btn.primary:hover{background:var(--accent-hover)}
.btn.ok{background:var(--ok);color:var(--accent-fg)}.btn.ok:hover{background:var(--ok-hover)}
.btn.danger{color:var(--bad-ink)}
.btn.ghost{box-shadow:none;background:transparent}.btn.ghost:hover{background:var(--sage)}
.btn.sm{height:28px;padding:0 11px;font-size:var(--fs-sm);border-radius:14px}
/* A control is one clear step from its ground: the paper's lighter step on the canvas (the modal's body is canvas too), the
   sage, a step darker, on a paper region, where the paper's own next step washes out (Steven, 2026-09-24). */
:is(.card,.tk-list,.shelf,.sug-list,table.grid,.picker-panel,.settings-nav) .btn:not(.primary):not(.ok):not(.ghost):not(.danger):not(.danger-text){background:var(--sage)}
:is(.card,.tk-list,.shelf,.sug-list,table.grid,.picker-panel,.settings-nav) .btn:not(.primary):not(.ok):not(.ghost):not(.danger):not(.danger-text):hover{background:var(--sage-2)}
:is(.card,.tk-list,.shelf,.sug-list) .icon-btn{background:var(--sage)}
/* a destructive action: the bad ink, a hairline of it, and its wash on hover; never a pastel of its own */
.btn.danger,.btn.danger-text{background:transparent;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--bad-ink) 45%,transparent)}
.btn.danger:hover,.btn.danger-text:hover{background:color-mix(in srgb,var(--bad-ink) 9%,transparent)}
.btn svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.btn[disabled],.btn[aria-disabled=true]{opacity:.5;cursor:default}
/* A field is a well with a hairline of ink, rounded like the search; the ring says which one has focus. */
input,select,textarea{font:inherit;color:var(--ink);background:var(--field);border:1px solid color-mix(in srgb,var(--ink) 18%,transparent);border-radius:var(--r);padding:0 11px;height:36px;transition:border-color .12s,box-shadow .12s}
textarea{height:auto;padding:8px 11px;width:100%;resize:vertical;line-height:1.5}
input::placeholder,textarea::placeholder{color:var(--muted);opacity:1}  /* the secondary, as the search box has it: a hint is small text and clears AA on the field in both palettes (F13) */
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--ring)}
select{appearance:none;-webkit-appearance:none;padding-right:28px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center}
input[disabled]{background:var(--well);color:var(--muted);border-color:transparent}
input[type=checkbox],input[type=radio]{width:16px;height:16px;margin:0;padding:0;border:0;background:none;box-shadow:none;accent-color:var(--accent)}
/* the search box of the older lists (review, calls, activity): the Tickets search at rest */
.search{position:relative;display:inline-flex;align-items:center;min-width:280px}
.search svg{position:absolute;left:12px;width:14px;height:14px;stroke:var(--muted);fill:none;stroke-width:2;pointer-events:none}
.search input{padding-left:32px;width:100%;border-radius:18px}
form.filters{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin:0 0 16px}
form.filters .status-strip{width:100%}
/* the review inbox's tabs: the view switch's shape, one pill per state with its count */
.status-strip{display:inline-flex;gap:3px;padding:4px;background:var(--switch);border-radius:var(--r-pane);flex-wrap:wrap;margin-bottom:8px}
.chip{position:relative;display:inline-flex;align-items:center;gap:6px;padding:7px 12px;border-radius:var(--r-ctl);color:var(--ink);font-size:12px;cursor:pointer;user-select:none;transition:background .12s,color .12s}
/* A tab is a label around a real radio, hidden out of sight but kept in the layout, so Tab reaches the group and the
   arrow keys move through it. */
.chip input{position:absolute;opacity:0;width:1px;height:1px}
.chip:has(input:focus-visible){outline:2px solid var(--focus);outline-offset:2px}
.chip:hover{text-decoration:none;background:color-mix(in srgb,var(--paper) 55%,transparent)}
.chip.on{background:var(--paper-hi);color:var(--accent-ink);box-shadow:var(--sh-control)}
.chip b{font-weight:500;color:var(--muted)}.chip.on b{color:var(--accent-ink)}
.stack{display:flex;flex-direction:column;gap:10px}
.stack label{display:flex;flex-direction:column;gap:4px;font-size:var(--fs-sm);color:var(--muted);font-weight:500}
.stack label input,.stack label select,.stack label textarea{font-size:var(--fs-md);color:var(--ink);font-weight:400}
.row{display:flex;gap:8px;align-items:flex-end;flex-wrap:wrap}.inline{display:inline}
.danger-zone h2{color:var(--bad-ink)}

/* spacing classes, so a template never carries a margin of its own (style= is for data-driven values only) */
.note{margin:0 0 10px}                /* a short explanation that introduces what follows */
.note.after{margin:10px 0 0}          /* one that follows content */
.card>.note:last-child{margin-bottom:0}
.after{margin-top:10px}               /* a form, a list or a details block that follows other content */
.stack>p{margin:0}                    /* the stack's gap spaces a paragraph */
.page-head .meta-line{margin:6px 0 0}
.quick .meta-line{margin:0 0 6px}
.change .after{margin-top:4px}
.picker-vals .note{margin:6px 10px}
.empty h1{margin-bottom:6px}
.card.narrow{max-width:680px}
.two-col.even{grid-template-columns:1fr 1fr}
.main-col>.progress{margin-bottom:16px}   /* the bar under an epic's title */
input.short{width:180px}input.wide{min-width:260px}
.uppercase{text-transform:uppercase}
.stack label.check{flex-direction:row;align-items:center;gap:8px}.stack label.check input{height:auto}
table.grid td.col-label{width:180px}

/* inline editing */
/* inline editing: .editable says a cell edits in place; the affordance depends on what it holds.
   A text cell and a badge get a dashed underline and a soft ground on hover, an avatar a ring on
   its circle, a bounded field (.field.editable, below) its own ring. */
.editable{cursor:text;transition:background .12s,border-color .12s,box-shadow .12s}
.editable:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:var(--r-xs)}
.editable-text{border-bottom:1px dashed transparent}
.editable-text:hover{border-bottom-color:var(--accent);background:var(--accent-soft)}
.editable-badge:hover{background:var(--accent-soft)}
/* Editable text says so: a pencil after the value on hover or focus. The icon is a mask over the
   text's own colour, and its space is reserved so nothing shifts when it appears. */
.editable-text::after{content:"";display:inline-block;width:11px;height:11px;margin-left:5px;vertical-align:-1px;background:currentColor;opacity:0;-webkit-mask:var(--pencil) center/contain no-repeat;mask:var(--pencil) center/contain no-repeat;transition:opacity .12s ease}
.editable-text:hover::after,.editable-text:focus-visible::after{opacity:.7}
.editable-text.editing::after{display:none}
.editable-badge{cursor:pointer}
.editable-avatar{display:inline-flex;border-radius:var(--r-pill);cursor:pointer}
.editable-avatar:hover .av{box-shadow:0 0 0 2px var(--accent-line)}
.editable-avatar.editing{display:inline-block}
.editable.editing:not(.menu-open){border-bottom:0;background:transparent;cursor:default}  /* the input path; a cell whose menu is open keeps its badge */
.inline-input{font:inherit;padding:4px 8px;border:1px solid var(--accent);border-radius:var(--r-sm);background:var(--paper-hi);color:var(--ink);box-shadow:0 0 0 3px var(--ring);height:auto}
h1 .inline-input,.inline-title{font-size:var(--fs-xl);font-weight:500;width:100%}
.inline-description{width:100%;font-family:inherit}

/* ---------------------------------------------------------------- content blocks */
.prose p{margin:0 0 8px}.prose ul,.prose ol{margin:0 0 8px 18px;padding:0}.prose h1,.prose h2,.prose h3{font-size:var(--fs);color:var(--ink);margin:12px 0 6px}.prose code{background:var(--well)}.prose table{border-collapse:collapse}.prose td,.prose th{border:1px solid var(--line);padding:3px 6px}
.meta-line{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:6px 0 16px}
blockquote.evidence{margin:6px 0 0;padding:8px 12px;border-left:3px solid var(--violet);background:var(--violet-soft);color:var(--ink-2);font-style:italic;border-radius:0 var(--r-sm) var(--r-sm) 0}
pre.json,pre.body{background:var(--code-bg);color:var(--code-ink);padding:14px;border-radius:var(--r);overflow:auto;font:var(--fs-sm)/1.55 var(--mono);margin:0;white-space:pre-wrap;word-break:break-word}
pre.body{max-height:320px;transition:max-height .2s}pre.body.expanded{max-height:none}
.body-head{display:flex;justify-content:space-between;align-items:center;margin:12px 0 6px}
.body-head h2{margin:0}
.brief{font:var(--fs-sm)/1.6 var(--mono);white-space:pre-wrap;background:var(--well);border-radius:var(--r);padding:14px 16px;color:var(--ink-2)}
.comment-head{display:flex;gap:8px;align-items:center;margin-bottom:4px;flex-wrap:wrap}.comment-head>.remove{margin-left:auto}
ul.timeline{list-style:none;margin:0;padding:0}ul.timeline li{padding:8px 0;border-top:1px solid var(--separator)}ul.timeline li:first-child{border-top:0;padding-top:0}
ul.plain{list-style:none;margin:0;padding:0}ul.plain li{padding:4px 0}
table.transcript{width:100%;border-collapse:collapse}table.transcript td{padding:5px 8px;vertical-align:top;border-bottom:1px solid var(--separator)}
table.transcript td.ts{width:76px;font-family:var(--mono);font-size:var(--fs-xs);color:var(--muted)}table.transcript td.spk{width:150px;font-weight:500;color:var(--ink-2)}
table.transcript tr.hl td{background:var(--warn-soft)}table.transcript tr:target td{background:var(--warn-line)}
.context-line{display:grid;grid-template-columns:70px 130px 1fr;gap:8px;padding:5px 0;border-top:1px solid var(--separator);font-size:var(--fs-md)}
.context-line.hl{background:var(--warn-soft)}.context-line .ts{font-family:var(--mono);color:var(--muted);font-size:var(--fs-xs)}.context-line .spk{font-weight:500}
.cand{display:flex;justify-content:space-between;padding:6px 0;border-top:1px solid var(--separator)}.cand:first-of-type{border-top:0}
.timeline-bar{display:flex;gap:18px;font-size:var(--fs-sm);color:var(--muted);flex-wrap:wrap}.timeline-bar b{color:var(--ink);font-weight:500}
.original{background:var(--warn-soft);border:1px solid var(--warn-line);border-radius:var(--r-sm);padding:8px 10px;font-size:var(--fs-sm);margin-top:8px}
/* The Complete column on the projects list: the same figure the project page leads with. The flex
   box sits inside the cell rather than being the cell: a td made flex stops being a table cell, no
   longer fills the row's height, and the row's hover shows through around it. */
.complete{display:flex;align-items:center;gap:8px;min-width:120px}
.complete .bar{flex:1;height:6px;border-radius:3px}.complete .bar>span{border-radius:3px}
.complete .n{font-variant-numeric:tabular-nums;color:var(--muted);font-size:var(--fs-sm)}
/* A team as a row of faces, each with a hover box (.tip) naming the person and their role. The
   circles overlap slightly with a rim of the paper between them; the hovered one comes forward. */
.av-stack{display:inline-flex;align-items:center}
.av-stack .tip+.tip{margin-left:-5px}
.av-stack .av{box-shadow:0 0 0 2px var(--paper)}
.av-stack .tip:hover{z-index:2}
.tip{position:relative;display:inline-flex}
.tip::after{content:attr(data-tip);position:absolute;left:50%;bottom:calc(100% + 7px);transform:translateX(-50%);padding:5px 9px;border-radius:var(--r-sm);background:var(--ink);color:var(--paper);font-size:var(--fs-sm);font-weight:500;white-space:nowrap;box-shadow:var(--sh-lg);opacity:0;pointer-events:none;transition:opacity .12s ease;z-index:30}
.tip:hover::after,.tip:focus-within::after{opacity:1}
.who{font-weight:500}

/* change preview: the change a suggestion makes, in a well of the region it sits in */
.change{margin:6px 0 8px;padding:10px 12px;background:var(--well);border-radius:var(--r)}
.change-target{font-weight:500;margin-bottom:4px}.change-target .key{margin-right:6px}
.change-diff{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:var(--fs-md)}
.change-diff .arrow{color:var(--faint)}
.change-label{font-size:var(--fs-xs);color:var(--muted);font-weight:500;margin-bottom:4px}
/* the previews render Markdown (`md`, nl2br) like the ticket page, so no pre-wrap: it would double every line break */
.comment-preview{background:var(--paper-hi);border-left:3px solid var(--accent);padding:6px 10px;border-radius:0 var(--r-sm) var(--r-sm) 0}
.ticket-preview{background:var(--paper-hi);border-radius:var(--r-sm);padding:8px 10px}
.comment-preview p:last-child,.ticket-preview .prose p:last-child{margin-bottom:0}

/* ---------------------------------------------------------------- review: dense rows */
.call-group{margin-bottom:22px}
.call-group-head{display:flex;justify-content:space-between;align-items:center;padding:0 4px 8px;gap:12px}
.call-group-head .title{font-weight:500;font-size:var(--fs);color:var(--ink)}
.sug-list{background:var(--paper);border:1px solid var(--edge);border-radius:var(--r-region);box-shadow:var(--sh-region);overflow:hidden}
.sug-row{display:grid;grid-template-columns:96px minmax(0,1fr) 150px auto;gap:14px;align-items:center;padding:12px 18px;border-top:1px solid var(--separator)}
.sug-row:first-child{border-top:0}
.sug-row:hover{background:var(--paper-hi)}
.sug-row.is-rejected,.sug-row.is-reverted{opacity:.7}
.sug-row.is-failed{background:var(--bad-soft)}
.sug-main{min-width:0}
.sug-line1{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;line-height:1.35}
.sug-title{font-weight:500;color:var(--ink)}
.sug-delta{color:var(--ink-2);font-size:var(--fs-md);display:inline-flex;gap:6px;align-items:center;flex-wrap:wrap}
.sug-delta .arrow{color:var(--faint)}
.sug-quote{font-size:var(--fs-sm);color:var(--muted);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sug-quote em{color:var(--ink-2)}
.sug-stat{font-size:var(--fs-sm);color:var(--muted);line-height:1.35}
.sug-stat .badge{margin-bottom:2px}
.sug-actions{display:flex;gap:6px;justify-content:flex-end;flex-wrap:wrap}
.sug-actions form{display:inline}

/* ---------------------------------------------------------------- activity: trace timeline */
.trace{position:relative;padding-left:34px}
.trace::before{content:"";position:absolute;left:11px;top:6px;bottom:6px;width:2px;background:var(--line)}
.trace-step{position:relative;margin-bottom:18px}
.trace-step .dot{position:absolute;left:-34px;top:2px;width:24px;height:24px;border-radius:12px;background:var(--sage);border:2px solid var(--line);display:grid;place-items:center;font-size:var(--fs-xs);font-weight:600;color:var(--muted)}
.trace-step.done .dot{border-color:var(--ok);color:var(--ok)}
.trace-step h3{font-size:var(--fs);margin-bottom:2px}
.trace-step .blurb{color:var(--muted);font-size:var(--fs-sm);margin:0 0 8px}
.trace-step .pending{color:var(--muted);font-size:var(--fs-sm)}  /* the secondary: "Not yet." is text, and --faint is for hairlines and marks (F33) */
.req-list{display:flex;flex-direction:column;gap:4px;margin:0 0 8px}
.req-line{display:flex;gap:10px;align-items:center;font-size:var(--fs-sm);padding:7px 10px;background:var(--well);border-radius:10px}
.req-line .mono{flex:1;color:var(--muted)}
.sub-list{display:flex;flex-direction:column;gap:3px}
.sub-line{display:flex;gap:10px;align-items:baseline;font-size:var(--fs-md);padding:4px 0;border-top:1px solid var(--separator)}
.sub-line:first-child{border-top:0}
.sub-line .grow{flex:1;min-width:0}
.gate{font-size:var(--fs-sm);color:var(--muted)}
.call-block{border:1px solid var(--edge);border-radius:var(--r-region);padding:16px 18px;margin-bottom:14px;background:var(--paper);box-shadow:var(--sh-region)}
.call-block-head{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:12px}

/* ---------------------------------------------------------------- home, epics, team */
.progress{display:flex;align-items:center;gap:10px;font-size:var(--fs-sm);color:var(--muted)}
/* One progress bar for every page: a track a step below every ground it sits on, and a filled span sized by the template. */
.bar{height:8px;background:var(--track);border-radius:4px;overflow:hidden}
.bar>span{display:block;height:100%;background:var(--accent);border-radius:4px}
.progress .bar{flex:1}
/* The project page. The head names the project and who is on it; `standing` is the progress block,
   where a piece's bar is drawn to its share of the project so width reads as size and fill as
   progress. `queue-strip` is an access point to Review, deliberately not a list of suggestions. */
.project-head .page-head{margin:0}
.project-head .page-head .key{font-size:var(--fs-sm);letter-spacing:.06em}
.project-head .goal{margin:10px 0 0;font-size:var(--fs);max-width:62ch}
/* A grid, not a wrapped row: as many equal columns as fit, so the people line up whatever the width. */
.roster{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:12px 18px;margin-top:14px;padding-top:14px;border-top:1px solid var(--separator);align-items:start}
/* The circle labels the name, so it aligns to the name's line rather than centring on the two-line
   block, where it reads as sitting a half-line low. */
.roster-person{display:flex;align-items:flex-start;gap:7px;color:inherit}
.roster-person a{color:inherit;text-decoration:none}
.roster-person a:hover b{text-decoration:underline}
.roster-who{display:flex;flex-direction:column;line-height:1.3;min-width:0}
.roster-who b{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* the role and the PM stamp on one line, the input included; Make PM shows as the row is hovered, like Remove, and on
   any focus (as Remove's :focus-within): the menu that demotes a PM focuses the control, and a mouse-driven focus is not
   :focus-visible, so the row had shown nothing where the stamp was until the mouse came back (S2.3) */
.roster-role{display:flex;align-items:center;gap:6px;min-width:0;flex-wrap:nowrap}
/* the role text keeps to one line like the name (the full role is in its title): free to wrap, a long one had put its pencil
   on a second line beside the reserved Make PM and made one row taller than its neighbours (S2.4); the overflow stays
   visible while editing, or the input's focus ring is clipped */
.roster-role .editable-text{white-space:nowrap;min-width:0}
.roster-role .editable-text:not(.editing){overflow:hidden;text-overflow:ellipsis}
.roster-role .inline-input{width:auto;min-width:0}  /* the script sizes it to the role's width at rest (beginEdit), so the controls beside it keep their place */
.roster-role .pm-make{opacity:0;white-space:nowrap}
.roster-person:hover .pm-make,.pm-make:focus,.pm-make.menu-open{opacity:1}
.roster-remove{opacity:0;transition:opacity .12s ease;margin-left:2px}
.roster-person:hover .roster-remove,.roster-remove:focus-within{opacity:1}
/* .icon-btn is a 32px pill with side padding; this one is a bare 20px circle, so the padding goes
   or the 14px icon has no room and never shows. */
.roster-remove .icon-btn{width:20px;height:20px;padding:0;justify-content:center;color:var(--muted);box-shadow:none;background:transparent}
.roster-remove .icon-btn svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2.4;stroke-linecap:round}
.roster-remove .icon-btn:hover{color:var(--bad-ink);box-shadow:inset 0 0 0 1px var(--bad-line);background:var(--bad-soft)}
.roster-remove.confirming{opacity:1}
.roster-add{align-self:center;justify-self:start}
.row-foot .roster-add{margin:0}
/* The figure, the bar and the button share one line: the bar centres on the percentage's own line and
   the note sits under it beside "complete", so nothing floats between rows. */
.headline-progress{display:flex;align-items:flex-start;gap:18px;margin-bottom:6px}
.headline-progress .grow .bar.lg{margin-top:6px}
.headline-progress .figure{display:flex;flex-direction:column;align-items:flex-start;line-height:1.1}
.headline-progress .figure b{font-size:var(--fs-xl);font-weight:500}
.headline-progress .grow{flex:1;min-width:0}
.headline-progress>.btn{flex:none;align-self:flex-start;margin-top:-2px}
.bar.lg{height:12px;border-radius:6px}.bar.lg>span{border-radius:6px}
.breakdown{display:flex;flex-direction:column;margin-top:6px}
.piece{padding:12px 0;border-top:1px solid var(--separator)}
.piece-head{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:var(--fs-md)}
.piece-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.piece-name b{font-weight:500}
.piece-meta{display:flex;align-items:center;gap:8px;flex:none}
.piece-meta .n{font-variant-numeric:tabular-nums;color:var(--muted)}
/* Width is data-driven (the share), so the track needs a floor or a one-ticket piece disappears. */
.piece-bar{margin-top:7px;min-width:44px;max-width:100%}
.piece-bar .bar{height:7px;border-radius:4px}
.piece.loose .piece-bar .bar>span{background:var(--muted)}
.piece-note{margin:6px 0 0;max-width:70ch}
/* The project page's rows: a <details> per section, full width, its summary a heading and a chevron.
   Native, so the keyboard and no-JavaScript both work. */
.row-section{padding:0}
.row-section>summary{display:flex;align-items:baseline;gap:12px;padding:14px 20px;cursor:pointer;list-style:none;border-radius:var(--r-region)}
.row-section>summary::-webkit-details-marker{display:none}
.row-section>summary::before{content:"";width:8px;height:8px;border-right:2px solid var(--muted);border-bottom:2px solid var(--muted);transform:rotate(-45deg);align-self:center;margin-right:2px;transition:transform .15s ease;flex:none}
.row-section[open]>summary::before{transform:rotate(45deg)}
.row-section>summary h2{margin:0;font-size:var(--fs);}
.row-section>summary:hover{background:var(--paper-hi)}
.row-section[open]>summary{border-bottom:1px solid var(--separator);border-radius:var(--r-region) var(--r-region) 0 0}
.row-section .row-body{padding:14px 20px 18px}
/* a row that is not available yet (the Brief, until the AI release): its heading, a lock, no disclosure */
.row-section.locked{color:var(--muted)}
.row-locked{display:flex;align-items:center;gap:10px;padding:14px 20px}
.row-locked h2{margin:0;font-size:var(--fs);color:var(--muted)}
.row-locked .lock{width:14px;height:14px;color:var(--faint)}
.row-section .row-body .narrow{max-width:520px}
.row-foot{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:14px;padding-top:14px;border-top:1px solid var(--separator)}
/* Manage epics: what exists, for reference above the form that adds the next one. */
.epic-refs{list-style:none;margin:0 0 16px;padding:0;display:flex;flex-direction:column;gap:6px}
.epic-refs li{font-size:var(--fs-md);min-width:0}
.epic-refs .n{margin-left:auto;color:var(--muted);font-variant-numeric:tabular-nums}
/* Each epic is a well with a chevron, so it reads as expandable at a glance; open, it lifts a step. Inside, an
   editable value carries its underline and pencil at rest, not only on hover, and Remove is a button in the bad ink. */
.epic-item{border-radius:var(--r);background:var(--well)}
.epic-item>summary{display:flex;align-items:center;gap:8px;padding:9px 12px;cursor:pointer;list-style:none;border-radius:var(--r)}
.epic-item>summary::-webkit-details-marker{display:none}
.epic-item>summary::before{content:"";width:7px;height:7px;border-right:2px solid var(--muted);border-bottom:2px solid var(--muted);transform:rotate(-45deg);flex:none;margin:0 4px 0 2px;transition:transform .15s ease}
.epic-item[open]>summary::before{transform:rotate(45deg)}
.epic-item>summary:hover{background:var(--sage)}
.epic-item>summary b{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.epic-item[open]{box-shadow:var(--sh-card)}
.epic-item[open]>summary{background:var(--sage);border-radius:var(--r) var(--r) 0 0}
.epic-body{display:flex;flex-direction:column;gap:10px;padding:12px 12px 14px 29px}
.epic-body .editable-text{border-bottom-color:var(--line-strong)}
.epic-body .editable-text::after{opacity:.55}
.epic-body .editable-text:hover::after,.epic-body .editable-text:focus-visible::after{opacity:1}
.epic-body .epic-remove{align-self:flex-start;margin-top:4px}
.epic-body .epic-remove .btn{color:var(--bad-ink)}
.row-foot>a:last-child{margin-left:auto}
/* people: initials on one flat mineral disc, the same for everyone (the reference's .cw-person, 2026-09-24); nobody is
   the same disc with a dash */
.av{display:inline-grid;place-items:center;width:26px;height:26px;border-radius:50%;background:var(--av-bg);color:var(--av-ink);font-size:11px;font-weight:500;letter-spacing:.02em;line-height:1;flex:none;vertical-align:middle;font-family:var(--font)}
.av.sm{width:20px;height:20px;font-size:9px}
.av.lg{width:36px;height:36px;font-size:var(--fs)}
.av.none{color:var(--muted)}.av.none::before{content:"–"}
.av-name{display:inline-flex;align-items:center;gap:7px;vertical-align:middle;min-width:0}
.av-name>span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
a.av-link{color:var(--ink);font-weight:500}a.av-link:hover{text-decoration:none;color:var(--accent-ink)}
h1.av-name{gap:10px}
.section-title{font-size:var(--fs);font-weight:500;color:var(--ink);margin:8px 0 10px;display:flex;align-items:center;gap:8px}
.section-title .muted{font-weight:400}

/* ---------------------------------------------------------------- home: the projects as rows */
.home-pct{flex:none;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.home-pms{display:inline-flex;align-items:center;flex:none}
.home-pms .tip::after{left:auto;right:0;transform:none}  /* the disc sits at the row's edge: the tooltip hangs left of it, inside the region */
.home-bar{display:inline-block;width:88px;height:6px;border-radius:3px;vertical-align:middle}
.home-bar>span{border-radius:3px}
.proj-chip{display:inline-flex;align-items:center;gap:4px;padding:1px 7px;border-radius:var(--r-xs);background:var(--well);color:var(--ink-2);font-size:var(--fs-xs);font-weight:500;font-family:var(--mono)}
a.proj-chip:hover{text-decoration:none;background:var(--accent-soft);color:var(--accent-ink)}

/* ---------------------------------------------------------------- settings */
/* The sections at the left on the drawer's pane ground (the same list the drawer's Settings pane shows), the page beside. */
.settings{display:grid;grid-template-columns:220px minmax(0,1fr);gap:24px;align-items:start}
.settings-nav{display:block;position:sticky;top:76px;background:var(--pane);border:1px solid var(--edge);border-radius:var(--r-pane);padding:10px;box-shadow:var(--sh-region)}
/* The sections are a <details> rendered closed (the narrow screen's collapsed row, Steven, 2026-09-25); a wide screen shows its list
   regardless and hides the row. A browser without ::details-content keeps the row on a wide screen too, so the list can still be opened. */
.settings-nav>summary{list-style:none;display:none;align-items:center;gap:8px;padding:9px 12px;border-radius:12px;color:var(--ink);font-size:var(--fs-md);cursor:pointer}
.settings-nav>summary::-webkit-details-marker{display:none}
.settings-nav>summary .i{width:16px;height:16px;color:var(--muted)}.settings-nav>summary .chev{margin-left:auto;transition:transform var(--t-drawer) ease}.settings-nav[open]>summary .chev{transform:rotate(180deg)}
.settings-nav>summary:hover{background:var(--sage)}
@supports not selector(::details-content){.settings-nav>summary{display:flex}}
/* The list opens and closes smoothly, and crossing 900px runs the same motion either way (Steven, 2026-09-25): the content's
   height goes between auto and 0 (interpolate-size lets auto animate; a browser without it switches at once), its visibility
   flipping at the end of a close and the start of an open (allow-discrete). Reduced motion zeroes it with everything else. */
.settings-nav{interpolate-size:allow-keywords}
.settings-nav::details-content{content-visibility:visible;display:block;height:auto;overflow:hidden;transition:height var(--t-drawer) ease,content-visibility var(--t-drawer) allow-discrete}
.settings-nav a,.settings-nav .locked{display:flex;align-items:center;gap:8px;padding:9px 12px;border-radius:12px;color:var(--ink);font-size:var(--fs-md)}
.settings-nav a:hover{background:var(--sage);text-decoration:none}
.settings-nav a.on{background:var(--sage);color:var(--accent-ink)}
.settings-nav .locked{color:var(--muted);cursor:default}
.settings-nav .locked .lock{margin-left:auto;width:14px;height:14px;color:var(--faint)}
.settings-nav .group{font-size:11px;color:var(--muted);padding:10px 12px 4px}
.settings-body>.page-head:first-child{margin-top:0}

.inline-form{display:flex;gap:8px;flex-wrap:wrap;align-items:flex-end}
.inline-form label{display:flex;flex-direction:column;gap:4px;font-size:var(--fs-sm);color:var(--muted);font-weight:500}
.inline-form label input{font-size:var(--fs-md);color:var(--ink);font-weight:400;min-width:180px}
.inline-form label.check{flex-direction:row;align-items:center;gap:8px;padding-bottom:9px}.inline-form label.check input{min-width:0;height:auto}  /* a box beside its words, on the row's baseline (the Team form's "Email them a link", 2026-09-25) */


/* ---------------------------------------------------------------- the Tickets page (the mineral direction, 2026-09-24)
   A heading with the search at its right, the filter bar under it and the conditions applied, then the two lists:
   paper regions on the canvas, each a column of rows told apart by a hairline, the title leading and its metadata
   quieter under it. On a wide screen the lists fill the height left under the controls and scroll on their own (the
   script measures it into --lists-h and marks the holder data-fit, a ceiling a short list stays under); on a narrow one
   (to 700px: one at a time on the track) or one too short to hold them (under 320px of room, R3.1) they sit in the
   page's flow. */
.tk-head{position:relative;display:flex;align-items:center;justify-content:space-between;gap:20px;margin:0 0 23px;padding:0 4px}
.tk-title{flex:none}
.tk-context{margin-bottom:2px;color:var(--muted);font-size:12px}
.tk-head h1{font-size:27px;line-height:1.2;font-weight:500;letter-spacing:-.7px}
.tk-head-tools{display:flex;align-items:center;justify-content:flex-end;gap:12px;flex:1;min-width:0}
.tk-head-tools>.btn{flex:none;height:38px;padding:0 15px;border:0;border-radius:19px}
.tk-head-tools>.btn svg{width:15px;height:15px}
/* The search rests compact at the right and widens to the left, its right edge anchored, when the mouse rests on
   it or it takes focus (to twice its resting width, so it never reaches the title; Steven, 2026-09-24); the
   suggestions hang under it with a bridge over the gap, so a pointer can cross to them. */
.search-shell{position:relative;z-index:8;flex:0 1 220px;min-width:0;transition:flex-basis var(--t-expand) var(--ease-settle)}
.tk[data-search-open] .search-shell{flex-basis:440px}
.search-field{display:flex;align-items:center;gap:8px;padding:0 5px 0 11px;border:1px solid color-mix(in srgb,var(--ink) 18%,transparent);border-radius:var(--r-field);background:var(--field);color:var(--muted);transition:background-color var(--t-expand) ease,box-shadow var(--t-expand) ease}
.tk[data-search-open] .search-field{background:var(--field-on);box-shadow:var(--sh-lift)}
.search-field:focus-within{outline:2px solid var(--focus);outline-offset:2px}
.search-input{flex:1;min-width:0;height:auto;padding:10px 0;border:0;border-radius:0;background:none;font-size:var(--fs-md)}
.search-input:focus{box-shadow:none}
.search-input::placeholder{color:var(--muted);opacity:1}
.search-input::-webkit-search-cancel-button{display:none}
.search-btn{display:grid;place-items:center;flex:none;width:30px;height:30px;padding:0;border:0;border-radius:50%;background:none;color:var(--ink);cursor:pointer}
.search-btn:hover{background:var(--sage)}
.search-close{background:var(--accent-soft)}
.suggestions{position:absolute;top:calc(100% + 10px);right:0;z-index:7;width:100%;min-width:260px;padding:10px;border-radius:var(--r-field);background:var(--popover);box-shadow:var(--sh-pop)}
.suggestions::before{content:"";position:absolute;top:-12px;left:0;right:0;height:13px}
.suggestion-head{margin:4px 12px 6px;font-size:11px;font-weight:500;color:var(--muted)}
.suggestion{display:flex;align-items:center;gap:11px;width:100%;padding:11px 12px;border:0;border-radius:12px;background:none;color:var(--ink);font:inherit;font-size:var(--fs-md);line-height:1.4;text-align:left;cursor:pointer}
.suggestion>span{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.suggestion:hover{background:var(--sage)}
.suggestion[aria-pressed=true]{background:var(--accent-soft)}
.suggestion[aria-pressed=true]:hover{background:var(--accent-soft-hover)}
.suggestion:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
.suggestion small{display:block;margin-top:2px;font-size:11px;color:var(--muted)}
.suggestion>svg:first-child{color:var(--ink-2)}
.suggestion>.status-mark,.opt>.status-mark{width:16px;justify-content:center;flex:none}
.suggestion .tick{margin-left:auto;color:var(--accent-ink)}
/* the filter bar: the picker, the two quick toggles, the order and the count */
.tk-filters{display:flex;align-items:center;gap:10px 14px;flex-wrap:wrap;min-height:44px}
.ctl{display:inline-flex;align-items:center;gap:7px;min-height:36px;padding:8px 16px;border:0;border-radius:18px;background:var(--paper);box-shadow:var(--sh-control);color:var(--ink);font:inherit;font-size:12px;line-height:1.4;cursor:pointer;user-select:none;list-style:none}
.ctl::-webkit-details-marker{display:none}
.ctl:hover,.picker[open]>.ctl{background:var(--sage-2)}
.ctl:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.ctl-count{display:grid;place-items:center;min-width:18px;height:18px;padding:0 4px;border-radius:7px;background:var(--sage-2);color:var(--accent-ink);font-size:11px}
.tk-quick{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.ctl-quick{padding:8px 10px;background:transparent;box-shadow:none;color:var(--ink-2)}
.ctl-quick[aria-pressed=true]{background:var(--sage-2);color:var(--accent-ink)}
.sorter{margin-left:auto}
.tk-count{font-size:12px;color:var(--ink-2);white-space:nowrap;font-variant-numeric:tabular-nums}
.picker{position:relative}
.picker-panel{position:absolute;top:calc(100% + 9px);left:0;z-index:25;display:grid;grid-template-columns:160px minmax(0,1fr);gap:12px;width:560px;max-width:calc(100vw - 32px);padding:14px;border-radius:var(--r-field);background:var(--popover);box-shadow:var(--sh-pop)}
.picker-dims{display:flex;flex-direction:column;gap:5px}
.picker-dims button{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:10px;border:0;border-radius:var(--r-ctl);background:transparent;color:var(--ink);font:inherit;font-size:var(--fs-md);text-align:left;cursor:pointer}
.picker-dims button:hover,.picker-dims button.on{background:var(--sage)}
.picker-dims .pill{background:var(--accent)}
.picker-vals{max-height:360px;min-width:0;overflow:auto;padding:13px 10px;border-radius:var(--r-card);background:var(--well)}
.picker-vals-head{display:flex;justify-content:space-between;align-items:baseline;gap:8px;padding:0 8px 10px;font-size:var(--fs-md);font-weight:500}
:is(.picker-vals,.sorter-panel) .opt{display:flex;align-items:center;gap:10px;padding:9px 8px;border-radius:11px;cursor:pointer;font-size:var(--fs-md);color:var(--ink)}
:is(.picker-vals,.sorter-panel) .opt:hover{background:var(--sage)}
:is(.picker-vals,.sorter-panel) .opt input{width:16px;height:16px;margin:0;accent-color:var(--accent);flex:none}
/* a project's epics, folded under it once it is checked (Steven, 2026-09-24); "No epic" is one line at the foot */
.opt-epics{margin:-4px 0 4px 34px}
.opt-epics>summary{display:flex;align-items:center;gap:4px;padding:4px 8px;border-radius:9px;font-size:11px;color:var(--muted);cursor:pointer;list-style:none}
.opt-epics>summary::-webkit-details-marker{display:none}
.opt-epics>summary svg{width:12px;height:12px;transition:transform .15s ease}
.opt-epics[open]>summary svg{transform:rotate(90deg)}
.opt-epics>summary:hover{background:var(--sage)}
.opt-sub{padding:6px 8px}
.opt-none{margin-top:8px;padding-top:12px;border-top:1px solid var(--separator);border-radius:0 0 11px 11px}
/* a value and its hint share one line and truncate, never wrap: a value is small print, its full text in the title */
:is(.picker-vals,.sorter-panel) .opt .opt-text{flex:0 1 auto;min-width:3ch;max-width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
:is(.picker-vals,.sorter-panel) .opt .hint{color:var(--muted);font-size:11px}
.picker-vals .opt>.hint{flex:1 1 0;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-align:right}
.sorter-panel .opt .hint{display:block}
.picker-vals .range{display:flex;flex-direction:column;gap:6px;margin-top:6px;padding:10px 8px 4px;border-top:1px solid var(--separator)}
.picker-vals .range label{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:var(--fs-sm);color:var(--muted)}
.picker-vals .range input{height:32px;width:160px;border-color:color-mix(in srgb,var(--ink) 18%,transparent);background:var(--paper);font-size:var(--fs-sm)}
.picker-foot{grid-column:1/-1;display:flex;align-items:center;gap:4px 16px;flex-wrap:wrap;margin:0 3px;padding-top:10px;border-top:1px solid var(--separator);font-size:11px;color:var(--muted)}
.picker-foot [data-nojs-apply]{margin-left:auto}
.sorter-panel{left:auto;right:0;grid-template-columns:minmax(0,1fr);width:290px}
.sorter-panel fieldset{min-width:0;margin:0;padding:10px;border:0;border-radius:var(--r-card);background:var(--well)}
.sorter-panel legend{float:left;width:100%;padding:0 8px 8px;font-size:var(--fs-md);font-weight:500}
.sorter-panel .picker-foot:has([data-nojs-apply][hidden]){display:none}
/* the conditions applied: a chip per property, "or" between its values, and one for the text searched */
.tk-applied{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:11px}
.chips{display:flex;gap:7px;flex-wrap:wrap;align-items:center;min-width:0}
.fchip{display:inline-flex;align-items:stretch;max-width:100%;overflow:hidden;border-radius:12px;background:var(--paper);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--accent-ink) 13%,transparent);color:var(--ink);font-size:12px}
.fchip button{display:inline-flex;align-items:baseline;gap:5px;min-width:0;padding:8px 10px;border:0;background:transparent;color:inherit;font:inherit;text-align:left;cursor:pointer}
.fchip button:first-child{max-width:320px}
.fchip button>span{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.fchip b{flex:none}
.fchip button:hover{background:var(--sage-2)}
.fchip button:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
.fchip b{font-weight:500;color:var(--accent-ink)}
.fchip .x{flex:none;align-items:center;justify-content:center;min-width:29px;padding:0 7px;font-size:15px;line-height:1}
.clear-all{padding:6px 4px;color:var(--ink-2);font-size:12px;text-decoration:underline;text-decoration-color:color-mix(in srgb,var(--ink) 35%,transparent);text-underline-offset:3px}
/* the view switch, while the project shelves are a preview (CABANA_PREVIEWS) */
.view-bar{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin:0 0 19px}
.view-switch{display:flex;gap:3px;padding:4px;border-radius:var(--r-pane);background:var(--switch)}
.view-switch a{display:flex;align-items:center;gap:7px;padding:8px 13px;border-radius:var(--r-ctl);color:var(--ink);font-size:12px}
.view-switch a:hover{text-decoration:none;background:color-mix(in srgb,var(--paper) 55%,transparent)}
.view-switch a[aria-current=page]{background:var(--paper-hi);box-shadow:var(--sh-control);color:var(--accent-ink)}
.view-switch a:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.view-switch .badge{color:inherit;margin-left:2px}  /* Beta on By project (Steven, 2026-09-25): the stamp in the option's own ink, so no new pair to measure */
/* the results: how they are ordered, then the two lists */
.tk-results{margin-top:20px}
.tk-results-head{display:flex;align-items:center;gap:4px 10px;flex-wrap:wrap;min-height:27px;margin:0 4px 10px;font-size:12px;color:var(--muted)}
.tk-results-head a{color:var(--ink-2);text-decoration:underline;text-decoration-color:color-mix(in srgb,var(--ink) 35%,transparent);text-underline-offset:3px}
.tk-results-head .btn.ghost:hover{background:var(--sage)}
.tk-lists{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px;align-items:start}
/* the narrow screen's switch between the two lists (hidden while both fit side by side): the view switch's shape */
.tk-switch{display:none;gap:3px;margin:0 0 12px;padding:4px;border-radius:var(--r-pane);background:var(--switch)}
.tk-switch button{flex:1;display:flex;align-items:center;justify-content:center;gap:7px;padding:8px 10px;border:0;border-radius:var(--r-ctl);background:transparent;color:var(--ink);font:inherit;font-size:12px;cursor:pointer}
.tk-switch button[aria-pressed=true]{background:var(--paper-hi);box-shadow:var(--sh-control);color:var(--accent-ink)}
.tk-switch button:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.tk-switch-count{color:var(--muted);font-variant-numeric:tabular-nums}
.tk-list{position:relative;display:flex;flex-direction:column;min-width:0;overflow:hidden;border:1px solid var(--edge);border-radius:var(--r-region);background:var(--paper);box-shadow:var(--sh-region)}
/* a list is as tall as its rows and no taller (Steven, 2026-09-24): the height the window leaves is its ceiling, not its size */
.tk-results[data-fit] .tk-list{max-height:var(--lists-h)}
.tk-list-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:18px 20px 10px}
.tk-list-head h2{font-size:var(--fs);line-height:1.5;font-weight:500;letter-spacing:-.15px;border-radius:var(--r-xs)}
.tk-list-count{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.tk-rows{--fade-top:0px;--fade-bottom:0px;flex:1;min-height:0;margin:0;padding:0 0 4px;list-style:none;scrollbar-width:thin;scrollbar-color:var(--sage-2) transparent}
/* the rows scroll only where the lists are fitted to the window; elsewhere the box stays open, so a tooltip above a row is not clipped */
.tk-results[data-fit] .tk-rows{overflow-y:auto;overscroll-behavior:contain}
/* A list with more rows than fit is open-ended (Steven, 2026-09-24): the rows fade out at the edge they continue past
   (a mask on the scroller, which stays put while the rows move under it) and a small arrow at that edge scrolls a
   page of them; the script sets data-more-above and data-more-below from the scroller's position. */
.tk-results[data-fit] .tk-rows{-webkit-mask-image:linear-gradient(to bottom,transparent 0,var(--ink) var(--fade-top),var(--ink) calc(100% - var(--fade-bottom)),transparent 100%);mask-image:linear-gradient(to bottom,transparent 0,var(--ink) var(--fade-top),var(--ink) calc(100% - var(--fade-bottom)),transparent 100%)}  /* only where the rows scroll: a mask clips a tooltip that rises above the rows (Home's PMs) */
.tk-list[data-more-above] .tk-rows{--fade-top:44px}
.tk-list[data-more-below] .tk-rows{--fade-bottom:64px}
.tk-more{position:absolute;left:50%;z-index:2;display:grid;place-items:center;width:30px;height:30px;padding:0;border:0;border-radius:50%;background:var(--sage);box-shadow:var(--sh-control);color:var(--ink);cursor:pointer;transform:translateX(-50%)}
.tk-more.up{top:50px}.tk-more.down{bottom:10px}
.tk-more:hover{background:var(--sage-2)}
.tk-more:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.tk-row{position:relative;padding:16px 20px;cursor:pointer}
.tk-row+.tk-row::before{content:"";position:absolute;top:0;left:20px;right:20px;border-top:1px solid var(--separator)}
/* The completed tickets' fold (2026-09-25): one quiet row at the top of Active + finished that counts the done tickets and opens
   or closes them; its chevron turns; the done rows under it keep the hairline like any row. */
.tk-fold{position:relative;padding:4px 12px}
.tk-fold button{display:flex;align-items:center;gap:8px;width:100%;padding:8px 10px;border:0;border-radius:12px;background:var(--sage);color:var(--muted);font:inherit;font-size:var(--fs-sm);font-weight:500;text-align:left;cursor:pointer}  /* the sage step at rest, as any control on a paper region: an option, not a shout (Steven, 2026-09-25) */
.tk-fold button:hover{background:var(--sage-2);color:var(--ink)}.tk-fold button:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.tk-fold .chev{width:16px;height:16px;transition:transform var(--t-drawer) ease}.tk-fold button[aria-expanded=true] .chev{transform:rotate(90deg)}  /* right while closed, down while open */
.tk-fold+.tk-row::before{content:"";position:absolute;top:0;left:20px;right:20px;border-top:1px solid var(--separator)}
.tk-row:hover{background:var(--paper-hi)}
.tk-row:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
.tk-row-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.tk-title-wrap{min-width:0;font-size:var(--fs);line-height:1.5;font-weight:500;letter-spacing:-.06px;overflow-wrap:anywhere}
.tk-title{color:var(--ink)}
.tk-title:hover{color:var(--ink);text-underline-offset:3px}
.tk-title:focus-visible,.tk-meta a:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:3px}
/* one line, always (Steven, 2026-09-24): the key, the status, Archive and the date keep their width; the project and
   epic between them take what is left and truncate, their full names in the links' titles */
.tk-meta{display:flex;align-items:center;gap:8px;margin-top:7px;color:var(--muted);font-size:12px;line-height:1.5;white-space:nowrap}
.tk-meta>*{flex:none}
.tk-meta a{color:inherit}
.tk-meta a:hover{color:var(--ink)}
.tk-key{font:11px/1.5 var(--mono)}
.tk-where{flex:0 1 auto;min-width:2ch;overflow:hidden;text-overflow:ellipsis}
.tk-dot{margin-left:-6px}
.tk-date{margin-left:auto}
.tk-row .target.past{color:var(--late);font-weight:400}
.tk-row .target.past::before{content:none}
.tk-row .btn.archive{height:22px;padding:0 7px;border-radius:9px;font-size:11px}
.tk-row .btn.archive:hover{background:var(--sage)}
.tk-empty{margin:0;padding:8px 20px 24px;color:var(--muted);font-size:var(--fs-md)}
.tk-rows:empty{min-height:48px}  /* room to drop a row into a list that has none */
.tk-none{color:var(--ink-2)}
.tk-results-head button.link{color:var(--ink-2);text-decoration-color:color-mix(in srgb,var(--ink) 35%,transparent);text-underline-offset:3px}
[data-sortable] .tk-row{cursor:grab}
.tk-row.drag-ghost{opacity:.35}
.tk-row.drag-chosen{background:var(--paper-hi)}
.tk-lists.moving .tk-row{transition:transform .55s cubic-bezier(.2,.7,.2,1)}
@keyframes glow{from{background-color:var(--accent-soft)}to{background-color:var(--paper)}}
.tk-row.pulse{animation:glow .9s ease-out}
/* A status in the lists: the word, with a small shape before it that says how far the work has come: hollow while
   it waits (dotted in the backlog), filled once it moves, ringed while it is in review, a square once it ends (filled
   for done, crossed out for canceled). The shape alone wears its state's ink (Steven, 2026-09-24: the eye finds the
   status without a scramble, and the word stays quiet): the accent for in progress, the violet for in review, the ok
   ink for done, the bad ink for canceled; to do is the ink, hollow, and the backlog the faint, dotted. */
.status-mark{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
.status-mark::before{content:"";flex:none;width:8px;height:8px;border:1.5px solid var(--ink);border-radius:50%}
.status-mark.sm-backlog::before{border-style:dotted;border-color:var(--faint)}
.status-mark.sm-in_progress::before{border-color:var(--accent);background:var(--accent)}
.status-mark.sm-in_review::before{border-color:var(--violet-ink);background:radial-gradient(circle,var(--violet-ink) 0 1.5px,transparent 2px)}
.status-mark.sm-done::before{border-color:var(--ok-ink);border-radius:2px;background:var(--ok-ink)}
.status-mark.sm-canceled::before{border-color:var(--bad-ink);border-radius:2px;background:linear-gradient(45deg,transparent 40%,var(--bad-ink) 40% 60%,transparent 60%),linear-gradient(-45deg,transparent 40%,var(--bad-ink) 40% 60%,transparent 60%)}
.editable-mark{margin:-1px -4px;padding:1px 4px;border-radius:var(--r-xs);cursor:pointer}
.editable-mark:hover{background:var(--accent-soft)}
/* the same rows inside a region (an epic's tickets, a person's open tickets): the region's own rows, no scroller of their own */
.card .tk-rows{margin:0 -20px;padding:0;overflow:visible;-webkit-mask-image:none;mask-image:none}
.card .tk-rows .tk-row:first-child::before{content:"";position:absolute;top:0;left:20px;right:20px;border-top:1px solid var(--separator)}
.tk-extra{margin-left:4px}

/* ---------------------------------------------------------------- project shelves (the By project preview, CABANA_PREVIEWS)
   Stacked down the page, one per project, each a list region like the Tickets lists: its head names the project with its
   counts, its rows are the same rows laid sideways on a track that scrolls on its own (a hairline between them, the next
   one peeking in at the edge), Previous and Next page it, and Show all lays every row out in a grid. */
.shelves{display:grid;gap:18px;min-width:0}
.shelf{--card-w:278px;min-width:0;overflow:hidden;border:1px solid var(--edge);border-radius:var(--r-region);background:var(--paper);box-shadow:var(--sh-region)}
.shelf-head{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:18px 20px 10px}
.shelf-heading{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 12px;min-width:0}
.shelf-heading h2{margin:0;font-size:var(--fs);line-height:1.5;font-weight:500;letter-spacing:-.15px;overflow-wrap:anywhere}
.shelf-heading h2 a{color:var(--ink)}
.shelf-summary{display:flex;align-items:center;flex-wrap:wrap;gap:4px 10px;color:var(--muted);font-size:12px;font-variant-numeric:tabular-nums}
.shelf-late{color:var(--late)}
.shelf-controls{display:flex;align-items:center;gap:6px;flex:none}
.shelf-controls button{display:grid;place-items:center;width:30px;height:30px;padding:0;border:0;border-radius:50%;background:var(--sage);box-shadow:var(--sh-control);color:var(--ink);font:inherit;font-size:12px;cursor:pointer}
.shelf-controls .shelf-all{display:inline-flex;width:auto;padding:0 12px;border-radius:15px;background:transparent;box-shadow:none;white-space:nowrap}
.shelf-controls .shelf-range{padding:0 6px 0 4px;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.shelf-controls button[aria-disabled=true]{background:transparent;box-shadow:none;color:var(--disabled);cursor:default}
.shelf-controls button:not([aria-disabled=true]):hover{background:var(--sage-2)}
.shelf-controls button:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.shelf-track{display:flex;min-width:0;margin:0;padding:0 0 12px;list-style:none;overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x proximity;scrollbar-width:thin;scrollbar-color:var(--sage-2) transparent}
.shelf-card{display:flex;flex:0 0 min(var(--card-w),calc(100% - 25px));min-width:0;scroll-snap-align:start}
.shelf-open{position:relative;display:flex;flex-direction:column;width:100%;padding:16px 20px;color:var(--ink)}
.shelf-card+.shelf-card .shelf-open::before{content:"";position:absolute;top:14px;bottom:14px;left:0;border-left:1px solid var(--separator)}
.shelf-open:hover{text-decoration:none;background:var(--paper-hi)}
.shelf-open:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
.shelf-card-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.shelf-card-title{min-width:0;font-size:var(--fs);line-height:1.5;font-weight:500;letter-spacing:-.06px;overflow-wrap:anywhere}
.shelf-meta{display:flex;align-items:center;gap:8px;margin-top:auto;padding-top:7px;color:var(--muted);font-size:12px;line-height:1.5;white-space:nowrap}
.shelf-meta>*{flex:none}
.shelf-due{margin-left:auto}
.shelf-due.late{color:var(--late)}
.shelf-empty{margin:0;padding:0 20px 20px;color:var(--muted);font-size:var(--fs-md)}
.shelf[data-expanded] .shelf-track{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(250px,100%),1fr));overflow:visible;scroll-snap-type:none}
.shelf[data-expanded] .shelf-open::before{content:"";position:absolute;top:0;left:20px;right:20px;bottom:auto;border-left:0;border-top:1px solid var(--separator)}

/* target dates: a calm cue, never an alarm */
.target{white-space:nowrap;font-variant-numeric:tabular-nums}
.target.past{color:var(--warn-ink);font-weight:500}
.target.past::before{content:"";display:inline-block;width:6px;height:6px;border-radius:3px;background:var(--warn);margin-right:6px;vertical-align:1px}
.target-wrap{display:inline-flex;gap:5px;align-items:baseline}
input.inline-target_date{height:28px;padding:2px 6px;font-size:var(--fs-sm)}

/* ---------------------------------------------------------------- fields: bounded text areas on ticket views
   A label sits above, the well marks exactly where the text (and the click-to-edit area) is. */
.field{display:block;border-radius:var(--r);padding:10px 13px;background:var(--well);margin:0;transition:background .12s,box-shadow .12s}
/* the description reads on the region's own ground (Steven, 2026-09-24: not the well); the hover ring still says it edits */
.field.prose{background:transparent;padding:6px 8px;margin:0 -8px}
.field.editable{cursor:text}
.field.editable:hover{background:var(--accent-soft);box-shadow:0 0 0 1px var(--accent-line-strong),0 0 0 4px var(--ring)}
.field.editing{padding:0;background:transparent;box-shadow:none}
.field.static{cursor:default}
h1.field{padding:8px 13px;line-height:1.35}
h2.field.quick-title{margin:2px 0 10px}
.field.prose p:last-child,.field.prose ul:last-child,.field.prose ol:last-child{margin-bottom:0}
ul.timeline.field li{padding:6px 0}
.comment{border-radius:var(--r);padding:10px 13px;margin:0 0 8px;background:var(--well)}
.comment.from-pipeline{background:var(--violet-soft);box-shadow:inset 3px 0 0 var(--violet-line)}

/* ---------------------------------------------------------------- @mentions */
.mention{display:inline-block;padding:0 6px;border-radius:var(--r-sm);background:var(--accent-soft);color:var(--accent-ink);font-weight:600;text-decoration:none;line-height:1.5}
a.mention:hover{text-decoration:none;background:var(--accent-soft-hover)}
/* the app's own menu: the option list under an editable cell and the @mention picker, on the popover ground */
.menu{position:absolute;z-index:40;min-width:180px;background:var(--popover);border-radius:var(--r-card);box-shadow:var(--sh-pop);padding:6px;max-height:280px;overflow:auto}
.menu-row{display:flex;align-items:center;gap:9px;padding:7px 10px;border-radius:10px;cursor:pointer;font-size:var(--fs-md);white-space:nowrap}
.menu-row.on,.menu-row:hover{background:var(--sage)}
.menu-row b{font-weight:500}
.menu-row .muted{font-size:var(--fs-sm)}
.menu-row .badge{pointer-events:none}
.menu-tick{margin-left:auto;padding-left:12px;color:var(--accent);font-weight:600}
/* A second look before an irreversible post (form[data-confirm]): a small box beside the button. It never
   outgrows the viewport: the question wraps, the buttons (.btn is flex:none) keep their width. */
.popover{position:absolute;z-index:40;display:flex;align-items:center;gap:10px;padding:9px 12px;background:var(--popover);border-radius:var(--r-card);box-shadow:var(--sh-pop);font-size:var(--fs-md);white-space:normal;max-width:min(360px,calc(100vw - 32px))}
.editable.menu-open{outline:2px solid var(--focus);outline-offset:2px;border-radius:var(--r-xs)}  /* the cell a menu is open under */

/* ---------------------------------------------------------------- modal: quick view and create forms
   The modal is a piece of page: the canvas, with the record's regions on it, lifted over the page behind. */
dialog.modal{border:0;padding:0;background:transparent;width:min(880px,94vw);max-width:none;max-height:none;overflow:visible;color:var(--ink)}
dialog.modal::backdrop{background:var(--backdrop);backdrop-filter:blur(2px)}
dialog.modal .flash.js{position:absolute;top:12px;right:12px;left:auto;z-index:2}
.modal-body{background:var(--bg);border-radius:var(--r-region);box-shadow:var(--sh-drawer);max-height:88vh;overflow:auto;overscroll-behavior:contain;padding:18px 24px 24px}
html:has(dialog.modal[open]){overflow:hidden} /* the page stays put while a modal is open; the modal body scrolls on its own */
.modal-body:empty{display:none}
.modal-head{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:8px}
.modal-title{font-size:var(--fs-lg);font-weight:500;margin:0}
.modal-crumbs{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap}
.modal-actions{display:flex;gap:8px;align-items:center;flex:none}
.modal-close{width:32px;padding:0;justify-content:center;font-size:20px;line-height:1}
.quick-title{font-size:19px;font-weight:500;line-height:1.3;margin:2px 0 8px;letter-spacing:-.01em}
/* The ticket, on its page and in the quick view: one head, then the same rows (_components.html). */
.ticket-head .page-head{margin:0 0 8px}.ticket-head .page-head .key{display:block;font-size:var(--fs-sm);letter-spacing:.06em;margin-bottom:4px}
.ticket-head h1{display:inline-block;padding:2px 4px;margin:0 -4px;border-radius:var(--r-xs)}
.quick .meta-line.where,.ticket-head .meta-line.where{gap:14px;margin:0}.ticket-head .meta-line{margin:8px 0 0}
.where-item{display:inline-flex;gap:5px;align-items:baseline}.where-item .editable-text{padding:0 2px;border-radius:var(--r-xs)}
.quick .quick-title{display:inline-block;padding:2px 4px;margin:2px -4px 6px;border-radius:var(--r-xs)}
.quick .meta-line.where{margin-bottom:14px}
.quick .card{margin-bottom:10px}.quick .card:last-child{margin-bottom:0}
/* A record's own actions (archive, delete) are buttons on their ground (the ticket page's paper, the quick view's canvas); the list's archive control stays bare so it wears its row. */
.record-actions{display:flex;gap:6px;align-items:center}.record-actions.wrap{flex-wrap:wrap;row-gap:6px}
/* A disclosure whose summary is a pill on the paper (the Connections page's connect and replace-key forms): no marker, the form below it when open. */
details.connect{margin-top:10px}details.connect>summary{list-style:none;display:inline-flex;cursor:pointer}details.connect>summary::-webkit-details-marker{display:none}details.connect[open]>summary{margin-bottom:12px}.record-actions.modal-foot{justify-content:flex-end;margin-top:14px}
.record-actions .btn.archive{color:var(--ink)}
.btn.danger-text{color:var(--bad-ink)}
.ticket-head .meta-line:not(.where),.quick .meta-line:not(.where){gap:18px}
.quick-field{display:flex;flex-direction:column;gap:3px;font-size:var(--fs-sm)}
.quick-field .editable{align-self:flex-start;font-size:var(--fs-md);color:var(--ink);font-weight:500;padding:1px 0}
.create-form .row>label{flex:1 1 140px}
.form-actions{align-items:center;margin-top:4px}
.form-error{background:var(--bad-soft);color:var(--bad-ink);padding:8px 12px;border-radius:var(--r-sm);font-size:var(--fs-md)}


/* ---------------------------------------------------------------- four widths
   Medium (to 900px): two-column pages stack, the review
   row and the settings sidebar too. Lists (to 700px, the mineral reference's width): the Tickets page's two lists
   leave the fitted height and sit side by side on a track in the page's flow that shows one at a time, full width
   and snapping, with the switch above naming each list with its count. Narrow (to 640px; the reference's 600 folded in): one column
   everywhere, the chrome tightens, the page loses most of its margin, the search takes a row of its own at full
   width, the drawer's child pane replaces its primary pane (with Back), and a table becomes its own scroll box.
   Small (to 480px): a project shelf's controls take a row of their own. Above 640px the holder is what scrolls a
   wide table (`.main-col` and the rule beside it), at every width. A coarse pointer gets 44px targets throughout. */
@media(max-width:900px){
  .two-col{grid-template-columns:1fr}
  .sug-row{grid-template-columns:1fr;gap:8px}.sug-actions{justify-content:flex-start}
  .settings{grid-template-columns:minmax(0,1fr)}.settings-nav{position:static}
  .settings-nav>summary{display:flex}.settings-nav:not([open])::details-content{content-visibility:hidden;height:0}  /* the row, closed on arrival; a tap opens the list, with the motion above */
  .settings-nav[open]>summary{margin-bottom:4px}
}
@media(max-width:700px){
  /* one list at a time, full width, on a track that snaps (Steven, 2026-09-24): the switch above it says which */
  .tk-switch{display:flex}
  .tk-lists{display:flex;gap:16px;overflow-x:auto;scroll-snap-type:x mandatory;scroll-padding-inline:var(--gutter);overscroll-behavior-x:contain;scrollbar-width:none;margin:0 calc(-1 * var(--gutter));padding:0 var(--gutter)}
  .tk-lists::-webkit-scrollbar{display:none}
  .tk-list{flex:0 0 100%;scroll-snap-align:start}
  .shelf{--card-w:258px}.shelf-head{gap:9px}.shelf-controls{gap:3px}
}
@media(max-width:640px){
  header.top{flex-wrap:wrap;gap:10px;padding:17px 16px 6px}
  .wordmark{font-size:21px}.brand-symbol{height:25px}.brand-wordmark{height:17px}.menu-trigger{padding:9px 14px}
  main{--gutter:14px;padding:16px var(--gutter) 48px}footer.bottom{padding:0 16px 20px}
  .drawer-panel[data-depth]{width:340px}.drawer-panel[data-depth] .drawer-main{display:none}.drawer-main{width:100%}.drawer-pane{margin-left:0}
  .tk-head{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"title new" "search search";align-items:end;gap:15px 12px;margin-bottom:18px}
  .tk-head:not(:has(.search-shell)){grid-template-areas:"title new"}
  .tk-head-tools{display:contents}.tk-title{grid-area:title}.tk-head-tools>.btn{grid-area:new}
  .search-shell,.tk[data-search-open] .search-shell{grid-area:search;width:100%}
  .search-input{font-size:16px}
  .tk-quick{order:4;flex-basis:100%}
  .tk-list-head{padding:14px 14px 8px}.tk-list .tk-row{padding:14px}.tk-list .tk-row+.tk-row::before{left:14px;right:14px}.tk-empty{padding:8px 14px 20px}  /* the lists alone: a card's rows keep the card's 20px gutter and its first hairline's length (R2.3) */
  .modal-body{padding:14px 16px 18px}
  .picker-panel{grid-template-columns:1fr;width:min(92vw,360px)}.picker-dims{flex-direction:row;flex-wrap:wrap}
  table.grid{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch}
}
@media(max-width:480px){
  header.top{gap:8px}.menu-trigger{gap:8px;padding:9px 12px}.menu-word{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}  /* the icon alone; the word stays for a screen reader */
  .shelf-head{flex-wrap:wrap;align-items:flex-start}.shelf-heading{width:100%}.shelf-controls{width:100%;justify-content:flex-end}.shelf-controls .shelf-all{margin-right:auto;padding-left:0}
  .shelf-open{padding:14px}.shelf[data-expanded] .shelf-open::before{left:14px;right:14px}.shelf-head,.shelf-empty{padding-left:14px;padding-right:14px}
  .shelf-card{flex-basis:calc(100% - 22px)}
}
@media(pointer:coarse){
  .round-btn,.drawer-head .round-btn,.top-tools .me .av,.search-btn,.shelf-controls button{width:44px;height:44px}
  .ctl,.suggestion,.fchip button,.view-switch a,.drawer-back,:is(.picker-vals,.sorter-panel) .opt,.picker-dims button,.shelf-controls .shelf-all,.menu-trigger,.tk-head-tools>.btn,.tk-switch button{min-height:44px}
  .tk-row .editable-avatar{padding:9px;margin:-9px}
  .tk-row .editable-mark{padding:13px 6px;margin:-13px -6px}
  .tk-row .target.editable{padding:14px 6px;margin:-14px -6px}
  .tk-row .btn.archive,.tk-row .tk-extra .btn{height:44px;padding:0 8px;margin:-13px 0}  /* Archive and a page's own control (the epic's Remove): 44 tall and 18 in the flow, the mark's pair, so the meta line does not grow (F14, R2.4) */
  /* the roster's controls: 44px hit areas taken back by their margins, so a row and the roster keep their height (S2.1) */
  .roster-remove .icon-btn{width:44px;height:44px;margin:-12px}
  .roster-role .pm-make{min-height:44px;margin:-12px 0}
  .roster-role .editable-text{padding:12px 0;margin:-12px 0}
  .home-pms .tip{padding:9px;margin:-9px}.home-pms .tip+.tip{margin-left:-14px}  /* a Home row's PM disc: 44px, the row's owner's pair; the discs still overlap by 5 (S2.6) */
}
/* Where nothing hovers (a phone) the roster's Make PM and Remove rest shown: the hover reveal (the seventh look, 2026-09-24)
   needs a pointer that hovers, and hidden at rest they were reachable only by accident (S2.1). */
@media(hover:none){.roster-role .pm-make,.roster-remove{opacity:1}}

/* ---------------------------------------------------------------- quiet movement
   Things settle rather than appear: a refreshed list, the modal. Off when the system asks for less motion. */
@keyframes settle{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
@keyframes fade{from{opacity:0}to{opacity:1}}
.settle{animation:settle .22s ease-out}
dialog.modal[open] .modal-body{animation:settle .18s ease-out}
dialog.modal[open]::backdrop{animation:fade .18s ease-out}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:0s!important;transition-duration:0s!important}}

/* The login page: one region in the middle of an otherwise empty page (login.html, E1). */
.login{max-width:420px;margin:56px auto 0}
.login h1{margin:0 0 6px;font-size:var(--fs-xl)}
.login input{width:100%;box-sizing:border-box}

/* a short numeric input in an inline form (the token form's days) */
.inline-form input.narrow{width:6em}
#tokens h3.others{margin-top:14px}
