/* Throughline app stylesheet (ALN-282).

   Authored inline in index.html until it reached 262 KB, 76% of a shell the server
   must serve `no-store` so a deploy lands immediately (ALN-154). That meant every
   open re-downloaded 76 KB brotli of CSS that had not changed in weeks. As its own
   file it is version-stamped like the bundles and cached `immutable`.

   It is still render-blocking, linked from the same position in <head> the <style>
   block occupied, so nothing about paint order changed. The @font-face declarations
   stayed behind in the shell: they are ~1 KB and they pair with the four rel=preload
   font hints directly above them, so the type system applies exactly when it did.

   Two things read this file rather than the document now, and a move has to take
   them with it: scripts/check-controls.js and test/controls-browser.test.mjs. */

  :root{
    --bg-top:#EAEEF2;--glass:rgba(255,255,255,.72);--on-ink:#FFFFFF;
    --warm-top:#FFFCF7;--warm-ink:#86511c;--warm-ink-b:#6b4012;
    --mist:#E3E8ED;--mist-2:#D6DDE4;--surface:#FFFFFF;--surface-2:#EEF2F6;
    --ink:#1B232B;--ink-soft:#54606C;--ink-faint:#6B7681;--hair:#CDD5DD;--hair-2:#DDE3E9;
    --now:#D9842E;--now-soft:#F4D9B4;--now-tint:#FFF6EA;--now-glow:rgba(217,132,46,.18);
    --calendar:#4E6E8E;--canvas:#BF5F4F;--code:#43856E;--health:#9C6A96;--arc:#2E9BB8;
    --github:#333C49;--align:#6F5FC0;--railway:#9A4EC2;--event:#D6337E;--break:#8B9AAE;
    --ok:#43856E;--warn:#BF5F4F;--idle:#C2902F;
    --hair-lit:#B4BFC9;--sentry:#B3415F;--custom:#5E6A8A;--hud-strength:0;--is-dark:0;--grid-line:rgba(27,35,43,.028);--noise:rgba(0,0,0,.012);
    --now-deep:#86511C;--on-now:#1B232B;--now-text:#86511C;--bg-3:#E3E8ED;--ink-3:#A9B3BD;--amber-deep:#86511C;--amber-glow:rgba(217,132,46,.18);
    --font-display:"Rajdhani",system-ui,sans-serif;--font-ui:"Archivo",system-ui,-apple-system,sans-serif;--font-mono:"ascsys",ui-monospace,SFMono-Regular,Menlo,monospace;
    --drawer:33vw;--radius:var(--r-lg);--topbar:56px;--botnav-h:74px;
    /* ALN-276: a hairline border PLUS a wide diffuse shadow is two redundant depth cues.
       Blur stays under 16px so elevation reads as a defined edge, not a halo. */
    --shadow:0 1px 2px rgba(27,35,43,.06),0 4px 10px -4px rgba(27,35,43,.18);
    --shadow-lg:0 2px 4px rgba(27,35,43,.07),0 8px 14px -5px rgba(27,35,43,.26);
  }
  /* ── Design-system foundation, STYLE_GUIDE §2-3, lifted from tokens/{spacing,typography,effects}.css.
     Constant across palettes; per-palette colour + per-family radii/effects live in theme.mjs.
     Values here are the light-family default; theme.mjs overrides them for the dark HUD palettes. ── */
  :root{
    --sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:20px;--sp-6:24px;--sp-8:32px;--sp-10:40px;--sp-12:48px;--sp-16:64px;
    --r-xs:6px;--r-sm:9px;--r-md:14px;--r-lg:18px;--r-pill:999px;--bw-hair:1px;--bw-lit:1.5px;--content-max:820px;
    /* ALN-273: the bottom two steps were 11px/10px. Contrast was never the problem here
       (--ink-faint on --surface measures 5.17:1 on Cyan Terminal), size was: an ADHD-first
       planner cannot ask you to read the day at 10px. --fs-xs is the floor for anything
       that is body copy; --fs-micro is for mono uppercase labels ONLY, never a sentence. */
    --fs-display:32px;--fs-h1:26px;--fs-h2:20px;--fs-h3:16px;--fs-body:14.5px;--fs-ui:13.5px;--fs-sm:12.5px;--fs-xs:12px;--fs-micro:11px;
    --lh-tight:1.12;--lh-snug:1.3;--lh-body:1.55;--fw-reg:400;--fw-med:500;--fw-semi:600;--fw-bold:700;
    --track-display:-0.01em;--track-tight:-0.005em;--track-label:0.15em;--track-wide:0.06em;
    --ease:cubic-bezier(.4,0,.2,1);--ease-out:cubic-bezier(.16,1,.3,1);--dur-fast:.14s;--dur:.24s;--dur-slow:.4s;
    /* The one chevron every native <select> wears (ALN-160, tokenised in ALN-263).
       A select cannot host a child element, so its arrow has to be a background
       image; authored once here so the six selects that draw it cannot drift. */
    --select-chevron:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2 4.5l4 4 4-4' fill='none' stroke='%238A95A1' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    --tex-grid:linear-gradient(var(--grid-line) 1px,transparent 1px),linear-gradient(90deg,var(--grid-line) 1px,transparent 1px);--tex-grid-size:28px 28px;
    --page-gradient:linear-gradient(180deg,var(--bg-top) 0%,var(--mist) 42%,var(--mist-2) 100%);
    --glow-now:0 0 0 1px var(--now-soft),0 5px 14px -7px var(--now-glow);--glow-soft:0 5px 14px -8px var(--now-glow);--glow-hazard:0 0 0 1px var(--idle),0 5px 14px -7px rgba(194,144,47,.22);--ring:0 0 0 1px var(--now),0 0 0 3px var(--now-glow);
    /* Alias layer: DS component token names → app canonical tokens, so the customizer's per-token pickers flow through */
    --bg-0:var(--mist);--bg-1:var(--surface);--bg-2:var(--surface-2);--bg-mist:var(--mist);--void:var(--mist-2);--surface-3:var(--mist);
    --ink-0:var(--ink);--ink-1:var(--ink-soft);--ink-2:var(--ink-faint);
    --on-accent:var(--on-ink);--text-strong:var(--ink);--text-body:var(--ink-soft);--text-muted:var(--ink-faint);--text-faint:var(--ink-3);--border:var(--hair);--border-lit:var(--hair-lit);
  }
  /* Shared motion keyframes (STYLE_GUIDE §3); disabled under reduced-motion */
  @keyframes tl-blink{0%,100%{opacity:1}50%{opacity:.25}}
  @keyframes tl-beat{0%{box-shadow:0 0 0 0 var(--now-glow)}70%{box-shadow:0 0 0 7px transparent}100%{box-shadow:0 0 0 0 transparent}}
  @keyframes tl-rise{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
  @keyframes tl-breathe{0%,100%{box-shadow:0 0 0 1px var(--now),0 0 18px -2px var(--now-glow),var(--shadow-lg);filter:drop-shadow(0 0 calc(var(--hud-strength) * .5px) var(--nc-edge)) drop-shadow(0 0 calc(var(--hud-strength) * .5px) var(--nc-edge)) drop-shadow(0 0 calc(var(--hud-strength) * .5px) var(--nc-edge)) drop-shadow(0 0 calc(var(--hud-strength) * 10px) var(--now-glow))}50%{box-shadow:0 0 0 1px var(--now),0 0 34px 1px var(--now-glow),var(--shadow-lg);filter:drop-shadow(0 0 calc(var(--hud-strength) * .5px) var(--nc-edge)) drop-shadow(0 0 calc(var(--hud-strength) * .5px) var(--nc-edge)) drop-shadow(0 0 calc(var(--hud-strength) * .5px) var(--nc-edge)) drop-shadow(0 0 calc(var(--hud-strength) * 20px) var(--now-glow))}}
  @keyframes tl-shimmer{0%{background-position:-460px 0}100%{background-position:460px 0}}
  @keyframes tl-flicker{0%,19%,21%,23%,80%,100%{opacity:1}20%,22%{opacity:.55}}
  @media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
  *{box-sizing:border-box;margin:0;padding:0}
  /* a11y (ALN-101): a card title rendered as a real <button> to open detail,
     placed before the title classes so each title's own font/colour wins, letting
     the card container drop role=button (WCAG 4.1.2: no button inside a button). */
  .cardopen{appearance:none;-webkit-appearance:none;background:none;border:0;margin:0;padding:0;font:inherit;color:inherit;letter-spacing:inherit;text-align:inherit;cursor:pointer}
  .cardopen:focus-visible{outline:2px solid var(--now);outline-offset:2px;border-radius:3px}
  /* ── Icons (ALN-245) ───────────────────────────────────────────────────────
     RemixIcon, inlined by TL.icons (client/src/icons.mjs) or written by hand in the
     static markup below. The interface used to be drawn with Unicode dingbats and
     emoji; both were unreliable (emoji render as Apple's colour artwork, dingbats
     inherit the text font so weight and alignment drift per platform).
     Sized in EM so an icon tracks the type it sits beside, and coloured by
     currentColor so it needs no second colour to keep in sync. Baseline nudge is
     the standard trick for optical alignment with lowercase text. */
  .ic{width:1em;height:1em;flex:none;fill:currentColor;vertical-align:-.125em;pointer-events:none}
  /* There is deliberately no "cancel the nudge inside a button" rule here (ALN-263).
     vertical-align has no effect on a flex item, so the nudge already stands down by
     itself wherever the button primitive below applies. The opt-out that used to live
     here fired on every `button .ic` whether or not the button actually was a flex
     row, so in the ~30 rules that painted a button surface but never set a display it
     dropped the icon onto the text baseline and it rode high above the label. Where an
     icon is wrapped (`.da-ic > svg.ic`) the svg is not the flex item, so the nudge is
     still doing real work and must stay. */

  /* ── Button primitive (ALN-263) ─────────────────────────────────────────────
     Every control that paints as a button lines its icon up with its label by
     construction, rather than each of the ~40 button classes rediscovering it (or
     not). Written at zero specificity via :where(), so it only ever fills in what a
     component rule did not already say: any class declaring its own display,
     alignment or gap still wins regardless of source order, which is what keeps
     this safe to drop in above two thousand lines of existing rules.
     Buttons that are really rows of text (a menu item, a list row) opt out. They
     are exactly the ones carrying text-align:left, so that is the marker to use if
     you add another.
     A <label> wrapping a file input is a button in everything but tag name, and it
     is the one such case that can be recognised structurally rather than by class,
     so it is named here and needs no opt-in. Everything else that acts like a button
     without being one is caught in the markup by scripts/check-controls.js.
     Widening this to [class*="btn"] was tried and rejected: `.ac-btns` and
     `.ac-rem-btns` are button GROUPS, divs holding buttons, so the substring match
     would have centred their contents. Class names signal intent too loosely. */
  /* SCOPED TO CONTROLS THAT ACTUALLY PAIR AN ICON WITH A LABEL, which is the entire
     problem this solves. The first cut of this rule applied to every button and it
     was too much: `.daycell` is a <button> with flex-direction:column, so "centre"
     there meant HORIZONTALLY, and it centred every day number and event chip in the
     month grid. A button that is a layout, not a row of icon-then-label, has nothing
     to gain here and everything to lose, so it is simply not addressed.
     `.link` and the file-picker <label> are listed because a pressable affordance is
     not always a <button>, and a label would otherwise print its icon hard against
     its text (which is exactly what shipped).
     Kept on ONE line on purpose: these :where() parts form a single compound
     selector, and a newline between them would be a descendant combinator, which
     silently stops the rule matching anything at all. */
  :where(button,[role="button"],.btn,.chip,.tab,.link,label:has(>input[type="file"])):where(:has(> svg,> .ic,> img,> span > svg)):where(:not(.da-item,.imp-row,.sr-row,.checkitem,.pm-item,.cw-thread-row,.notif-item,.cd-row,.daycell,.bn-item,.stg-item,.tg-head,.dis-toggle,.goal-more,.month-next,.cat-card,.ff,.ev-open,.conn,.add-conn,.prep-summary,.fpick,.acct-input,.cw-invite,.sp-main,.ho-fr,.arc-open,.arc-field,.arc-const,.card,.suggested,.cw-menu-item)){display:inline-flex;align-items:center;justify-content:center;gap:.5em}
  body{font-family:var(--font-ui);color:var(--ink);background:var(--mist-2);
    -webkit-font-smoothing:antialiased;line-height:1.5;min-height:100vh;overflow-x:hidden}
  body::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
    background:radial-gradient(120% 90% at 100% 0%,var(--bg-top) 0%,var(--mist) 44%,var(--mist-2) 100%);transition:background .3s}
  /* 28px canvas grid over the wash (STYLE_GUIDE §5). Now LIGHT-ONLY: gated to fade
     out as --hud-strength rises, so the dark HUD palettes drop the two-axis grid
     (which read as a generated tell) in favour of the living dot field painted by
     TL.dotfield (client/src/dotfield.mjs, ALN-139). Light Default is unchanged. */
  body::after{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;background-image:var(--tex-grid);background-size:var(--tex-grid-size);opacity:calc((1 - var(--hud-strength)) * .6)}
  .topbar{height:var(--topbar);display:flex;align-items:center;justify-content:space-between;gap:18px;padding:0 26px;border-bottom:1px solid var(--hair);background:var(--glass);backdrop-filter:blur(8px);position:fixed;top:0;left:0;right:0;z-index:40}
  .brand{font-family:var(--font-display);font-weight:600;font-size:18px;display:flex;align-items:center;gap:10px;letter-spacing:.02em;text-transform:uppercase;flex:0 0 auto;white-space:nowrap}
  /* ALN-247: the "throughline" brand mark, a reticle closing on now. The day's line
     runs edge to edge and four corner brackets frame the one lit node, which is the
     NowCard's own IN FOCUS lamp drawn as geometry (ALN-175 established the line + node;
     this adds the instrument the dark HUD palettes already speak in). Em-scaled so it
     holds from the 16px favicon through the sign-in lockup. Frame and node are both
     --now, so the mark recolours with the palette and the One-Signal Rule holds. */
  .brand-mark{flex:none;width:1.35em;height:1.35em;overflow:visible}
  .brand-mark .bm-line{stroke:var(--ink-faint);stroke-width:1.7;stroke-linecap:round;opacity:.5}
  .brand-mark .bm-frame{fill:none;stroke:var(--now);stroke-width:2.1;stroke-linejoin:miter;stroke-linecap:butt}
  .brand-mark .bm-node{fill:var(--now)}
  .brand-mark .bm-halo{fill:var(--now-glow);transform-box:fill-box;transform-origin:center;animation:tl-nodebeat 2.4s var(--ease) infinite}
  @keyframes tl-nodebeat{0%,100%{opacity:.6;transform:scale(.62)}50%{opacity:.1;transform:scale(1.22)}}
  /* The tabs are the flexible middle: they shrink + scroll (hidden scrollbar) when
     the window is tight rather than overflowing onto the right-side actions. */
  .tabs{display:flex;gap:4px;background:var(--surface-2);padding:4px;border-radius:var(--r-sm);border:1px solid var(--hair);min-width:0;flex:0 1 auto;overflow-x:auto;overflow-y:hidden;scrollbar-width:none}
  .tabs::-webkit-scrollbar{display:none}
  .tab{flex:none}
  .tab{font:inherit;font-size:13.5px;font-weight:500;color:var(--ink-soft);background:transparent;border:1px solid transparent;padding:6px 14px;border-radius:var(--r-xs);cursor:pointer;transition:.15s}
  /* ALN-274: "selected" no longer glows. The tab already reads as chosen from its fill, colour
     and border; the inner accent glow made a selected tab compete with the things that are
     actually live (the NowCard, today's cell, a running routine). Glow means now, not here. */
  .tab.active{background:var(--bg-0);color:var(--now-text);border-color:var(--now-soft)}
  .tab:hover:not(.active){color:var(--ink)}
  /* Bottom tab bar (ALN-167): the real small-screen navigation. Desktop keeps the
     in-topbar segmented tabs; ≤860 (the drawer-overlay / compact breakpoint) the five
     destinations move to a native bottom bar so the top bar can breathe. Reuses showView;
     active state carries the one amber signal + a slim indicator, obeying the One-Signal Rule. */
  .botnav{display:none}
  .bn-item{position:relative;flex:1 1 0;min-width:0;min-height:48px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;background:transparent;border:none;border-radius:13px;color:var(--ink-faint);font:inherit;cursor:pointer;padding:7px 2px 6px;transition:color .15s,background .15s;-webkit-tap-highlight-color:transparent}
  .bn-item svg{width:22px;height:22px;display:block;flex:none}
  .bn-label{font-size:10px;font-weight:600;letter-spacing:.005em;line-height:1;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .bn-item:hover{color:var(--ink-soft)}
  .bn-item.active{color:var(--now-text)}                       /* one amber signal marks the current view */
  .bn-item.active .bn-label{font-weight:700}
  .bn-dot{position:absolute;top:5px;left:calc(50% + 9px);width:7px;height:7px;border-radius:50%;background:var(--now);display:none;box-shadow:0 0 0 2px var(--glass)}
  .bn-dot.on{display:block}
  .clock{font-family:var(--font-mono);font-size:12px;color:var(--ink-faint);font-variant-numeric:tabular-nums;letter-spacing:.02em}
  .shell{display:flex;min-height:calc(100vh - var(--topbar));margin-top:var(--topbar)}
  /* ALN-287: the width is still what pushes .content aside, but it no longer TRANSITIONS.
     ALN-273 kept the transition here, reasoning that a transform on .drawer would move the
     drawer without pushing its sibling (true) and that only one flex sibling reflows. That
     sibling is .content, which holds the whole active view, so the old rule relayed out the
     day once per frame for 340ms. The push now runs as FLIP: app.js flips this width in a
     single pass and TL.motion.slideAfter (client/src/motion.mjs) slides .content back on the
     compositor, so the motion on screen is unchanged and layout runs twice, not twenty times.
     Do not put a transition back on this property: it would double with the FLIP slide. */
  .drawer{flex:none;width:0}
  .drawer.open{width:var(--drawer)}
  /* ALN-277: overflow was `hidden`, which clipped #quickPop (position:absolute, opening
     upward from .composer-wrap). Nothing here needs the parent to clip: no child declares a
     background, so none can paint past the radius, and .stream does its own scrolling with
     overflow-y:auto + min-height:0. Dropping it lets the popover escape, which is the real fix
     rather than ALN-273's max-height bound (kept as a belt-and-braces cap). */
  .drawer-inner{width:calc(var(--drawer) - 18px);position:fixed;top:calc(var(--topbar) + 14px);bottom:14px;left:14px;z-index:25;display:flex;flex-direction:column;overflow:visible;
    background:var(--surface);border:1px solid var(--hair-2);border-radius:18px;box-shadow:var(--shadow);transform:translateX(calc(-100% - 18px));transition:transform .34s cubic-bezier(.4,0,.2,1)}
  .drawer.open .drawer-inner{transform:none}
  .content{flex:1;min-width:0}
  main{max-width:820px;margin:0 auto;padding:30px 32px 90px}
  .drawer-toggle{position:fixed;left:0;top:calc(var(--topbar) + 22px);z-index:35;background:var(--ink);color:var(--on-ink);border:none;cursor:pointer;font:inherit;font-size:12.5px;font-weight:600;padding:11px 9px;border-radius:0 12px 12px 0;display:flex;align-items:center;gap:7px;writing-mode:vertical-rl;box-shadow:var(--shadow);transition:.2s}
  .drawer-toggle .ic{writing-mode:horizontal-tb}.drawer-toggle:hover{padding-left:13px}
  body.drawer-open .drawer-toggle{opacity:0;pointer-events:none}
  .backdrop{position:fixed;inset:var(--topbar) 0 0 0;background:rgba(27,35,43,.28);opacity:0;pointer-events:none;transition:.3s;z-index:20}
  .dr-head{display:flex;align-items:center;justify-content:space-between;padding:22px 22px 4px}
  .dr-title{font-family:var(--font-display);font-weight:500;font-size:18px;display:flex;align-items:center;gap:9px}
  /* ALN-175: the assistant's mark, a terminal command prompt (>_), the ONE glyph used
     everywhere the assistant appears (drawer header, desktop edge tab, mobile bottom-nav).
     Deliberately not a sparkle; reads as the "private terminal" you talk to. */
  .dr-mark{display:inline-flex;align-items:center;justify-content:center;flex:none;color:var(--now)}
  .dr-mark svg{width:21px;height:21px}
  .dr-persona{font-size:var(--fs-xs);color:var(--now-text);font-weight:600;padding:0 22px 2px}
  .dr-close{background:none;border:none;cursor:pointer;color:var(--ink-faint);font-size:22px;line-height:1;padding:4px}.dr-close:hover{color:var(--ink)}
  .dr-tag{color:var(--ink-soft);font-size:12.5px;padding:4px 22px 8px;line-height:1.5}
  .stream{flex:1;overflow-y:auto;padding:8px 20px 6px;display:flex;flex-direction:column;gap:13px;min-height:0}
  .msg{max-width:94%;font-size:14.5px}
  .msg.you{align-self:flex-end;background:var(--ink);color:var(--on-ink);padding:10px 14px;border-radius:16px 16px 4px 16px}
  .msg.planner{align-self:flex-start;line-height:1.55}
  .msg.planner .who{font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--now);font-weight:700;margin-bottom:3px}
  .msg.planner p{margin:0 0 7px}.msg.planner p:last-child{margin-bottom:0}
  .msg.planner ul,.msg.planner ol{margin:5px 0;padding-left:20px}.msg.planner li{margin:2px 0}
  .msg.planner strong{font-weight:700}
  .msg.planner code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12.5px;background:var(--mist);padding:1px 5px;border-radius:5px}
  .msg.planner pre{background:var(--mist);padding:9px 11px;border-radius:9px;overflow-x:auto;margin:7px 0}.msg.planner pre code{background:none;padding:0;font-size:12px}
  .msg.planner blockquote{margin:7px 0;padding-left:11px;border-left:3px solid var(--hair);color:var(--ink-soft)}
  .msg.planner .md-table{border-collapse:collapse;display:block;overflow-x:auto;max-width:100%;margin:7px 0;font-size:13px}
  .msg.planner .md-table th,.msg.planner .md-table td{border:1px solid var(--hair);padding:4px 9px;text-align:left;white-space:nowrap}
  .msg.planner .md-table th{background:var(--mist);font-weight:600}
  .dl-chip{display:inline-flex;align-items:center;gap:7px;margin-top:8px;background:var(--now-tint);border:1px solid var(--now-soft);color:var(--now-text);font-size:13px;font-weight:600;font-family:inherit;padding:8px 13px;border-radius:11px;cursor:pointer}.dl-chip:hover{background:color-mix(in srgb,var(--now) 12%,var(--now-tint))}
  .thinking{align-self:flex-start;display:flex;flex-direction:column;gap:7px}
  .tdots{display:flex;gap:7px;align-items:center;padding:3px 2px}
  .tdot{width:6px;height:6px;border-radius:50%;background:var(--now);box-shadow:0 0 7px var(--now);animation:pulse 1.15s ease-in-out infinite}
  .tdot:nth-child(2){animation-delay:.16s}.tdot:nth-child(3){animation-delay:.32s}
  @keyframes pulse{0%,80%,100%{opacity:.25;transform:translateY(0)}40%{opacity:1;transform:translateY(-2px)}}
  .feel-label{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint);font-weight:600;padding:8px 22px 0}
  .chips{display:flex;flex-wrap:wrap;gap:7px;padding:8px 20px}
  .composer-wrap{position:relative}
  /* ALN-273: #quickPop is position:absolute inside .drawer-inner, which is overflow:hidden,
     so anything taller than the gap above the composer is silently cut off rather than
     scrolled. 74vh was measured against the VIEWPORT, but the clipper is the drawer, which is
     shorter than the viewport by the topbar (and on mobile the bottom nav too). Bound it to
     the drawer instead. The durable fix is the popover API so it escapes the clipper
     entirely; this keeps the current structure and stops the clipping. */
  .quick-pop{position:absolute;left:16px;right:16px;bottom:calc(100% + 6px);z-index:40;background:var(--surface);border:1px solid var(--hair);border-radius:14px;box-shadow:var(--shadow-lg);padding:12px 12px 14px;animation:rise .18s ease both;max-height:min(560px,calc(100dvh - var(--topbar) - 150px));overflow-y:auto}
  .qp-tone-row{display:flex;align-items:center;justify-content:space-between;gap:10px}
  .tone-select{font:inherit;font-size:13px;color:var(--now);font-weight:600;background-color:var(--surface-2);border:1px solid var(--hair);border-radius:9px;padding:7px 28px 7px 10px;cursor:pointer;max-width:62%;background-image:var(--select-chevron);background-repeat:no-repeat;background-position:right 10px center;-webkit-appearance:none;appearance:none}
  .tone-select:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .quick-pop[hidden]{display:none}
  .quick-pop .chips{padding:0;gap:7px}
  .qp-label{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint);font-weight:700;margin:2px 4px 8px}
  .qp-divider{height:1px;background:var(--hair-2);margin:12px 4px 10px}
  .icon-btn.active{border-color:var(--now);color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .chip{font:inherit;font-size:12.5px;color:var(--ink-soft);background:var(--surface);border:1px solid var(--hair);border-radius:999px;padding:6px 12px;cursor:pointer;transition:.15s}
  .chip:hover{border-color:var(--now);color:var(--ink);box-shadow:0 0 0 3px var(--now-glow)}
  .attach-chip{display:flex;align-items:center;gap:8px;margin:0 20px 4px;background:var(--surface-2);border:1px solid var(--hair);border-radius:10px;padding:7px 11px;font-size:12.5px;color:var(--ink-soft)}
  .attach-chip b{color:var(--ink);font-weight:600}.attach-chip .x{margin-left:auto;cursor:pointer;color:var(--ink-faint);font-size:15px;border:0;background:none;font-family:inherit;padding:0}
  .composer{display:flex;gap:8px;align-items:flex-end;padding:6px 20px 20px}
  .icon-btn{border:1px solid var(--hair);background:var(--surface);width:42px;height:42px;border-radius:var(--r-sm);cursor:pointer;font-size:17px;display:grid;place-items:center;flex:none;color:var(--ink-soft)}.icon-btn:hover{border-color:var(--now);color:var(--ink)}
  .composer textarea{flex:1;min-width:0;min-height:44px;resize:none;font:inherit;font-size:14.5px;color:var(--ink);background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-sm);padding:11px 14px;max-height:110px;line-height:1.4}
  .composer textarea::placeholder{color:var(--ink-soft);opacity:1}
  .composer textarea:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .send{position:relative;border:none;background:var(--ink);color:var(--on-ink);width:42px;height:42px;border-radius:9px;cursor:pointer;font-size:17px;display:grid;place-items:center;flex:none}.send:hover{opacity:.88}.send:disabled{opacity:.4;cursor:default}
  .send svg{display:block}
  /* ALN-65: while generating, a point of light travels around the send button's edge (the reduced-motion reset above stills it) */
  .send .beam{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .2s}
  .send .beam svg{width:100%;height:100%;display:block;overflow:visible}
  .send .beam rect{fill:none;stroke:var(--now);stroke-width:2.4;stroke-linecap:round;stroke-dasharray:22 123;filter:drop-shadow(0 0 5px var(--now-glow))}
  .send.busy{opacity:1}
  .send.busy .beam{opacity:1}
  .send.busy .beam rect{animation:beamRun 1.25s linear infinite}
  @keyframes beamRun{to{stroke-dashoffset:-145}}
  .view{display:none;animation:fade .35s ease}.view.active{display:block}
  @keyframes fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
  @keyframes rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
  .h{font-family:var(--font-display);font-weight:500;font-size:31px;letter-spacing:-.015em}
  .sub{color:var(--ink-soft);font-size:14.5px;margin:3px 0 22px;max-width:62ch}
  .label{font-family:var(--font-mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft);font-weight:600;margin:0 0 12px 2px}
  /* Source tag (STYLE_GUIDE §6.2): outlined channel tint (text = channel, 12% fill, 45% border) via a single --sc var, replaces the solid white-on-color pills. */
  .src{font-family:var(--font-mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;padding:2px 7px;border-radius:var(--r-xs);white-space:nowrap;color:var(--ink-faint);background:transparent;border:1px solid color-mix(in srgb,var(--sc,var(--break)) 38%,transparent)}
  .src.calendar{--sc:var(--calendar)}.src.canvas{--sc:var(--canvas)}.src.github{--sc:var(--github)}
  .src.align{--sc:var(--align)}.src.railway{--sc:var(--railway)}.src.health{--sc:var(--health)}.src.break{--sc:var(--break)}
  .src.sentry{--sc:var(--sentry)}.src.custom{--sc:var(--custom)}.src.code{--sc:var(--code)}.src.event{--sc:var(--event)}.src.arc{--sc:var(--arc)}
  .ev.sentry{--sc:var(--sentry)}.ev.custom{--sc:var(--custom)}.ev.event{--sc:var(--event)}
  .today-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:18px;flex-wrap:wrap}
  /* ── The segmented switch: ONE primitive (ALN-270) ───────────────────────────
     Every two-or-three-way view switch in the app is the same control, a pill
     track with the selected segment lifted onto the surface. It had been
     re-invented five times (Cards/List, Sign in/Sign up, the host presets,
     List/Web, Chat/Group) with different radii, shadows, type sizes and active
     colours, so the same gesture looked like a different component in each place.
     This is the single definition; each control keeps only its own layout quirks
     further down (where it sits, whether it stretches, whether it scrolls).

     Selected state is written three different ways by the five modules that own
     these (`.active`, `aria-selected`, `aria-pressed`), so the primitive matches
     all of them rather than forcing a rewrite of five modules to change a look.
     `--ink`, never amber: the One-Signal Rule keeps amber for "now" and the
     primary action, and a lifted segment already reads as selected.

     The selected segment must read as the RAISED one, and that cannot be a fixed
     pair of tokens, because the two invert between themes:
         light  --surface #FFFFFF  >  --surface-2 #EEF2F6
         dark   --surface #1E252D  <  --surface-2 #262E37
     which is exactly why List/Web looked right on one palette and Chat/Group on
     another: each was correct in one theme and recessed in the other. So the pair
     is chosen by `--is-dark` (added to the palette sets for this, since
     `--hud-strength` says whether the HUD layer is on, not whether the palette is
     dark: both base palettes set it to 0). The chip is always the lighter of the
     two, and a custom palette that changes its surfaces gets this right for free
     because the colours are derived, never hardcoded.

     No drop shadow on the chip: on the dark palettes `--shadow` is a wide soft
     black, which on near-black reads as a smear around the segment rather than a
     lift (the Lit-Not-Stacked Rule). A hairline ring does the job in both. */
  .seg,.auth-seg,.lh-seg,.line-reg,.cw-compose-seg,.cw-tabs{
    --seg-track:color-mix(in oklab, var(--surface-2), var(--surface) calc(var(--is-dark, 0) * 100%));
    --seg-chip:color-mix(in oklab, var(--surface), var(--surface-2) calc(var(--is-dark, 0) * 100%));
    display:inline-flex;gap:2px;padding:3px;width:max-content;max-width:100%;background:var(--seg-track);border:1px solid var(--hair-2);border-radius:var(--r-pill)}
  .seg>button,.auth-seg>button,.lh-seg>button,.line-reg>button,.cw-compose-seg>button,.cw-tabs>button{font:inherit;font-size:var(--fs-sm);font-weight:600;color:var(--ink-soft);background:transparent;border:0;padding:7px 16px;min-height:34px;border-radius:var(--r-pill);cursor:pointer;white-space:nowrap;transition:color .15s,background .15s,box-shadow .15s}
  .seg>button:hover,.auth-seg>button:hover,.lh-seg>button:hover,.line-reg>button:hover,.cw-compose-seg>button:hover,.cw-tabs>button:hover{color:var(--ink)}
  .seg>button.active,.seg>button.on,.seg>button[aria-selected="true"],.seg>button[aria-pressed="true"],
  .auth-seg>button.active,.auth-seg>button.on,.auth-seg>button[aria-selected="true"],.auth-seg>button[aria-pressed="true"],
  .lh-seg>button.active,.lh-seg>button.on,.lh-seg>button[aria-selected="true"],.lh-seg>button[aria-pressed="true"],
  .line-reg>button.active,.line-reg>button.on,.line-reg>button[aria-selected="true"],.line-reg>button[aria-pressed="true"],
  .cw-compose-seg>button.active,.cw-compose-seg>button.on,.cw-compose-seg>button[aria-selected="true"],.cw-compose-seg>button[aria-pressed="true"],
  .cw-tabs>button.active,.cw-tabs>button.on,.cw-tabs>button[aria-selected="true"],.cw-tabs>button[aria-pressed="true"]{background:var(--seg-chip);color:var(--ink);box-shadow:inset 0 0 0 1px var(--hair-2)}
  .seg>button:focus-visible,.auth-seg>button:focus-visible,.lh-seg>button:focus-visible,.line-reg>button:focus-visible,.cw-compose-seg>button:focus-visible,.cw-tabs>button:focus-visible{outline:none;box-shadow:var(--ring)}
  @media (prefers-reduced-motion:reduce){.seg>button,.auth-seg>button,.lh-seg>button,.line-reg>button,.cw-compose-seg>button,.cw-tabs>button{transition:none}}
  .export-btn{font:inherit;font-size:12.5px;font-weight:600;color:var(--ink-soft);background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-sm);padding:8px 13px;cursor:pointer;display:flex;align-items:center;gap:6px;white-space:nowrap;flex:none}.export-btn:hover{border-color:var(--now);color:var(--ink)}
  .export-btn.danger:hover{border-color:var(--warn);color:var(--warn)}
  /* ALN-178: the account danger zone */
  .danger-card{border-color:color-mix(in srgb,var(--warn) 45%,transparent)}
  .btn-danger{font:inherit;font-size:13.5px;font-weight:600;color:#fff;background:color-mix(in srgb,var(--warn) 75%,#000);border:1px solid color-mix(in srgb,var(--warn) 75%,#000);padding:9px 14px;border-radius:10px;cursor:pointer;transition:.15s}
  .btn-danger:hover{filter:brightness(1.08)}
  .btn-danger:disabled{opacity:.55;cursor:default}
  /* Day actions overflow menu (ALN-95): collapses Add/Carry/Export/Clear off the
     header strip so the NowCard greets the user. Mirrors the .profile-menu popover. */
  .today-controls{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
  .day-actions{position:relative}
  .day-actions-btn{font-size:15px;font-weight:700;line-height:1;padding:8px 12px;letter-spacing:.08em}
  .day-actions-btn[aria-expanded="true"]{border-color:var(--now);color:var(--ink);box-shadow:0 0 0 3px var(--now-glow)}
  .day-actions-menu{position:absolute;top:calc(100% + 8px);right:0;min-width:214px;background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-md);box-shadow:var(--shadow-lg);padding:6px;z-index:60;display:flex;flex-direction:column;gap:1px;animation:notifIn .16s ease both}
  .day-actions-menu[hidden]{display:none}
  .da-item{display:flex;align-items:center;gap:10px;width:100%;text-align:left;font:inherit;font-size:13.5px;font-weight:500;color:var(--ink);background:none;border:none;border-radius:var(--r-sm);padding:9px 11px;cursor:pointer;white-space:nowrap;transition:background .12s,color .12s}
  .da-item:hover{background:var(--surface-2)}
  .da-item:focus-visible{outline:none;background:var(--surface-2);box-shadow:0 0 0 2px var(--now-glow)}
  /* A grid rather than text-align:center, so the icon is centred as a box on both
     axes. As an inline wrapper the svg inside it was still a text-baseline citizen,
     which left the menu icons about half a pixel high of their labels (ALN-263). */
  .da-ic{font-size:13px;width:15px;display:grid;place-items:center;color:var(--ink-faint);flex:none}
  .da-item:hover .da-ic,.da-item:focus-visible .da-ic{color:var(--ink-soft)}
  .da-sep{height:1px;background:var(--hair-2);margin:5px 4px}
  .da-danger .da-ic{color:var(--warn)}
  .da-danger:hover,.da-danger:focus-visible{background:color-mix(in srgb,var(--warn) 12%,transparent);color:var(--warn)}
  .date-nav{display:flex;align-items:center;gap:6px}
  /* One row, one control height (ALN-263). These five controls sit shoulder to
     shoulder, and a ragged set of heights reads as "not aligned" even though every
     one of them is perfectly centred: the row measured 33, 34, 37.5 and 38.8px tall.
     Centring cannot fix that, only a shared height can, so the row states one. */
  .today-controls{--control-h:38px}
  .date-nav>button:not(.export-btn){width:34px;height:var(--control-h,34px);border-radius:9px;border:1px solid var(--hair);background:var(--surface);cursor:pointer;font-size:15px;color:var(--ink-soft)}
  .date-nav>button:not(.export-btn):hover{border-color:var(--now);color:var(--ink)}
  /* min-height, NOT height: on a coarse pointer each segment is raised to the 44px
     touch floor below, and a fixed 38px track cannot hold them, so the segments
     burst out of the pill (owner screenshot, ALN-270). The track states a floor
     for the row and grows if its contents need more. */
  .today-controls .seg{min-height:var(--control-h);align-items:center}
  .today-controls .export-btn{min-height:var(--control-h)}
  #datePick{font:inherit;font-size:13px;color:var(--ink);background:var(--surface);border:1px solid var(--hair);border-radius:9px;padding:7px 9px;cursor:pointer;white-space:nowrap;min-height:var(--control-h)}
  #datePick:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  /* Touch pointers meet the product's ≥44px target floor (ALN-111); fine (mouse) pointers stay compact. */
  @media (pointer:coarse){
    .today-controls .export-btn,.today-controls .day-actions-btn,.now-actions .btn,.src-add{min-height:44px;display:inline-flex;align-items:center;justify-content:center}
    /* Every segmented switch, not just `.seg`: the touch floor belongs to the
       primitive now that they are one control (ALN-270). */
    .seg>button,.auth-seg>button,.lh-seg>button,.line-reg>button,.cw-compose-seg>button,.cw-tabs>button{min-height:44px}
    .date-nav>button:not(.export-btn){width:44px;height:44px}
    #datePick{min-height:44px}
    .da-item{min-height:44px}
    .dr-undo{min-height:44px;padding-left:10px;padding-right:10px}
  }
  /* NowCard (STYLE_GUIDE §6.1): chamfered silhouette (dark) + breathing border + "In focus" lamp.
     HUD flourishes gate on --hud-strength (0 light / 1 dark). ALN-278 removed the scanline wash:
     it was a ~20% dark screen over the single most important surface in the product. */
  .now-card{position:relative;--nc-edge:var(--now);--nc-glow:var(--now-glow);--nc-gblur:14px;--nc-fill:linear-gradient(180deg,var(--now-tint),var(--surface));background:linear-gradient(180deg,var(--now-tint),var(--surface));border:1px solid var(--now);border-radius:var(--r-lg);box-shadow:0 0 0 1px var(--now),0 0 22px -2px var(--now-glow),var(--shadow-lg);animation:tl-rise .5s var(--ease) both,var(--nc-anim,tl-breathe 4.2s ease-in-out infinite);cursor:pointer}
  .nc-in{position:relative;border-radius:inherit;overflow:hidden;padding:22px 22px 20px}
  /* Chamfered silhouette (dark HUD palettes) replaces the old corner brackets: see .now-card clip-path + filter, gated on --hud-strength (ALN-118). */
  /* Apply the chamfer whenever the HUD is lit, keyed on --hud-strength itself (a style query), robust even for a saved/tweaked Cyan or Midnight that predates the --nowcard-clip token, since it no longer depends on that token reaching stored theme state (ALN-118 follow-up). */
  @container style(--hud-strength: 1){
    .now-card{padding:1.4px;border:0;box-shadow:none;background:linear-gradient(150deg,color-mix(in srgb,var(--nc-edge) 50%,#fff),var(--nc-edge) 46%);clip-path:polygon(0 10px,0.76px 6.17px,2.93px 2.93px,6.17px 0.76px,10px 0,calc(100% - 18px) 0,100% 18px,100% calc(100% - 10px),calc(100% - 0.76px) calc(100% - 6.17px),calc(100% - 2.93px) calc(100% - 2.93px),calc(100% - 6.17px) calc(100% - 0.76px),calc(100% - 10px) 100%,18px 100%,0 calc(100% - 18px));filter:drop-shadow(0 0 var(--nc-gblur) var(--nc-glow));--nc-anim:nc-breathe 4.2s ease-in-out infinite}
    .nc-in{background:var(--nc-fill);border-radius:8px;clip-path:polygon(0 8px,0.61px 4.94px,2.34px 2.34px,4.94px 0.61px,8px 0,calc(100% - 16px) 0,100% 16px,100% calc(100% - 8px),calc(100% - 0.61px) calc(100% - 4.94px),calc(100% - 2.34px) calc(100% - 2.34px),calc(100% - 4.94px) calc(100% - 0.61px),calc(100% - 8px) 100%,16px 100%,0 calc(100% - 16px))}
  }
  @keyframes nc-breathe{0%,100%{filter:drop-shadow(0 0 12px var(--nc-glow))}50%{filter:drop-shadow(0 0 26px var(--nc-glow))}}
  .now-meta{position:relative;display:flex;align-items:center;gap:9px;margin-bottom:9px;z-index:1}
  .now-lamp{position:relative;width:8px;height:8px;flex:none;border-radius:50%;background:var(--now)}
  .now-lamp::after{content:"";position:absolute;inset:0;border-radius:50%;box-shadow:0 0 0 0 var(--now-glow);animation:tl-beat 2.2s ease-out infinite}
  .now-live-label{font-family:var(--font-mono);font-size:10px;font-weight:700;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-soft)}
  .now-time{font-family:var(--font-mono);font-size:12px;color:var(--ink-soft);font-variant-numeric:tabular-nums;margin-left:auto}
  .now-title{position:relative;display:block;width:fit-content;max-width:100%;font-family:var(--font-display);font-weight:600;font-size:25px;letter-spacing:-.01em;line-height:1.3;color:var(--ink);z-index:1}
  .first-step{position:relative;margin-top:13px;background:color-mix(in srgb,var(--now) 7%,transparent);border:1px solid var(--hair);border-radius:var(--r-sm);padding:10px 13px;font-size:14px;color:var(--ink-soft);display:flex;gap:8px;z-index:1}.first-step b{color:var(--ink);font-weight:600}.first-step .fs-arrow{color:var(--now);font-weight:700;flex:none}
  .now-card.idle{--now:var(--idle);--now-glow:var(--amber-glow);--nc-edge:var(--idle);--nc-glow:var(--amber-glow);--nc-fill:linear-gradient(180deg,color-mix(in srgb,var(--idle) 12%,transparent),var(--surface));border-color:var(--idle);background:linear-gradient(180deg,color-mix(in srgb,var(--idle) 10%,transparent),var(--surface))}
  /* ALN-115: a not-yet-started (or all-past) hero block is calm, no amber, no beat, no breathe. Amber "now" + the breathing border stay reserved for the block you're actually in (DESIGN.md One-Signal rule). */
  .now-card.upcoming{border-color:var(--hair-2);background:var(--surface);box-shadow:var(--shadow);--nc-anim:none;--nc-edge:var(--now-soft);--nc-glow:color-mix(in srgb,var(--now) 13%,transparent);--nc-gblur:11px;--nc-fill:var(--surface)}
  .now-card.upcoming .now-lamp{background:var(--ink-faint)}
  .now-card.upcoming .now-lamp::after{animation:none;box-shadow:none}
  .now-row{position:relative;z-index:1;display:flex;align-items:center;gap:13px;margin-top:15px;flex-wrap:wrap}
  .when{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-size:12.5px;letter-spacing:.04em;color:var(--ink-soft)}
  @keyframes beat{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--now) 45%,transparent)}70%{box-shadow:0 0 0 8px color-mix(in srgb,var(--now) 0%,transparent)}100%{box-shadow:0 0 0 0 color-mix(in srgb,var(--now) 0%,transparent)}}
  .now-actions{margin-left:auto;display:flex;gap:8px;flex-wrap:wrap}
  .now-actions .btn{display:inline-flex;align-items:center;justify-content:center;line-height:1}
  .btn{font:inherit;font-size:13px;border-radius:var(--r-sm);padding:8px 14px;cursor:pointer;border:1px solid transparent;transition:.15s}
  .btn-go{background:var(--now);color:var(--on-now);font-weight:600}.btn-go:hover{filter:brightness(.96)}
  .btn-ghost{background:var(--surface);border-color:var(--hair);color:var(--ink-soft)}.btn-ghost:hover{border-color:var(--ink-faint);color:var(--ink)}
  .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(228px,1fr));gap:12px;margin-top:8px}
  /* Progressive disclosure (ALN-111): "From your connections" shows the first 6; the rest stay one calm tap away instead of reconstituting the pile below the NowCard. */
  .grid.src-capped>:nth-child(n+7){display:none}
  .src-more{margin-top:12px;width:100%;min-height:44px;font:inherit;font-size:13px;font-weight:600;color:var(--ink-soft);background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-sm);padding:11px;cursor:pointer;transition:border-color .15s,color .15s}
  .src-more:hover{border-color:var(--now);color:var(--ink)}
  /* One-Signal (ALN-111): the Suggested "Add to today" is a calm primary (ink, hairline), not amber, amber stays the NowCard's. */
  .sg-add.btn-ghost{color:var(--ink);border-color:var(--hair-lit);font-weight:600}
  .sg-add.btn-ghost:hover{border-color:var(--now);color:var(--ink)}
  .card{position:relative;background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-md);padding:15px 16px 13px;box-shadow:var(--shadow);cursor:pointer;transition:transform .15s,box-shadow .15s,border-color .15s;animation:rise .45s ease both;overflow:hidden;display:flex;flex-direction:column}
  .card:hover{transform:translateY(-2px);box-shadow:var(--shadow-lg);border-color:var(--hair)}
  /* a11y (critique P1): visible keyboard focus for cards that open detail (role=button wired in app.js) */
  .now-card:focus-visible,.card:focus-visible,.row:focus-visible,.done-row:focus-visible{outline:2px solid var(--now);outline-offset:2px}
  .now-card:focus-visible{outline-offset:calc(2px - var(--hud-strength) * 4px)} /* dark: inset so the chamfer clip-path doesn't clip the ring (ALN-118) */
  a.card{text-decoration:none;color:var(--ink)}a.card .card-title{color:var(--ink)}
  #sourcesBody .card{cursor:default}
  #tasksBody .card{cursor:pointer}
  .task-pri{font-family:var(--font-mono);font-size:9.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;padding:2px 7px;border-radius:var(--r-xs);color:var(--ink-soft);background:var(--surface-2);border:1px solid var(--hair-2)}
  .task-pri.pri-high{color:var(--idle);border-color:var(--idle)}
  .task-pri.pri-critical{color:var(--warn);border-color:var(--warn)}
  /* "To take care of", Suggested next + calm grouped list (ALN-97, replaces the deck) */
  .tasks-wrap{display:flex;flex-direction:column;gap:14px}
  .tasks-clear{color:var(--ink-soft);font-size:14px;padding:6px 2px}
  .suggested{background:linear-gradient(180deg,var(--surface-2),var(--surface));border:1px solid var(--hair);border-radius:var(--r-md);padding:15px 16px 14px;box-shadow:var(--shadow);cursor:pointer;display:flex;flex-direction:column;gap:8px;transition:border-color .15s,box-shadow .15s}
  .suggested:hover{border-color:var(--hair-lit);box-shadow:var(--shadow-lg)}
  .suggested:focus-visible{outline:2px solid var(--now);outline-offset:2px}
  .sg-head{display:flex;align-items:center;gap:9px}
  .sg-eyebrow{font-family:var(--font-mono);font-size:10px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft)}
  .sg-why{font-family:var(--font-mono);font-size:9.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft);background:var(--surface-2);border:1px solid var(--hair-2);padding:1px 6px;border-radius:var(--r-xs)}
  .sg-head .src{margin-left:auto}
  .sg-title{font-family:var(--font-display);font-weight:600;font-size:18px;letter-spacing:-.01em;color:var(--ink);line-height:1.32}
  .sg-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
  .sg-meta{font-size:12.5px;color:var(--ink-soft);text-transform:capitalize}
  .sg-add{margin-left:auto;flex:none}
  .tasks-list-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:2px}
  .tasks-list-lead{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft);font-weight:700}
  .tasks-groupctl{display:flex;align-items:center;gap:7px}
  .tg-label{font-size:12px;color:var(--ink-soft)}
  .tg-select{font:inherit;font-size:12.5px;color:var(--ink-soft);background-color:var(--surface);border:1px solid var(--hair);border-radius:var(--r-sm);padding:5px 26px 5px 8px;cursor:pointer;background-image:var(--select-chevron);background-repeat:no-repeat;background-position:right 10px center;-webkit-appearance:none;appearance:none}
  .tg-select:focus-visible{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .tgroups{display:flex;flex-direction:column;gap:8px}
  .tgroup{border:1px solid var(--hair-2);border-radius:var(--r-md);overflow:hidden;background:var(--surface)}
  .tg-head{display:flex;align-items:center;gap:9px;width:100%;text-align:left;font:inherit;background:none;border:none;padding:11px 14px;cursor:pointer;color:var(--ink)}
  .tg-head:hover{background:var(--surface-2)}
  .tg-head:focus-visible{outline:2px solid var(--now);outline-offset:-2px}
  .tg-chev{color:var(--c,var(--ink-faint));font-size:11px;transition:transform .18s;flex:none}
  .tgroup.collapsed .tg-chev{transform:rotate(-90deg)}
  .tg-name{font-weight:600;font-size:14px}
  .tg-sub{font-size:12px;color:var(--ink-soft)}
  .tg-count{margin-left:auto;font-family:var(--font-mono);font-size:11px;color:var(--ink-soft);font-variant-numeric:tabular-nums}
  .tgroup.collapsed .tg-rows{display:none}
  .task-row{display:flex;align-items:center;gap:12px;padding:10px 14px;border-top:1px solid var(--hair-2);cursor:pointer;transition:background .12s}
  .task-row:hover{background:var(--surface-2)}
  .task-row:focus-visible{outline:2px solid var(--now);outline-offset:-2px}
  .tr-main{display:flex;align-items:center;gap:9px;min-width:0;flex:1}
  .tr-title{font-size:14px;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
  .tr-actions{display:flex;align-items:center;gap:9px;flex:none}
  .src-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:auto}
  .src-open{font-size:12px;font-weight:600;color:var(--ink-faint);text-decoration:none}.src-open:hover{color:var(--ink-soft)}
  .src-add{font:inherit;font-size:12px;font-weight:600;color:var(--ink-soft);background:transparent;border:1px solid var(--hair);padding:5px 11px;border-radius:9px;cursor:pointer;transition:.15s;white-space:nowrap}
  .src-add:hover{background:var(--surface-2);border-color:var(--hair)}
  .src-add.added{color:var(--ok);border-color:transparent;cursor:pointer;background:transparent}
  .src-add.resched{color:var(--now);border-color:var(--now-soft)}
  /* ALN-76: dismiss + the Dismissed archive */
  .tr-dismiss{font:inherit;font-size:13px;line-height:1;color:var(--ink-faint);background:transparent;border:none;padding:6px 7px;border-radius:var(--r-xs);cursor:pointer;transition:.15s;flex:none}
  .tr-dismiss:hover{color:var(--ink);background:var(--surface-2)}
  .tr-dismiss:focus-visible{outline:2px solid var(--now);outline-offset:-2px}
  .dis-sec{border-top:1px solid var(--hair-2);margin-top:4px}
  .dis-toggle{display:flex;align-items:center;gap:9px;width:100%;text-align:left;font:inherit;font-size:12.5px;font-weight:600;color:var(--ink-soft);background:none;border:none;padding:11px 2px;cursor:pointer}
  .dis-toggle:hover{color:var(--ink)}
  .dis-toggle:focus-visible{outline:2px solid var(--now);outline-offset:-2px}
  .dis-toggle .tg-chev{transition:transform .18s}
  .dis-rows{border:1px solid var(--hair-2);border-radius:var(--r-md);overflow:hidden;background:var(--surface);margin-bottom:8px}
  .dis-row{cursor:default;opacity:.75}
  .dis-row:first-child{border-top:none}
  .dis-optout{display:flex;align-items:center;gap:8px;font-size:13.5px;color:var(--ink-soft);margin:12px 0 4px;cursor:pointer}
  .dis-optout input{accent-color:var(--now)}
  .hero-clear{color:var(--ink-soft);font-size:15px;line-height:1.5;padding:18px 18px;background:var(--surface);border:1px solid var(--hair-2);border-radius:15px;box-shadow:var(--shadow)}
  .hc-done{display:flex;align-items:center;gap:8px;font-weight:600;color:var(--ink);font-size:15.5px}
  .hc-spark{color:var(--now);font-size:13px}
  .hc-nudge{margin-top:7px;color:var(--ink-soft);font-size:14.5px;line-height:1.5}
  .done-list{display:flex;flex-direction:column;gap:6px}
  .done-row{position:relative;display:flex;align-items:center;gap:10px;padding:9px 13px;background:var(--surface);border:1px solid var(--hair-2);border-radius:11px;cursor:pointer;opacity:.7;transition:opacity .15s,border-color .15s;overflow:hidden}
  /* ALN-66: no left spine, provenance is the outlined --sc source tag on the row */
  .done-row:hover{opacity:1;border-color:var(--hair)}
  .done-row.s-canvas{--c:var(--canvas)}.done-row.s-github{--c:var(--github)}.done-row.s-align{--c:var(--align)}.done-row.s-railway{--c:var(--railway)}.done-row.s-health{--c:var(--health)}.done-row.s-calendar{--c:var(--calendar)}.done-row.s-sentry{--c:#b3415f}.done-row.s-break{--c:var(--break)}
  .dr-check{color:var(--ok);font-weight:700;font-size:13px;flex:none}
  .done-row .dr-title{flex:1;min-width:0;font-size:14px;font-weight:500;color:var(--ink-soft);text-decoration:line-through;text-decoration-color:var(--hair);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .dr-undo{font:inherit;font-size:12px;font-weight:600;color:var(--ink-soft);background:transparent;border:none;cursor:pointer;flex:none;padding:2px 4px}.dr-undo:hover{color:var(--ink)}
  /* ALN-110: a calendar event that already happened today, shown read-only in Completed */
  .dr-past{color:var(--ink-soft)}
  .dr-when{font-size:12px;color:var(--ink-soft);flex:none;white-space:nowrap}
  .done-row.dr-ev{cursor:default}.done-row.dr-ev .dr-title{text-decoration:none}
  /* ── ALN-200: daily goals strip + end-of-day reflection ─────────────────────
     The strip sits between "Right now" and "Later today"; the reflection card
     sits after Completed and reveals as the day winds down. Both are calm
     surfaces: no new accent, nothing breathes, unfinished is never shamed. */
  .goals-strip{background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-md);box-shadow:var(--shadow);padding:3px 6px}
  .goal-row{display:flex;align-items:center;gap:11px;padding:9px 9px}
  .goal-row + .goal-row,.goal-row + .goal-add{border-top:1px solid var(--hair-2)}
  .goal-check{appearance:none;-webkit-appearance:none;width:20px;height:20px;flex:none;border-radius:50%;border:1.5px solid var(--hair-lit);background:transparent;cursor:pointer;display:grid;place-items:center;font-size:11px;font-weight:700;line-height:1;color:transparent;padding:0;transition:border-color var(--dur-fast),color var(--dur-fast)}
  .goal-check:hover{border-color:var(--ok)}
  .goal-check:focus-visible{outline:none;box-shadow:var(--ring)}
  .goal-row.done .goal-check{border-color:var(--ok);color:var(--ok)}
  .goal-text{flex:1;min-width:0;font-size:14.5px;color:var(--ink);overflow-wrap:break-word}
  .goal-row.done .goal-text{color:var(--ink-soft);text-decoration:line-through;text-decoration-color:var(--hair)}
  .goal-from{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;color:var(--ink-faint);border:1px solid var(--hair);border-radius:var(--r-xs);padding:2px 6px;flex:none;white-space:nowrap;order:3}
  .goal-acts{display:flex;gap:2px;flex:none;opacity:0;transition:opacity var(--dur-fast);order:2}
  .goal-row:hover .goal-acts,.goal-row:focus-within .goal-acts{opacity:1}
  @media (hover:none){.goal-acts{opacity:1}}
  .goal-act{font:inherit;font-size:12px;font-weight:600;color:var(--ink-faint);background:none;border:none;cursor:pointer;padding:4px 7px;border-radius:var(--r-xs)}
  .goal-act:hover{color:var(--ink)}
  .goal-act.gx:hover{color:var(--warn)}
  .goal-act:focus-visible{outline:none;box-shadow:var(--ring)}
  .goal-add{display:flex;align-items:center;gap:11px;padding:5px 9px}
  .goal-add .ghost{width:20px;height:20px;flex:none;border-radius:50%;border:1.5px dashed var(--hair-lit);opacity:.6}
  .goal-add input{flex:1;min-width:0;border:none;background:transparent;font:inherit;font-size:14.5px;color:var(--ink);padding:8px 0}
  .goal-add input::placeholder{color:var(--ink-soft);opacity:1}
  .goal-add input:focus{outline:none} /* the caret is the focus signal; an accent underline read as a spine (owner, ALN-200) */
  .goal-more{font:inherit;font-size:13px;font-weight:500;color:var(--ink-faint);background:none;border:none;cursor:pointer;display:flex;align-items:center;gap:9px;padding:9px 10px;width:100%;text-align:left;border-radius:var(--r-xs)}
  .goal-more:hover{color:var(--ink-soft)}
  .goal-more:focus-visible{outline:none;box-shadow:var(--ring)}
  .goal-row + .goal-more{border-top:1px solid var(--hair-2)}
  .goal-edit{flex:1;min-width:0;border:none;background:transparent;font:inherit;font-size:14.5px;color:var(--ink);padding:0}
  .goal-edit:focus{outline:none}
  .reflect-card{background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-md);box-shadow:var(--shadow);padding:16px 18px 14px}
  .rf-recap{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:13px}
  .rf-goal{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;color:var(--ink-soft);border:1px solid var(--hair);border-radius:var(--r-pill);padding:5px 11px}
  .rf-goal .ck{font-size:11px;font-weight:700;color:var(--ok)}
  .rf-goal .op{font-size:11px;color:var(--ink-faint)}
  .rf-goal.done{color:var(--ink-faint)}
  .reflect-card textarea{width:100%;min-height:76px;resize:vertical;font:inherit;font-size:14.5px;line-height:1.55;color:var(--ink);background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-sm);padding:11px 14px}
  .reflect-card textarea::placeholder{color:var(--ink-soft);opacity:1}
  .reflect-card textarea:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .rf-foot{display:flex;align-items:center;gap:10px;margin-top:12px;flex-wrap:wrap}
  /* ALN-271 follow-up: with the attachments widget collapsed and nothing to carry, the foot is a
     zero-height flex line, but its top margin still held 12px of air against the card's bottom
     edge, so the space under "Attachments" read as twice the space above the note. It reserves
     nothing until it actually holds something. */
  .rf-foot:has(> .rf-saved:only-child:empty){margin-top:0}
  .rf-carry{font-size:13px;color:var(--ink-soft)}
  .rf-carry-btn{font:inherit;font-size:12.5px;font-weight:600;color:var(--ink-soft);background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-sm);padding:7px 12px;cursor:pointer}
  .rf-carry-btn:hover{border-color:var(--now);color:var(--ink)}
  .rf-saved{margin-left:auto;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;font-weight:700;color:var(--ink-faint)}
  .reflect-card .attachments{margin-top:14px}
  @media (max-width:640px){
    .goal-row{flex-wrap:wrap;row-gap:4px}
    .goal-text{flex:1 1 calc(100% - 31px)}
    .goal-from{margin-left:31px}
    .goal-acts{margin-left:auto}
  }
  @media (max-width:640px) and (hover:hover){.goal-acts{display:none}.goal-row:focus-within .goal-acts{display:flex}}
  /* ALN-164: the HUD corner ticks were removed (owner: ugly, and they cramped the right
     edge). Provenance is the outlined --sc source chip (.src) the cards already carry; the
     --c channel below is kept because the connection card's .src-add action still reads it. */
  .card.s-canvas{--c:var(--canvas)}.card.s-github{--c:var(--github)}.card.s-align{--c:var(--align)}.card.s-railway{--c:var(--railway)}.card.s-health{--c:var(--health)}.card.s-calendar{--c:var(--calendar)}.card.s-break{--c:var(--break)}
  .card.active{background:var(--now-tint);border-color:var(--now-soft);box-shadow:var(--glow-soft)}
  .card.done{opacity:.62}
  /* ── "To take care of": the shuffleable-deck/stacks CSS was removed in ALN-97;
     the Suggested-next + grouped-list styles live above (.tasks-wrap / .suggested
     / .tgroup / .task-row). ── */
  .card-top{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}
  .card-time{font-family:var(--font-mono);font-size:12px;color:var(--ink-soft);font-variant-numeric:tabular-nums;font-weight:600;letter-spacing:.01em}
  .card-title{font-size:15px;font-weight:600;line-height:1.25;margin-bottom:4px}
  .card.s-break .card-title{font-style:italic;font-weight:500;color:var(--ink-soft)}
  .card-note{font-size:12px;color:var(--ink-soft);line-height:1.35;margin-bottom:10px}
  /* ALN-186: a subtle location line on blocks (card / NowCard / list row) and the month day row. */
  .card-loc{font-size:12px;color:var(--ink-faint);display:flex;align-items:center;gap:5px;line-height:1.3;margin:0 0 8px}
  .now-loc{position:relative;z-index:1;font-size:12.5px;color:var(--ink-soft);display:flex;align-items:center;gap:6px;line-height:1.3;margin:9px 0 2px}
  .dv-loc{font-size:var(--fs-xs);color:var(--ink-faint);display:flex;align-items:center;gap:5px;line-height:1.3;margin-top:3px}
  .add-attach{margin-top:2px}
  .card-foot{display:flex;align-items:center;gap:8px;margin-top:auto}
  .card-prog{flex:1;height:6px;background:var(--surface-2);border-radius:99px;overflow:hidden}
  .card-prog>span{display:block;height:100%;width:100%;transform-origin:left center;transform:scaleX(0);border-radius:99px;background:var(--break);transition:transform .5s ease} /* ALN-254: scaleX, not width, so the bar composites instead of triggering layout on every tick */
  .card.active .card-prog>span{background:var(--now)}.card.done .card-prog>span{background:var(--ok)}
  .card-stat{font-family:var(--font-mono);font-size:10.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;white-space:nowrap}
  .card-stat.up{color:var(--ink-soft)}.card-stat.now{color:var(--now)}.card-stat.done{color:var(--ok)}.card-stat.ended{color:var(--ink-soft)}
  .live-dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--now);margin-right:5px;animation:beat 2s infinite;vertical-align:middle}
  /* ALN-164: list rows carry no corner ticks either, provenance is the outlined --sc source chip on the row. */
  .list .row{position:relative;display:grid;grid-template-columns:100px 1fr auto;gap:18px;align-items:center;background:var(--surface);border:1px solid var(--hair-2);border-radius:13px;padding:14px 18px;margin-bottom:10px;box-shadow:0 1px 2px rgba(27,35,43,.05);cursor:pointer;transition:.15s;animation:rise .4s ease both}
  .list .row:hover{box-shadow:var(--shadow);transform:translateY(-1px)}
  .list .row.s-canvas{--c:var(--canvas)}.list .row.s-github{--c:var(--github)}.list .row.s-align{--c:var(--align)}.list .row.s-railway{--c:var(--railway)}.list .row.s-health{--c:var(--health)}.list .row.s-calendar{--c:var(--calendar)}.list .row.s-break{--c:var(--break)}
  .list .row.done{opacity:.62}
  .list .t{font-size:13px;color:var(--ink-soft);font-variant-numeric:tabular-nums;font-weight:600}
  /* ALN-164 follow-up: the inline source chip sits ON the title line, center it and give it room (was baseline-aligned + too tight).
     ALN-187: relieve the cramping, more room between title and its meta chip (gap), and a little vertical rhythm so the
     title, badge, and note line breathe instead of stacking flush against each other. */
  .list .mid{min-width:0}
  .list .mid .title{font-size:14.5px;font-weight:500;display:flex;align-items:center;gap:11px;flex-wrap:wrap;margin-bottom:4px}.list .row.s-break .title{font-style:italic;color:var(--ink-soft)}
  /* ALN-187: the source chip no longer hugs the title on the left, it sits at the right of the title line
     (aligned down the list, like the card view), so the meta reads as its own column instead of bunched leftward. */
  .list .mid .title .src{margin-left:auto}
  .list .mid .note{font-size:12px;color:var(--ink-soft);line-height:1.4}
  /* month */
  .month-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px;flex-wrap:wrap}
  /* Next-up banner (ALN-114): the "what now" answer, pinned above the grid; jumps to the day. */
  .month-next{display:flex;align-items:center;gap:11px;width:100%;margin:0 0 16px;padding:12px 15px;border:1px solid var(--hair);border-radius:var(--r-md);background:var(--surface);box-shadow:var(--shadow);cursor:pointer;font:inherit;color:inherit;text-align:left;transition:border-color .15s,box-shadow .15s,transform .15s}
  .month-next:hover{border-color:var(--ink-faint);transform:translateY(-1px);box-shadow:var(--shadow-lg)}
  .month-next:focus-visible{outline:none;border-color:var(--now);box-shadow:var(--ring)}
  .month-next[hidden]{display:none}
  .mn-ey{font-family:var(--font-mono);font-size:10px;line-height:1;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft);font-weight:700;flex:0 0 auto}
  .mn-body{display:flex;align-items:center;gap:8px;min-width:0;flex:1}
  .mn-when{font-weight:600;color:var(--ink);flex:0 0 auto;white-space:nowrap}
  .mn-title{display:flex;align-items:center;gap:7px;min-width:0;color:var(--ink-soft)}
  .mn-tt{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .mn-none{color:var(--ink-soft)}
  .mn-go{margin-left:auto;color:var(--ink-faint);flex:0 0 auto;font-size:16px;line-height:1}
  /* Empty / new-user teaching (ALN-114): the bare grid taught nothing; give a calm path forward. */
  .month-empty{width:100%;margin:0 0 18px;padding:22px;border:1px solid var(--hair);border-radius:var(--r-lg);background:var(--surface);box-shadow:var(--shadow);text-align:center}
  .month-empty[hidden]{display:none}
  .mte-h{font-family:var(--font-display);font-size:19px;font-weight:600;color:var(--ink);margin:0 0 5px}
  .mte-p{color:var(--ink-soft);font-size:14px;max-width:46ch;margin:0 auto 15px;line-height:1.5}
  .mte-cta{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
  .month-nav{display:flex;align-items:center;gap:10px;position:relative}
  .month-right{display:flex;align-items:center;gap:10px;flex-wrap:wrap;justify-content:flex-end}
  .month-nav>button,.ag-nav>button{width:34px;height:34px;border-radius:10px;border:1px solid var(--hair);background:var(--surface);cursor:pointer;font-size:16px;color:var(--ink-soft);flex:none;display:inline-flex;align-items:center;justify-content:center}
  .month-nav>button:hover,.ag-nav>button:hover{border-color:var(--now);color:var(--ink)}
  .ag-nav>button[disabled]{opacity:.42;cursor:default}
  .ag-nav>button[disabled]:hover{border-color:var(--hair);color:var(--ink-soft)}
  .month-title{font-family:var(--font-display);font-size:21px;font-weight:500;min-width:160px;text-align:center;background:none;border:1px solid transparent;border-radius:10px;color:inherit;cursor:pointer;padding:4px 12px;display:inline-flex;align-items:center;justify-content:center;gap:7px}
  .month-title::after{content:"";display:inline-block;width:.8em;height:.8em;background:var(--ink-faint);vertical-align:-.06em;
    -webkit-mask:url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2024%2024'%3E%3Cpath%20d%3D'M11.9999%2013.1714L16.9497%208.22168L18.3639%209.63589L11.9999%2015.9999L5.63599%209.63589L7.0502%208.22168L11.9999%2013.1714Z'%2F%3E%3C%2Fsvg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2024%2024'%3E%3Cpath%20d%3D'M11.9999%2013.1714L16.9497%208.22168L18.3639%209.63589L11.9999%2015.9999L5.63599%209.63589L7.0502%208.22168L11.9999%2013.1714Z'%2F%3E%3C%2Fsvg%3E") center/contain no-repeat}
  .month-title:hover{border-color:var(--hair);color:var(--now)}
  .month-pop{position:absolute;top:46px;left:50%;transform:translateX(-50%);z-index:50;background:var(--surface);border:1px solid var(--hair);border-radius:14px;box-shadow:var(--shadow-lg);padding:14px;width:264px}
  .month-pop[hidden]{display:none}
  .mp-year{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
  .mp-year b{font-family:var(--font-display);font-size:16px;font-weight:500}
  .mp-year button{width:30px;height:30px;border-radius:8px;border:1px solid var(--hair);background:var(--surface);color:var(--ink-soft);cursor:pointer;font-size:15px}
  .mp-year button:hover{border-color:var(--now);color:var(--ink)}
  .mp-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
  .mp-grid button{font:inherit;font-size:13px;padding:9px 0;border-radius:9px;border:1px solid var(--hair-2);background:var(--surface-2);color:var(--ink-soft);cursor:pointer}
  .mp-grid button:hover{border-color:var(--now);color:var(--ink)}
  .mp-grid button.cur{background:var(--now);color:var(--on-now);border-color:var(--now);font-weight:600}
  .mp-today{margin-top:11px;text-align:center}
  .dow{display:grid;grid-template-columns:repeat(7,1fr);gap:8px;margin-bottom:8px}
  .dow span{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft);font-weight:600;text-align:center;min-width:0;overflow:hidden}
  .month-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:8px}
  .daycell{width:100%;min-width:0;overflow:hidden;background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-sm);min-height:100px;padding:8px;display:flex;flex-direction:column;gap:4px;cursor:pointer;transition:box-shadow .15s,border-color .15s,background .15s;box-shadow:0 1px 2px rgba(27,35,43,.04);font:inherit;color:inherit;text-align:left;-webkit-appearance:none;appearance:none}
  .daycell:hover{box-shadow:var(--shadow);border-color:var(--hair)}
  .daycell:focus-visible{outline:none;border-color:var(--now);box-shadow:var(--ring)}
  /* Load map (ALN-114): days with no events recede so the eye lands on where the load actually is. */
  .daycell.bare{background:color-mix(in srgb,var(--surface) 46%,transparent);border-color:color-mix(in srgb,var(--hair-2) 55%,transparent);box-shadow:none}
  /* ALN-237: past the sync horizon. A hatched fill says "not fetched" rather than the
     blank cell that used to read as "nothing scheduled"; the banner above the grid
     carries the words, so this is never colour-alone signalling. */
  /* ALN-280: was a diagonal hatch. "Not fetched yet" was already carried by TWO other cues,
     the dashed border here and renderHorizonNote's plain-language note above the grid, so the
     stripes were a redundant third. A flat tint keeps the provisional read without them. */
  .daycell.unsynced{background:color-mix(in srgb,var(--hair-2) 16%,transparent);border-style:dashed}
  .daycell.unsynced .dn{opacity:.62}
  .month-horizon{margin:0 0 10px;padding:9px 12px;border:1px dashed var(--hair);border-radius:var(--r-sm);background:var(--surface-2);color:var(--ink-soft);font-size:var(--fs-sm);line-height:1.45}
  .month-horizon[hidden]{display:none}
  .daycell.bare:hover{background:var(--surface);border-color:var(--hair);box-shadow:var(--shadow)}
  .daycell.empty{background:transparent;border:none;box-shadow:none;cursor:default;pointer-events:none}
  .daycell .dn{font-size:13px;font-weight:600;color:var(--ink-soft)}
  .daycell.has-hard .dn{color:var(--ink)}
  .daycell.today{border-color:var(--now);box-shadow:0 0 14px -3px var(--now-glow);background:radial-gradient(120% 130% at 50% 0%,color-mix(in srgb,var(--now) 15%,var(--surface)) 0%,var(--surface) 78%)}
  .daycell.today.bare{background:radial-gradient(120% 130% at 50% 0%,color-mix(in srgb,var(--now) 15%,var(--surface)) 0%,var(--surface) 78%);border-color:var(--now);box-shadow:0 0 14px -3px var(--now-glow)}
  .daycell.today .dn{color:var(--now-text)}
  .ev-list{display:flex;flex-direction:column;gap:4px;min-width:0}
  /* Month event chips (STYLE_GUIDE §6.4): channel-coloured tinted outline via --sc (Google per-account colours route through the same var, staying distinct per account). */
  /* Month event chip (ALN-114): source dot carries identity; title renders in readable ink (was tinted-on-tint, failed AA for canvas/align/calendar). */
  .ev{display:flex;align-items:center;gap:5px;font-size:11px;font-weight:600;border-radius:var(--r-xs);padding:2px 6px;line-height:1.4;max-width:100%;color:color-mix(in srgb,var(--sc,var(--break)) 32%,var(--ink));background:color-mix(in srgb,var(--sc,var(--break)) 12%,transparent);border:1px solid color-mix(in srgb,var(--sc,var(--break)) 30%,transparent)}
  .ev .ev-t{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
  .ev-dot{width:7px;height:7px;border-radius:50%;background:var(--sc,var(--break));flex:0 0 auto}
  .ev.canvas{--sc:var(--canvas)}.ev.github{--sc:var(--github)}.ev.align{--sc:var(--align)}.ev.railway{--sc:var(--railway)}.ev.calendar{--sc:var(--calendar)}.ev.health{--sc:var(--health)}
  .ev-more{font-size:11px;color:var(--ink-soft);font-weight:600;padding:0 2px}
  /* Compact mobile representation: source-dot cluster + count instead of one-letter clipped text (ALN-114) */
  .ev-dots{display:none;align-items:center;gap:3px;flex-wrap:wrap;margin-top:auto}
  .ev-dots .ev-dot{width:7px;height:7px}
  .ev-ct{margin-left:3px;font-size:11px;font-weight:700;color:var(--ink-soft);font-family:var(--font-mono)}
  /* ALN-37: Google Calendar per-account legend + connection swatch */
  .cal-legend{display:flex;flex-wrap:wrap;gap:8px 14px;margin-top:12px;padding:2px}
  .cal-leg{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--ink-soft)}
  .cal-leg i{width:11px;height:11px;border-radius:3px;flex:0 0 auto}
  .conn-swatch{width:10px;height:10px;border-radius:3px;display:inline-block;margin-right:7px;vertical-align:middle}
  /* ALN-39: connector catalogue */
  .cat-search{width:100%;padding:10px 12px;border-radius:var(--r-sm);border:1px solid var(--hair);background:var(--surface);color:var(--ink);font-size:15px;margin:2px 0 6px;box-sizing:border-box}
  .cat-body{max-height:54vh;overflow-y:auto;overflow-x:hidden;margin:0 -2px;padding:0 2px}
  .cat-cat{font-family:var(--font-mono);font-size:10.5px;text-transform:uppercase;letter-spacing:.12em;color:var(--ink-faint);font-weight:700;margin:12px 2px 6px}
  .cat-grid{display:grid;grid-template-columns:1fr;gap:8px}
  .cat-card{display:flex;align-items:center;gap:12px;width:100%;text-align:left;padding:10px 12px;border-radius:var(--r-md);border:1px solid var(--hair);background:var(--surface);cursor:pointer;color:inherit;font:inherit;transition:border-color .15s,box-shadow .15s}
  .cat-card:hover{border-color:var(--align)}
  .cat-logo{font-size:22px;flex:0 0 auto;line-height:1}
  .cat-main{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
  .cat-name{font-weight:650;font-size:14px;display:flex;align-items:center;gap:7px;flex-wrap:wrap}
  .cat-desc{font-size:12px;color:var(--ink-faint);line-height:1.35;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .cat-go{flex:0 0 auto;font-size:13px;font-weight:650;color:var(--align);white-space:nowrap}
  .cat-badge{font-family:var(--font-mono);font-size:9px;text-transform:uppercase;letter-spacing:.06em;font-weight:700;padding:1px 6px;border-radius:var(--r-xs);background:var(--hair);color:var(--ink-faint)}
  .cat-badge.ok{background:color-mix(in srgb,var(--ok) 16%,transparent);color:color-mix(in srgb,var(--ok) 55%,var(--ink))}
  @media (max-width:1100px){.month-grid,.dow{gap:6px}.daycell{min-height:96px;padding:7px}}
  /* Phone (ALN-114): chips clipped to one letter here, swap to a source-dot cluster + count, and bump nav arrows to the 44px touch floor. */
  @media (max-width:760px){.month-grid,.dow{gap:5px}.daycell{min-height:76px;padding:7px;border-radius:10px}.daycell .dn{font-size:12px}.dow span{font-size:10px}.month-nav>button{width:44px;height:44px}.ev-list{display:none}.ev-dots{display:flex}}
  @media (max-width:520px){.daycell{min-height:66px;border-radius:9px;padding:6px}.month-title{min-width:110px;font-size:18px}}
  /* detail sheet + quiz overlay */
  .sheet-bd{position:fixed;inset:0;background:rgba(27,35,43,.4);opacity:0;pointer-events:none;transition:.25s;z-index:70;display:grid;place-items:center;padding:20px}
  .sheet-bd.show{opacity:1;pointer-events:auto}
  /* ALN-66: no top spine, hairline border + the --hud-strength-gated cyan HUD frame (dark) + glow */
  /* ALN-72: the outer card rounds + clips so the scrollbar can't square its corners; an inner .sheet-body scrolls (mirrors .quiz). Brackets pulled to the inside corners so overflow:hidden doesn't clip them. */
  .sheet{--sh-edge:var(--now);--sh-glow:var(--now-glow);background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-lg);max-width:460px;width:100%;box-shadow:0 0 0 calc(var(--hud-strength) * 1px) var(--now),var(--shadow-lg);transform:translateY(14px);transition:.25s;overflow:hidden}
  .sheet-body{max-height:84vh;overflow-y:auto;padding:26px;border-radius:inherit}
  /* Detail sheets: the same crisp 2-corner chamfer as the NowCard (rim + steady neon glow) on dark HUD; calm rounded panel on light. Replaces the old .hud-frame corner brackets (ALN-118 follow-up).
     ALN-260: the rim gradient runs at 135deg, PERPENDICULAR to the NE/SW chamfer diagonal, which puts both chamfers at exactly 50% along it, and the highlight sits on that stop. At the old 150deg the highlight sat at the START (the NW corner), so the two chamfers, the whole point of the silhouette, measured 201 and 191 and the SW was the dimmest point on the sheet. Both now measure 218. Measured by sampling the rendered rim, not by eye: reordering the drop-shadows and softening the dark one were both tried first and changed nothing. */
  @container style(--hud-strength: 1){
    .sheet{padding:1.4px;border:0;box-shadow:none;background:linear-gradient(135deg,var(--sh-edge),color-mix(in srgb,var(--sh-edge) 55%,#fff) 50%,var(--sh-edge));clip-path:polygon(0 0,calc(100% - 20px) 0,100% 20px,100% 100%,20px 100%,0 calc(100% - 20px));filter:drop-shadow(0 0 18px var(--sh-glow)) drop-shadow(0 22px 44px rgba(0,0,0,.7))}
    .sheet-body{background:var(--surface);clip-path:polygon(0 0,calc(100% - 18px) 0,100% 18px,100% 100%,18px 100%,0 calc(100% - 18px))}
  }
  body.sheet-open{overflow:hidden}
  .sheet-bd.show .sheet{transform:none}
  .sheet h3{font-family:var(--font-display);font-weight:500;font-size:23px;letter-spacing:-.01em;margin:8px 0 4px;line-height:1.2}
  .sheet h3[contenteditable]{cursor:text;outline:none;border-radius:8px;padding:2px 6px;margin:8px -6px 4px;transition:box-shadow .15s}
  .sheet h3[contenteditable]:focus{box-shadow:inset 0 0 0 1px var(--now-soft)}
  .sheet h3[contenteditable]:empty::before{content:attr(data-ph);color:var(--ink-faint)}
  .sheet .meta-row{display:flex;align-items:center;gap:10px;color:var(--ink-soft);font-size:13.5px}
  .sheet .ctx{margin-top:14px;font-size:14px;color:var(--ink-soft);line-height:1.55}.sheet .ctx b{color:var(--ink)}
  .sheet .prog{height:7px;background:var(--surface-2);border-radius:99px;margin-top:16px;overflow:hidden}.sheet .prog>span{display:block;height:100%;background:var(--now);border-radius:99px}
  .sheet-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:20px}
  .day-ev{display:flex;align-items:center;gap:10px;padding:10px 0;border-top:1px solid var(--hair-2)}.day-ev:first-of-type{border-top:none}
  .day-ev .x{margin-left:auto;cursor:pointer;color:var(--ink-faint);font-size:17px;flex:none;line-height:1;border:0;background:none;font-family:inherit;padding:0}.day-ev .x:hover{color:var(--warn)}
  .day-ev .x.confirm{font-size:11.5px;font-weight:700;color:var(--warn);line-height:1.1;padding:2px 7px;border-radius:var(--r-xs);background:color-mix(in srgb,var(--warn) 12%,transparent)}
  .sheet-form{display:flex;flex-direction:column;gap:12px;margin-top:14px}
  /* ALN-138: schedule-import preview (confirm before the bulk add) */
  .imp-sub{font-size:13px;color:var(--ink-soft);margin:2px 0 12px}
  .imp-note{font-size:12.5px;color:var(--ink-soft);background:var(--surface-2);border:1px solid var(--hair-2);border-radius:9px;padding:8px 11px;margin:2px 0 8px} /* assumed-term note (ALN-219) */
  .imp-list{display:flex;flex-direction:column;gap:8px;max-height:44vh;overflow-y:auto;margin:0 -4px;padding:0 4px}
  .imp-hint{font-size:12px;color:var(--ink-faint);margin:0 0 8px}
  /* A row is a toggle (ALN-260): full-width, left-aligned, and it must not inherit
     the button reset's centring or its own text would jump when it turns off. */
  .imp-row{background:var(--surface-2);border:1px solid var(--hair);border-radius:var(--r-sm);padding:10px 12px;width:100%;text-align:left;font:inherit;color:inherit;cursor:pointer;transition:opacity var(--dur) var(--ease),border-color var(--dur) var(--ease),background var(--dur) var(--ease)}
  .imp-row:hover{border-color:var(--hair-lit)}
  .imp-row:focus-visible{outline:none;box-shadow:var(--ring)}
  /* Left out: dimmed and struck, but still readable and still in place, so the list
     never reflows under the finger and the row stays clickable to put it back. */
  .imp-row.off{opacity:.45;background:transparent;border-style:dashed}
  .imp-row.off .imp-title{text-decoration:line-through}
  .imp-undo{margin-left:auto}
  .imp-title{font-size:14.5px;font-weight:600;color:var(--ink)}
  .imp-meta{font-size:12.5px;color:var(--ink-soft);margin-top:3px}
  .ff{display:flex;flex-direction:column;gap:5px;font-size:12px;font-weight:600;color:var(--ink-soft)}
  .ff input,.ff select{font:inherit;font-size:14.5px;font-weight:400;color:var(--ink);background:var(--surface-2);border:1px solid var(--hair);border-radius:var(--r-sm);padding:10px 12px}
  .ff select{background-color:var(--surface-2);background-image:var(--select-chevron);background-repeat:no-repeat;background-position:right 10px center;-webkit-appearance:none;appearance:none;padding:10px 30px 10px 12px;cursor:pointer}
  .ff input:focus,.ff select:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .ff-row{display:flex;gap:10px}.ff-row .ff{flex:1;min-width:0}
  .me-add{display:flex;gap:8px;align-items:center;margin-top:16px;padding-top:14px;border-top:1px solid var(--hair-2)}
  .me-add #meTitle{flex:1;min-width:0;font:inherit;font-size:14px;color:var(--ink);background:var(--surface-2);border:1px solid var(--hair);border-radius:10px;padding:10px 12px}
  .me-add #meTitle:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .me-add #meAdd{flex:none;font:inherit;font-size:13px;font-weight:600;color:var(--on-now);background:var(--now);border:none;border-radius:10px;padding:10px 16px;cursor:pointer}
  .me-add #meAdd:hover{filter:brightness(.96)}
  /* ALN-112: progressive "Time & details" disclosure on the month day-sheet, and the shared parity form */
  .em-toggle{display:inline-flex;align-items:center;gap:7px;margin-top:10px;margin-left:-4px;font:inherit;font-size:12.5px;font-weight:600;color:var(--ink-soft);background:none;border:none;padding:5px 4px;border-radius:7px;cursor:pointer}
  .em-toggle:hover{color:var(--now)}
  .em-toggle:focus-visible{outline:none;box-shadow:0 0 0 3px var(--now-glow)}
  .em-toggle .chev{font-size:10px;color:var(--ink-faint);transition:transform .18s ease}
  .em-toggle:hover .chev,.em-toggle[aria-expanded="true"] .chev{color:var(--now)}
  .em-toggle[aria-expanded="true"] .chev{transform:rotate(180deg)}
  .em-details{margin-top:12px}
  .em-details[hidden]{display:none}
  .em-custom[hidden]{display:none}
  /* ALN-120: repeat/multi-day controls, the custom-interval row + "repeat until" reveal on demand */
  .em-rep-custom[hidden],.em-rep-until[hidden]{display:none}
  .em-rep-until{margin-top:10px}
  .em-presets{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
  .em-presets button{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.02em;padding:6px 10px;border-radius:var(--r-xs);border:1px solid var(--hair);background:var(--surface-2);color:var(--ink-soft);cursor:pointer;transition:border-color .15s,color .15s}
  .em-presets button:hover{border-color:var(--now);color:var(--ink)}
  .em-presets button:focus-visible{outline:none;box-shadow:0 0 0 3px var(--now-glow)}
  /* ALN-236: weekday picker for a week-stepped repeat + the plain-language rule note.
     Seven equal targets read as ONE control; the pressed state carries a border + fill +
     weight, never colour alone (the provenance rule applies to state too). */
  .em-wd-wrap{margin-top:10px}
  .em-wd-wrap[hidden]{display:none}
  .em-wd-wrap .ff-sub,.em-when-wrap .ff-sub{display:block;font-family:var(--font-mono);font-size:var(--fs-xs);font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft);margin-bottom:6px}
  .em-wd{display:grid;grid-template-columns:repeat(7,1fr);gap:6px}
  .em-wd button{min-height:44px;font-family:var(--font-mono);font-size:var(--fs-sm);font-weight:600;border-radius:var(--r-xs);border:1px solid var(--hair);background:var(--surface-2);color:var(--ink-soft);cursor:pointer;transition:border-color .15s,color .15s,background .15s}
  .em-wd button:hover{border-color:var(--now);color:var(--ink)}
  .em-wd button:focus-visible{outline:none;box-shadow:0 0 0 3px var(--now-glow)}
  .em-wd button[aria-pressed="true"]{border-color:var(--now);background:var(--now);color:var(--on-now);font-weight:700}
  .em-rep-note{margin-top:8px;font-size:var(--fs-sm);line-height:1.45;color:var(--ink-soft)}
  .em-rep-note:empty{display:none}
  /* ALN-242: the When control. Three mutually exclusive answers about an event's time,
     in the ALN-236 weekday-picker vocabulary (one control, 44px targets, pressed state
     carried by border + fill + weight, never colour alone). Sits above the time row it
     governs, so the cause is read before the effect. */
  .em-when-wrap{margin-bottom:2px}
  .em-when{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
  .em-when button{min-height:44px;padding:0 6px;font:inherit;font-size:var(--fs-sm);font-weight:600;border-radius:var(--r-xs);border:1px solid var(--hair);background:var(--surface-2);color:var(--ink-soft);cursor:pointer;transition:border-color .15s,color .15s,background .15s}
  .em-when button:hover{border-color:var(--now);color:var(--ink)}
  .em-when button:focus-visible{outline:none;box-shadow:0 0 0 3px var(--now-glow)}
  .em-when button[aria-pressed="true"]{border-color:var(--now);background:var(--now);color:var(--on-now);font-weight:700}
  .em-timerow[hidden]{display:none}
  /* An event with no time picked yet is an open loop, not a settled all-day thing.
     A dashed rule UNDER the label reads as a blank still to be filled, which is what
     it is, and it says so without spending the amber signal. Deliberately not a
     border on the column: this box is 52px and holds 7-character labels, and taking
     even 8px for a rule and its padding wrapped "no time" onto two lines. */
  .day-ev .dv-when.dv-open .dv-ap{color:var(--ink-faint);border-bottom:1px dashed var(--hair);padding-bottom:2px}
  /* ── ALN-241: offline ─────────────────────────────────────────────────────────
     The pill is the quiet marker; the curtain is the full explanation, and it only
     appears when the app genuinely has nothing to show. Deliberately calm: this is
     not an error screen, it is a status report, and the brand mark sitting above it
     says the app is still itself rather than broken. */
  .offline-pill{color:var(--ink-soft)}
  /* The read-only bar (half B). Idle ochre, not the amber accent: this is the app
     reporting a state, and amber means "now" everywhere else (the One-Signal Rule). */
  .stale-bar{position:fixed;top:var(--topbar);left:0;right:0;z-index:39;display:flex;align-items:center;gap:9px;
    padding:9px 26px;font-size:var(--fs-sm);line-height:1.45;color:var(--ink);
    background:color-mix(in srgb,var(--idle) 13%,var(--surface));border-bottom:1px solid color-mix(in srgb,var(--idle) 45%,transparent)}
  .stale-bar[hidden]{display:none}
  .stale-bar b{font-weight:700}
  .sb-dot{flex:none;width:7px;height:7px;border-radius:50%;background:var(--idle)}
  /* The bar is fixed under the fixed top bar, so the things anchored to the top bar
     have to move down by its height while it is up, or it sits on top of the first
     row of the day. Driven by a body class (TL.offline) rather than by measuring. */
  body.stale-open .shell{margin-top:calc(var(--topbar) + var(--stale-h))}
  body.stale-open .drawer-inner{top:calc(var(--topbar) + var(--stale-h) + 14px)}
  body.stale-open .drawer-toggle{top:calc(var(--topbar) + var(--stale-h) + 22px)}
  :root{--stale-h:39px}
  @media (max-width:640px){ .stale-bar{padding:8px 14px} :root{--stale-h:56px} }
  .oc{position:fixed;inset:0;z-index:210;display:grid;place-items:center;padding:24px;
    background:var(--page-gradient,var(--mist));animation:searchIn .2s var(--ease-out) both}
  .oc[hidden]{display:none}
  .oc-panel{max-width:52ch;text-align:center;background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);padding:34px 32px 30px}
  .oc-mark{width:44px;height:44px;margin:0 auto 18px;display:block;overflow:visible}
  .oc-mark .bm-line{stroke:var(--ink-faint);stroke-width:1.7;stroke-linecap:round;opacity:.5}
  .oc-mark .bm-frame{fill:none;stroke:var(--now);stroke-width:2.1;stroke-linejoin:miter;stroke-linecap:butt}
  .oc-mark .bm-node{fill:var(--now)}
  .oc-head{font-family:var(--font-display);font-weight:500;font-size:var(--fs-h1);line-height:1.15;color:var(--ink);margin-bottom:11px;text-wrap:balance}
  .oc-body{font-size:var(--fs-body);line-height:1.6;color:var(--ink-soft);text-wrap:pretty}
  .oc-hint{margin-top:15px;font-family:var(--font-mono);font-size:var(--fs-xs);font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-faint)}
  .oc-hint:empty{display:none}
  .oc-retry{margin-top:20px;display:inline-flex;align-items:center;gap:7px;min-height:44px}
  .oc-retry[hidden]{display:none}
  @media (max-width:520px){ .oc-panel{padding:26px 20px 24px} }
  /* ── ALN-240: local search ────────────────────────────────────────────────────
     A command palette in the app's own instrument voice: hairline frame, mono
     provenance and time columns, one amber signal on the selected row. It sits high
     rather than centred, because the list grows downward and a centred panel would
     jump the input around as results arrive. <dialog> puts it in the top layer, so
     it needs no z-index and cannot be clipped by the fixed top bar. */
  /* The display MUST be scoped to [open]. A <dialog> is closed by the UA sheet's
     `dialog:not([open]){display:none}`, but author styles beat UA styles whatever the
     specificity, so an unconditional `display:flex` here re-showed the CLOSED dialog as
     an ordinary in-flow block at the end of <body>: the palette sat permanently at the
     bottom of every view, and showModal() then painted a second copy in the top layer. */
  .search-dlg{padding:0;border:1px solid var(--hair);border-radius:var(--r-lg);background:var(--surface);color:var(--ink);
    width:min(680px,calc(100vw - 32px));max-height:min(70vh,620px);margin:max(8vh,56px) auto auto;overflow:hidden;
    box-shadow:var(--shadow-lg);animation:searchIn .18s var(--ease-out) both}
  .search-dlg[open]{display:flex;flex-direction:column}
  .search-dlg::backdrop{background:rgba(27,35,43,.42);backdrop-filter:blur(3px)}
  @keyframes searchIn{from{opacity:0;transform:translateY(-8px) scale(.99)}to{opacity:1;transform:none}}
  .search-head{display:flex;align-items:center;gap:11px;padding:14px 16px;border-bottom:1px solid var(--hair-2);flex:none}
  .search-ic{flex:none;display:flex;color:var(--ink-faint)}.search-ic .ic{width:18px;height:18px}
  .search-input{flex:1;min-width:0;font:inherit;font-size:var(--fs-h3);color:var(--ink);background:none;border:none;outline:none;padding:2px 0}
  .search-input::placeholder{color:var(--ink-soft);opacity:1}   /* never a faint grey (PRODUCT.md a11y floor) */
  .search-count{flex:none;font-family:var(--font-mono);font-size:var(--fs-xs);font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-faint);white-space:nowrap}
  .search-results{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:6px}
  .sr-row{display:flex;align-items:flex-start;gap:12px;width:100%;text-align:left;font:inherit;cursor:pointer;
    padding:10px 10px;border:1px solid transparent;border-radius:var(--r-sm);background:none;color:inherit}
  .sr-row:hover{background:var(--surface-2)}
  /* Selected state is a full ring plus a fill, never a side stripe: the accent frames
     the row it is naming rather than growing a bar beside it. */
  .sr-row.on{background:var(--surface-2);border-color:var(--now-soft);box-shadow:inset 0 0 0 1px var(--now-soft),0 0 14px -8px var(--now-glow)}
  .sr-row:focus-visible{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .sr-row>.src{flex:none;margin-top:2px;width:74px;text-align:center;overflow:hidden;text-overflow:ellipsis}
  /* The kind lives on the group heading, so a row never repeats it. */
  .sr-group+.sr-group{margin-top:4px}
  .sr-ghead{display:flex;align-items:center;gap:7px;padding:9px 11px 5px;font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-faint)}
  .sr-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
  .sr-title{font-size:var(--fs-body);font-weight:500;color:var(--ink);overflow-wrap:anywhere}
  .sr-title.sr-done{color:var(--ink-soft);text-decoration:line-through}
  .sr-snip{font-size:var(--fs-sm);line-height:1.45;color:var(--ink-soft);display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .sr-field{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-faint);margin-right:7px}
  .sr-when{flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:3px;padding-top:1px;text-align:right}
  .sr-date{font-family:var(--font-mono);font-size:var(--fs-xs);font-weight:700;font-variant-numeric:tabular-nums;color:var(--ink);white-space:nowrap}
  .sr-date.sr-undated{color:var(--ink-faint);font-weight:600}
  .sr-time{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft);white-space:nowrap}
  .sr-empty{padding:26px 18px 30px;max-width:58ch}
  .sr-empty-h{font-size:var(--fs-h3);font-weight:600;color:var(--ink);margin-bottom:7px}
  .sr-empty p{font-size:var(--fs-body);line-height:1.55;color:var(--ink-soft)}
  .search-foot{flex:none;display:flex;align-items:center;gap:14px;flex-wrap:wrap;padding:10px 16px;border-top:1px solid var(--hair-2);background:var(--surface-2)}
  .search-hint{display:flex;align-items:center;gap:5px;font-size:var(--fs-xs);color:var(--ink-soft)}
  .search-hint kbd{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;color:var(--ink-soft);background:var(--surface);border:1px solid var(--hair);border-bottom-width:2px;border-radius:var(--r-xs);padding:2px 5px;line-height:1.2}
  .search-note{margin-left:auto;font-size:var(--fs-xs);color:var(--ink-faint)}
  @media (max-width:640px){
    .search-dlg{width:calc(100vw - 16px);max-height:min(80vh,640px);margin-top:12px}
    .sr-kind{width:auto;flex-direction:row;align-items:center;gap:6px}
    .sr-row{flex-wrap:wrap;gap:7px}
    .sr-main{flex-basis:100%;order:3}
    .sr-when{margin-left:auto;flex-direction:row;align-items:baseline;gap:7px}
    .search-note{display:none}   /* the reassurance is nice-to-have; the key hints are not */
  }
  /* The series band on an occurrence's detail sheet: what it repeats as + the edit scope. */
  .ser-band{margin-top:12px;padding:11px 12px;border:1px solid var(--hair);border-radius:var(--r-sm);background:var(--surface-2)}
  .ser-rule{font-size:var(--fs-sm);line-height:1.45;color:var(--ink);display:flex;align-items:flex-start;gap:7px}
  .ser-rule .ic{color:var(--now);margin-top:.15em} /* the repeat icon carries the accent, not a side bar */
  .ser-scope{display:flex;align-items:center;gap:9px;margin-top:9px;flex-wrap:wrap}
  .ser-scope span{font-family:var(--font-mono);font-size:var(--fs-xs);font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft)}
  .ser-scope select{flex:1;min-width:170px;font:inherit;font-size:var(--fs-ui);color:var(--ink);background-color:var(--surface);border:1px solid var(--hair);border-radius:var(--r-xs);padding:8px 28px 8px 10px;min-height:40px;background-image:var(--select-chevron);background-repeat:no-repeat;background-position:right 10px center;-webkit-appearance:none;appearance:none}
  .ser-scope select:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .ser-actions{flex-wrap:wrap}
  .ed-when{margin-top:14px}
  .meta-row .mr-when{font-family:var(--font-mono);font-weight:700;font-variant-numeric:tabular-nums;color:var(--ink)}
  .ff-opt{font-family:var(--font-mono);font-size:9px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-soft);margin-left:7px}
  .day-ev .t{font-size:14.5px;font-weight:500}
  a.day-ev .t,.day-ev a.t{color:var(--ink);text-decoration:none}.day-ev a.t:hover{text-decoration:underline;color:var(--now)}
  .day-ev .ev-meta{margin-left:auto;font-size:var(--fs-xs);color:var(--ink-faint);flex:none;white-space:nowrap}
  .day-ev .ev-open{font:inherit;font-size:14.5px;font-weight:500;color:var(--ink);background:none;border:none;padding:0;cursor:pointer;text-align:left;min-width:0;word-break:break-word}.day-ev .ev-open:hover{color:var(--now)}
  .ev-clip{font-size:12px;opacity:.65;margin-left:2px}
  /* ── ALN-64: typed connection cards (event/task/status; events expand to detail) ── */
  #sourcesBody .card.ev-card{cursor:pointer}
  /* ALN-164: with the corner ticks gone, the connection event cards get more vertical
     rhythm so the eyebrow, title, time block, prep row, and actions breathe. Scoped to
     .ev-card so the dense plan grid cards keep their compact spacing. */
  .ev-card{padding-bottom:15px}
  .ev-card .card-top{margin-bottom:11px}
  .ev-card .card-title{margin-bottom:10px;line-height:1.3}
  .ev-card .timeblock{margin:0 0 10px}
  .ev-card .getready{margin-bottom:10px}
  .ev-card .cd-foot{margin-top:6px}
  .card .c-type{font-family:var(--font-mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;font-weight:700;color:var(--ink-faint)}
  .card .c-chev{margin-left:auto;color:var(--ink-faint);font-size:11px;transition:transform .2s}
  .card.open .c-chev{transform:rotate(180deg)}
  .card .cd-foot{display:flex;align-items:center;gap:8px;margin-top:2px}
  .timeblock{display:flex;align-items:center;gap:11px;background:var(--now-tint);border:1px solid var(--now-soft);border-radius:var(--r-sm);padding:9px 12px;margin:2px 0 4px}
  .timeblock .tl{font-size:10px;color:var(--now-text);letter-spacing:.05em;text-transform:uppercase;font-weight:700;margin-bottom:3px}
  .timeblock .tt{font-family:var(--font-mono);font-size:17px;font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:-.01em;color:var(--ink);line-height:1}
  .timeblock .tt small{font-size:11px;font-weight:700;margin-left:1px}
  .timeblock .dur{margin-left:auto;font-size:11px;color:var(--ink-faint);font-variant-numeric:tabular-nums}
  .getready{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-xs);font-weight:600;line-height:1;color:var(--idle);background:color-mix(in srgb,var(--idle) 12%,transparent);border:1px solid color-mix(in srgb,var(--idle) 34%,transparent);border-radius:var(--r-xs);padding:4px 8px;margin-bottom:2px}
  .getready .gr-ic{display:inline-flex;align-items:center;justify-content:center;line-height:1;font-size:1.08em;flex:none}
  /* On the NowCard the title is an inline-block <button>, so the camera-ready pill dropped onto its own line needs breathing room below the 25px title. */
  .now-card .getready{position:relative;z-index:1;margin-top:10px}
  .statuspill{display:inline-flex;align-items:center;gap:6px;font-family:var(--font-mono);font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:3px 9px;border-radius:var(--r-pill);white-space:nowrap;color:var(--sc,var(--now));background:color-mix(in srgb,var(--sc,var(--now)) 12%,transparent);border:1px solid color-mix(in srgb,var(--sc,var(--now)) 40%,transparent)}
  .statuspill.st-in_progress{--sc:var(--idle)}.statuspill.st-open{--sc:var(--now)}.statuspill.st-assigned{--sc:var(--health)}.statuspill.st-blocked{--sc:var(--warn)}
  .cd-join{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;color:var(--on-now);background:var(--now);border:none;border-radius:var(--r-xs);padding:6px 12px;cursor:pointer;text-decoration:none}
  .cd-avatars{display:inline-flex;align-items:center;margin-left:2px}
  .cd-avatars .av{width:22px;height:22px;border-radius:50%;border:1.5px solid var(--surface);margin-left:-6px;font-size:9px;font-weight:700;display:grid;place-items:center;color:#fff}.cd-avatars .av:first-child{margin-left:0}
  .cd-detail{border-top:1px dashed var(--hair-2);margin-top:6px;padding-top:11px;display:flex;flex-direction:column;gap:9px}
  .cd-detail[hidden]{display:none}
  .cd-row{display:flex;gap:9px;font-size:12px;color:var(--ink-soft);align-items:flex-start;line-height:1.45}
  /* ALN-245: the row mark is an <svg class="ic cd-ic"> now, not a glyph in a span, so
     it sizes itself (1em) and only needs the accent colour and a baseline nudge to sit
     with the first line of wrapped text. */
  .cd-row .cd-ic{color:var(--now);margin-top:.16em}
  .cd-row a{color:var(--now);word-break:break-word}
  .cd-cta{display:flex;flex-wrap:wrap;gap:8px;margin-top:2px}
  .assist-btn{display:inline-flex;align-items:center;gap:6px;font:inherit;font-size:12px;font-weight:600;color:var(--on-now);background:var(--now);border:none;border-radius:var(--r-sm);padding:8px 12px;cursor:pointer}
  .assist-btn .tdot{width:5px;height:5px;background:var(--on-ink);box-shadow:none}
  /* ── ALN-64: timed month-day rows (real times + get-ready + join; preserves ALN-30/37) ── */
  .day-ev{align-items:flex-start}
  .day-ev .dv-when{flex:none;width:52px;text-align:right;padding-top:1px}
  .day-ev .dv-when .dv-h{display:block;font-family:var(--font-mono);font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--ink);line-height:1.15}
  .day-ev .dv-when .dv-ap{font-size:9.5px;color:var(--ink-soft);letter-spacing:.06em;font-weight:700;text-transform:uppercase}
  .day-ev .dv-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}
  .day-ev .dv-line{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
  .day-ev .dv-body .ev-meta{margin-left:0}
  .readyline{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-xs);font-weight:600;color:var(--idle);background:color-mix(in srgb,var(--idle) 11%,transparent);border:1px solid color-mix(in srgb,var(--idle) 28%,transparent);border-radius:var(--r-xs);padding:3px 8px;align-self:flex-start}
  /* ═══ ALN-239 agenda ("Ahead"): the middle horizon, a day-grouped list ═══════════
     Rows deliberately reuse the Month day-sheet language (.day-ev / .dv-when /
     .dv-body / .readyline above), so one event reads identically wherever you meet
     it and this block only has to style the day GROUPING. */
  .mode-off{display:none!important}                    /* the grid and the agenda are alternatives; beats the inline display the legend sets */
  .agenda{display:flex;flex-direction:column;gap:6px}
  .ag-bar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:0 0 12px}
  /* The window stepper. Same control vocabulary as the month nav (shared rule below), so
     paging a span feels like paging a month. */
  .ag-nav{display:flex;align-items:center;gap:8px}
  .ag-range{font-family:var(--font-mono);font-size:12.5px;font-weight:600;color:var(--ink);letter-spacing:.02em;min-width:11ch;text-align:center}
  .ag-now{font-size:12.5px}
  .ag-none{color:var(--ink-soft);font-size:14px;padding:14px 2px;max-width:62ch}
  /* ONE opaque surface behind the whole list, not a stack of cards: the page's dot field
     (ALN-139) reads straight through a transparent list and makes small text muddy, and an
     opaque panel is the fix that also keeps the day rhythm on hairlines. */
  .ag-list{display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-md);overflow:hidden}
  .ag-day{padding:13px 14px 6px;border-top:1px solid var(--hair-2)}
  .ag-day:first-child{border-top:none}
  .ag-day.is-clear{padding-bottom:13px}                /* one line, so the group carries its own breathing room */
  .ag-head{display:flex;align-items:baseline;gap:9px;margin:0 0 6px;font-family:var(--font-display);font-size:16px;font-weight:600;letter-spacing:.01em;color:var(--ink)}
  .ag-day.is-clear .ag-head{margin-bottom:0}
  .ag-day-date{font-family:var(--font-mono);font-size:11.5px;font-weight:600;color:var(--ink-soft);letter-spacing:.03em}
  /* The scan column: read straight down the right edge to get the shape of the week. Uses
     the app's own .label voice (mono, tracked, uppercase) since it IS a status marker, at
     --ink-soft so it clears AA rather than whispering at 3.9:1 like --ink-faint did. */
  .ag-count{margin-left:auto;font-family:var(--font-mono);font-size:11px;font-weight:600;color:var(--ink-soft);text-transform:uppercase;letter-spacing:.12em;white-space:nowrap}
  /* Today anchors the list: a FLAT tinted band (--now-tint, the token the palettes already
     carry), not a gradient and not a coloured edge. --now-text for the type, since the
     accent exists in a text-safe shade per palette and raw --now is 2.5:1 in light. */
  .ag-day.is-today{background:var(--now-tint)}
  .ag-day.is-today .ag-head{color:var(--now-text)}
  .ag-day.is-today .ag-count{color:var(--now-text)}
  .ag-day.is-clear .ag-day-name{color:var(--ink-soft)}
  /* Tighter rows than the day sheet's: this surface is for SCANNING a week, and the
     sheet's air costs a whole extra day of scrolling here. */
  .agenda .day-ev{padding:7px 0;align-items:flex-start}
  .agenda .day-ev .dv-when{padding-top:2px}
  .agenda .day-ev:first-of-type{border-top:1px solid var(--hair-2)}   /* the head is not a row, so the first row keeps its rule */
  .agenda .ag-check{color:var(--ok);display:inline-flex;align-items:center}
  /* De-emphasis, not illegibility: a done row and the "Plan" tag are secondary, so they sit
     at --ink-soft rather than --ink-faint, which whispers at ~4:1 on the HUD palettes. */
  .agenda .ag-is-done .t{text-decoration:line-through;color:var(--ink-soft)}
  .agenda .ev-meta{color:var(--ink-soft)}
  @media (max-width:760px){.ag-head{font-size:14px}.ag-count{font-size:10px}.ag-day{padding-left:11px;padding-right:11px}.ag-nav>button{width:44px;height:44px}.ag-bar{gap:10px}}
  .joininline{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:700;color:var(--now);text-decoration:none}.joininline:hover{text-decoration:underline}
  .day-sub{font-size:12.5px;color:var(--ink-soft);margin:2px 0 6px}
  .freefoot{margin-top:14px;font-size:12px;color:var(--ink-soft);display:flex;align-items:center;gap:7px;padding-top:12px;border-top:1px dashed var(--hair-2)}
  /* notes & attachments on blocks / events (ALN-30) */
  .ff textarea{font:inherit;font-size:14.5px;font-weight:400;color:var(--ink);background:var(--surface-2);border:1px solid var(--hair);border-radius:var(--r-sm);padding:10px 12px;resize:vertical;min-height:44px;line-height:1.5;width:100%;box-sizing:border-box}
  .ff textarea:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .sheet-note{margin-top:16px}
  /* ALN-271: collapsed by default when empty (the summary is the whole widget), so the add
     form is not permanent furniture under every reflection. Same disclosure shape as the
     blocked-users card: title, count, caret that flips on [open]. */
  .attachments{margin-top:16px}
  .att-summary{display:flex;align-items:center;gap:8px;cursor:pointer;list-style:none;padding:3px 2px;user-select:none;border-radius:var(--r-sm)}
  .att-summary::-webkit-details-marker{display:none}
  .att-summary:hover .att-label,.att-summary:hover .att-caret{color:var(--ink-soft)}
  .att-summary:focus-visible{outline:2px solid var(--now);outline-offset:2px}
  .att-label{font-size:12px;font-weight:600;color:var(--ink-soft)}
  .att-count{min-width:17px;height:17px;padding:0 5px;border-radius:9px;background:var(--surface-2);border:1px solid var(--hair-2);color:var(--ink-soft);font-size:10.5px;font-weight:700;line-height:15px;text-align:center}
  .att-count[hidden]{display:none}
  .att-caret{width:15px;height:15px;color:var(--ink-faint);margin-left:auto;transition:transform .18s}
  .attachments[open] .att-caret{transform:rotate(180deg)}
  .att-open{padding-top:6px}
  .att-empty{font-size:13px;color:var(--ink-faint);padding:2px 0 4px}
  .att-row{display:flex;align-items:center;gap:8px;padding:7px 0;border-top:1px solid var(--hair-2)}.att-row:first-of-type{border-top:none}
  .att-ic{flex:none}
  .att-name{font-size:14px;color:var(--ink);text-decoration:none;min-width:0;overflow-wrap:anywhere}
  a.att-name:hover{color:var(--now);text-decoration:underline}
  .att-size{font-size:var(--fs-xs);color:var(--ink-faint);flex:none;white-space:nowrap}
  .att-del{margin-left:auto;flex:none;background:none;border:none;cursor:pointer;color:var(--ink-faint);font-size:18px;line-height:1;padding:0 2px}.att-del:hover{color:var(--warn)}
  /* One row, one control height, same as the today-controls row (ALN-263). */
  .att-add{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:10px;--control-h:44px}
  .att-add input{flex:1;min-width:150px;font:inherit;font-size:13.5px;color:var(--ink);background:var(--surface-2);border:1px solid var(--hair);border-radius:10px;padding:9px 11px;min-height:var(--control-h)}
  .att-add input:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  /* "Add link" and the file picker do the same job as the input they sit beside, so
     they have to read as pressable. Both were `.link`, which is bare accent text with
     no surface and no border, and against a filled input they did not look like
     buttons at all. The file one is a <label> wrapping a hidden input, which is why
     it needs the same treatment spelled out rather than inheriting a button class.
     Scoped through .att-add so it outranks `.link`, which declares the bare-text look
     160 lines further down and would otherwise win on source order at equal weight.
     ALN-271: they are neutral, not accent. Two accent-coloured controls sitting beside a
     plain input read as the loudest thing in the reflection card, and neither is the primary
     action there (writing the reflection is). The border still carries the pressable read. */
  .att-add .att-link-add,.att-add .att-file{flex:none;font-size:12.5px;font-weight:600;color:var(--ink-soft);background:var(--surface);border:1px solid var(--hair);border-radius:10px;padding:0 14px;min-height:var(--control-h);cursor:pointer;white-space:nowrap;transition:border-color .15s,background .15s,color .15s}
  .att-add .att-link-add:hover,.att-add .att-file:hover{color:var(--ink);border-color:var(--ink-faint);background:var(--surface-2);text-decoration:none}
  .att-hint{font-size:var(--fs-xs);color:var(--ink-faint);margin-top:8px}
  /* quiz */
  .quiz-bd{position:fixed;inset:0;background:rgba(27,35,43,.55);opacity:0;pointer-events:none;transition:.25s;z-index:90;display:grid;place-items:center;padding:20px}
  .quiz-bd.show{opacity:1;pointer-events:auto}
  .quiz{background:var(--surface);border-radius:22px;max-width:600px;width:100%;max-height:88vh;display:flex;flex-direction:column;box-shadow:var(--shadow-lg);overflow:hidden;transform:translateY(16px);transition:.25s}
  .quiz-bd.show .quiz{transform:none}
  .quiz-h{padding:22px 26px 14px;border-bottom:1px solid var(--hair-2)}
  .quiz-h h3{font-family:var(--font-display);font-weight:500;font-size:23px;letter-spacing:-.01em}
  .quiz-h p{font-size:13.5px;color:var(--ink-soft);margin-top:4px}
  .quiz-body{overflow-y:auto;padding:10px 26px}
  .qitem{padding:15px 0;border-top:1px solid var(--hair-2)}.qitem:first-child{border-top:none}
  .qitem .qtext{font-size:14.5px;margin-bottom:9px}
  .likert{display:flex;gap:6px}
  .likert label{flex:1;position:relative;text-align:center;font-size:11px;color:var(--ink-soft);cursor:pointer}
  .likert input{position:absolute;opacity:0;width:1px;height:1px;margin:0;pointer-events:none}
  .likert .dot{display:block;height:30px;border-radius:9px;border:1.5px solid var(--hair);margin-bottom:4px;transition:.12s;background:var(--surface)}
  .likert input:checked+.dot{background:var(--now);border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .likert label:hover .dot{border-color:var(--now)}
  .likert input:focus-visible+.dot{border-color:var(--now);box-shadow:var(--ring)}
  .quiz-f{padding:16px 26px;border-top:1px solid var(--hair-2);display:flex;align-items:center;justify-content:space-between;gap:10px}
  .quiz-f .prog-text{font-size:12.5px;color:var(--ink-faint)}
  /* result */
  .result h2{font-family:var(--font-display);font-size:30px;font-weight:500;letter-spacing:-.015em;color:var(--now)}
  .result .desc{font-size:15px;color:var(--ink-soft);margin:6px 0 18px;line-height:1.55}
  .pbar{margin:11px 0}
  .pbar .pl{display:flex;justify-content:space-between;font-size:12px;color:var(--ink-soft);margin-bottom:4px}
  .pbar .track{height:8px;background:var(--surface-2);border-radius:99px;position:relative;overflow:hidden}
  .pbar .track>span{position:absolute;top:0;bottom:0;background:var(--align);border-radius:99px}
  .pbar.center .track::before{content:"";position:absolute;left:50%;top:-2px;bottom:-2px;width:1px;background:var(--hair)}
  .secondary{font-size:13px;color:var(--ink-faint);margin-top:14px}
  .ac-warn{font-size:12.5px;color:var(--warn);margin-top:10px}
  /* persona card in admin */
  .persona-card{background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--radius);padding:20px 22px;box-shadow:var(--shadow);margin-bottom:34px;display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap}
  .persona-card .pc-name{font-family:var(--font-display);font-size:20px;font-weight:500}
  .persona-card .pc-desc{font-size:13px;color:var(--ink-soft);margin-top:3px;max-width:46ch}
  .persona-card .pc-tag{font-size:11px;color:var(--ink-soft);font-weight:700;letter-spacing:.06em;text-transform:uppercase}
  /* routines / admin (shared) */
  .routine-tabs{display:flex;gap:8px;margin-bottom:20px;flex-wrap:wrap}
  .rt{font:inherit;font-size:13px;color:var(--ink-soft);background:var(--surface);border:1px solid var(--hair);border-radius:999px;padding:8px 16px;cursor:pointer}.rt.active{background:var(--now-tint);color:var(--now-deep);border-color:var(--now);box-shadow:var(--glow-soft)}
  .rt-add{border-style:dashed;color:var(--ink-soft);font-weight:600}.rt-add:hover{background:var(--now-tint)}
  .routine-card{background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--radius);padding:8px;box-shadow:var(--shadow)}
  .routine-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:10px 14px 4px;flex-wrap:wrap} /* ALN-34: the name + Delete/Done wrap instead of pushing Done off-screen on a phone */
  .routine-head .rname{font-family:var(--font-display);font-size:19px;font-weight:500;min-width:0}
  .rname-input{font:inherit;font-size:16px;font-weight:600;color:var(--ink);background:var(--surface-2);border:1px solid var(--hair);border-radius:9px;padding:7px 11px;flex:1;min-width:0;max-width:320px}
  .rname-input:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .edit-items{display:flex;flex-direction:column;gap:8px;padding:8px 14px 14px}
  .edit-item{display:flex;gap:8px;align-items:center}
  .edit-item.add{margin-top:6px;padding-top:12px;border-top:1px dashed var(--hair)}
  .ei-label,.ei-sub{font:inherit;font-size:14px;color:var(--ink);background:var(--surface);border:1px solid var(--hair);border-radius:9px;padding:8px 11px}
  .ei-label{flex:1.4;min-width:0}.ei-sub{flex:1;color:var(--ink-soft);min-width:0} /* ALN-34: shrink so the row + Add button never overflow on a phone */
  @media (max-width:460px){.edit-item{flex-wrap:wrap}.ei-label{flex:1 1 100%}} /* stack the note under the step on narrow screens */
  .ei-label:focus,.ei-sub:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .ei-del{flex:none;width:32px;height:34px;border-radius:9px;border:1px solid var(--hair);background:var(--surface);color:var(--ink-faint);font-size:17px;cursor:pointer}.ei-del:hover{border-color:var(--warn);color:var(--warn)}
  .ei-add{flex:none;font:inherit;font-size:13px;font-weight:600;color:var(--on-now);background:var(--now);border:none;border-radius:9px;padding:8px 14px;cursor:pointer}.ei-add:hover{filter:brightness(.96)}
  .progress{height:6px;background:var(--surface-2);border-radius:99px;margin:14px 16px 6px;overflow:hidden}.progress>span{display:block;height:100%;background:var(--now);border-radius:99px;width:0;transition:width .4s ease;box-shadow:0 0 8px -1px var(--now)} /* ALN-254: deliberately NOT scaleX. box-shadow scales with the transform, so the amber glow would squash to nothing at low fill. Kept on width, like .drawer. */
  .checkitem{display:flex;align-items:center;gap:13px;padding:14px 16px;border-radius:12px;cursor:pointer;border:0;background:transparent;width:100%;text-align:left;font:inherit;color:inherit}.checkitem:focus-visible{outline:none;box-shadow:var(--ring)}.checkitem:hover{background:var(--surface-2)}
  .box{width:24px;height:24px;border-radius:var(--r-xs);border:2px solid var(--hair);flex:none;display:grid;place-items:center;transition:.18s;color:var(--on-ink);font-size:14px}
  .checkitem.done .box{background:var(--ok);border-color:var(--ok);box-shadow:0 0 10px -2px var(--ok)}.checkitem.done .ci-label{color:var(--ink-faint);text-decoration:line-through}
  .ci-label{display:block;font-size:15px;font-weight:500}.ci-sub{display:block;font-size:12px;color:var(--ink-faint);margin-top:1px}
  .rt[data-r]{user-select:none}
  .rt-time{margin-left:7px;font-size:11px;opacity:.72;font-variant-numeric:tabular-nums}
  .rt-dragging{opacity:.4}
  .rt-drop{box-shadow:inset 0 0 0 2px var(--now)}
  .routine-time{display:flex;align-items:center;gap:9px;flex-wrap:wrap;padding:4px 14px 8px}
  .rtime-label{font-size:12.5px;font-weight:600;color:var(--ink-soft)}
  .rtime{font:inherit;font-size:13px;color:var(--ink);background:var(--surface-2);border:1px solid var(--hair);border-radius:8px;padding:5px 8px;font-variant-numeric:tabular-nums}
  .rtime:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .rtime-dash{color:var(--ink-faint)}
  .rtime-hint{font-size:var(--fs-xs);color:var(--ink-faint)}
  .rtime-chip{margin-left:10px;font-size:12px;font-weight:600;color:var(--ink-soft);background:var(--surface-2);border:1px solid var(--hair);border-radius:999px;padding:2px 9px;vertical-align:middle;font-variant-numeric:tabular-nums}
  .routine-done{padding:22px 18px;text-align:center;color:var(--ok);font-size:15px;font-weight:500;display:none}.routine-done.show{display:block;animation:rise .4s ease}
  .conn-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:12px;margin-bottom:34px}
  /* ALN-254: `rise` is gated on .is-entering, which only the view-enter render sets.
     It used to sit on .conn unconditionally, and renderConn() rebuilds #connGrid by
     replacing innerHTML, so every card replayed its entrance on EVERY repaint: the
     30s ALN-161 poll tick, an assistant call resolving, or any toggle. A screen of
     cards animating on a timer is the Breathing-Now Rule inverted. Cards are visible
     by default and the animation only adds to that, so a missed .is-entering can
     never leave the grid blank. */
  .conn{background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-md);padding:16px;display:flex;flex-direction:column;gap:9px;box-shadow:var(--shadow);overflow:hidden}
  .conn-grid.is-entering .conn{animation:rise .4s ease both}
  .conn-head{display:flex;align-items:center;justify-content:space-between;gap:8px}.conn-name{font-size:15px;font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .badge{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;padding:2px 8px;border-radius:var(--r-xs);flex-shrink:0;white-space:nowrap}.badge.on{background:rgba(67,133,110,.16);color:#2f6353}.badge.off{background:var(--surface-2);color:var(--ink-faint)}.badge.setup{background:rgba(194,144,47,.18);color:#8a6720}
  .conn-desc{font-size:12.5px;color:var(--ink-soft);min-height:32px}.conn-kind{font-size:var(--fs-xs);color:var(--ink-faint)}
  .conn-foot{display:flex;align-items:center;justify-content:space-between}
  /* ALN-243: per-calendar visibility. One row per calendar Google shows, each with
     its accent, its NAME (hue is never the only signal) and its own switch. Capped
     in height with a scroll rather than growing the card without limit, since an
     account can carry up to the ALN-238 breadth budget of 25 calendars. */
  /* ALN-254: the cap is relative, not a fixed 170px. At 200% text zoom a fixed px
     cap turns the list into a peephole, since the rows grow and the box does not. */
  /* `overflow:hidden auto`, not `overflow-y:auto`: setting one axis makes the other
     compute from `visible` to `auto`, so a horizontal scrollbar could appear on a list
     whose names already truncate with an ellipsis. Nothing to scroll to. */
  .conn-cals{display:flex;flex-direction:column;max-height:min(44vh,270px);overflow:hidden auto;margin:-2px 0}
  /* 44px rows, so each row's hit target meets the PRODUCT.md floor AND adjacent
     targets tile exactly instead of overlapping (the reason .sm was 34px before). */
  .conn-cal{display:flex;align-items:center;gap:2px;min-height:44px;min-width:0}
  .conn-cal-name{font-size:12.5px;color:var(--ink-soft);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  /* A smaller switch for a list of them. The knob geometry is re-derived, not
     inherited: .switch::after is sized for the 42x24 control and would overflow
     this one. The ::before hit expander (inherited from .switch) is re-derived too,
     taking this 36x20 control to a full 44x44 target inside its 44px row. */
  .switch.sm{width:36px;height:20px}
  .switch.sm::after{width:14px;height:14px}.switch.sm.on::after{transform:translateX(18px)}
  .switch.sm::before{inset:-12px -4px}
  /* ALN-161: at-a-glance connection health. The badge + dot carry the semantic
     colour (pine ok / ochre idle / clay warn / muted neutral); the reason stays
     calm ink-soft so the surface never shouts. Amber (--now) is untouched, it
     stays the One-Signal accent, so "Live" no longer steals it. */
  /* Theme-adaptive: the tint is the palette's own semantic hue, and the text
     colour crossfades from a dark shade (AA on the light surface) to the bright
     token (AA on the dark HUD surface) via --hud-strength (0 light / 1 dark). */
  .badge.st-ok{background:color-mix(in srgb,var(--ok) 16%,transparent);color:color-mix(in srgb,var(--ok) 55%,var(--ink))}
  .badge.st-idle{background:color-mix(in srgb,var(--idle) 18%,transparent);color:color-mix(in srgb,var(--idle) 55%,var(--ink))}
  .badge.st-warn{background:color-mix(in srgb,var(--warn) 17%,transparent);color:color-mix(in srgb,var(--warn) 55%,var(--ink))}
  .badge.st-neutral{background:var(--surface-2);color:var(--ink-soft)}
  .conn-status{display:flex;align-items:flex-start;gap:7px;font-size:var(--fs-xs);line-height:1.4;color:var(--ink-soft)}
  .conn-status .st-dot{width:7px;height:7px;margin-top:4px;border-radius:50%;flex-shrink:0;background:var(--ink-faint)}
  .conn-status.st-ok .st-dot{background:var(--ok)}
  .conn-status.st-idle .st-dot{background:var(--idle)}
  .conn-status.st-warn .st-dot{background:var(--warn)}
  .conn-status .st-text{min-width:0}
  .st-since{color:var(--ink-faint)}
  .st-details{align-self:flex-start;background:none;border:0;padding:4px 0;margin:-4px 0 0;display:inline-flex;align-items:center;gap:3px;min-height:24px;font-family:var(--font-mono);font-size:10px;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-faint);cursor:pointer} /* ALN-254: 10px text with padding:0 was a ~12px target, under WCAG 2.5.8; the negative margin absorbs the new padding so the row does not move */
  .st-details:hover{color:var(--ink-soft)}
  .st-raw{margin:2px 0 0;padding:8px 10px;background:var(--surface-2);border:1px solid var(--hair-2);border-radius:var(--r-xs);font-family:var(--font-mono);font-size:10.5px;line-height:1.45;color:var(--ink-soft);white-space:pre-wrap;overflow-wrap:anywhere;max-height:120px;overflow:auto}
  .conn-status.is-checking .st-dot{animation:st-pulse 1.3s ease-in-out infinite}
  @keyframes st-pulse{0%,100%{opacity:1}50%{opacity:.3}}
  @media (prefers-reduced-motion:reduce){.conn-status.is-checking .st-dot{animation:none}}
  .ai-card .conn-foot.ai-foot{gap:10px;margin-top:1px}
  /* ALN-273 follow-up: this holds a sentence ("Health from your real calls."), so it is body
     copy and belongs on --fs-xs. --fs-micro is the mono-uppercase-label step, not a text size. */
  .conn-kind-sm{font-size:var(--fs-xs);color:var(--ink-faint);line-height:1.4;min-width:0}
  .ai-check{flex-shrink:0;font-weight:600}
  .add-conn{font:inherit;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;min-height:118px;background:transparent;border:1.5px dashed var(--hair);border-radius:var(--r-md);color:var(--ink-soft);cursor:pointer;font-size:13.5px;font-weight:600;transition:.15s}
  .add-conn:hover{border-color:var(--now);color:var(--ink);background:var(--now-tint)}
  .add-conn .ac-plus{font-size:22px;line-height:1;color:var(--ink-soft)}
  .addform{display:flex;flex-direction:column;gap:12px;margin-top:16px}
  .addform label{display:flex;flex-direction:column;gap:5px;font-size:12.5px;font-weight:600;color:var(--ink-soft)}
  .addform input{font:inherit;font-size:14px;color:var(--ink);background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-sm);padding:10px 12px;font-weight:400}
  .addform input:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .ac-err{font-size:12.5px;color:var(--warn);min-height:0}
  .ac-hint{display:block;font-size:var(--fs-xs);color:var(--ink-faint);margin-top:4px}.ac-hint a{color:var(--now);text-decoration:none}.ac-hint a:hover{text-decoration:underline}
  .ac-disco{font-size:var(--fs-xs);line-height:1.45;background:var(--surface);border:1px solid var(--hair-2);border-radius:10px;padding:10px;max-height:220px;overflow:auto;white-space:pre-wrap;word-break:break-word;color:var(--ink-soft);margin:0}
  /* ALN-254: the OFF border is --ink-faint, not --hair. A hairline is a divider and
     measures ~1.5:1 against surface, so an off switch was effectively invisible while
     the on state passed: the control read as present-when-on and absent-when-off,
     backwards for a "hidden calendar" affordance. WCAG 1.4.11 wants 3:1 for a control
     that carries state; --ink-faint now clears 4.4:1 in every palette.
     The ::before is an invisible hit expander taking the target to 44x44 (the
     PRODUCT.md floor); the control itself stays 42x24 so nothing moves visually. */
  .switch{width:42px;height:24px;padding:0;flex:none;appearance:none;font:inherit;border-radius:99px;background:var(--mist-2);position:relative;cursor:pointer;transition:.2s;border:1px solid var(--ink-faint)}.switch.on{background:var(--ok);border-color:var(--ok)}.switch:focus-visible{outline:none;box-shadow:var(--ring)}
  .switch::before{content:"";position:absolute;inset:-10px -1px;border-radius:99px}
  .switch::after{content:"";position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;background:#fff;transition:.2s;box-shadow:0 1px 2px rgba(0,0,0,.2)}.switch.on::after{transform:translateX(18px)}
  /* ALN-254: a bare text button rendered ~15px tall, under WCAG 2.5.8's 24x24 floor,
     and the 24px-spacing exception did not rescue Re-auth / Remove (they sit in a
     gap:12px row). The padding is vertical only, so nothing shifts horizontally. */
  /* ALN-275: a secondary text action is not a primary action, a selection or a live state,
     so it does not get the accent. It gains a resting underline in exchange: colour was the
     only thing marking it clickable, and dropping both would delete the affordance. */
  .link{font-size:12.5px;color:var(--ink-soft);cursor:pointer;font-weight:600;background:none;border:none;font-family:inherit;display:inline-flex;align-items:center;min-height:24px;padding:2px 0;text-decoration:underline;text-decoration-color:var(--hair-lit);text-underline-offset:3px}.link:hover{color:var(--ink);text-decoration-color:currentColor}
  .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0} /* visually hidden, SR-announced (ALN-217) */
  .sync-pill{font-family:var(--font-mono);font-size:9.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:color-mix(in srgb,var(--warn) 55%,var(--ink));background:color-mix(in srgb,var(--warn) 14%,transparent);border:1px solid color-mix(in srgb,var(--warn) 30%,transparent);border-radius:999px;padding:4px 9px;white-space:nowrap;line-height:1.35} /* saving trouble, quiet not nagging (ALN-218) */
  /* ── App settings shell (ALN-288) ────────────────────────────────────────────
     Ten sections used to be one 4,314px scroll with every section open, the two
     you set once at the top, and no index. They are now an index plus one panel.
     Desktop is two-pane; at ≤860 the index IS the page and a section pushes a
     full screen over it. Owned by client/src/settingsnav.mjs; the sections hold
     the same DOM the feature modules already render into. */
  /* Settings is the one view that earns more than the 820px reading column: the
     index takes the width that used to hold nothing, and the panel keeps roughly
     the measure the rows were designed at. Every other view is unaffected. */
  main:has(#admin.active){max-width:1040px}
  .stg{display:flex;gap:34px;align-items:flex-start}
  .stg-nav{flex:0 0 210px;display:flex;flex-direction:column;gap:2px;position:sticky;top:calc(var(--topbar) + 26px)}
  /* Opted out of the centring primitive above (ALN-263), like .cw-menu-item: this is
     a navigation row, not an icon-then-label button, and its own layout is stated here. */
  .stg-item{display:flex;align-items:center;justify-content:flex-start;gap:10px;width:100%;text-align:left;font:inherit;font-size:var(--fs-ui);
    color:var(--ink-soft);background:transparent;border:1px solid transparent;border-radius:var(--r-sm);
    padding:9px 11px;min-height:40px;cursor:pointer;transition:color .15s,background .15s}
  .stg-item:hover{color:var(--ink);background:var(--surface-2)}
  .stg-item[aria-selected="true"]{background:var(--surface);border-color:var(--hair-2);color:var(--ink);font-weight:600;box-shadow:var(--shadow)}
  .stg-item:focus-visible{outline:none;box-shadow:var(--ring)}
  .stg-item .stg-sum,.stg-item .ic{display:none}          /* desktop index carries the name only */
  .stg-body{flex:1;min-width:0}
  .stg-sec[hidden]{display:none}
  .stg-sec>.h:first-child{margin-top:0}
  /* The section a search hit landed on. Held for ~1.6s by settingsnav, so it does
     not depend on an animation that reduced motion would suppress. */
  .stg-flash{border-radius:var(--r-sm);box-shadow:var(--ring)}
  /* Back out of a pushed section. A real control, not a text link: surface fill,
     hairline border, pill, 40px tall, so it reads as a button on a phone. */
  .stg-back{display:none;align-items:center;gap:7px;min-height:40px;padding:8px 15px 8px 11px;margin:0 0 18px;
    font:inherit;font-size:var(--fs-ui);font-weight:600;color:var(--ink-soft);background:var(--surface);
    border:1px solid var(--hair);border-radius:var(--r-pill);box-shadow:var(--shadow);cursor:pointer;
    transition:color .15s,border-color .15s}
  .stg-back:hover{color:var(--ink);border-color:var(--ink-faint)}
  .stg-back:focus-visible{outline:none;box-shadow:var(--ring)}
  .stg-back svg{width:17px;height:17px;flex:none}
  @media (prefers-reduced-motion:reduce){.stg-item,.stg-back{transition:none}}
  /* Phone (ALN-288 round 2, option P1): the index IS the page, and choosing a
     section pushes a full screen over it. Not the desktop two-pane squeezed into
     390px, which is what the first mock got wrong. Rows are 56px with the current
     value on the right, so the list answers "how is this set" without a tap. */
  @media (max-width:860px){
    .stg{display:block}
    .stg-nav{position:static;gap:0;background:var(--surface);border:1px solid var(--hair-2);
      border-radius:var(--r-md);box-shadow:var(--shadow);overflow:hidden}
    .stg-item{border:0;border-top:1px solid var(--hair-2);border-radius:0;min-height:56px;
      padding:15px 16px;font-size:var(--fs-body);color:var(--ink);font-weight:500}
    .stg-item:first-child{border-top:0}
    .stg-item[aria-selected="true"]{background:transparent;border-color:transparent;box-shadow:none}
    .stg-item .stg-name{flex:none}
    .stg-item .stg-sum{display:block;margin-left:auto;font-size:var(--fs-sm);color:var(--ink-faint);
      text-align:right;max-width:50%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
    .stg-item .ic{display:block;width:17px;height:17px;color:var(--ink-faint);flex:none}
    .stg.is-detail .stg-nav{display:none}
    .stg:not(.is-detail) .stg-body{display:none}
    .stg.is-detail .stg-back{display:inline-flex}
  }
  .settings{background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--radius);padding:8px 24px;box-shadow:var(--shadow);margin-bottom:34px}
  .set-row{display:flex;align-items:center;justify-content:space-between;gap:18px;padding:16px 0;border-top:1px solid var(--hair-2);flex-wrap:wrap}.set-row:first-child{border-top:none} /* ALN-32: controls wrap below the label instead of overflowing on narrow screens */
  .set-row .meta{flex:1;min-width:190px}.set-row .meta .n{font-size:14.5px;font-weight:500}.set-row .meta .d{font-size:12.5px;color:var(--ink-faint);margin-top:2px}
  /* ALN-298: the row description doubles as the refused-write narrator while the latch is
     held, so it lifts off --ink-faint. This is TEXT at 12.5px, so the floor is 4.5:1, not
     the 3:1 the ALN-297 mark mix was tuned for: that mix measures 4.06:1 here and fails.
     Pulled further toward --ink it reads 6.08:1 on light and 8.9:1+ on the dark families. */
  .set-row .meta .d.held{color:color-mix(in srgb,var(--idle) 55%,var(--ink))}
  .set-row input[type=range]{width:150px;max-width:100%;accent-color:var(--now)}
  /* ALN-188: assistant action permissions, the confirm card + the settings list */
  .agent-confirm{border:1px solid var(--hair);border-radius:var(--r-md);padding:11px 13px;margin-top:6px;background:var(--surface)}
  .agent-confirm.external{border-color:var(--warn)}
  .agent-confirm .ac-head{font-weight:600;font-size:14px;margin-bottom:5px;color:var(--ink)}
  .agent-confirm .ac-item{font-size:13px;margin:4px 0}
  .agent-confirm .ac-input{color:var(--ink-faint);font-size:12px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre-wrap;word-break:break-word;margin-top:2px}
  .agent-confirm .ac-btns{display:flex;gap:16px;margin-top:9px;align-items:center}
  .agent-confirm .ac-btns .ac-skip{color:var(--ink-faint)}
  .ac-remember{margin-top:10px;padding-top:9px;border-top:1px solid var(--hair-2)}
  .ac-remember .ac-rem-q{font-size:12.5px;color:var(--ink-soft);margin-bottom:6px}
  .ac-remember .ac-rem-q code{font-size:12px}
  .ac-remember .ac-rem-btns{display:flex;gap:16px;flex-wrap:wrap;align-items:center}
  .ac-remember .ac-not{color:var(--ink-faint)}
  .ac-remember .ac-rem-done{font-size:12.5px;color:var(--ok)}
  .ac-remember .ac-rem-done .link{color:var(--now)}
  .perm-list{border-top:1px solid var(--hair-2);padding:16px 0}
  .perm-list-head{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-faint);font-weight:700;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;margin-bottom:9px}
  .perm-note{font-size:12.5px;color:var(--ink-soft);margin-bottom:8px}
  .perm-empty{font-size:12.5px;color:var(--ink-faint);line-height:1.5}
  .perm-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 0}
  .perm-row+.perm-row{border-top:1px solid var(--hair-2)}
  .perm-meta{display:flex;align-items:center;gap:9px;min-width:0;flex-wrap:wrap}
  .perm-meta code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12.5px;background:var(--surface-2);padding:1px 6px;border-radius:5px;color:var(--ink)}
  .perm-src{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-faint);font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
  .perm-revoke{color:var(--ink-faint)}.perm-revoke:hover{color:var(--warn)}
  .val{font-variant-numeric:tabular-nums;font-size:13px;color:var(--ink-soft);min-width:60px;text-align:right}
  .tz-select{font:inherit;font-size:13.5px;color:var(--ink);background-color:var(--surface-2);border:1px solid var(--hair);border-radius:9px;padding:9px 29px 9px 11px;cursor:pointer;max-width:240px;background-image:var(--select-chevron);background-repeat:no-repeat;background-position:right 10px center;-webkit-appearance:none;appearance:none}
  .tz-select:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  /* ALN-165 (redesigned): the prep-preset library, compact rows you click to edit, one labelled editor at a time. */
  .set-prep{padding-bottom:2px}
  .prep-presets{display:flex;flex-direction:column;gap:8px;width:100%;margin:6px 0 4px}
  .prep-builtin{display:flex;align-items:baseline;gap:8px 12px;flex-wrap:wrap;padding:2px 2px 11px;border-bottom:1px dashed var(--hair)}
  .prep-name-static{font-size:14px;font-weight:600;color:var(--ink);display:inline-flex;align-items:center;gap:7px}
  .prep-tag{font-size:9.5px;text-transform:uppercase;letter-spacing:.07em;font-weight:700;color:var(--ink-faint);border:1px solid var(--hair);border-radius:5px;padding:1px 6px}
  .prep-builtin-meta{font-size:12.5px;color:var(--ink-faint)}
  .prep-summary{display:flex;align-items:center;gap:12px;width:100%;text-align:left;font:inherit;background:var(--surface-2);border:1px solid var(--hair);border-radius:10px;padding:11px 14px;cursor:pointer;transition:border-color .15s,background .15s}
  .prep-summary:hover{border-color:var(--now-soft);background:var(--surface)}
  .prep-summary:focus-visible{outline:2px solid var(--now);outline-offset:2px}
  .prep-sum-name{font-size:14px;font-weight:600;color:var(--ink);white-space:nowrap}
  .prep-sum-meta{font-size:12.5px;color:var(--ink-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .prep-sum-go{margin-left:auto;font-size:12px;font-weight:600;color:var(--now);white-space:nowrap}
  .prep-edit{display:flex;flex-direction:column;gap:13px;background:var(--surface-2);border:1px solid var(--now-soft);border-radius:11px;padding:15px}
  .prep-field{display:flex;flex-direction:column;gap:6px}
  .prep-field>label{font-size:12px;font-weight:600;color:var(--ink-soft)}
  .prep-field input{font:inherit;font-size:14px;color:var(--ink);background:var(--surface);border:1px solid var(--hair);border-radius:9px;padding:9px 11px;width:100%}
  .prep-field input:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .prep-lead-row{display:flex;align-items:center;gap:10px}
  .prep-lead-row input{width:84px;text-align:center;flex:none}
  .prep-unit{font-size:13px;color:var(--ink-soft)}
  .prep-opt{font-weight:400;font-size:11px;color:var(--ink-faint);margin-left:7px}
  .prep-help{font-size:var(--fs-xs);color:var(--ink-faint);line-height:1.45}
  .prep-edit-actions{display:flex;align-items:center;gap:9px;margin-top:2px}
  .prep-btn{font:inherit;font-size:13px;font-weight:600;border-radius:9px;padding:9px 16px;cursor:pointer;border:1px solid var(--hair);background:var(--surface);color:var(--ink-soft)}
  .prep-btn:hover{border-color:var(--now-soft);color:var(--ink)}
  .prep-save{margin-left:auto;color:var(--now);border-color:var(--now-soft)}
  .prep-save:hover{background:var(--now-tint);border-color:var(--now)}
  .prep-remove{color:var(--warn);border-color:transparent;background:transparent}
  .prep-remove:hover{border-color:var(--warn);color:var(--warn)}
  .prep-add-btn{align-self:flex-start;font:inherit;font-size:13px;font-weight:600;color:var(--ink-soft);background:transparent;border:1px dashed var(--hair-2);border-radius:9px;padding:10px 15px;cursor:pointer;transition:border-color .15s,background .15s}
  .prep-add-btn:hover{border-color:var(--now);background:var(--surface-2)}
  .adv-panel{background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--radius);padding:18px 22px;box-shadow:var(--shadow);margin-bottom:34px}
  .cgroup{margin-bottom:14px}
  .cgroup>h5{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-faint);font-weight:700;margin:0 0 9px}
  .cgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(204px,1fr));gap:8px}
  .cpick{display:flex;align-items:center;gap:10px;font-size:12.5px;color:var(--ink-soft);background:var(--surface-2);border:1px solid var(--hair-2);border-radius:10px;padding:7px 10px}
  .cpick .cl{display:flex;flex-direction:column;line-height:1.25;min-width:0}
  .cpick .cl b{font-size:12.5px;font-weight:600;color:var(--ink)}
  .cpick .cl i{font-size:10.5px;font-style:normal;color:var(--ink-faint)}
  .fgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px}
  .fpick{display:flex;flex-direction:column;gap:5px;font-size:12px;font-weight:600;color:var(--ink-soft)}
  .fpick select{font:inherit;font-size:14px;font-weight:400;color:var(--ink);background-color:var(--surface);border:1px solid var(--hair);border-radius:9px;padding:9px 29px 9px 11px;cursor:pointer;background-image:var(--select-chevron);background-repeat:no-repeat;background-position:right 10px center;-webkit-appearance:none;appearance:none}
  .fpick select:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .edit-hint{font-size:12px;color:var(--ink-faint)}
  .tpl.editing{border-color:var(--now);box-shadow:0 0 0 2px var(--now-glow)}
  .cpick input[type=color]{-webkit-appearance:none;appearance:none;width:26px;height:26px;border:none;border-radius:7px;background:none;cursor:pointer;padding:0;flex:none}
  .cpick input[type=color]::-webkit-color-swatch-wrapper{padding:0}
  .cpick input[type=color]::-webkit-color-swatch{border:1px solid var(--hair);border-radius:7px}
  .adv-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:14px;padding-top:14px;border-top:1px solid var(--hair-2)}
  .adv-actions input[type=text]{font:inherit;font-size:13px;color:var(--ink);background:var(--surface-2);border:1px solid var(--hair);border-radius:9px;padding:8px 11px;flex:1;min-width:140px}
  .adv-actions input[type=text]:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .tpl{position:relative;background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-md);padding:14px 15px;box-shadow:var(--shadow);display:flex;flex-direction:column;gap:8px}
  .tpl.applied{border-color:var(--now-soft);background:var(--now-tint)}                 /* ALN-162: the equipped template, selected fill + amber edge */
  .tpl-badge{position:absolute;top:10px;right:11px;font-family:var(--font-mono);font-size:9px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:var(--now-deep);background:var(--surface);border:1px solid var(--now-soft);padding:2px 7px;border-radius:100px}
  .tpl-inuse{font-size:12.5px;font-weight:600;color:var(--now-deep)}
  .tpl .swatches{display:flex;gap:5px}.tpl .sw{width:18px;height:18px;border-radius:5px;border:1px solid var(--hair)}
  .tpl-name{font-size:14.5px;font-weight:600}
  /* ALN-276: .tpl.applied fills with --now-tint, where --ink-faint measured 3.63:1.
     --ink-soft is 5.36:1 on that fill. */
  .tpl-base{font-size:var(--fs-xs);color:var(--ink-soft)}
  .tpl-foot{display:flex;align-items:center;justify-content:space-between;margin-top:2px}
  /* ALN-162: which look is currently applied + the de-equip control (populated by theme.mjs) */
  .theme-active{display:flex;align-items:center;gap:11px;flex-wrap:wrap;margin:14px 0 20px;padding:11px 14px;background:var(--surface-2);border:1px solid var(--hair-2);border-radius:var(--r-sm)}
  .theme-active .ta-k{font-family:var(--font-mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint);flex:none}
  .theme-active .ta-v{font-size:13.5px;font-weight:600;color:var(--ink)}
  .theme-active .ta-revert{margin-left:auto;flex:none}
  /* ALN-274: the toast has an AMBER border but used to inherit a CYAN halo from --shadow-lg,
     which is the semantic inversion in miniature. --glow-hazard was defined in every palette
     and used nowhere; this is what it was named for. */
  .toast{position:fixed;right:24px;bottom:24px;max-width:330px;background:var(--surface);border:1px solid color-mix(in srgb,var(--idle) 50%,transparent);border-radius:var(--r-md);box-shadow:var(--glow-hazard),var(--shadow-lg);padding:16px 18px;z-index:80;transform:translateY(20px);opacity:0;pointer-events:none;transition:.3s}
  .toast.show{transform:none;opacity:1;pointer-events:auto}
  .toast .toast-title{font-size:14.5px;margin-bottom:4px;font-weight:600;color:var(--ink)}.toast p{font-size:13px;color:var(--ink-soft);margin-bottom:12px;line-height:1.45}.toast .row2{display:flex;gap:7px}.toast .btn{font-size:12px;padding:6px 11px}
  .snackbar{position:fixed;left:50%;bottom:24px;transform:translate(-50%,20px);display:flex;align-items:center;gap:14px;max-width:min(92vw,440px);background:var(--surface);border:1px solid var(--now-soft);border-radius:var(--r-md);box-shadow:var(--shadow-lg);padding:10px 12px 10px 16px;z-index:85;opacity:0;pointer-events:none;transition:.25s}
  .snackbar.show{transform:translate(-50%,0);opacity:1;pointer-events:auto}
  .snackbar .sb-msg{font-size:13px;color:var(--ink-soft);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .snackbar .sb-undo{font-size:12.5px;padding:6px 12px;flex:none}
  @media (max-width:860px){:root{--drawer:88vw}.drawer,.drawer.open{width:0}.drawer-inner{left:50%;right:auto;width:min(92vw,460px);top:auto;bottom:calc(var(--botnav-h) + 20px + env(safe-area-inset-bottom));max-height:calc(100dvh - var(--topbar) - var(--botnav-h) - 52px);box-shadow:var(--shadow-lg);z-index:30;transform:translate(-50%,calc(100% + var(--botnav-h) + 36px + env(safe-area-inset-bottom)))}.drawer.open .drawer-inner{transform:translate(-50%,0)}body.drawer-open .backdrop{opacity:1;pointer-events:auto}main{padding:24px 18px calc(var(--botnav-h) + 22px + env(safe-area-inset-bottom)) 18px}}
  /* ALN-167 compact-mode nav (floating dock + de-crammed top bar) lives in ONE block at
     the END of the stylesheet, so it wins the cascade over the later base rules it overrides
     (.topbar-right / .notif-bell / the bottom-anchored toasts). Search "ALN-167 compact". */
  /* ALN-34: iOS Safari zooms the page (and shifts/clips the layout) whenever a
     focused field is < 16px. Pin every text field to 16px on phone widths so
     focusing the composer, a routine step, or an auth input never zooms. */
  @media (max-width:640px){ input:not([type=range]),select,textarea{font-size:16px !important} }
  /* ALN-273: on phones the drawer also loses the bottom nav's height, and the composer wraps
     to two rows (the rule below), so the space above it shrinks again. */
  @media (max-width:860px){ .quick-pop{max-height:min(560px,calc(100dvh - var(--topbar) - var(--botnav-h) - 190px))} }
  /* ALN-202: on phones the composer wraps so the textarea is full-width (never squeezed/cut off) and the actions sit on a row below. */
  @media (max-width:640px){ .composer{flex-wrap:wrap} .composer textarea{order:-1;flex:1 1 100%;min-height:46px} .composer .send{margin-left:auto} }
  /* Window-size awareness: the brand + notifications + profile stay reachable at
     any width; the clock, email and (last) the brand text give way first, and
     the tabs shrink before anything on the right is ever pushed off-screen. */
  /* The 5-tab pill must stay fully visible (Sessions included): free space by
     dropping the clock, then the profile email, then the wordmark BEFORE the tabs
     would be forced to shrink + scroll. Only a true phone width scrolls them. */
  @media (max-width:1160px){ .uc-email{display:none} .profile-btn{padding:4px 6px} }
  @media (max-width:1000px){ .topbar{padding:0 16px} .topbar-right{gap:11px} .clock{display:none} }
  /* ALN-167: the wordmark used to collapse to just the spark at ≤860 to make room for the
     tabs; the tabs now live in the bottom bar, so the wordmark stays (see the compact block above). */
  @media (max-width:640px){
    /* Phone: the tab pill can now scroll (base rule) rather than clip; tighten it. */
    .topbar{padding:0 12px}
    .tab{padding:7px 10px;font-size:12.5px}
    .tabs{gap:2px;-webkit-overflow-scrolling:touch}
    .h{font-size:26px}
    /* ALN-203: a real small-screen layout for the day + month headers (title on its own line, controls in a clean row below) instead of the desktop row shrunk and wrapped. */
    .today-head,.month-head{flex-direction:column;align-items:stretch;gap:14px}
    .today-controls{width:100%;flex-wrap:wrap;gap:10px}
    .today-controls .date-nav{flex:1 1 100%}
    .today-controls .day-actions{margin-left:auto}
    .month-right{width:100%;justify-content:space-between;flex-wrap:wrap}
    .month-pop{left:auto;right:0;transform:none;width:min(264px,calc(100vw - 24px))}
    .today-head{gap:10px}
  }
  @media (max-width:380px){
    .topbar{padding:0 10px;gap:6px}
    .tabs{overflow-x:auto;-webkit-overflow-scrolling:touch}
  }
  /* topbar user chip */
  .topbar-right{display:flex;align-items:center;gap:14px;flex:none}
  .user-chip{display:flex;align-items:center;gap:9px}
  .uc-email{font-size:12.5px;color:var(--ink-soft);max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  /* profile menu */
  .profile{position:relative}
  .profile-btn{display:flex;align-items:center;gap:9px;background:transparent;border:1px solid transparent;border-radius:var(--r-sm);padding:4px 7px;cursor:pointer;color:var(--ink-soft);transition:.15s}
  .profile-btn:hover{background:var(--surface-2);border-color:var(--hair-2)}
  .pf-caret{color:var(--ink-faint);flex:none}
  .pf-avatar{width:28px;height:28px;border-radius:50%;background:var(--now);color:var(--on-now);font-family:var(--font-mono);font-weight:700;font-size:11px;display:flex;align-items:center;justify-content:center;text-transform:uppercase;flex:none;overflow:hidden;box-shadow:0 0 0 3px var(--now-glow)}
  .pf-avatar img{width:100%;height:100%;object-fit:cover;display:block}
  .pf-avatar-lg{width:40px;height:40px;font-size:16px}
  .pf-avatar-xl{width:84px;height:84px;font-size:30px}
  .profile-menu{position:absolute;top:calc(100% + 8px);right:0;min-width:230px;background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);padding:7px;z-index:60;animation:notifIn .16s ease both}
  .profile-menu[hidden]{display:none}
  .pm-head{display:flex;align-items:center;gap:11px;padding:9px 9px 11px;border-bottom:1px solid var(--hair);margin-bottom:6px}
  .pm-id{min-width:0}
  .pm-email{font-size:13px;font-weight:600;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:150px}
  .pm-role{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--now-text);margin-top:2px}
  .pm-item{display:block;width:100%;text-align:left;font:inherit;font-size:13.5px;color:var(--ink-soft);background:transparent;border:none;border-radius:var(--r-xs);padding:9px 10px;cursor:pointer;transition:.12s}
  .pm-item:hover{background:var(--surface-2);color:var(--ink)}
  .pm-sep{height:1px;background:var(--hair);margin:6px 4px}
  .pm-signout{color:var(--warn)}
  /* account view */
  .acct-card{display:flex;flex-direction:column;gap:16px;background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--radius,14px);padding:22px;margin-bottom:26px;max-width:560px}
  .acct-pic{display:flex;align-items:center;gap:20px;flex-wrap:wrap}
  .acct-pic-actions{display:flex;flex-direction:column;gap:8px;align-items:flex-start}
  .acct-hint{font-size:12px;color:var(--ink-faint)}
  .acct-field{display:flex;justify-content:space-between;gap:14px;border-top:1px solid var(--hair);padding-top:14px;flex-wrap:wrap} /* ALN-32: long values wrap below the label rather than overflow */
  .af-label{font-size:13px;color:var(--ink-faint)}
  .af-value{font-size:13px;color:var(--ink);font-weight:500;overflow-wrap:anywhere;min-width:0}
  .acct-input{display:flex;flex-direction:column;gap:5px}
  .acct-input span{font-size:12.5px;color:var(--ink-soft)}
  .acct-input input{font:inherit;font-size:14px;color:var(--ink);background:var(--surface-2);border:1px solid var(--hair-2);border-radius:11px;padding:11px 14px;max-width:320px}
  .acct-input input:focus{outline:none;border-color:var(--now)}
  /* ALN-160: theme the native select (e.g. Screen lock "Lock after"), it rendered as a
     white UA control, off-theme on every dark palette. appearance:none is required for the
     themed background to actually paint; a custom chevron replaces the native arrow. */
  .acct-input select{font:inherit;font-size:14px;color:var(--ink);background-color:var(--surface-2);background-image:var(--select-chevron);background-repeat:no-repeat;background-position:right 13px center;border:1px solid var(--hair);border-radius:11px;padding:11px 36px 11px 14px;max-width:320px;cursor:pointer;-webkit-appearance:none;appearance:none}
  .acct-input select:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .acct-input select:disabled{opacity:.5;cursor:not-allowed}
  .ai-status{font-size:13px;color:var(--ink-soft);padding:9px 12px;border:1px solid var(--hair-2);border-radius:10px;background:var(--surface-2)}
  .ai-status .dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:7px;background:var(--ink-faint);vertical-align:middle}
  .ai-status.ok .dot{background:var(--ok)}.ai-status.warn .dot{background:var(--warn)}
  .ai-adv summary{font-size:12.5px;color:var(--ink-soft);cursor:pointer;padding:2px 0}
  /* auth gate */
  .auth-bd{position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;padding:24px;
    background:radial-gradient(120% 90% at 100% 0%,var(--bg-top) 0%,var(--mist) 44%,var(--mist-2) 100%)}
  .auth-bd[hidden]{display:none}
  /* Animated login background (ALN-137): a full-bleed WebGL canvas injected by TL.authscene,
     behind the card. Absent when WebGL is unavailable, the .auth-bd gradient shows through. */
  .auth-scene{position:fixed;inset:0;width:100%;height:100%;z-index:0;pointer-events:none;display:block;opacity:var(--auth-scene-opacity,.72)} /* ALN-172: sit back as a backdrop, not a video game. ALN-208: explicit 100% size, the backing renders at a fixed pixel budget and CSS scales it up (a bare inset:0 leaves a replaced element at its intrinsic size) */
  .auth-card{position:relative;z-index:1;width:100%;max-width:400px;background:var(--surface);border:1px solid var(--hair-2);border-radius:20px;box-shadow:var(--shadow-lg);padding:30px 28px}
  .auth-brand{font-family:var(--font-display);font-weight:500;font-size:24px;display:flex;align-items:center;gap:10px;letter-spacing:-.01em}
  .auth-tag{color:var(--ink-soft);font-size:14px;line-height:1.5;margin:8px 0 22px}
  /* layout only, the look is the segmented primitive above */
  .auth-seg{display:flex;width:100%;margin-bottom:20px}
  .auth-seg>button{flex:1}
  .auth-field{display:block;margin-bottom:14px}
  .auth-field span{display:block;font-size:12.5px;font-weight:600;color:var(--ink-soft);margin-bottom:6px}
  .auth-field input{width:100%;font:inherit;font-size:14.5px;color:var(--ink);background:var(--surface-2);border:1px solid var(--hair);border-radius:var(--r-sm);padding:11px 13px;transition:.15s}
  .auth-field input:focus{outline:none;border-color:var(--now-soft);background:var(--surface)}
  .auth-msg{font-size:13px;line-height:1.45;min-height:1px;margin:2px 0 12px}
  .auth-msg.err{color:var(--warn)}.auth-msg.ok{color:var(--ok)}.auth-msg.info{color:var(--ink-soft)}
  .auth-submit{width:100%;justify-content:center;padding:12px}
  .auth-links{display:flex;justify-content:center;margin-top:14px}
  .auth-link{font:inherit;font-size:13px;font-weight:500;color:var(--ink-soft);background:none;border:none;cursor:pointer;padding:4px}
  .auth-link:hover{color:var(--ink)}
  .auth-field[hidden]{display:none}
  /* platform users table */
  .users-wrap{margin-top:6px}
  .users-empty{color:var(--ink-faint);font-size:14px;padding:16px 2px}
  .user-row{display:flex;align-items:center;gap:14px;padding:13px 16px;background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-md);margin-bottom:9px;flex-wrap:wrap}
  .ur-main{flex:1;min-width:180px}
  .ur-email{font-size:14.5px;font-weight:600;color:var(--ink);display:flex;align-items:center;gap:8px}
  .ur-you{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--now);background:var(--now-tint);padding:2px 7px;border-radius:6px}
  .ur-meta{font-size:12px;color:var(--ink-faint);margin-top:3px}
  .ur-badges{display:flex;gap:6px}
  .ur-badge{font-family:var(--font-mono);font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;padding:3px 9px;border-radius:var(--r-xs)}
  .ur-badge.role-admin{background:var(--align);color:#fff}.ur-badge.role-user{background:var(--surface-2);color:var(--ink-soft)}
  .ur-badge.st-active{background:color-mix(in srgb,var(--ok) 16%,transparent);color:color-mix(in srgb,var(--ok) 55%,var(--ink))}.ur-badge.st-pending{background:color-mix(in srgb,var(--idle) 18%,transparent);color:color-mix(in srgb,var(--idle) 55%,var(--ink))}.ur-badge.st-disabled{background:color-mix(in srgb,var(--break) 18%,transparent);color:color-mix(in srgb,var(--break) 55%,var(--ink))}
  .ur-actions{display:flex;gap:7px;flex-wrap:wrap}
  .ur-btn{font:inherit;font-size:12px;font-weight:600;color:var(--ink-soft);background:transparent;border:1px solid var(--hair);padding:6px 11px;border-radius:9px;cursor:pointer;transition:.15s;white-space:nowrap}
  .ur-btn:hover{color:var(--ink);border-color:var(--hair);background:var(--surface-2)}
  .ur-btn.go{color:color-mix(in srgb,var(--ok) 55%,var(--ink));border-color:var(--ok)}.ur-btn.go:hover{background:color-mix(in srgb,var(--ok) 16%,transparent);color:color-mix(in srgb,var(--ok) 55%,var(--ink))}
  .ur-btn.warn{color:var(--warn)}.ur-btn.warn:hover{background:var(--warn);color:#fff;border-color:var(--warn)}
  /* Blocked users (ALN-170), a manage-list under Friends; block from a friend row,
     unblock here. Collapsed by default via <details>. */
  .blocks-card{margin-top:22px;padding-top:18px;border-top:1px solid var(--hair-2)}
  .blocks-summary{display:flex;align-items:center;gap:9px;cursor:pointer;list-style:none;padding:2px 2px;user-select:none;border-radius:var(--r-sm)}
  .blocks-summary::-webkit-details-marker{display:none}
  .blocks-summary:hover .blocks-title{color:var(--ink-soft)}
  .blocks-summary:focus-visible{outline:2px solid var(--now);outline-offset:2px}
  .blocks-title{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-faint)}
  .blocks-count{min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--surface-2);border:1px solid var(--hair-2);color:var(--ink-soft);font-size:11px;font-weight:700;line-height:16px;text-align:center}
  .blocks-count[hidden]{display:none}
  .blocks-caret{color:var(--ink-faint);margin-left:auto;transition:transform .18s}
  .blocks-card[open] .blocks-caret{transform:rotate(180deg)}
  .blocks-body{padding-top:12px}
  .blocks-note{font-size:12.5px;color:var(--ink-soft);margin:0 2px 12px;max-width:60ch;line-height:1.5}
  .block-row{display:flex;align-items:center;gap:13px;padding:11px 14px;background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-md);margin-bottom:8px}
  .block-row .ur-av{width:32px;height:32px;border-radius:50%;background:color-mix(in srgb,var(--break) 18%,transparent);color:color-mix(in srgb,var(--break) 55%,var(--ink));font-weight:700;font-size:13px;display:flex;align-items:center;justify-content:center;flex:none;text-transform:uppercase;overflow:hidden}
  .block-row .ur-av img{width:100%;height:100%;object-fit:cover;display:block}
  .block-main{flex:1;min-width:0}
  .block-name{font-size:14px;font-weight:600;color:var(--ink)}
  .block-sub{font-size:12.5px;color:var(--ink-faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* friends */
  .friend-add{display:flex;gap:10px;margin:14px 0 4px;flex-wrap:wrap}
  .friend-add input{flex:1;min-width:200px;font:inherit;font-size:14px;color:var(--ink);background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-sm);padding:11px 14px}
  .friend-add input:focus{outline:none;border-color:var(--now)}
  .friend-msg{font-size:13px;min-height:18px;padding:2px;color:var(--ink-soft)}
  .friend-msg.ok{color:var(--ok)}.friend-msg.err{color:var(--warn)}
  .friend-group{margin-top:18px}
  .friend-group .fg-title{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-faint);margin:0 2px 8px}
  .fr-avatar{position:relative;width:34px;height:34px;border-radius:50%;background:var(--now);color:var(--on-now);font-weight:700;font-size:14px;display:flex;align-items:center;justify-content:center;flex:none;text-transform:uppercase}
  .fr-avatar img,.chat-avatar img{width:100%;height:100%;object-fit:cover;border-radius:50%;display:block}
  .fr-dot{position:absolute;right:-1px;bottom:-1px;width:11px;height:11px;border-radius:50%;background:var(--ink-faint);border:2px solid var(--surface);transition:.2s}
  .fr-dot.online{background:var(--ok);box-shadow:0 0 8px 0 var(--ok)}
  .fr-status{font-size:12.5px;color:var(--ink-soft);margin-top:2px}
  .fr-status.live{color:var(--ok)}
  .share-card{display:flex;flex-direction:column;gap:12px;background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-md);padding:16px 18px;margin-top:14px}
  .share-toggle{display:flex;align-items:flex-start;gap:11px;cursor:pointer}
  .share-toggle input{margin-top:3px;width:16px;height:16px;accent-color:var(--now);flex:none;cursor:pointer}
  .share-toggle span{display:flex;flex-direction:column;gap:2px}
  .share-toggle strong{font-size:14px;font-weight:600;color:var(--ink)}
  .share-toggle em{font-size:12.5px;color:var(--ink-faint);font-style:normal}
  .nudge-pop{position:fixed;right:22px;bottom:22px;z-index:9999;display:flex;align-items:center;gap:12px;background:var(--surface);border:1px solid var(--hair-2);border-radius:14px;padding:13px 17px;box-shadow:var(--shadow);transform:translateY(16px);opacity:0;transition:.3s cubic-bezier(.2,.8,.3,1)}
  .nudge-pop.show{transform:translateY(0);opacity:1}
  .nudge-pop .np-mark{flex:none;width:10px;height:10px;border-radius:50%;background:var(--now);box-shadow:0 0 0 0 var(--now);animation:nudgepulse 1.2s ease 2}
  .nudge-pop .np-text{font-size:14px;color:var(--ink)}
  @keyframes nudgepulse{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--now) 60%,transparent)}100%{box-shadow:0 0 0 10px transparent}}
  .fr-unread{display:none;margin-left:6px;min-width:17px;height:17px;padding:0 5px;border-radius:9px;background:var(--now);color:var(--on-now);font-size:11px;font-weight:700;line-height:17px;text-align:center}
  .fr-unread.on{display:inline-block}
  .tab .tab-dot{display:none;width:7px;height:7px;border-radius:50%;background:var(--now);margin-left:5px;vertical-align:middle}
  .tab .tab-dot.on{display:inline-block}
  /* lines (ALN-142), Calm/List register: professional by default, accent used only for state */
  /* ── Sessions overview (ALN-169): a legible, inviting hero + live cards. The
     primary actions are filled and sit up top; a live strip + roster avatars do the
     "at a glance" work so the page reads without the intro paragraph. ── */
  .lines-hero{display:flex;align-items:flex-start;justify-content:space-between;gap:16px 24px;flex-wrap:wrap;margin-top:2px}
  .lines-hero-text{flex:1;min-width:min(100%,240px)}
  .lines-tagline{margin:7px 0 0;max-width:54ch;font-size:14px;line-height:1.5;color:var(--ink-soft)}
  .lines-hero-actions{display:flex;align-items:center;gap:10px;flex:none;flex-wrap:wrap}
  /* ALN-277: glow marks what is LIVE (ALN-274). A "new line" button is a primary action,
     not a live state, so it keeps accent weight but not the glow. */
  .ln-new-primary{display:inline-flex;align-items:center;gap:7px;font-size:13.5px;font-weight:600;padding:10px 16px;min-height:40px}
  /* The -1px optical nudge this used to carry was correcting the old baseline
     drop. The button centres its own icon now, so the nudge is just a 1px tilt. */
  .ln-plus{font-size:15px;line-height:1}
  .ln-join-btn{background:var(--surface-2);border:1px solid var(--hair-lit);color:var(--ink);font-weight:600;font-size:13.5px;padding:10px 16px;min-height:40px}
  .ln-join-btn:hover{border-color:var(--now-soft);background:var(--now-tint);color:var(--now)}
  /* live-now strip, the at-a-glance "there's activity, hop in" signal */
  .lines-summary{display:inline-flex;align-items:center;gap:8px;margin-top:14px;padding:7px 13px;background:color-mix(in srgb,var(--ok) 9%,var(--surface));border:1px solid color-mix(in srgb,var(--ok) 24%,var(--hair));border-radius:var(--r-pill);font-size:12.5px;font-weight:600;color:var(--ink)}
  .lines-summary[hidden]{display:none}
  .ls-dot{width:8px;height:8px;border-radius:50%;background:var(--ok);box-shadow:0 0 8px 0 var(--ok);animation:ln-pulse 2.4s ease-in-out infinite}
  .ls-rooms{color:var(--ok)}
  .ls-sep{color:var(--ink-faint)}
  .ls-ppl{color:var(--ink-soft)}
  @keyframes ln-pulse{0%,100%{opacity:1}50%{opacity:.45}}
  .lines-wrap{display:flex;flex-direction:column;gap:10px;margin-top:14px}
  .ln-card{position:relative;background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-md);padding:18px 20px;transition:.15s}
  .ln-card:hover{border-color:var(--hair-lit)}
  /* Quiet sessions still get a solid filled slot (like every other surface), the
     dot-field never shows through; an active session reads richer via its roster. */
  .ln-card-quiet{background:var(--surface)}
  /* A live room earns a calm green accent so the eye finds it, no side spine. */
  .ln-card-live{border-color:color-mix(in srgb,var(--ok) 24%,var(--hair-2))}
  .ln-card-live:hover{border-color:color-mix(in srgb,var(--ok) 40%,var(--hair-lit))}
  .ln-head{display:flex;align-items:center;gap:8px 11px;flex-wrap:wrap}
  .ln-name{font-size:15px;font-weight:600;color:var(--ink)}
  .ln-tag{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--now);background:var(--now-tint);padding:2px 7px;border-radius:6px}
  .ln-here{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;color:var(--ok)}
  .ln-dot{width:8px;height:8px;border-radius:50%;background:var(--ok);box-shadow:0 0 8px 0 var(--ok)}
  .ln-quiet{font-size:12.5px;color:var(--ink-soft)}
  .ln-cta{margin-left:auto}
  .ln-cta-btn{white-space:nowrap;min-height:38px;display:inline-flex;align-items:center;justify-content:center}
  .ln-metarow{margin-top:10px}
  /* Host-set room note (ALN-205): a quiet line under the title on the card + interior. */
  .ln-note{margin-top:7px;font-size:13px;color:var(--ink-soft);line-height:1.45}
  .line-note{margin:2px 0 10px;font-size:13.5px;color:var(--ink-soft);line-height:1.5;max-width:64ch}
  .line-note[hidden]{display:none}
  .ln-join{font-weight:600}
  /* Quiet-room Join is a calm secondary; the active-room Join is a filled btn-go and
     keeps its own hover, so the tint-hover is scoped to the quiet variant only. */
  .ln-join-quiet{background:var(--surface-2);border:1px solid var(--hair);color:var(--ink-soft)}
  .ln-join-quiet:hover{color:var(--now);border-color:var(--now-soft);background:var(--now-tint)}
  /* A live room's Join matches its green live indicator, not the gold accent (ALN-204). */
    /* Roster reads as a clean left-aligned stack of full-width rows, the avatar
     shares the card's content edge with the name + "N here" dot (no pill inset),
     the name fills the row, and the status sits at the right so the card's width
     is actually used instead of everything jammed into the corner. */
  .ln-people{display:flex;flex-direction:column;gap:12px;margin-top:14px}
  .ln-chip{display:flex;align-items:center;gap:11px;width:100%}
  .ln-av{position:relative;width:34px;height:34px;border-radius:50%;background:var(--now);color:var(--on-now);font-weight:700;font-size:14px;display:flex;align-items:center;justify-content:center;flex:none;text-transform:uppercase}
  .ln-av.sm{width:26px;height:26px;font-size:11px}
  .ln-av img{width:100%;height:100%;object-fit:cover;border-radius:50%;display:block}
  .ln-on{position:absolute;right:-1px;bottom:-1px;width:11px;height:11px;border-radius:50%;background:var(--ok);border:2px solid var(--surface);box-shadow:0 0 8px 0 var(--ok)}
  .ln-chip-name{flex:1 1 auto;min-width:0;font-size:13px;font-weight:600;color:var(--ink);line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .ln-chip-task{flex:none;padding-left:12px;font-size:12px;color:var(--ink-soft);line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:55%}
  /* inviting first-run / empty state, a calm orbit motif + the two primary actions */
  .ln-empty-state{display:flex;flex-direction:column;align-items:center;text-align:center;gap:13px;padding:40px 22px;background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-lg);box-shadow:var(--shadow)}
  .ln-empty-orbit{position:relative;width:76px;height:76px;display:block}
  .lo-core{position:absolute;left:50%;top:50%;width:16px;height:16px;margin:-8px 0 0 -8px;border-radius:50%;background:var(--now);box-shadow:0 0 16px -2px var(--now);animation:ln-pulse 3s ease-in-out infinite}
  .lo-ring{position:absolute;inset:5px;border:1px solid var(--hair-lit);border-radius:50%}
  .lo-dot{position:absolute;width:9px;height:9px;border-radius:50%;background:var(--ok);box-shadow:0 0 8px 0 var(--ok)}
  .lo-d1{left:50%;top:-1px;margin-left:-4.5px}
  .lo-d2{right:5px;bottom:14px;background:var(--align);box-shadow:0 0 8px 0 var(--align)}
  .lo-d3{left:3px;bottom:17px;background:var(--now);box-shadow:0 0 8px 0 var(--now)}
  .ln-empty-h{font-family:var(--font-display);font-size:1.15rem;color:var(--ink);margin:0}
  .ln-empty-p{max-width:46ch;color:var(--ink-soft);font-size:.9rem;line-height:1.55;margin:0}
  .ln-empty-actions{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin-top:4px}
  @media (prefers-reduced-motion:reduce){ .ls-dot,.lo-core{animation:none} }
  /* Tablet + mobile: the hero actions get their own centered row instead of inheriting
     the right-aligned desktop layout (ALN-204). */
  @media (max-width:900px){ .lines-hero-actions{width:100%;justify-content:center} }
  @media (max-width:560px){ .lines-hero-actions .btn{flex:1} }
  .line-interior{margin-top:4px}
  .line-bar{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:6px}
  .line-back,.line-leave{font-size:12.5px;padding:8px 14px;min-height:38px}
  .line-title{margin-top:2px}
  .line-sub{margin-bottom:14px;display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}
  .line-sub .ls-dot{width:8px;height:8px;border-radius:50%;background:var(--ok);box-shadow:0 0 8px 0 var(--ok);animation:ln-pulse 2.4s ease-in-out infinite}
  .ln-quiet-dot{width:8px;height:8px;border-radius:50%;background:var(--ink-faint)}
  .ln-sub-sep{color:var(--ink-faint)}
  .line-roster{display:flex;flex-direction:column;gap:8px}
  .line-roster[hidden]{display:none}
  .ln-row{display:flex;align-items:center;gap:13px;padding:12px 15px;background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-md)}
  .ln-row-main{flex:1;min-width:0}
  .ln-row-name{font-size:14px;font-weight:600;color:var(--ink)}
  .ln-row-task{font-size:12.5px;color:var(--ink-soft);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .ln-focus{display:flex;align-items:center;gap:11px;flex:none}
  .ln-status{font-size:12px;color:var(--ink-soft);white-space:nowrap}
  .ln-ring{position:relative;width:36px;height:36px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;background:conic-gradient(var(--now) calc(var(--pct,0)*1%),var(--hair-2) 0)}
  .ln-ring::before{content:"";position:absolute;inset:3px;border-radius:50%;background:var(--surface)}
  .ln-min{position:relative;font-family:var(--font-mono);font-size:9.5px;font-weight:700;color:var(--ink-soft);letter-spacing:-.02em}
  .ln-empty{color:var(--ink-soft);font-size:14px;padding:20px 2px;line-height:1.5}
  /* lines · Web register (constellation, ALN-142 slice 2). The pill sits right-aligned
     to the constellation window's edge (ALN-204). */
  /* layout only (right-aligned to the constellation edge, ALN-204); the look is
     the segmented primitive. This control IS the reference the others match. */
  .line-reg{display:flex;margin-left:auto;margin-bottom:14px}
  /* keyboard focus rings, the Lines module was missing the app's standardized :focus-visible */
  .ln-cta-btn:focus-visible,.ln-new:focus-visible,.ln-kick:focus-visible,.line-back:focus-visible,.line-leave:focus-visible,.lh-btn:focus-visible,.lh-step button:focus-visible,.lm-actions .btn:focus-visible{outline:2px solid var(--now);outline-offset:2px}
  .btn-warn{background:color-mix(in srgb,var(--warn) 75%,#000);color:#fff;font-weight:600;border-color:transparent}
  .btn-warn:hover{filter:brightness(.96)}
  .line-web{position:relative;height:min(68vh,560px);border-radius:var(--r-md);overflow:hidden;background:#010206;border:1px solid var(--hair-2)}   /* the void, VOID in client/src/space.mjs */
  .line-web canvas{display:block;width:100%;height:100%;touch-action:none;cursor:grab}
  .line-web canvas:active{cursor:grabbing}
  /* ALN-273: was 36 characters of uppercased body copy at 10px. All-caps costs word-shape,
     which is the cue that makes a sentence skimmable, so it belongs on 1-2 word labels only. */
  .line-web-hint{position:absolute;left:0;right:0;bottom:10px;text-align:center;font-family:var(--font-mono);font-size:var(--fs-xs);letter-spacing:.02em;color:rgba(188,208,232,.8);pointer-events:none}
  /* lines · session control (ALN-143 slice 5a): badges, host panel, kick, toast, password modal */
  .ln-badge{font-size:10.5px;font-weight:700;letter-spacing:.03em;padding:2px 8px;border-radius:var(--r-pill);background:var(--surface-2);color:var(--ink-soft);border:1px solid var(--hair-2);text-transform:uppercase}
  .ln-badge.host{color:var(--ink);background:var(--surface-2);border-color:var(--hair-lit)}
  .ln-badge.full{color:color-mix(in srgb,var(--warn) 55%,var(--ink));background:color-mix(in srgb,var(--warn) 17%,transparent);border-color:transparent}
  .line-host[hidden]{display:none}
  .line-host{margin:0 0 16px}
  /* Host controls, instrument panel (ALN-158): mono field labels, stepper, toggle switches, segmented voice, grouped actions */
  /* ALN-271: the panel is a <details>, collapsed by default. Its head is the summary, and it
     carries the current settings in words so a shut panel still answers "how is this room set
     up?" without a click. */
  .lh-panel{background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-md);box-shadow:var(--shadow);overflow:hidden}
  /* Baseline, not centre. The eyebrow is 10.5px uppercase mono and the gist is 12px mixed-case
     Archivo, so centring their BOXES leaves the glyphs on two different lines (the gist's box
     carries descender room the all-caps mono does not). The dot and the caret are marks, not
     text, so they stay optically centred. */
  .lh-head{display:flex;align-items:baseline;gap:9px;padding:12px 16px;border-bottom:1px solid var(--hair-2);background:var(--surface-2);cursor:pointer;list-style:none;user-select:none}
  .lh-head .lh-dot,.lh-head .lh-caret{align-self:center}
  .lh-head::-webkit-details-marker{display:none}
  .lh-head:hover .lh-eyebrow{color:var(--ink)}
  .lh-head:focus-visible{outline:2px solid var(--now);outline-offset:-2px}
  .lh-panel:not([open]) .lh-head{border-bottom:0}
  .lh-gist{font-size:12px;color:var(--ink-faint);margin-left:6px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .lh-panel[open] .lh-gist{display:none}
  .lh-caret{width:16px;height:16px;color:var(--ink-faint);margin-left:auto;flex:none;transition:transform .18s}
  .lh-panel[open] .lh-caret{transform:rotate(180deg)}
  .lh-dot{width:7px;height:7px;border-radius:50%;background:var(--now);box-shadow:0 0 0 3px var(--now-glow);flex:none}
  .lh-eyebrow{font-family:var(--font-mono);font-size:10.5px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft)}
  .lh-body{display:flex;flex-wrap:wrap;align-items:flex-end;gap:16px 26px;padding:16px}
  .lh-cell{display:flex;flex-direction:column;gap:9px;min-width:0}
  .lh-cell-grow{flex:1 1 240px}
  /* Room note editor (ALN-205): a full-width row under the other controls. */
  .lh-cell-note{flex:1 1 100%}
  .lh-note-in{font:inherit;font-size:13.5px;color:var(--ink);background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-sm);padding:10px 12px;min-height:40px;width:100%}
  .lh-note-in::placeholder{color:var(--ink-faint)}
  .lh-note-in:focus{outline:none;border-color:var(--now)}
  .lh-lbl{font-family:var(--font-mono);font-size:10px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft)}
  .lh-step{display:inline-flex;align-items:center;border:1px solid var(--hair-2);border-radius:var(--r-sm);background:var(--surface);height:40px;width:fit-content}
  .lh-step button{width:38px;height:38px;border:0;background:transparent;color:var(--ink-soft);font-size:19px;line-height:1;cursor:pointer;display:grid;place-items:center;transition:.15s}
  .lh-step button:hover:not(:disabled){background:var(--surface-2);color:var(--ink)}
  .lh-step button:disabled{opacity:.32;cursor:default}
  .lh-step-val{min-width:52px;text-align:center;font-family:var(--font-mono);font-size:13.5px;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;border-left:1px solid var(--hair-2);border-right:1px solid var(--hair-2);align-self:stretch;display:grid;place-items:center;padding:0 6px}
  .lh-switches{display:flex;gap:10px;flex-wrap:wrap}
  .lh-switch{display:inline-flex;align-items:center;gap:9px;cursor:pointer;font-size:13px;font-weight:600;color:var(--ink);user-select:none;padding:8px 12px 8px 10px;border:1px solid var(--hair-2);border-radius:var(--r-sm);background:var(--surface);transition:.15s;min-height:40px}
  .lh-switch:hover{border-color:var(--hair)}
  .lh-switch:has(input:checked){border-color:var(--now-soft)}
  .lh-switch input{position:absolute;opacity:0;width:0;height:0}
  .lh-tr{position:relative;width:36px;height:21px;border-radius:999px;background:var(--surface-2);border:1px solid var(--hair);transition:.18s var(--ease-out);flex:none}
  .lh-tr::after{content:"";position:absolute;top:2px;left:2px;width:15px;height:15px;border-radius:50%;background:#fff;box-shadow:0 1px 2px rgba(27,35,43,.28);transition:.18s var(--ease-out)}
  .lh-switch input:checked + .lh-tr{background:var(--now);border-color:transparent}
  .lh-switch input:checked + .lh-tr::after{transform:translateX(15px)}
  .lh-switch input:focus-visible + .lh-tr{box-shadow:0 0 0 3px var(--now-glow)}
  .lh-seg{overflow-x:auto;scrollbar-width:none}   /* layout only, see the segmented primitive */
  .lh-seg::-webkit-scrollbar{display:none}
  .lh-actions{display:flex;flex-wrap:wrap;align-items:center;gap:9px;padding:13px 16px;border-top:1px solid var(--hair-2);background:var(--surface-2)}
  .lh-btn{font:inherit;font-size:12.5px;font-weight:600;min-height:38px;padding:8px 14px;border-radius:var(--r-sm);cursor:pointer;transition:.15s;border:1px solid transparent;display:inline-flex;align-items:center;gap:7px;white-space:nowrap}
  .lh-ico{flex:none;opacity:.8}
  .lh-btn.go .lh-ico{opacity:.95}
  .lh-btn.go{background:var(--now);color:var(--on-now)}.lh-btn.go:hover{filter:brightness(.96)}
  .lh-btn.ghost{background:var(--surface);border-color:var(--hair);color:var(--ink-soft)}.lh-btn.ghost:hover{border-color:var(--ink-faint);color:var(--ink)}
  .lh-btn.danger{background:transparent;border-color:var(--hair);color:var(--ink-soft);margin-left:auto}.lh-btn.danger:hover{background:color-mix(in srgb,var(--warn) 75%,#000);color:#fff;border-color:transparent}
  .ln-kick{font:inherit;font-size:11.5px;font-weight:600;color:var(--warn);background:transparent;border:1px solid var(--hair);border-radius:9px;padding:4px 10px;cursor:pointer;transition:.15s;white-space:nowrap}
  .ln-kick:hover{background:color-mix(in srgb,var(--warn) 75%,#000);color:#fff;border-color:transparent}
  .ln-row .ln-vol{width:64px;accent-color:var(--now);flex:none} /* per-peer volume, keyboard path for the node menu (ALN-217) */
  /* Roles + moderation (ALN-180): role badge on the roster name, promote/mute controls, force-muted dock state. */
  .ln-role{font-size:9.5px;font-weight:700;letter-spacing:.04em;padding:1px 6px;border-radius:var(--r-pill);text-transform:uppercase;margin-left:7px;vertical-align:middle;background:var(--surface-2);color:var(--ink-soft);border:1px solid var(--hair-2)}
  .ln-role.host{color:var(--now);background:var(--now-tint);border-color:transparent}
  .ln-role.mod{color:color-mix(in srgb,var(--align) 70%,var(--ink));background:color-mix(in srgb,var(--align) 15%,transparent);border-color:transparent}
  .ln-modbtn{font:inherit;font-size:11.5px;font-weight:600;color:var(--ink-soft);background:transparent;border:1px solid var(--hair);border-radius:9px;padding:4px 10px;cursor:pointer;transition:.15s;white-space:nowrap}
  .ln-modbtn:hover{border-color:var(--ink-faint);color:var(--ink)}
  .ln-modbtn.mute.on{color:var(--now);border-color:transparent;background:var(--now-tint)}
  .la-core.forced{opacity:.55;cursor:not-allowed}
  .ln-toast{position:fixed;left:50%;bottom:26px;transform:translate(-50%,16px);z-index:10000;display:flex;align-items:center;gap:12px;background:var(--ink);color:var(--on-ink);font-size:13.5px;font-weight:500;padding:11px 12px 11px 18px;border-radius:var(--r-pill);box-shadow:var(--shadow-lg);opacity:0;transition:.28s cubic-bezier(.2,.8,.3,1);pointer-events:none;max-width:88vw}
  .ln-toast.show{opacity:1;transform:translate(-50%,0)}
  .ln-toast-act{font:inherit;font-size:12.5px;font-weight:700;color:var(--now);background:transparent;border:0;padding:4px 10px;border-radius:var(--r-pill);cursor:pointer;white-space:nowrap;pointer-events:auto}
  .ln-toast-act:hover{background:rgba(255,255,255,.12)}
  .line-modal[hidden]{display:none}
  .line-modal{position:fixed;inset:0;z-index:10001;display:flex;align-items:center;justify-content:center;background:rgba(15,20,30,.42);backdrop-filter:blur(3px);padding:16px}
  .lm-card{background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);padding:20px 22px;width:min(380px,100%);display:flex;flex-direction:column;gap:12px}
  .lm-title{font-size:15px;font-weight:600;color:var(--ink)}
  .lm-msg{font-size:13px;color:var(--ink-soft);line-height:1.45}
  .lm-input{font:inherit;font-size:14px;color:var(--ink);background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-sm);padding:11px 13px}
  .lm-input:focus{outline:none;border-color:var(--now)}
  .lm-err{font-size:12.5px;color:var(--warn);font-weight:500}
  .lm-input[hidden],.lm-err[hidden],.lm-msg[hidden]{display:none}
  .lm-actions{display:flex;justify-content:flex-end;gap:9px;margin-top:2px}
  /* lines · narrow viewports: keep the roster row + card header from crowding (the ring still carries depth without the status phrase) */
  @media (max-width:520px){
    .ln-status{display:none}
    .ln-focus{gap:9px}
    .ln-head{gap:6px 8px}
    .lh-body{gap:14px 18px}
    .line-web{height:min(56vh,380px)}
    .lc-log{height:min(46vh,300px)}
    .lc-msg{max-width:90%}
  }
  /* lines · voice (ALN-147): mesh push-to-talk dock */
  /* Voice dock, centered circular controls (ALN-158): a mic core (connect / hold-to-talk / open-mic mute) flanked by verify + leave */
  .line-audio[hidden]{display:none}
  .line-audio{display:flex;flex-direction:column;align-items:center;gap:13px;margin-top:16px;padding:20px 16px 6px;border-top:1px solid var(--hair-2)}
  .la-cluster{display:flex;align-items:center;justify-content:center;gap:18px}
  .la-core{position:relative;display:inline-flex;align-items:center;justify-content:center;width:64px;height:64px;border-radius:50%;color:var(--ink);background:var(--surface);border:1px solid var(--hair);box-shadow:var(--shadow);cursor:pointer;transition:transform .15s var(--ease-out),background .15s,border-color .15s,box-shadow .15s;user-select:none;-webkit-user-select:none;touch-action:none;flex:none}
  .la-core:hover{border-color:var(--hair-lit);transform:translateY(-1px)}
  .la-core svg{width:25px;height:25px}
  .la-core.la-connect{color:var(--on-now);background:var(--now);border-color:transparent;box-shadow:var(--glow-now)}
  .la-core.la-connect:hover{filter:brightness(.97)}
  .la-core.live{color:var(--on-now);background:var(--now);border-color:transparent;box-shadow:0 0 0 6px var(--now-glow),var(--shadow)}
  .la-core.live::after{content:"";position:absolute;inset:-1px;border-radius:50%;animation:laPulse 1.9s var(--ease) infinite;pointer-events:none}
  @keyframes laPulse{0%{box-shadow:0 0 0 1px var(--now-soft)}70%{box-shadow:0 0 0 14px transparent}100%{box-shadow:0 0 0 0 transparent}}
  .la-ring{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:50%;color:var(--ink-soft);background:var(--surface);border:1px solid var(--hair);cursor:pointer;transition:.15s;flex:none}
  .la-ring:hover{color:var(--ink);border-color:var(--hair-lit)}
  .la-ring svg{width:18px;height:18px}
  .la-ring.on{color:var(--now);border-color:var(--now-soft);box-shadow:0 0 0 3px var(--now-glow)}
  .la-leave:hover{color:var(--warn);border-color:var(--warn)}
  .la-core:focus-visible,.la-ring:focus-visible{outline:2px solid var(--now);outline-offset:3px}
  .la-caption{display:flex;flex-direction:column;align-items:center;gap:5px;text-align:center}
  .la-label{font-size:13.5px;font-weight:600;color:var(--ink);letter-spacing:.01em}
  .la-label.denied{color:var(--warn)}
  .la-meta{font-family:var(--font-mono);font-size:10px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-soft);font-variant-numeric:tabular-nums}
  .la-meta.reconnecting{color:var(--now)}
  .la-note{font-size:12px;color:var(--ink-soft);max-width:34ch;line-height:1.45;text-align:center}
  .line-verify{margin:8px 0 0}
  .line-verify .sn-ip{margin-top:9px;padding-top:9px;border-top:1px solid var(--hair);color:var(--ink-faint);font-size:11px;line-height:1.5}
  /* Speaking pulse on the List roster dot, driven live by voice level (--spk 0..1) */
  .ln-row .ln-on{transition:transform .08s linear,box-shadow .08s linear}
  .ln-row[style*="--spk"] .ln-on{transform:scale(calc(1 + var(--spk,0) * .55));box-shadow:0 0 calc(6px + var(--spk,0) * 12px) 0 var(--ok)}
  /* Per-node menu (ALN-147): a dark-glass card floating over the constellation */
  .line-node-menu[hidden]{display:none}
  .line-node-menu{position:absolute;z-index:6;width:236px;padding:13px 14px 12px;border-radius:14px;background:rgba(12,16,24,.92);border:1px solid rgba(150,175,210,.16);box-shadow:0 6px 14px -5px rgba(0,0,0,.8);backdrop-filter:blur(9px);-webkit-backdrop-filter:blur(9px);color:#eaf0f8;font-size:13px;animation:lnmIn .14s ease}
  @keyframes lnmIn{from{opacity:0;transform:translateY(4px) scale(.98)}to{opacity:1;transform:none}}
  .lnm-head{display:flex;align-items:center;gap:10px;margin-bottom:11px}
  .lnm-av{width:32px;height:32px;border-radius:50%;background:var(--now);color:var(--on-now);font-weight:700;font-size:13px;display:flex;align-items:center;justify-content:center;flex:none;text-transform:uppercase;overflow:hidden}
  .lnm-av img{width:100%;height:100%;object-fit:cover;display:block}
  .lnm-id{min-width:0;flex:1}
  .lnm-name{font-weight:700;font-size:13.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .lnm-status{font-size:var(--fs-xs);color:rgba(188,208,232,.72);display:flex;align-items:center;gap:5px;margin-top:1px}
  .lnm-status .dot{width:6px;height:6px;border-radius:50%;background:var(--ok);flex:none}
  .lnm-status.reconnecting .dot{background:var(--now);animation:lnmBlink 1s ease infinite}
  @keyframes lnmBlink{50%{opacity:.3}}
  .lnm-close{position:absolute;top:9px;right:10px;width:22px;height:22px;border-radius:50%;border:none;background:transparent;color:rgba(188,208,232,.6);font-size:16px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center}
  .lnm-close:hover{color:#eaf0f8;background:rgba(150,175,210,.12)}
  .lnm-vol{display:flex;align-items:center;gap:9px;margin:2px 0 11px}
  .lnm-vol svg{flex:none;color:rgba(188,208,232,.7)}
  .lnm-vol input{flex:1;-webkit-appearance:none;appearance:none;height:4px;border-radius:3px;background:rgba(150,175,210,.22);outline:none;margin:0}
  .lnm-vol input::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:15px;height:15px;border-radius:50%;background:var(--now);cursor:pointer;border:2px solid rgba(12,16,24,.9)}
  .lnm-vol input::-moz-range-thumb{width:15px;height:15px;border-radius:50%;background:var(--now);cursor:pointer;border:2px solid rgba(12,16,24,.9)}
  .lnm-acts{display:flex;gap:8px}
  .lnm-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;font:inherit;font-size:12.5px;font-weight:600;color:#eaf0f8;background:rgba(150,175,210,.1);border:1px solid rgba(150,175,210,.16);border-radius:10px;padding:9px 8px;cursor:pointer;transition:.14s}
  .lnm-btn:hover{background:rgba(150,175,210,.18)}
  .lnm-btn.on{color:var(--on-now);background:var(--now);border-color:transparent}
  .lnm-btn.warn{color:#ffb3ad;border-color:rgba(255,120,110,.3)}
  .lnm-btn.warn:hover{background:rgba(255,120,110,.14)}
  .lnm-btn svg{flex:none}
  .lnm-you{font-size:11.5px;color:rgba(188,208,232,.72);margin-top:-2px}
  /* lines · encrypted session chat (ALN-144, slices 3–4 + 5b) */
  .line-bar-right{display:flex;align-items:center;gap:9px}
  .line-chat-toggle{display:inline-flex;align-items:center;gap:7px;font:inherit;font-size:12.5px;font-weight:600;color:var(--ink-soft);background:var(--surface-2);border:1px solid var(--hair-2);border-radius:var(--r-pill);padding:8px 14px;min-height:38px;cursor:pointer;transition:.15s}
  .line-chat-toggle[hidden]{display:none}
  .line-chat-toggle:hover{color:var(--ink);border-color:var(--hair)}
  .line-chat-toggle.active{color:var(--now);background:var(--now-tint);border-color:transparent}
  .line-chat-toggle .lc-tog-glyph{display:inline-flex}
  .lc-unread{display:inline-flex;align-items:center;justify-content:center;min-width:17px;height:17px;padding:0 5px;font-size:10.5px;font-weight:700;font-family:var(--font-mono);color:var(--on-now);background:var(--now);border-radius:9px;line-height:1}
  .line-chat[hidden]{display:none}
  .line-chat{margin-top:14px;border:1px solid var(--hair-2);border-radius:var(--r-md);background:var(--surface);display:flex;flex-direction:column;overflow:hidden}
  .lc-head{display:flex;align-items:center;gap:8px;padding:11px 15px;border-bottom:1px solid var(--hair-2);background:var(--surface-2)}
  .lc-lock{display:inline-flex;color:var(--ink-soft);transition:color .2s}
  .lc-lock.on{color:var(--ok)}
  .lc-title{font-size:13px;font-weight:600;color:var(--ink)}
  .lc-sub{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-soft);margin-left:auto}
  .lc-log{display:flex;flex-direction:column;gap:8px;padding:14px 15px;height:min(42vh,320px);overflow-y:auto;overscroll-behavior:contain}
  .lc-empty{color:var(--ink-soft);font-size:13px;text-align:center;margin:auto;line-height:1.5;max-width:38ch}
  .lc-msg{display:flex;gap:9px;align-items:flex-end;max-width:82%}
  .lc-msg.mine{align-self:flex-end;flex-direction:row-reverse}
  .lc-av{flex:none;width:26px;height:26px;border-radius:50%;overflow:hidden;font-size:11px;display:inline-flex;align-items:center;justify-content:center;background:var(--surface-2)}
  .lc-av :where(img,span){width:100%;height:100%;display:block}
  .lc-bubble{position:relative;background:var(--surface-2);border:1px solid var(--hair-2);border-radius:14px;padding:8px 12px;font-size:13.5px;line-height:1.42;color:var(--ink);word-break:break-word;min-width:0}
  .lc-msg.mine .lc-bubble{background:var(--now);border-color:transparent;color:var(--on-now)}
  .lc-bubble.lc-locked{background:transparent;border-style:dashed;color:var(--ink-soft);font-size:12.5px}
  .lc-name{display:block;font-size:11px;font-weight:700;color:var(--ink-soft);margin-bottom:2px}
  .lc-text{white-space:pre-wrap}
  .lc-del{position:absolute;top:-9px;right:-9px;width:20px;height:20px;border-radius:50%;border:1px solid var(--hair-2);background:var(--surface);color:var(--ink-soft);font-size:11px;line-height:1;cursor:pointer;display:none;align-items:center;justify-content:center;box-shadow:var(--shadow)}
  .lc-msg:hover .lc-del,.lc-del:focus-visible{display:inline-flex}
  .lc-del:hover{color:var(--warn);border-color:var(--warn)}
  /* Pin a message (ALN-182): per-bubble pin action + the pinned banner at the top of the chat. */
  .lc-pinbtn{position:absolute;top:-9px;right:15px;width:20px;height:20px;border-radius:50%;border:1px solid var(--hair-2);background:var(--surface);color:var(--ink-soft);cursor:pointer;display:none;align-items:center;justify-content:center;box-shadow:var(--shadow);padding:0}
  .lc-pinbtn svg{width:11px;height:11px}
  .lc-msg:hover .lc-pinbtn,.lc-pinbtn:focus-visible{display:inline-flex}
  .lc-pinbtn:hover{color:var(--now);border-color:var(--now)}
  .lc-pin{display:flex;align-items:center;gap:9px;padding:9px 13px;border-bottom:1px solid var(--hair-2);background:var(--now-tint)}
  .lc-pin[hidden]{display:none}
  .lc-pin-ico{flex:none;color:var(--now);display:inline-flex}
  .lc-pin-main{min-width:0;flex:1;display:flex;flex-direction:column;gap:1px}
  .lc-pin-label{font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--now)}
  .lc-pin-text{font-size:13px;line-height:1.4;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .lc-pin-text.held{color:var(--ink-soft);font-style:italic}
  .lc-pin-x{flex:none;width:22px;height:22px;border-radius:50%;border:1px solid var(--hair-2);background:var(--surface);color:var(--ink-soft);font-size:12px;line-height:1;cursor:pointer;display:inline-flex;align-items:center;justify-content:center}
  .lc-pin-x:hover{color:var(--warn);border-color:var(--warn)}
  .lc-gate{padding:12px 15px;font-size:12.5px;color:var(--ink-soft);border-top:1px solid var(--hair-2);background:var(--surface-2);line-height:1.45}
  .lc-gate[hidden]{display:none}
  .lc-composer{display:flex;gap:8px;padding:11px 12px;border-top:1px solid var(--hair-2)}
  .lc-composer[hidden]{display:none}
  .lc-input{flex:1;min-width:0;font:inherit;font-size:14px;color:var(--ink);background:var(--surface-2);border:1px solid var(--hair-2);border-radius:var(--r-pill);padding:10px 15px}
  /* single, clean focus (ALN-158): amber border + hugging glow, no offset outline, so no double border */
  .lc-input:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .lc-send{flex:none;padding:9px 18px;min-height:0}
  .line-chat-toggle:focus-visible,.lc-send:focus-visible,.lc-del:focus-visible{outline:2px solid var(--now);outline-offset:2px}
  /* chat */
  /* Non-blocking layer: clicks pass through to the app behind it. */
  /* ── Messages: a unified, draggable multi-session chat console (ALN-136). A master–detail
     window in the .chat-win/.pomo floating family, a conversation rail + the active E2EE
     thread. Calm by default (no HUD chamfer, like the chat it replaces); one amber signal
     marks the active row + verification. ── */
  .chat-bd{position:fixed;inset:0;z-index:1000;display:none;pointer-events:none}
  .chat-bd.open{display:block}
  .chat-win{pointer-events:auto;position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);display:flex;width:min(720px,94vw);height:min(74vh,600px);background:var(--surface);border:1px solid var(--hair-2);border-radius:18px;box-shadow:var(--shadow-lg);overflow:hidden}
  /* left rail */
  .cw-rail{position:relative;flex:none;width:256px;display:flex;flex-direction:column;min-height:0;background:var(--surface-2);border-right:1px solid var(--hair-2)}
  .cw-rail-head{display:flex;align-items:center;gap:8px;padding:14px 10px 14px 16px;border-bottom:1px solid var(--hair-2);flex:none;cursor:move;user-select:none;touch-action:none}
  .cw-title{font-family:var(--font-display);font-weight:600;font-size:16px;color:var(--ink);letter-spacing:-.01em}
  .cw-grip{margin-left:auto;color:var(--ink-faint);font-size:12px;letter-spacing:1px;opacity:.5}
  .cw-icon{flex:none;width:30px;height:30px;border-radius:var(--r-sm);border:1px solid transparent;background:transparent;color:var(--ink-soft);cursor:pointer;display:grid;place-items:center;font-size:15px;line-height:1;transition:.15s}
  .cw-icon:hover{background:var(--surface);border-color:var(--hair);color:var(--ink)}
  .cw-icon svg{display:block}
  .cw-new{color:var(--ink-soft)}
  .cw-railbody{display:flex;flex-direction:column;min-height:0;flex:1}
  .cw-search{flex:none;padding:10px 12px 8px;position:relative}
  .cw-search svg{position:absolute;left:23px;top:calc(50% - 1px);transform:translateY(-50%);color:var(--ink-faint);pointer-events:none}
  .cw-search input{width:100%;font:inherit;font-size:13px;color:var(--ink);background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-sm);padding:8px 11px 8px 33px}
  .cw-search input::placeholder{color:var(--ink-soft)}
  .cw-search input:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .cw-threads{flex:1;min-height:0;overflow-y:auto;padding:2px 8px 10px;display:flex;flex-direction:column;gap:2px}
  .cw-thread-row{display:flex;align-items:center;gap:11px;width:100%;text-align:left;padding:9px 10px;border:1px solid transparent;border-radius:var(--r-md);background:transparent;cursor:pointer;transition:.12s}
  .cw-thread-row:hover{background:var(--surface)}
  .cw-thread-row.on{background:var(--surface);border-color:var(--now-soft);box-shadow:inset 0 0 0 1px var(--now-soft)}
  .cw-av{position:relative;flex:none}
  .cw-av .chat-avatar{width:38px;height:38px;font-size:15px}
  .cw-dot{position:absolute;right:-1px;bottom:-1px;width:11px;height:11px;border-radius:50%;background:var(--ink-faint);border:2px solid var(--surface-2)}
  .cw-thread-row:hover .cw-dot,.cw-thread-row.on .cw-dot{border-color:var(--surface)}
  .cw-dot.online{background:var(--ok)}
  .cw-row-main{min-width:0;flex:1;display:flex;flex-direction:column;gap:2px}
  .cw-row-top{display:flex;align-items:baseline;gap:8px}
  .cw-row-name{flex:1;min-width:0;font-size:13.5px;font-weight:600;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .cw-row-time{flex:none;font-family:var(--font-mono);font-size:10px;color:var(--ink-faint);letter-spacing:.02em}
  .cw-row-sub{display:flex;align-items:center;gap:8px}
  .cw-row-preview{flex:1;min-width:0;font-size:12.5px;color:var(--ink-soft);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .cw-thread-row.unread .cw-row-name,.cw-thread-row.unread .cw-row-preview{color:var(--ink)}
  .cw-thread-row.unread .cw-row-preview{font-weight:500}
  .cw-unread{flex:none;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--now);color:var(--on-now);font-size:11px;font-weight:700;line-height:18px;text-align:center;display:none}
  .cw-unread.on{display:block}
  .cw-rail-empty{color:var(--ink-faint);font-size:13px;text-align:center;padding:34px 20px;line-height:1.6}
  .cw-rail-empty b{color:var(--ink-soft);font-weight:600}
  /* new-chat compose (overlays the rail body) */
  .cw-compose{position:absolute;inset:0;z-index:2;background:var(--surface-2);display:flex;flex-direction:column;min-height:0}
  .cw-compose[hidden]{display:none}
  .cw-compose-head{display:flex;align-items:center;gap:8px;padding:13px 12px;border-bottom:1px solid var(--hair-2);flex:none}
  .cw-back{font-family:var(--font-ui);font-size:13px;font-weight:600;color:var(--ink-soft);background:none;border:none;cursor:pointer;padding:4px 6px;border-radius:var(--r-sm)}
  .cw-back:hover{background:var(--surface)}
  .cw-compose-msg{flex:none;font-size:12.5px;color:var(--ok);line-height:1.45;padding:10px 14px 0}
  .cw-compose-msg:empty{display:none}
  .cw-compose-msg.err{color:var(--warn)}
  .cw-compose-results{flex:1;min-height:0;overflow-y:auto;padding:8px;display:flex;flex-direction:column;gap:2px}
  .cw-res-hint{color:var(--ink-faint);font-size:12.5px;text-align:center;padding:22px 18px;line-height:1.55}
  .cw-invite{display:flex;align-items:center;gap:11px;width:100%;text-align:left;padding:11px 10px;border:1px dashed var(--hair);border-radius:var(--r-md);background:transparent;cursor:pointer;color:var(--ink);font-size:13px;transition:.12s}
  .cw-invite:hover{border-color:var(--now);background:var(--surface)}
  .cw-invite-ic{flex:none;width:38px;height:38px;border-radius:50%;background:var(--now-tint);color:var(--now);display:grid;place-items:center;font-size:16px}
  .cw-invite b{font-weight:600}
  .cw-invite-sub{display:block;color:var(--ink-soft);font-size:var(--fs-xs);margin-top:1px}
  /* group compose (ALN-163): Chat/Group toggle + multi-select + name */
  /* layout only, the look is the segmented primitive above */
  .cw-compose-seg{display:flex;margin:10px 12px 0}
  .cw-compose-seg>button{flex:1}
  .cw-group-name{margin:10px 12px 0;font:inherit;font-size:14px;color:var(--ink);background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-sm);padding:10px 12px}
  .cw-group-name:focus{outline:none;border-color:var(--now)}
  .cw-group-name[hidden]{display:none}
  .cw-group-chips{display:flex;flex-wrap:wrap;gap:6px;margin:8px 12px 0}
  .cw-group-chips[hidden]{display:none}
  .cw-chip{display:inline-flex;align-items:center;gap:6px;background:var(--now-tint);border:1px solid var(--now-soft);color:var(--now);font-size:12px;font-weight:600;padding:4px 6px 4px 10px;border-radius:999px}
  .cw-chip-x{all:unset;cursor:pointer;color:var(--now);font-size:11px;line-height:1;padding:2px 4px;border-radius:50%}
  .cw-chip-x:hover{background:var(--now);color:var(--on-now)}
  .cw-chip-hint{color:var(--ink-faint);font-size:12px;padding:3px 2px}
  .cw-pick{margin-left:auto;flex:none;width:22px;height:22px;border-radius:50%;border:1.5px solid var(--hair-lit);color:var(--ink-faint);display:grid;place-items:center;font-size:13px;font-weight:700}
  .cw-pick.on{background:var(--now);border-color:var(--now);color:var(--on-now)}
  .cw-thread-row.picked{background:var(--now-tint)}
  .cw-group-foot{flex:none;padding:10px 12px;border-top:1px solid var(--hair-2)}
  .cw-group-create{width:100%;justify-content:center}
  .cw-group-create:disabled{opacity:.5;cursor:default}
  /* group thread: stacked avatar in the rail + header */
  .cw-gav{position:relative;display:inline-flex;width:38px;height:38px;flex:none}
  .cw-gav .chat-avatar{position:absolute;width:26px;height:26px;font-size:11px;border:2px solid var(--surface-2)}
  .cw-gav .cw-gav-0{left:0;top:0;z-index:1}
  .cw-gav .cw-gav-1{right:0;bottom:0}
  .chat-head .cw-gav .chat-avatar{border-color:var(--surface)}
  /* Group header avatar is the two-circle stack itself, no filled disc behind it. */
  #chatAvatar.is-group{background:none;width:38px;height:38px}
  .sn-member{padding:8px 0;border-bottom:1px solid var(--hair-2)}
  .sn-member-name{font-size:12.5px;font-weight:600;color:var(--ink);margin-bottom:3px}
  .sn-pending{color:var(--ink-faint);font-weight:500}
  /* right: active thread pane */
  .cw-thread{position:relative;flex:1;min-width:0;display:flex;flex-direction:column}
  .cw-empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:12px;padding:36px 30px}
  .cw-empty-mark{width:54px;height:54px;border-radius:15px;background:var(--surface-2);color:var(--ink-faint);display:grid;place-items:center}
  .cw-empty-title{font-family:var(--font-display);font-weight:600;font-size:17px;color:var(--ink)}
  .cw-empty-sub{font-size:13.5px;color:var(--ink-soft);line-height:1.55;max-width:34ch;margin:0}
  .cw-empty-new{margin-top:4px}
  .cw-thread-inner{flex:1;min-height:0;display:none;flex-direction:column}
  .chat-win.has-thread .cw-empty{display:none}
  .chat-win.has-thread .cw-thread-inner{display:flex}
  .chat-head{display:flex;align-items:center;gap:11px;padding:13px 14px;border-bottom:1px solid var(--hair-2);flex:none;cursor:move;user-select:none;touch-action:none}
  .chat-avatar{width:34px;height:34px;border-radius:50%;background:var(--now);color:var(--on-now);font-weight:700;font-size:14px;display:flex;align-items:center;justify-content:center;text-transform:uppercase;flex:none}
  .chat-who-wrap{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
  .chat-who{font-weight:600;font-size:15px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.2}
  .chat-presence{font-size:11.5px;color:var(--ink-soft);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.2}
  .chat-presence.live{color:var(--ok)}
  .cw-thread-back{display:none;flex:none;border:none;background:transparent;color:var(--ink-soft);font-size:23px;line-height:1;cursor:pointer;padding:0 4px;border-radius:var(--r-sm)}
  .cw-thread-back:hover{background:var(--surface-2);color:var(--ink)}
  .chat-x{font:inherit;font-size:16px;color:var(--ink-soft);background:transparent;border:none;cursor:pointer;padding:4px 8px;border-radius:8px}
  .chat-x:hover{background:var(--surface-2);color:var(--ink)}
  .cw-thread-x{flex:none;display:none}
  .chat-log{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:8px}
  .chat-empty{color:var(--ink-faint);font-size:14px;margin:auto;text-align:center;padding:0 24px;line-height:1.5}
  .cb{max-width:78%;padding:9px 13px;border-radius:15px;font-size:14px;line-height:1.4;word-wrap:break-word;white-space:pre-wrap}
  .cb.theirs{align-self:flex-start;background:var(--surface-2);color:var(--ink);border-bottom-left-radius:5px}
  .cb.mine{align-self:flex-end;background:var(--now);color:var(--on-now);border-bottom-right-radius:5px}
  .cb-time{font-size:10.5px;opacity:.6;margin-top:3px}
  /* DM file attachments (ALN-133), image preview + downloadable file chip; neutral
     translucent fills read fine on both the accent (.mine) and surface (.theirs) bubble. */
  .cb-img{display:block;margin:0 0 2px;max-width:230px;border-radius:10px;overflow:hidden;line-height:0}
  .cb-img img{display:block;width:100%;height:auto;max-height:300px;object-fit:cover}
  .cb-file{display:flex;align-items:center;gap:9px;margin-bottom:2px;padding:8px 11px;border-radius:11px;background:rgba(127,127,127,.16);text-decoration:none;color:inherit;max-width:250px}
  .cb-file:hover{background:rgba(127,127,127,.26)}
  .cb-file-ic{font-size:19px;flex:none;line-height:1}
  .cb-file-main{min-width:0;display:flex;flex-direction:column;gap:1px}
  .cb-file-name{font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .cb-file-size{font-size:var(--fs-xs);opacity:.72}
  .chat-attach{flex:none;width:42px;height:42px;border:none;background:var(--surface-2);color:var(--ink-soft);border-radius:12px;cursor:pointer;font-size:17px;line-height:1;display:grid;place-items:center;transition:.15s}
  .chat-attach:hover{background:var(--hair-2);color:var(--ink)}
  .chat-pend{display:flex;align-items:center;gap:9px;margin:0 14px 2px;padding:8px 11px;border:1px solid var(--hair-2);border-radius:11px;background:var(--surface-2);font-size:13px;color:var(--ink);flex:none}
  /* [hidden] must win over the display:flex above, or the empty pending-attachment
     bar shows as a gray eyesore whenever no file is staged (it's only meant to
     appear while a file is pending). */
  .chat-pend[hidden]{display:none}
  .chat-pend.err{color:var(--warn);border-color:var(--warn)}
  .chat-pend .cp-ic{flex:none}
  .chat-pend .cp-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .chat-pend .cp-size{color:var(--ink-faint);font-size:var(--fs-xs);flex:none}
  .chat-pend .cp-x{flex:none;border:none;background:transparent;color:var(--ink-soft);cursor:pointer;font-size:15px;line-height:1;padding:2px 5px;border-radius:6px}
  .chat-pend .cp-x:hover{background:var(--hair-2);color:var(--ink)}
  /* E2EE affordances (ALN-134/136): a bare lock glyph in the thread header carries encryption
     state, green when the thread is end-to-end encrypted (safety number ready), grey when not,
     and opens the comparable safety-number panel on click. No box, just the icon. */
  .chat-lock{flex:none;width:32px;height:32px;display:grid;place-items:center;border:none;background:none;color:var(--ink-faint);border-radius:var(--r-sm);cursor:pointer;transition:color .15s,filter .15s}
  .chat-lock svg{display:block}
  .chat-lock:hover{color:var(--ink-soft)}
  .chat-lock.ok{color:var(--ok)}
  .chat-lock.ok:hover{filter:brightness(1.12)}
  .chat-lock:focus-visible{outline:2px solid var(--now);outline-offset:2px}
  .chat-safety{flex:none;margin:8px 14px 2px;padding:12px 13px;background:var(--surface-2);border:1px solid var(--hair-2);border-radius:var(--r-md);font-size:12.5px;color:var(--ink-soft);line-height:1.5}
  .chat-safety[hidden]{display:none}
  .chat-safety .sn-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
  .chat-safety .sn-title{font-family:var(--font-mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint)}
  .chat-safety .sn-copy{font-family:var(--font-mono);font-size:9.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--now);background:none;border:1px solid var(--now-soft);border-radius:var(--r-xs);padding:4px 8px;cursor:pointer;transition:.15s}
  .chat-safety .sn-copy:hover{background:var(--now);color:var(--on-now);border-color:transparent}
  .chat-safety .sn-num{margin:9px 0;font-family:var(--font-mono);font-size:15px;letter-spacing:.06em;color:var(--ink);word-spacing:4px;word-break:break-word;line-height:1.75;text-align:center;background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-sm);padding:11px 8px}
  .chat-safety .sn-hint{color:var(--ink-soft);font-size:var(--fs-xs);line-height:1.5}
  .chat-gate{flex:none;margin:0 14px 6px;padding:9px 12px;background:var(--surface-2);border:1px solid var(--hair-2);border-radius:11px;font-size:12.5px;color:var(--ink-soft);text-align:center}
  .cb-att{min-width:120px}
  .cb-att .cb-att-ph{display:grid;place-items:center;min-height:88px;min-width:120px;font-size:26px;opacity:.55}
  .cb-err{opacity:.75;font-style:italic}
  /* A legacy (pre-E2EE, server-readable) message, visually distinct so it can't
     be mistaken for an end-to-end-authenticated one (ALN-134 security review). */
  .cb-legacy{font-size:10px;letter-spacing:.02em;opacity:.6;margin-top:3px}
  .cb-legacy-msg{border:1px dashed var(--hair);opacity:.9}   /* --line was never a token: this always fell through to a fixed grey that ignored the palette */
  .chat-input input:disabled,.chat-attach:disabled,.chat-input .btn:disabled{opacity:.45;cursor:not-allowed}
  .chat-day{align-self:center;font-size:11px;color:var(--ink-faint);margin:6px 0}
  /* ── Shared plan panel (ALN-141) ────────────────────────────────────────────
     Three zones carry the anti-backlog design: "up next" at full weight, "also"
     receded, "settled" collapsed behind a count. Amber is spent only on the
     take-into-my-day action and focus rings (the One-Signal Rule), and nothing
     here breathes, so the current task in Today keeps that signal to itself. */
  /* [hidden] is only a UA `display:none`, so ANY author display rule beats it.
     These four all set display, so without this the Plan pane, the chat log and
     the composer would all render at once whichever tab was chosen (ALN-141). */
  .cw-tabs[hidden],.plan-pane[hidden],.chat-log[hidden],.chat-input[hidden],.cw-menu[hidden]{display:none}
  /* Thread actions (ALN-267 / ALN-268). Anchored to the thread pane, which is the
     positioned ancestor, so it escapes the head's own layout without a portal. */
  .chat-more{flex:none;background:transparent;border:none;color:var(--ink-faint);font-size:var(--fs-body);line-height:1;padding:6px;border-radius:var(--r-sm);cursor:pointer}
  .chat-more:hover{color:var(--ink)}
  .chat-more:focus-visible{outline:none;box-shadow:var(--ring)}
  .cw-menu{position:absolute;top:52px;right:12px;z-index:5;min-width:210px;display:flex;flex-direction:column;padding:6px;background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-md);box-shadow:var(--shadow-lg)}
  .cw-menu-item{width:100%;justify-content:flex-start;font:inherit;font-size:var(--fs-ui);color:var(--ink);background:transparent;border:none;border-radius:var(--r-sm);padding:9px 10px;text-align:left;cursor:pointer}
  .cw-menu-item:hover{background:var(--surface-2)}
  .cw-menu-item:focus-visible{outline:none;box-shadow:var(--ring)}
  .cw-menu-warn{color:var(--warn)}
  .cw-menu-note{margin:4px 8px 2px;font-size:var(--fs-sm);color:var(--ink-soft);line-height:1.45;max-width:34ch}
  /* In the header row, so the plan costs the conversation no vertical space.
     Layout only, the look is the segmented primitive above. */
  .cw-tabs{flex:none}
  .cw-tabs>button{padding:6px 13px;min-height:30px}   /* a touch tighter: it sits in a dense header */
  .plan-pane{flex:1;min-height:0;display:flex;flex-direction:column}
  .pl-body{flex:1;min-height:0;overflow-y:auto;padding:14px 14px 8px;display:flex;flex-direction:column;gap:18px}
  .pl-zone{display:flex;flex-direction:column;gap:2px}
  .pl-zone-label{font-family:var(--font-mono);font-size:var(--fs-xs);font-weight:700;letter-spacing:.14em;color:var(--ink-faint);margin-bottom:6px}
  .pl-row{display:flex;align-items:flex-start;gap:10px;padding:8px 8px 8px 6px;border:1px solid transparent;border-radius:var(--r-md);transition:background .15s,border-color .15s}
  .pl-row:hover{background:var(--surface-2)}
  /* Icons take the type step they sit beside (1em, currentColor) rather than
     declaring their own size, and the hit area is a real 44px target pulled back
     with negative margin so the row keeps its rhythm. */
  .pl-check{flex:none;min-width:44px;min-height:44px;margin:-10px 0 -10px -12px;font-size:var(--fs-h3);line-height:1;color:var(--ink-faint);background:transparent;border:none;border-radius:var(--r-pill);cursor:pointer;transition:color .15s}
  .pl-check:hover{color:var(--ink-soft)}
  .pl-check[aria-pressed="true"]{color:var(--ok)}
  .pl-check:focus-visible{outline:none;box-shadow:var(--ring)}
  .pl-main{flex:1;min-width:0}
  .pl-title{font-size:var(--fs-body);line-height:1.45;color:var(--ink);overflow-wrap:anywhere}
  .pl-row.quiet .pl-title{font-size:var(--fs-sm);color:var(--ink-soft)}
  .pl-row.done .pl-title{color:var(--ink-faint);text-decoration:line-through}
  .pl-meta{display:flex;flex-wrap:wrap;gap:10px;margin-top:3px;font-family:var(--font-mono);font-size:var(--fs-xs);font-weight:700;letter-spacing:.1em;color:var(--ink-faint)}
  /* No overdue state, ever: a day is a hint, so nothing here reddens or counts late. */
  .pl-when{color:var(--ink-faint)}
  .pl-take{flex:none;font:inherit;font-size:var(--fs-sm);color:var(--now);background:transparent;border:1px solid var(--now-soft);border-radius:var(--r-sm);padding:5px 10px;cursor:pointer;opacity:0;transition:opacity .15s,background .15s}
  .pl-row:hover .pl-take,.pl-take:focus-visible,.pl-row:focus-within .pl-take{opacity:1}
  .pl-take:hover{background:var(--now-tint)}
  .pl-take:focus-visible{outline:none;box-shadow:var(--ring)}
  .pl-del{flex:none;min-width:44px;min-height:44px;margin:-10px -10px -10px 0;font-size:var(--fs-body);line-height:1;color:var(--ink-faint);background:transparent;border:none;border-radius:var(--r-sm);cursor:pointer;opacity:0;transition:opacity .15s,color .15s}
  .pl-row:hover .pl-del,.pl-row:focus-within .pl-del,.pl-del:focus-visible{opacity:1}
  .pl-del:hover{color:var(--warn)}
  .pl-del:focus-visible{outline:none;box-shadow:var(--ring)}
  .pl-confirm{display:flex;align-items:center;gap:8px;margin-top:6px;font-size:var(--fs-sm);color:var(--ink-soft)}
  .pl-confirm button{font:inherit;font-size:var(--fs-sm);border-radius:var(--r-sm);padding:3px 9px;cursor:pointer;border:1px solid var(--hair-2);background:var(--surface)}
  .pl-yes{color:var(--warn)}
  .pl-no{color:var(--ink-soft)}
  .pl-confirm button:focus-visible{outline:none;box-shadow:var(--ring)}
  .pl-row.bad{color:var(--ink-faint)}
  .pl-row.bad .pl-title{font-size:var(--fs-sm);font-style:italic;color:var(--ink-faint)}
  .pl-badmark{flex:none;margin-top:2px;font-size:var(--fs-sm);color:var(--ink-faint)}
  .pl-settled-toggle{width:100%;justify-content:space-between;font-family:var(--font-mono);font-size:var(--fs-xs);font-weight:700;letter-spacing:.14em;color:var(--ink-faint);background:transparent;border:none;padding:4px 2px;cursor:pointer;border-radius:var(--r-sm)}
  .pl-settled-toggle:hover{color:var(--ink-soft)}
  .pl-settled-toggle:focus-visible{outline:none;box-shadow:var(--ring)}
  .pl-gate,.pl-empty{margin:auto 0;padding:18px 16px;text-align:center;color:var(--ink-soft)}
  .pl-empty-title{font-family:var(--font-display);font-size:var(--fs-h2);font-weight:600;color:var(--ink);margin-bottom:6px}
  .pl-empty-sub{font-size:var(--fs-sm);color:var(--ink-soft);max-width:42ch;margin:0 auto;line-height:1.5}
  .pl-gate{font-size:var(--fs-sm)}
  .pl-skeleton{display:flex;flex-direction:column;gap:10px;padding:4px 2px}
  .pl-skeleton span{height:34px;border-radius:var(--r-md);background:var(--surface-2)}
  .pl-add{flex:none;display:flex;flex-direction:column;gap:8px;padding:10px 14px 12px;border-top:1px solid var(--hair-2)}
  .pl-input{width:100%;font:inherit;font-size:var(--fs-body);color:var(--ink);background:var(--surface-2);border:1px solid var(--hair-2);border-radius:var(--r-sm);padding:10px 12px}
  .pl-input:focus{outline:none;border-color:var(--now)}
  .pl-add-opts{display:flex;gap:8px;align-items:center}
  .pl-day{font:inherit;font-size:var(--fs-sm);color:var(--ink-soft);background:var(--surface-2);border:1px solid var(--hair-2);border-radius:var(--r-sm);padding:7px 9px;min-width:0}
  /* Who an item is on is a SET (everyone / me / any combination), so it is toggle
     chips rather than a single-choice select. The roster is at most five people. */
  .pl-owner{flex:1;display:flex;flex-wrap:wrap;gap:4px;min-width:0}
  .pl-chip{font:inherit;font-size:var(--fs-sm);color:var(--ink-soft);background:var(--surface-2);border:1px solid var(--hair-2);border-radius:var(--r-pill);padding:5px 10px;cursor:pointer}
  .pl-chip:hover{color:var(--ink)}
  .pl-chip.on{color:var(--now);border-color:var(--now-soft);background:var(--now-tint)}
  .pl-chip:focus-visible{outline:none;box-shadow:var(--ring)}
  .pl-who{font:inherit;font-size:var(--fs-xs);font-weight:700;letter-spacing:.1em;color:var(--ink-faint);background:transparent;border:none;padding:0;cursor:pointer}
  .pl-who:hover{color:var(--ink-soft)}
  .pl-who:focus-visible{outline:none;box-shadow:var(--ring)}
  .pl-stand{color:var(--ink-faint)}
  .pl-row.mine-done .pl-title{color:var(--ink-soft)}
  .pl-assign{display:flex;flex-wrap:wrap;gap:4px;margin-top:8px}
  .pl-pick{font:inherit;font-size:var(--fs-sm);color:var(--ink-soft);background:var(--surface-2);border:1px solid var(--hair-2);border-radius:var(--r-pill);padding:5px 10px;cursor:pointer}
  .pl-pick.on{color:var(--now);border-color:var(--now-soft);background:var(--now-tint)}
  .pl-pick:focus-visible,.pl-assign-done:focus-visible{outline:none;box-shadow:var(--ring)}
  .pl-assign-done{font:inherit;font-size:var(--fs-sm);color:var(--ink-soft);background:transparent;border:none;padding:5px 8px;cursor:pointer;text-decoration:underline}
  .pl-owner:focus,.pl-day:focus{outline:none;border-color:var(--now)}
  .pl-add-go{flex:none}
  .pl-add input:disabled,.pl-add select:disabled,.pl-add .btn:disabled{opacity:.45;cursor:not-allowed}
  /* A write is in flight: the row dims until the server confirms. State, not decoration. */
  .pl-row.pending{opacity:.5}
  /* Hover is not available on touch, so the row actions are always present there,
     or "take into my day" and remove would simply not exist on a phone. */
  @media (hover:none){.pl-take,.pl-del{opacity:1}}
  @media (max-width:520px){
    /* The header is tight on a phone: the switch keeps its labels (an icon-only
       Chat/Plan toggle would be a guess), so the name column yields instead. */
    .cw-tab{padding:5px 8px}
    .chat-who-wrap{min-width:0}
    .pl-add-opts{flex-wrap:wrap}
    .pl-owner{flex:1 1 100%}
    .pl-day{flex:1}
    .pl-take span{display:none}   /* the icon carries it once the row is tight */
    .pl-body{padding:12px 10px 8px}
  }
  @media (prefers-reduced-motion:reduce){.cw-tab,.pl-row,.pl-take,.pl-del,.pl-check{transition:none}}
  .chat-input{display:flex;gap:9px;padding:12px 14px;border-top:1px solid var(--hair-2);flex:none}
  .chat-input input{flex:1;font:inherit;font-size:14px;color:var(--ink);background:var(--surface-2);border:1px solid var(--hair-2);border-radius:12px;padding:11px 14px}
  .chat-input input:focus{outline:none;border-color:var(--now)}
  /* Messages window, single-column on phones: the rail and the thread swap in place
     (thread overlays, .view-thread toggles), each full-width. Zero horizontal overflow (ALN-32/34). */
  @media (max-width:640px){
    .chat-win{width:calc(100vw - 16px);height:calc(100dvh - var(--topbar) - 24px);left:8px;top:calc(var(--topbar) + 12px);transform:none;border-radius:16px}
    .cw-rail{width:100%;border-right:none}
    .cw-thread{position:absolute;inset:0;background:var(--surface);z-index:3;display:none}
    .chat-win.view-thread .cw-thread{display:flex}
    .chat-win.view-thread .cw-rail{display:none}
    .cw-thread-back{display:block}
    .cw-thread-x{display:block}
  }
  /* ── Floating focus (Pomodoro) timer, ALN-67. Floats like .chat-win; HUD flourishes (2-corner chamfer) gate on --hud-strength (0 light / 1 dark); the border breathes when running, like the NowCard. ── */
  /* Floating session puck (ALN-181): a minimized session view, mini constellation + name +
     presence/audio, tap to return, close to dismiss. Bottom-right so it clears the top-right
     pomodoro puck; lifted above the mobile bottom nav. */
  .session-puck{position:fixed;right:16px;bottom:16px;z-index:59;display:flex;align-items:center;gap:6px;
    background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-pill);box-shadow:var(--shadow-lg);padding:6px 8px 6px 6px;max-width:min(280px,92vw)}
  .session-puck[hidden]{display:none}
  .sp-main{display:flex;align-items:center;gap:10px;background:transparent;border:0;cursor:pointer;padding:2px;border-radius:var(--r-pill);color:var(--ink);text-align:left;min-width:0}
  .sp-main:focus-visible{outline:2px solid var(--now);outline-offset:2px}
  .sp-web{position:relative;width:46px;height:46px;border-radius:50%;overflow:hidden;flex:none;background:#010206;box-shadow:inset 0 0 0 1px var(--hair-2)}
  .sp-web canvas{width:100%;height:100%;display:block;pointer-events:none}
  .sp-info{display:flex;flex-direction:column;gap:1px;min-width:0}
  .sp-name{font-size:12.5px;font-weight:700;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:150px}
  .sp-meta{font-size:var(--fs-xs);color:var(--ink-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:5px}
  .sp-live{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--now);box-shadow:0 0 6px var(--now)}
  .sp-close{flex:none;width:22px;height:22px;border-radius:50%;border:1px solid var(--hair-2);background:var(--surface-2);color:var(--ink-soft);cursor:pointer;font-size:11px;line-height:1;display:inline-flex;align-items:center;justify-content:center}
  .sp-close:hover{color:var(--ink);border-color:var(--ink-faint)}
  @media (max-width:860px){.session-puck{bottom:calc(var(--botnav-h,74px) + 12px)}}
  /* --nc-edge as well as --nc-glow (ALN-264). tl-breathe animates `filter` and builds
     it out of var(--nc-edge); .pomo declared only the glow, so the whole filter was
     invalid at computed-value time and fell back to `none`. Being an animation it also
     beat the @container rule below, so a RUNNING timer had no rim or glow at all.
     .now-card has always declared both, which is why it never showed this. */
  .pomo{position:fixed;right:18px;top:calc(var(--topbar) + 18px);z-index:60;width:min(340px,92vw);display:none;--nc-glow:var(--now-glow);--nc-edge:var(--now);
    background:var(--surface);border:1px solid var(--hair-2);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);overflow:hidden;transition:border-color .3s}
  .pomo.open{display:block}
  .pomo.running{border-color:var(--now-soft);animation:tl-breathe 4.2s ease-in-out infinite}
  /* Pomodoro: the same 2-corner chamfer as the NowCard/sheets on dark HUD, retiring the old .pomo-hud corner ticks. The minimised puck stays rounded. Gated on --hud-strength (ALN-118 follow-up). */
  @container style(--hud-strength: 1){
    /* The NowCard's lit rim, applied here too (ALN-264).
       Two things had to change together.
       1. The clip polygon now ROUNDS the NW/SE corners instead of squaring them, using
          the same quarter-circle approximation the NowCard uses (the 0.76/2.93/6.17
          steps are points on a 10px arc at 22.5 degree intervals). A square clip corner
          against a rounded background left a lens of slack that the cyan behind the
          panel showed through, which was the whole of "why does it only glow on NW and
          SE": measured peak cyan 73/16/73/16 around the four corners, now even.
       2. The rim itself is a PAINTED RING, not a shadow. drop-shadow draws behind the
          element, so on an opaque panel a hairline is hidden by the panel itself, and
          stacking more changes nothing (measured: 2, 4, 6, 8 and 10 stacked hairlines
          all read 16, against the NowCard's 73). So the border box carries a 1.4px
          gradient and ::after paints the surface inside it, exactly as .now-card does
          with .nc-in. The gradient runs at 135deg, PERPENDICULAR to the NE/SW chamfer
          diagonal, which is ALN-260's fix for the sheet: it puts both chamfers at 50%
          along the gradient so they get equal light. Deliberately NOT the NowCard's
          150deg, which is one-sided and is ALN-262's open bug.
       The minimised puck keeps its own rounding and surface, hence :not(.min). */
    .pomo:not(.min){clip-path:polygon(0 10px,0.76px 6.17px,2.93px 2.93px,6.17px 0.76px,10px 0,calc(100% - 15px) 0,100% 15px,100% calc(100% - 10px),calc(100% - 0.76px) calc(100% - 6.17px),calc(100% - 2.93px) calc(100% - 2.93px),calc(100% - 6.17px) calc(100% - 0.76px),calc(100% - 10px) 100%,15px 100%,0 calc(100% - 15px));border:0;border-radius:10px;padding:1.4px;background:linear-gradient(135deg,var(--nc-edge),color-mix(in srgb,var(--nc-edge) 55%,#fff) 50%,var(--nc-edge));filter:drop-shadow(0 0 13px var(--nc-glow))}
    /* The surface, inset by the ring. inset must be stated explicitly: an absolutely
       positioned box resolves against the PADDING box, which includes the padding, so
       inset:0 would cover the ring it is meant to sit inside. */
    .pomo:not(.min)::after{content:"";position:absolute;inset:1.4px;background:var(--surface);clip-path:polygon(0 8.6px,0.65px 5.31px,2.52px 2.52px,5.31px 0.65px,8.6px 0,calc(100% - 13px) 0,100% 13px,100% calc(100% - 8.6px),calc(100% - 0.65px) calc(100% - 5.31px),calc(100% - 2.52px) calc(100% - 2.52px),calc(100% - 5.31px) calc(100% - 0.65px),calc(100% - 8.6px) 100%,13px 100%,0 calc(100% - 13px));pointer-events:none;z-index:0}
  }
  /* The puck breathes with its box-shadow ONLY, never the filter (ALN-264 follow-up).
     tl-breathe runs on .pomo.running whether or not it is minimised, and its filter had
     been silently dead until --nc-edge was declared, so switching that on lit the puck
     up like a flare. The cause is not the blur radius: filter:drop-shadow re-renders the
     element INCLUDING its box-shadow, so four stacked shadows compound the 34px glow
     about fivefold. Zeroing the blur does nothing, the filter has to be absent. Hence a
     separate keyframes rather than a variable: an animation beats any normal
     declaration, so the only way to drop a property is to animate a different one. */
  @keyframes tl-breathe-min{0%,100%{box-shadow:0 0 0 1px var(--now),0 0 18px -2px var(--now-glow),var(--shadow-lg)}50%{box-shadow:0 0 0 1px var(--now),0 0 34px 1px var(--now-glow),var(--shadow-lg)}}
  .pomo.min.running{animation-name:tl-breathe-min}
  .pomo-btn:active{transform:scale(.93)}
  @keyframes pomoFlash{0%{transform:scale(1)}35%{transform:scale(1.04)}100%{transform:scale(1)}}
  .pomo-flash{animation:pomoFlash .34s var(--ease)}
  .pomo-head{position:relative;z-index:1;display:flex;align-items:center;gap:9px;padding:15px 13px 15px 22px;border-bottom:1px solid var(--hair-2);cursor:grab;user-select:none;touch-action:none}
  .pomo-head:active{cursor:grabbing}
  .pomo-lamp{width:9px;height:9px;border-radius:50%;background:var(--now);flex:none;box-shadow:0 0 0 4px var(--now-glow)}
  .pomo.running .pomo-lamp{animation:tl-beat 2.4s var(--ease) infinite}
  .pomo-title{font-family:var(--font-display);font-weight:600;font-size:14.5px;color:var(--ink);flex:none}
  .pomo-phase{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.15em;text-transform:uppercase;color:var(--now-text);border:1px solid var(--now-soft);background:var(--now-tint);border-radius:999px;padding:3px 9px;white-space:nowrap;line-height:1.35}
  .pomo-grip{margin-left:auto;color:var(--ink-faint);font-size:12px;letter-spacing:1px;opacity:.55}
  .pomo-x{background:none;border:none;color:var(--ink-faint);font-size:15px;line-height:1;cursor:pointer;padding:4px 6px;border-radius:7px}
  .pomo-x:hover{background:var(--surface-2);color:var(--ink)}
  .pomo-body{position:relative;z-index:1;padding:20px 18px 18px;display:flex;flex-direction:column;align-items:center;gap:14px}
  .pomo-dial{position:relative;width:176px;height:176px}
  .pomo-dial svg{width:100%;height:100%;transform:rotate(-90deg)}
  .pomo-dial circle{fill:none;stroke-width:7;stroke-linecap:round}
  .pomo-dial .trk{stroke:var(--hair-2)}
  .pomo-dial .prg{stroke:var(--now);filter:drop-shadow(0 0 6px var(--now-glow));transition:stroke-dashoffset .95s linear,stroke .3s}
  .pomo-cap{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px}
  .pomo-digits{font-family:var(--font-mono);font-weight:600;font-size:36px;letter-spacing:-.01em;color:var(--ink);font-variant-numeric:tabular-nums;line-height:1}
  .pomo-sub{font-family:var(--font-mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-faint)}
  .pomo-task{text-align:center;font-size:13.5px;color:var(--ink-soft);line-height:1.4;width:100%;padding:0 6px;overflow-wrap:anywhere}
  .pomo-task b{color:var(--ink);font-weight:600}
  .pomo .pomo-dots{display:flex;gap:7px;align-items:center;min-height:8px}
  .pomo .dot{width:8px;height:8px;border-radius:50%;border:1.5px solid var(--now-soft)}
  .pomo .dot.on{background:var(--now);border-color:var(--now);box-shadow:0 0 6px var(--now-glow)}
  .pomo .dot.cur{border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .pomo-ctrls{display:flex;align-items:center;gap:10px}
  .pomo-btn{width:42px;height:42px;border-radius:var(--r-sm);border:1px solid var(--hair);background:var(--surface);color:var(--ink-soft);font-size:15px;cursor:pointer;display:grid;place-items:center;transition:.15s}
  .pomo-btn:hover{border-color:var(--now);color:var(--ink)}
  .pomo-btn.go{width:52px;height:52px;border:none;background:var(--now);color:var(--on-now);box-shadow:0 0 0 4px var(--now-glow);font-size:18px}
  .pomo-btn.go:hover{filter:brightness(1.06)}
  .pomo-btn:focus-visible,.pomo-x:focus-visible,.pomo-preset:focus-visible,.pomo .tgl:focus-visible,.pomo-test:focus-visible,.pomo-back:focus-visible{outline:2px solid var(--now);outline-offset:2px}
  /* break phase, recolour to the recharge green (--ok exists in every palette) */
  .pomo.break{--now:var(--ok);--now-soft:color-mix(in srgb,var(--ok) 50%,transparent);--now-tint:color-mix(in srgb,var(--ok) 12%,var(--surface));--now-glow:color-mix(in srgb,var(--ok) 32%,transparent)}
  .pomo.paused .pomo-dial .prg{opacity:.5}
  .pomo.paused .pomo-digits{color:var(--ink-faint)}
  /* minimize → puck (owner ask: dbl-click to expand) */
  .pomo.min{width:auto}
  .pomo.min .pomo-head,.pomo.min .pomo-task,.pomo.min .pomo-dots,.pomo.min .pomo-ctrls,.pomo.min .pomo-sub,.pomo.min .pomo-set{display:none}
  .pomo.min .pomo-body{padding:12px}
  .pomo.min .pomo-dial{width:104px;height:104px;cursor:grab}
  .pomo.min .pomo-digits{font-size:23px}
  /* in-window settings face */
  .pomo-set{display:none;position:relative;z-index:1;background:var(--surface);max-height:372px;flex-direction:column}
  .pomo.settings .pomo-body{display:none}
  .pomo.settings .pomo-set{display:flex}
  .pomo.settings .pomo-gear{color:var(--now)}
  .pomo-set-head{display:flex;align-items:center;padding:12px 14px 6px}
  .pomo-back{font-family:var(--font-ui);font-size:12.5px;font-weight:600;color:var(--ink-soft);background:none;border:none;cursor:pointer;padding:4px 2px}
  .pomo-set-scroll{flex:1;min-height:0;overflow-y:auto;padding:2px 14px 16px;display:flex;flex-direction:column;gap:13px}
  .pomo-group{display:flex;flex-direction:column;gap:9px;padding-bottom:12px;border-bottom:1px solid var(--hair-2)}
  .pomo-group:last-child{border-bottom:none;padding-bottom:2px}
  .pomo-label{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.15em;text-transform:uppercase;color:var(--ink-faint)}
  .pomo-row{display:flex;align-items:center;justify-content:space-between;gap:12px}
  .pomo-name{font-size:13px;color:var(--ink-soft)}
  .pomo-presets{display:flex;flex-wrap:wrap;gap:6px}
  .pomo-preset{font-family:var(--font-ui);font-size:11.5px;color:var(--ink-soft);background:var(--surface);border:1px solid var(--hair);border-radius:999px;padding:5px 11px;cursor:pointer}
  .pomo-preset.on{color:var(--on-now);background:var(--now);border-color:transparent;font-weight:600}
  .pomo .stepper{display:flex;align-items:center;gap:7px;font-family:var(--font-mono);font-size:12.5px;color:var(--ink)}
  .pomo .stepper button{width:24px;height:24px;border-radius:var(--r-sm);border:1px solid var(--hair);background:var(--surface);color:var(--ink-soft);cursor:pointer;font-size:14px;line-height:1;display:grid;place-items:center}
  .pomo .stepper button:hover{border-color:var(--now);color:var(--ink)}
  .pomo .stepper b{min-width:18px;text-align:right;font-variant-numeric:tabular-nums}
  .pomo .stepper span{color:var(--ink-faint);font-size:10.5px;min-width:20px}
  .pomo .tgl{width:38px;height:22px;border-radius:999px;border:1px solid var(--hair);background:var(--surface-2);position:relative;cursor:pointer;flex:none;transition:.18s}
  .pomo .tgl::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--ink-faint);transition:.18s}
  .pomo .tgl.on{background:var(--now-tint);border-color:var(--now-soft)}
  .pomo .tgl.on::after{left:18px;background:var(--now);box-shadow:0 0 8px var(--now-glow)}
  .pomo-sel{font-family:var(--font-ui);font-size:12.5px;color:var(--ink);background:var(--surface-2);border:1px solid var(--hair);border-radius:var(--r-sm);padding:5px 8px;cursor:pointer}
  .pomo-sel:focus{outline:none;border-color:var(--now)}
  .pomo-range{accent-color:var(--now);max-width:120px}
  .pomo-test{align-self:flex-start;margin-top:2px;font-family:var(--font-ui);font-size:12.5px;font-weight:600;color:var(--on-now);background:var(--now);border:none;border-radius:var(--r-sm);padding:8px 14px;cursor:pointer;box-shadow:0 0 0 3px var(--now-glow)}
  .pomo-test:hover{filter:brightness(1.06)}
  @media (max-width:520px){.pomo{right:8px;left:8px;width:auto}.pomo.min{left:auto;width:auto}}
  /* notifications */
  .notif-bell{position:relative;color:var(--ink-soft);background:transparent;border:1px solid var(--hair);border-radius:var(--r-sm);width:36px;height:36px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:.15s}
  .notif-bell:hover{background:var(--surface-2);color:var(--ink)}
  .notif-bell svg{display:block}
  .notif-badge{display:none;position:absolute;top:-5px;right:-5px;min-width:17px;height:17px;padding:0 4px;border-radius:9px;background:color-mix(in srgb,var(--warn) 75%,#000);color:#fff;font-size:11px;font-weight:700;line-height:17px;text-align:center}
  .notif-badge.on{display:block}
  .notif-bd{position:fixed;inset:0;z-index:1100;background:transparent;display:none}
  .notif-bd.open{display:block}
  .notif-drawer{position:fixed;top:calc(var(--topbar) + 10px);right:14px;display:flex;flex-direction:column;width:min(380px,calc(100vw - 28px));max-height:min(70vh,560px);background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);overflow:hidden;animation:notifIn .2s cubic-bezier(.2,.8,.3,1)}
  @keyframes notifIn{from{transform:translateY(-8px);opacity:.4}to{transform:translateY(0);opacity:1}}
  .notif-head{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:14px 14px 14px 18px;border-bottom:1px solid var(--hair-2);flex:none}
  .nh-title{font-family:var(--font-display);font-weight:600;font-size:16px;color:var(--ink)}
  .nh-actions{display:flex;align-items:center;gap:6px}
  .nh-sort{font:inherit;font-size:12px;color:var(--ink-soft);background:var(--surface-2);border:1px solid var(--hair-2);border-radius:var(--r-xs);padding:5px 7px;cursor:pointer}
  .nh-sort:focus{outline:none;border-color:var(--now)}
  .nh-clear{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-soft);background:transparent;border:1px solid var(--hair-2);border-radius:var(--r-xs);padding:5px 10px;cursor:pointer;transition:.15s}
  .nh-clear:hover{color:var(--ink);background:var(--surface-2)}
  .notif-x{font:inherit;font-size:16px;color:var(--ink-soft);background:transparent;border:none;cursor:pointer;padding:4px 8px;border-radius:var(--r-xs)}
  .notif-x:hover{background:var(--surface-2);color:var(--ink)}
  .notif-list{flex:1;overflow-y:auto;padding:8px 0}
  .notif-empty{color:var(--ink-faint);font-size:14px;text-align:center;padding:48px 24px;line-height:1.5}
  .notif-item{display:flex;gap:12px;width:100%;text-align:left;padding:13px 18px;background:transparent;border:none;border-bottom:1px solid var(--hair);cursor:pointer;transition:.12s}
  .notif-item:hover{background:var(--surface-2)}
  .notif-item.unread{background:color-mix(in srgb,var(--now) 9%,transparent)}
  .notif-item.unread:hover{background:color-mix(in srgb,var(--now) 14%,transparent)}
  .ni-dot{flex:none;width:9px;height:9px;border-radius:50%;margin-top:5px;background:var(--ink-faint)}
  .ni-dot.ni-nudge,.ni-dot.ni-message{background:var(--now)}
  .ni-dot.ni-friend_accepted,.ni-dot.ni-online{background:var(--ok)}
  .ni-dot.ni-friend_request{background:var(--warn)}
  .ni-main{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
  .ni-text{font-size:14px;color:var(--ink);line-height:1.4}
  .ni-text strong{font-weight:600}
  .nt-sub{font-size:12.5px;color:var(--ink-soft);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ni-time{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-faint)}
  .ni-dot.ni-hand_off{background:var(--now)}
  .ni-dot.ni-handoff_accepted{background:var(--ok)}
  /* ── Hand-offs tray + compose (ALN-140). Mirrors the notifications dropdown: a
     top-right floating panel over the mist wash, hairline framed, mono labels,
     amber only on the actions (accept / send / new). ── */
  .handoff-bd{position:fixed;inset:0;z-index:1100;background:transparent;display:none}
  .handoff-bd.open{display:block}
  .handoff-drawer{position:fixed;top:calc(var(--topbar) + 10px);right:14px;display:flex;flex-direction:column;width:min(400px,calc(100vw - 28px));max-height:min(76vh,620px);background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);overflow:hidden;animation:notifIn .2s cubic-bezier(.2,.8,.3,1)}
  .handoff-head{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:14px 14px 14px 18px;border-bottom:1px solid var(--hair-2);flex:none}
  .hoh-title{font-family:var(--font-display);font-weight:600;font-size:16px;color:var(--ink)}
  .hoh-actions{display:flex;align-items:center;gap:6px}
  .hoh-new{font-family:var(--font-mono);font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft);background:transparent;border:1px solid var(--now-soft);border-radius:var(--r-xs);padding:6px 11px;cursor:pointer;transition:.15s}
  .hoh-new:hover{background:var(--now-tint);border-color:var(--now)}
  .handoff-list-wrap{flex:1;overflow-y:auto;min-height:0}
  .handoff-list{padding:8px 0}
  .ho-empty{color:var(--ink-soft);text-align:center;padding:40px 26px 34px;line-height:1.5}
  .ho-empty-lead{font-size:14.5px;color:var(--ink);margin:0 0 4px}
  .ho-empty-sub{font-size:13px;color:var(--ink-soft);margin:0 0 20px;max-width:30ch;margin-inline:auto}
  .ho-empty-new{font-family:var(--font-mono);font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--now);background:var(--now-tint);border:1px solid var(--now-soft);border-radius:var(--r-sm);padding:9px 15px;cursor:pointer;transition:.15s}
  .ho-empty-new:hover{border-color:var(--now)}
  .ho-item{display:flex;gap:12px;align-items:flex-start;padding:14px 18px;border-bottom:1px solid var(--hair)}
  .ho-item:last-child{border-bottom:none}
  .ho-av{flex:none;width:34px;height:34px;border-radius:50%;overflow:hidden;margin-top:1px}
  .ho-av :is(img,span,div){width:100%;height:100%}
  .ho-main{flex:1;min-width:0}
  .ho-from{font-size:12.5px;color:var(--ink-soft);line-height:1.35}
  .ho-from strong{font-weight:600;color:var(--ink)}
  .ho-title{font-size:15px;font-weight:600;color:var(--ink);line-height:1.3;margin:2px 0 3px;word-break:break-word}
  .ho-when{font-family:var(--font-mono);font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-soft)}
  .ho-note{font-size:12.5px;color:var(--ink-soft);line-height:1.45;margin-top:5px;word-break:break-word}
  .ho-unreadable{font-size:12.5px;color:var(--ink-faint);margin-top:3px}
  .ho-acts{flex:none;display:flex;flex-direction:column;gap:6px;align-items:stretch}
  .ho-btn{font-family:var(--font-mono);font-size:10.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-soft);background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-xs);padding:7px 12px;cursor:pointer;transition:.14s}
  .ho-btn:hover{border-color:var(--ink-faint);color:var(--ink)}
  .ho-btn.go{color:var(--on-now);background:var(--now);border-color:var(--now)}
  .ho-btn.go:hover{filter:brightness(.96)}
  /* compose */
  .handoff-compose{display:flex;flex-direction:column;min-height:0;overflow-y:auto;padding:14px 18px 18px}
  .ho-back{align-self:flex-start;font-family:var(--font-mono);font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft);background:transparent;border:none;cursor:pointer;padding:2px 0 12px}
  .ho-back:hover{color:var(--now)}
  .ho-form{display:flex;flex-direction:column;gap:13px}
  .ho-field{display:flex;flex-direction:column;gap:6px;position:relative;min-width:0}
  .ho-lbl{font-family:var(--font-mono);font-size:10px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint)}
  .ho-opt{color:var(--ink-faint);font-weight:400;letter-spacing:.04em;margin-left:7px}
  .ho-input{font:inherit;font-size:14px;color:var(--ink);background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-sm);padding:10px 12px;width:100%;transition:.15s}
  .ho-input::placeholder{color:var(--ink-soft)}
  .ho-input:focus{outline:none;border-color:var(--now);box-shadow:0 0 0 3px var(--now-glow)}
  .ho-ta{resize:vertical;min-height:44px}
  .ho-row{display:grid;grid-template-columns:1.3fr 1fr 1fr;gap:9px}
  .ho-fr-results{display:flex;flex-direction:column;gap:2px;margin-top:4px;max-height:190px;overflow-y:auto}
  .ho-fr{display:flex;align-items:center;gap:10px;text-align:left;background:transparent;border:1px solid transparent;border-radius:var(--r-sm);padding:7px 9px;cursor:pointer;transition:.12s}
  .ho-fr:hover{background:var(--surface-2);border-color:var(--hair-2)}
  .ho-fr-av{flex:none;width:28px;height:28px;border-radius:50%;overflow:hidden}
  .ho-fr-av :is(img,span,div){width:100%;height:100%}
  .ho-fr-main{display:flex;flex-direction:column;min-width:0}
  .ho-fr-name{font-size:13.5px;color:var(--ink);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ho-fr-mail{font-size:11.5px;color:var(--ink-soft);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ho-fr-empty{font-size:12.5px;color:var(--ink-faint);padding:8px 9px;line-height:1.45}
  .ho-selected{display:flex;align-items:center;gap:10px;background:var(--surface-2);border:1px solid var(--hair-2);border-radius:var(--r-sm);padding:9px 11px}
  .ho-sel-av{flex:none;width:30px;height:30px;border-radius:50%;overflow:hidden}
  .ho-sel-av :is(img,span,div){width:100%;height:100%}
  .ho-sel-main{display:flex;flex-direction:column;min-width:0;flex:1}
  .ho-sel-name{font-size:14px;color:var(--ink);font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ho-sel-state{font-family:var(--font-mono);font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;margin-top:2px}
  .ho-sel-state.ok{color:var(--ok)}
  .ho-sel-state.locked{color:var(--idle)}
  .ho-sel-x{flex:none;font-size:14px;color:var(--ink-faint);background:transparent;border:none;cursor:pointer;padding:4px 6px;border-radius:var(--r-xs)}
  .ho-sel-x:hover{color:var(--ink);background:var(--surface)}
  .ho-clear{display:flex;align-items:center;gap:9px;font-size:13px;color:var(--ink-soft);cursor:pointer;user-select:none}
  .ho-clear input{width:16px;height:16px;accent-color:var(--now);cursor:pointer}
  .ho-msg{font-size:12.5px;color:var(--ink-soft);min-height:0;line-height:1.4}
  .ho-msg.err{color:var(--warn)}
  .ho-send{width:100%;justify-content:center;margin-top:2px}
  .ho-send:disabled{opacity:.5;cursor:not-allowed}
  /* transient confirmation toast (no undo) */
  .tl-toast{position:fixed;left:50%;bottom:calc(22px + env(safe-area-inset-bottom));transform:translate(-50%,14px);z-index:9999;max-width:calc(100vw - 32px);background:var(--ink);color:var(--on-ink);font-size:13.5px;font-weight:500;padding:11px 18px;border-radius:var(--r-pill);box-shadow:var(--shadow-lg);opacity:0;pointer-events:none;transition:opacity .24s ease,transform .28s cubic-bezier(.2,.8,.3,1)}
  .tl-toast.show{opacity:1;transform:translate(-50%,0)}
  @media (max-width:520px){ .handoff-drawer{right:8px;left:8px;width:auto} .ho-row{grid-template-columns:1fr 1fr} .ho-row .ho-field:first-child{grid-column:1/-1} }
  @media (prefers-reduced-motion:reduce){ .handoff-drawer{animation:none} .tl-toast{transition:opacity .01s} }

  /* ═══ ALN-167 compact nav, the real small-screen IA (≤860px) ══════════════════════
     Placed last so it wins the cascade over the base .topbar-right/.notif-bell/toast rules.
     • primary navigation → a FLOATING DOCK (centred island) holding the five destinations + Assistant
     • the top bar de-crams to identity + focus timer + hand-offs + messages + notifications + avatar
     • the left-edge Assistant toggle retires, it lives on the dock now
     • hand-off keeps its own header icon on tablet/phone (owner ask), a dedicated
       inbox surface, not buried in Notifications */
  @media (max-width:860px){
    /*, top bar, */
    .tabs{display:none}                                  /* destinations move to the floating dock */
    .topbar{padding-left:16px;padding-right:16px}
    .topbar-right{gap:6px}
    .notif-bell{width:40px;height:40px}                   /* ALN-210: trimmed from 44 to reclaim width so the profile avatar is never clipped; 40px is still a comfortable tap target */
    .pf-caret{display:none}                               /* ALN-210: redundant on phones (tapping the avatar opens the menu); dropping it saves ~23px */
    .profile-btn{min-height:40px;padding:4px;gap:0}       /* ALN-210: avatar-only button now, so tighten padding and drop the caret gap */
    .drawer-toggle{display:none}                          /* Assistant lives on the dock now */
    /*, floating dock, */
    .botnav{display:flex;position:fixed;left:12px;right:12px;bottom:calc(12px + env(safe-area-inset-bottom));margin:0 auto;max-width:560px;z-index:45;
      justify-content:space-around;align-items:stretch;gap:2px;
      background:var(--glass);backdrop-filter:blur(16px) saturate(1.4);-webkit-backdrop-filter:blur(16px) saturate(1.4);
      border:1px solid var(--hair);border-radius:20px;box-shadow:var(--shadow-lg);padding:6px}
    body.drawer-open .botnav{display:flex}                /* keep the command dock reachable while the assistant is open (ALN-202) */
    /*, keep bottom-anchored popups above the floating dock, */
    .toast,.snackbar,.nudge-pop,.ln-toast,.tl-toast{bottom:calc(var(--botnav-h) + 20px + env(safe-area-inset-bottom))}
  }
  /* ALN-210: the full wordmark (fixed ~187px, never shrinks) plus the right-side control
     cluster cannot both fit on a phone, which is what pushed the avatar off the right edge.
     Even with the trimmed buttons above, the widest thing that can safely give way is the
     wordmark text, so on phones it collapses to just the spark mark (the SVG stays; only the
     "Throughline" text hides). Tablets keep the full wordmark. Breakpoint set to the crossover
     where the trimmed cluster + full wordmark start to fit. */
  @media (max-width:460px){ .brand{font-size:0;gap:0} .brand-mark{width:24px;height:24px} }  /* phones: the mark alone (px-sized so it survives font-size:0), wordmark text hidden; full wordmark returns >460px with margin */
  @media (max-width:360px){ .bn-label{font-size:9px} }   /* tiny phones: tighter dock labels */

  /* ── Arcs (ALN-173): goal surface. All theme-token-driven, so it inherits every
     palette (Cyan Terminal included). The nav-HUD figure is always deep-space,
     the markers read --now/--ok so they recolour with the active theme. ── */
  #arcs .arcs-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:16px}
  #arcsMount{display:flex;flex-direction:column;gap:14px}
  .arc-card{background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--shadow)}
  .arc-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;padding:14px 15px 10px}
  .arc-headtext{flex:1;min-width:0}
  .arc-open{all:unset;cursor:pointer;color:inherit;font:inherit;text-align:left}
  .arc-open:focus-visible{outline:2px solid var(--now);outline-offset:2px;border-radius:4px}
  .arc-t{font-family:var(--font-display);font-weight:600;font-size:1.02rem;color:var(--ink);letter-spacing:-.01em;margin:0}
  .arc-why{font-size:.85rem;color:var(--ink-soft);margin:3px 0 0}
  .arc-tag{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;padding:3px 8px;border-radius:999px;white-space:nowrap;border:1px solid var(--hair);align-self:flex-start}
  .arc-season{color:var(--ink-soft);background:transparent;border-color:var(--hair-lit)}
  .arc-open-tag{color:var(--ink-faint)}
  .arc-fig{position:relative;height:148px;background:#010206;border-top:1px solid #17222f;border-bottom:1px solid #17222f;overflow:hidden}
  .arc-fig-lg{height:208px;border-radius:var(--r-md);border:1px solid #17222f;margin-bottom:4px}
  .arc-canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
  .arc-next{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:11px 15px 14px;background:var(--now-tint);border:1px solid color-mix(in srgb,var(--now) 30%,var(--hair));border-radius:var(--r-sm);padding:10px 12px}
  .arc-next-done{background:var(--surface-2);border-color:var(--hair)}
  .arc-next-body{min-width:0}
  .arc-next-lbl{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--idle);display:block;margin-bottom:2px}
  .arc-next-step{font-size:.9rem;font-weight:600;color:var(--ink)}
  .arc-est{color:var(--ink-faint);font-weight:400}
  .arc-pull{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;text-transform:uppercase;border:1px solid color-mix(in srgb,var(--now) 45%,var(--hair));background:var(--surface);color:var(--ink);border-radius:999px;padding:7px 11px;cursor:pointer;white-space:nowrap;transition:background .15s,color .15s}
  .arc-pull:hover{background:var(--now);color:var(--on-now)}
  /* ALN-299: what stands where the pull button was while writes are refused. Not a
     disabled button: a disabled control still reads as "this is yours to press, later",
     and at the opacity that convention wants it measures 2.52:1. This is a readout, and
     it measures 5.40:1 on light, 7.5:1+ on the dark families. */
  .arc-paused{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;text-transform:uppercase;color:color-mix(in srgb,var(--idle) 55%,var(--ink));border:1px solid color-mix(in srgb,var(--idle) 40%,transparent);border-radius:999px;padding:7px 11px;white-space:nowrap;flex:none}
  .arc-charted-h{font-family:var(--font-mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-faint);margin:8px 2px 0}
  .arc-empty{text-align:center;padding:34px 20px;display:flex;flex-direction:column;align-items:center;gap:12px;background:var(--surface);border:1px solid var(--hair);border-radius:var(--r-lg);box-shadow:var(--shadow)}
  .arc-empty-fig{position:relative;width:calc(100% + 40px);height:184px;border:1px solid #17222f;border-left:0;border-right:0;border-radius:0;overflow:hidden;margin:4px -20px 16px}
  .arc-empty h3{font-family:var(--font-display);font-size:1.15rem;color:var(--ink);margin:0}
  .arc-empty p{max-width:44ch;color:var(--ink-soft);font-size:.9rem;margin:0}
  .arc-btn{font-family:var(--font-ui);font-weight:600;font-size:.9rem;border-radius:var(--r-sm);padding:9px 15px;cursor:pointer;border:1px solid var(--hair);background:var(--surface);color:var(--ink)}
  .arc-btn-primary{background:var(--now);color:var(--on-now);border-color:transparent}
  .arc-btn:disabled{opacity:.5;cursor:default}
  .arc-danger{color:var(--warn);border-color:color-mix(in srgb,var(--warn) 30%,var(--hair))}
  .arc-dlg{border:1px solid var(--hair);border-radius:var(--r-lg);background:var(--surface);color:var(--ink);max-width:460px;width:calc(100% - 32px);padding:0;box-shadow:var(--shadow-lg)}
  .arc-dlg::backdrop{background:rgba(0,0,0,.5);backdrop-filter:blur(3px)}
  .arc-form,.arc-detail{padding:18px}
  .arc-dlg-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:14px}
  .arc-dlg-head h3{font-family:var(--font-display);font-size:1.15rem;margin:0;color:var(--ink)}
  .arc-x{all:unset;cursor:pointer;color:var(--ink-faint);font-size:1rem;padding:2px 6px;border-radius:6px}
  .arc-x:hover{color:var(--ink);background:var(--surface-2)}
  .arc-field{display:flex;flex-direction:column;gap:5px;margin-bottom:12px}
  .arc-field>span{font-size:.8rem;color:var(--ink-soft);font-weight:600}
  .arc-field input,.arc-field textarea,.arc-add input{font:inherit;font-size:.92rem;padding:9px 11px;border:1px solid var(--hair);border-radius:var(--r-sm);background:var(--surface-2);color:var(--ink);width:100%;box-sizing:border-box}
  .arc-field textarea{resize:vertical}
  .arc-check{display:flex;align-items:center;gap:8px;font-size:.88rem;color:var(--ink-soft);margin-bottom:14px}
  .arc-dlg-foot{display:flex;gap:10px;justify-content:flex-end;margin-top:6px;flex-wrap:wrap}
  .arc-sec{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-faint);margin:14px 0 8px}
  .arc-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}
  .arc-mrow,.arc-srow{display:flex;align-items:center;gap:10px;font-size:.9rem;color:var(--ink);padding:5px 2px}
  .arc-mrow.done>span,.arc-srow.done .arc-stext{color:var(--ink-faint);text-decoration:line-through}
  .arc-mtoggle,.arc-stoggle{all:unset;cursor:pointer;width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;border-radius:6px;color:var(--now);flex:0 0 auto}
  .arc-mrow.done .arc-mtoggle,.arc-srow.done .arc-stoggle{color:var(--ok)}
  .arc-stext{flex:1;min-width:0}
  .arc-slink{all:unset;cursor:pointer;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-soft);padding:4px 8px;border:1px solid color-mix(in srgb,var(--now) 35%,var(--hair));border-radius:999px;flex:0 0 auto}
  .arc-muted{color:var(--ink-faint);font-size:.85rem;font-style:italic}
  .arc-add{display:flex;gap:8px;margin-top:8px}
  .arc-add input{flex:1}
  .arc-est-in{max-width:100px;flex:0 0 auto}
  /* ALN-291: the one refused-write explanation, shared by every surface that can
     refuse (client/src/lockbanner.mjs). Replaces .arc-locked, which said it only in
     the arc detail and said it a second, different way in a toast. --idle is the
     existing hazard hue, so the One-Signal rule holds: amber stays the accent. */
  .lk-banner{display:flex;gap:10px;align-items:flex-start;background:color-mix(in srgb,var(--idle) 12%,transparent);border:1px solid color-mix(in srgb,var(--idle) 34%,transparent);border-radius:var(--r-sm);padding:11px 12px;margin:0 0 12px}
  /* ALN-297: this selector was `.lk-banner>.icon` and matched NOTHING, because icon()
     emits class="ic" (client/src/icons.mjs). So the mark has never been amber. Two
     things go with the fix: the glyph now names the cause (lockbanner.mjs CAUSE), and
     the hue is idle pulled 22% toward ink. Flat --idle measures 2.56:1 against this
     banner's own tint on light, under the 3:1 floor for a non-text mark; the mix reads
     3.64:1 on light and 6.2:1+ on every dark family, and stays derived from --idle so
     it still tracks a palette edit. */
  .lk-banner>.ic{color:color-mix(in srgb,var(--idle) 78%,var(--ink));flex:0 0 auto;margin-top:1px}
  .lk-copy{flex:1;min-width:0;font-size:var(--fs-ui);color:var(--ink-soft);line-height:1.45}
  .lk-copy b{display:block;color:var(--ink);font-weight:var(--fw-semi)}
  .lk-act{font-family:var(--font-ui);font-weight:var(--fw-semi);font-size:var(--fs-ui);color:var(--ink);background:var(--surface);border:1px solid var(--hair-lit);border-radius:var(--r-sm);padding:6px 12px;flex:0 0 auto;cursor:pointer;min-height:32px}
  .lk-act:hover{border-color:var(--ink-faint)}
  @media (max-width:460px){.lk-banner{flex-wrap:wrap}.lk-act{width:100%;min-height:44px}}
  .arc-toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(16px);background:var(--ink);color:var(--surface);font-size:.86rem;font-weight:500;padding:10px 16px;border-radius:999px;box-shadow:var(--shadow-lg);opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;z-index:200}
  .arc-toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
  @media (prefers-reduced-motion:reduce){.arc-toast,.arc-pull{transition:none}}
  /* ── ALN-193 Arcs UX polish: centred + roomier dialog, whole-card open cue, editable detail, duration picker, balanced footer ── */
  .arc-dlg{max-width:520px;max-height:calc(100dvh - 32px);overflow:auto;margin:auto}  /* the *{margin:0} reset stripped the UA modal-centring margin:auto, restore it so the sheet opens centred, not in the corner */
  .arc-form,.arc-detail{padding:22px}
  .arc-head{gap:12px}
  .arc-head-meta{display:flex;align-items:center;gap:9px;flex:0 0 auto}
  .arc-card{cursor:pointer;transition:border-color .16s,box-shadow .16s,transform .16s}
  .arc-card:hover{border-color:color-mix(in srgb,var(--now) 40%,var(--hair));box-shadow:var(--shadow-lg)}
  .arc-open-cue{color:var(--ink-faint);font-size:22px;line-height:.7;font-weight:400;transition:color .16s,transform .16s}
  .arc-card:hover .arc-open-cue{color:var(--now);transform:translateX(2px)}
  .arc-ongoing{color:var(--ink-faint);background:color-mix(in srgb,var(--ink-faint) 12%,transparent);border-color:color-mix(in srgb,var(--ink-faint) 26%,transparent)}
  .arc-sec{margin-bottom:2px}
  .arc-sec-note{font-size:.82rem;color:var(--ink-soft);line-height:1.45;margin:0 2px 10px}
  .arc-dur{display:flex;flex-wrap:wrap;gap:6px}
  .arc-dur-opt{all:unset;cursor:pointer;font-family:var(--font-mono);font-size:11px;letter-spacing:.02em;padding:7px 12px;border:1px solid var(--hair);border-radius:var(--r-pill);color:var(--ink-soft);transition:background .15s,color .15s,border-color .15s}
  .arc-dur-opt:hover{border-color:var(--now);color:var(--ink)}
  .arc-dur-opt.on{background:var(--now);color:var(--on-now);border-color:transparent}
  .arc-custom{margin-top:9px;max-width:130px}
  .arc-dlg-head{align-items:flex-start;gap:10px}
  .arc-detail-title{flex:1;min-width:0}
  /* `all:unset` also resets display back to inline, which lands underneath the
     zero-specificity button primitive, so this one has to re-state it (ALN-263). */
  .arc-edit-btn{all:unset;display:inline-flex;align-items:center;justify-content:center;gap:.5em;cursor:pointer;color:var(--ink-faint);font-size:.98rem;padding:5px 9px;border-radius:8px;flex:0 0 auto;transition:color .15s,background .15s}
  .arc-edit-btn:hover{color:var(--now);background:var(--surface-2)}
  .arc-head-edit{flex:1;min-width:0;display:flex;flex-direction:column;gap:9px}
  .arc-edit-in{font:inherit;font-size:.95rem;padding:9px 11px;border:1px solid var(--hair);border-radius:var(--r-sm);background:var(--surface-2);color:var(--ink);width:100%}
  .arc-edit-in:focus{outline:none;border-color:var(--now)}
  .arc-edit-actions{display:flex;gap:8px}
  .arc-mrow{gap:8px}
  .arc-mlabel{flex:1;min-width:0}
  .arc-medit{all:unset;flex:1;min-width:0;font-size:.9rem;color:var(--ink);padding:6px 9px;border:1px solid transparent;border-radius:7px;transition:border-color .15s,background .15s}
  .arc-medit:hover{border-color:var(--hair)}
  .arc-medit:focus{border-color:var(--now);background:var(--surface-2)}
  .arc-mrow.done .arc-medit{color:var(--ink-faint);text-decoration:line-through}
  .arc-mdel{all:unset;cursor:pointer;color:var(--ink-faint);font-size:1.15rem;line-height:1;padding:2px 8px;border-radius:7px;flex:0 0 auto;transition:color .15s,background .15s}
  .arc-mdel:hover{color:var(--warn);background:color-mix(in srgb,var(--warn) 12%,transparent)}
  .arc-add{margin-top:10px;flex-wrap:wrap;align-items:center}
  .arc-add>input:not(.arc-est-in){flex:1 1 140px}
  .arc-dlg-foot{justify-content:space-between;align-items:center;margin-top:16px;padding-top:14px;border-top:1px solid var(--hair)}
  /* ── ALN-194: editable jumps (text + est), the "in today" state, and the pull-into-today confirm ── */
  .arc-srow{gap:8px;flex-wrap:wrap}
  .arc-sedit{all:unset;flex:1 1 150px;min-width:0;font-size:.9rem;color:var(--ink);padding:6px 9px;border:1px solid transparent;border-radius:7px;transition:border-color .15s,background .15s}
  .arc-sedit:hover{border-color:var(--hair)}
  .arc-sedit:focus{border-color:var(--now);background:var(--surface-2)}
  .arc-sedit.arc-est-in{flex:0 0 auto;max-width:96px}
  .arc-srow.done .arc-sedit{color:var(--ink-faint);text-decoration:line-through}
  .arc-srow.intoday .arc-sedit{color:var(--ink-soft)}
  .arc-intoday{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--ok);background:color-mix(in srgb,var(--ok) 12%,transparent);border:1px solid color-mix(in srgb,var(--ok) 35%,transparent);border-radius:999px;padding:5px 9px;white-space:nowrap;flex:0 0 auto}
  .arc-confirm{max-width:400px}
  .arc-confirm-body{padding:22px}
  .arc-confirm-body h3{font-family:var(--font-display);font-size:1.1rem;margin:0 0 8px;color:var(--ink)}
  .arc-confirm-step{font-size:.95rem;font-weight:600;color:var(--ink);margin:0 0 14px;line-height:1.4}
  .arc-confirm .arc-check{margin:0 0 16px;color:var(--ink-soft)}
  /* ── ALN-194 B: figure telemetry (DEST/DIST/ETA) + legend below the figure, and the tap-a-node tooltip ── */
  /* ALN-195: NO scrim band behind the readout (it hid the instrument grid), a text-shadow keeps it legible over the field, and the readout drops low to the bottom corner ticks. Cards + detail alike. */
  .arc-fig-hud{position:absolute;left:0;right:0;bottom:0;z-index:2;pointer-events:none;display:flex;flex-direction:column;gap:5px;padding:13px 13px 5px;background:none;text-shadow:0 1px 4px rgba(0,0,0,.94),0 0 3px rgba(0,0,0,.8)}
  .arc-fig-hud.framed{bottom:4px;padding:8px 13px 2px}
  .arc-hud-read{font-family:var(--font-mono);font-size:9px;letter-spacing:.04em;text-transform:uppercase;color:#7C93A2;display:flex;justify-content:center;flex-wrap:wrap;gap:6px 18px}
  .arc-hud-read b{color:#E7F1F5;font-weight:700}
  .arc-fig-hud.has-legend .arc-hud-read{justify-content:center;gap:6px 18px}
  .arc-hud-legend{font-family:var(--font-mono);font-size:8px;letter-spacing:.02em;text-transform:uppercase;display:flex;justify-content:center;flex-wrap:wrap;gap:5px 14px}
  .arc-hud-legend span{display:inline-flex;align-items:center;gap:5px;color:#8296a5;white-space:nowrap}
  .arc-hud-legend span::before{content:"";width:6px;height:6px;transform:rotate(45deg);background:currentColor;flex:none}
  .arc-hud-legend .ok{color:var(--ok)}.arc-hud-legend .now{color:var(--now)}.arc-hud-legend .dim{color:#8FA6BC}.arc-hud-legend .cy{color:#7CE0FF}
  .arc-node-tip{position:absolute;transform:translate(-50%,-100%);z-index:3;pointer-events:none;background:#0d1420;border:1px solid #24405c;border-radius:7px;padding:5px 9px;box-shadow:0 4px 12px -5px rgba(0,0,0,.85);max-width:min(72%,160px);white-space:normal;text-align:center;display:flex;flex-direction:column;gap:1px;line-height:1.2}
  .arc-node-tip.below{transform:translate(-50%,0)}  /* ALN-195: flips below the node when it'd clip the top */
  .arc-node-tip b{font-size:11px;color:#EAF0F5;font-weight:700}
  .arc-node-tip i{font-family:var(--font-mono);font-size:8px;letter-spacing:.06em;text-transform:uppercase;font-style:normal;color:#8FA6BC}
  .arc-node-tip.state-done i{color:var(--ok)}.arc-node-tip.state-here i{color:var(--now)}.arc-node-tip.state-goal i{color:#7CE0FF}
  /* ── ALN-194 C: the star-map, charted routes as distinct constellation shapes ── */
  /* ALN-195: star-map is compact grid blocks (constellation + name + tag). */
  .arc-starmap{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;margin-top:6px}
  .arc-const{all:unset;cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:6px;padding:10px;border:1px solid var(--hair);border-radius:var(--r-md);background:var(--surface);box-shadow:var(--shadow);transition:border-color .16s,box-shadow .16s,transform .16s}
  .arc-const:hover{border-color:color-mix(in srgb,var(--now) 40%,var(--hair));box-shadow:var(--shadow-lg)}
  .arc-const:focus-visible{outline:2px solid var(--now);outline-offset:2px}
  .arc-const-fig{position:relative;width:100%;height:112px;border-radius:var(--r-sm);border:1px solid #17222f;overflow:hidden;background:#010206}
  .arc-const-canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
  .arc-const-name{font-family:var(--font-display);font-weight:600;font-size:.95rem;color:var(--ink);text-align:center;line-height:1.15}
  .arc-const-tag{font-family:var(--font-mono);font-size:9px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-faint);text-align:center}
  .arc-foot-r{display:flex;gap:10px;align-items:center}
