/* ---------------------------------------------------------------------------
   base.css — lifted VERBATIM from design/console.html (the design of record).
   Every value here was contrast-tuned with the reasoning kept in the comments.
   Do not 'tidy' a colour in this file without re-checking the ratio it documents.
   New work belongs in app.css, which loads after this and only ADDS.
   --------------------------------------------------------------------------- */
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@500;600;700;800&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap');
/* Replaced Hanken Grotesk 2026-09-04 with the Zoho-leaning pass: Plus Jakarta
   Sans for headline-scale text (page titles, card titles, the hero digit,
   KPI/pipeline figures -- see the .pg-title/.card-t/... rule in app.css) and
   IBM Plex Sans as the body/data face everywhere else, including every
   tabular-nums numeric rule below. IBM Plex Sans carries real tabular
   figures the same way Hanken Grotesk did, so the fix that mattered here --
   Space Mono's zero read as a broken icon at 34px+ (flagged 2026-09-03) --
   still holds: every numeric rule keeps font-variant-numeric:tabular-nums,
   just on the new face. Space Mono is still not loaded anywhere. */

:root{
  /* page
     Cool-shifted 2026-09-04 toward a Zoho-leaning blue-gray, approved off a built
     preview (Lucas: "love it... design the entire crm following this design").
     This is a HUE-ONLY rotation (H->222°, same S/L as the values it replaces) run
     through a script that recomputed every contrast pair the comments below
     document — nothing here dropped by more than 0.2:1, nothing crossed a floor.
     The warm-lavender originals are kept in comments for the ratio history. */
  --ground:#eef0f5;      /* was #f1eef5 */
  --surface:#ffffff;
  --raised:#f5f6f9;      /* was #f7f5f9 */
  --sunken:#eaecf1;      /* was #edeaf1 */
  --line:#d6dae3;        /* was #ddd6e3 */
  --line-soft:#e3e6ed;   /* was #e8e3ed */
  --ink:#171a20;         /* was #1b1720 */
  /* The whole ramp moved down, rather than just darkening --ink-3. At #645b6d / #726879 these two
     were 5 L* apart — barely a ramp — and --ink-3 failed at 3.92:1 on the washed panels it gets
     used on. Darkening only --ink-3 would have landed it on top of --ink-2 and erased the step.
     Hue-rotated 2026-09-04 (was #554c5e / #655c6c): ink-2 on ground 7.08->6.96, ink-3 on ground
     5.54->5.45, ink-3 on raised 5.87->5.75 — re-measured, still clear of every floor above. */
  --ink-2:#4c515e;
  --ink-3:#5c616c;
  /* brand */
  /* Deepened from #d3384f: the accent is used as TEXT on --accent-wash ("What's new", the current
     app chip) and that pair measured 4.09:1. On white this also improves 4.72 -> 5.39. */
  --accent:#c53049;
  --accent-2:#b82c46;
  --accent-wash:#fdeaee;
  --accent-ink:#ffffff;
  /* The two stops of the primary-button / avatar gradient. These were the literals #e04156 and
     #e0566c written straight into the rules, which meant one fixed pair had to serve both themes —
     and it served neither: white on #e04156 measured 4.15:1 in LIGHT mode, below the 4.5 floor. */
  --accent-hi:#d3384f; --accent-lo:#b32e42;
  /* primary action -- structural blue, added 2026-09-04. Zoho's own convention
     (and the artifact Lucas approved): coral stays the BRAND colour (logo,
     avatars, the hero's alarm digit), blue is reserved for the one thing that
     needs to look actionable -- primary buttons. White text on --pri-lo
     measures 6.2:1; near-black on the dark theme's lighter --pri-hi measures
     7-8:1, both checked, not assumed. */
  --pri-hi:#4169ff; --pri-lo:#2547d1; --pri-2:#2547d1; --on-pri:#ffffff;
  --sh-action:0 1px 2px rgba(37,71,209,.24), 0 3px 8px -2px rgba(37,71,209,.30);
  /* semantic */
  --warn:#8a5813; --warn-wash:#fdf0da;
  --danger:#bb3238; --danger-wash:#fce7e6;
  --ok:#23684a; --ok-wash:#e0f2e8;
  --info:#2b5f9e; --info-wash:#e5eefa;
  /* Ink for text sitting ON a filled semantic chip. This has to be a per-theme token: the fills
     flip from deep (light) to tinted (dark), so a hard-coded #fff is only ever correct in one of
     them — it was failing at 2.6:1 on the dark-mode blue. */
  --on-danger:#ffffff; --on-info:#ffffff;
  /* rail (always dark) — hue-rotated with the ramp above, same method (was #1a1622/#231e2e/
     #2e2739/#332c3f/#f3f0f6/#b3a9bd/#9a90a4). rail-active / rail-active-bg are deliberately
     EXCLUDED: that background is tinted FROM the coral accent on purpose (the active item's own
     wash), not a neutral, so rotating it would fight the accent sitting on it instead of matching it. */
  --rail:#161a22;
  --rail-2:#1e232e;
  --rail-3:#272c39;
  --rail-line:#2c323f;
  --rail-ink:#f0f2f6;
  --rail-ink-2:#a9afbd;
  /* Lifted from #8d8298: the rail's ACTIVE item sits on --rail-active-bg, which is lighter than
     the rail, and the count on it measured 4.13:1. Checked against both grounds, not just --rail.
     Re-measured after the 2026-09-04 hue rotation: rail-ink-3 on rail 5.84->5.88, on rail-2
     5.32->5.31 — unchanged within rounding. */
  --rail-ink-3:#9096a4;
  --rail-active:#ef5f78;
  --rail-active-bg:#3b1e27;
  /* system -- tightened one notch each (was 6/8/11/14) after the Home
     redesign: the corporate-flat direction Lucas approved reads sharper
     with less roundover, sitewide, everywhere these tokens are already
     used instead of a literal radius. */
  --r-xs:5px;
  --r-sm:6px;
  --r:8px;
  --r-lg:10px;
  --h-ctl:34px;
  --sh-1:0 1px 2px rgba(27,23,32,.06), 0 1px 3px rgba(27,23,32,.04);
  --sh-2:0 2px 4px rgba(27,23,32,.05), 0 8px 18px -8px rgba(27,23,32,.18);
  --sh-3:0 10px 34px -10px rgba(27,23,32,.30);
  --sh-ctl:0 1px 1px rgba(27,23,32,.04), 0 1px 2.5px rgba(27,23,32,.07);
  --sh-ctl-h:0 1px 2px rgba(27,23,32,.06), 0 3px 6px -1px rgba(27,23,32,.10);
  --sh-pri:0 1px 2px rgba(146,28,48,.24), 0 3px 8px -2px rgba(146,28,48,.30);
  --ease:cubic-bezier(.32,.72,.28,1);
  /* type scale — 8 steps, nothing off-ladder */
  --t-micro:10px;   /* badge counts */
  --t-label:11px;   /* uppercase eyebrows */
  --t-meta:12px;    /* secondary / captions */
  --t-body:13px;    /* default UI text */
  --t-lead:14px;    /* card titles */
  --t-h3:17px;      /* list-view titles */
  --t-h2:21px;      /* page titles */
  --t-hero:34px;    /* the one number that matters */
  --rail-w:228px;
  --top-h:56px;
  --rstrip-w:48px;
  /* surfaces that are not plain tokens. Cool-shifted 2026-09-04 with the rest of
     the ramp EXCEPT where a surface is deliberately tinted from an accent/semantic
     colour rather than neutral: --hero-bg/--hero-line pair with --warn (the
     zero-hero figure background), --dgr-line pairs with --danger (.btn.dgr's
     border), --accent-wash-h pairs with --accent (hover wash on accent chips) —
     rotating those toward blue would fight the colour sitting on them, the same
     mistake caught and excluded on --rail-active-bg above. --lk-hover is already
     blue and untouched for the same reason there's nothing warm to fix. */
  --pic-bg:linear-gradient(150deg,#e9ecf2,#d4d9e5); --pic-ink:#515867; /* was #efe9f2,#ded4e5 / #5c5167 */
  --hero-bg:linear-gradient(160deg,#fdf3e2,#fbead1); --hero-line:#f0e0c4;
  --push-bg:linear-gradient(150deg,#e9ecf3,#dbdfe9); /* was #efe9f3,#e3dbe9 */
  --scroll:#c4c9d5; --scroll-h:#acb3c2; /* was #cdc4d5 / #b8acc2 */
  --chart-bar:#8a94ab; --chart-bar-h:#808aa2; /* was #9a8aab / #8f80a2 */
  --dgr-line:#eccdcc; --lk-hover:#1d4b81; --accent-wash-h:#fbdae1;
}

/* ── DARK ─────────────────────────────────────────────────────────────────────
   The rail keeps its own always-dark tokens, so only the page surfaces move.
   Surfaces sit LIGHTER than the rail in dark mode, so the rail stays a distinct
   zone instead of merging into the content area. */
@media (prefers-color-scheme:dark){ :root:not([data-theme="light"]){
  --ground:#101319; --surface:#1c202b; --raised:#222835; --sunken:#151924; /* hue-rotated 2026-09-04, was #131019/#201c2b/#282235/#191524 */
  /* Lifted from #332c42 / #2a2438. --line-soft sat 1.0 L* from --raised, and --raised IS the row
     hover colour, so mousing over a table row erased that row's own divider (1.03:1). Both rungs
     moved up together to keep the two-weight border ladder: soft is now 4.3 L* clear of a hovered
     row, and --line stays 3.7 L* above soft. */
  --line:#323a4d; --line-soft:#2b3140; /* hue-rotated 2026-09-04, was #3a324d/#312b40 */
  --ink:#eff1f6; --ink-2:#a8afc0; --ink-3:#8a91a2; /* hue-rotated 2026-09-04, was #f2eff6/#b3a8c0/#948aa2 — re-measured: ink-2 on ground 8.32->8.46, ink-3 on raised 4.68->4.68 (unchanged), ink-3 on surface 5.08->5.15 */
  /* accent-wash stays DARK, unlike the semantic washes. Those were lifted so a tinted chip keeps an
     edge against a hovered table row; --accent-wash is never used in a row (apps menu, bottom bar),
     and lifting it dropped accent-on-its-own-wash to 4.35:1. The constraint did not apply here. */
  --accent:#ef5f78; --accent-2:#d3384f; --accent-wash:#3a1e27;
  --pri-hi:#8fadff; --pri-lo:#6f91ff; --pri-2:#6f91ff; --on-pri:#171a20;
  --sh-action:0 1px 2px rgba(0,0,0,.4), 0 3px 8px -2px rgba(111,145,255,.45);
  /* Dark ink on the accent, not white. The dark-theme accent is a deliberately LIGHT coral, so
     white on it measured 3.19:1. Near-black reads 5.6-6.5:1 and keeps the fill vivid. */
  --accent-ink:#1b1720; --accent-hi:#f4738a; --accent-lo:#e85068;
  /* Amber DOWN and red UP, on purpose. Measured on the card, warn was the loudest colour in the
     palette (7.77:1) and danger the quietest (5.56:1) — "In review" optically outshouted "Grant
     failed". Now danger 7.02 leads and warn 6.00 sits under ok and info.
     The washes all rose ~3.5 L* above --raised too: at 1.00:1 against a hovered row a tinted chip
     had no edge left and became floating coloured text. */
  --warn:#d68b1f; --warn-wash:#392a0f;
  --danger:#f5898f; --danger-wash:#442325;
  --ok:#4fbb85; --ok-wash:#163221;
  --info:#6ba6e2; --info-wash:#1a2d46;
  --on-danger:#1b1720; --on-info:#1b1720;
  --pic-bg:linear-gradient(150deg,#2c3342,#222835); --pic-ink:#c2c9d8; /* was #332c42,#282235 / #cdc2d8 */
  --hero-bg:linear-gradient(160deg,#33270f,#2b2110); --hero-line:#4a3a17;
  --push-bg:linear-gradient(150deg,#222835,#1d222f); /* was #282235,#221d2f */
  --scroll:#353d50; --scroll-h:#434d64; /* was #3d3550 / #4d4364 */
  --chart-bar:#6a7795; --chart-bar-h:#808eb0; /* was #776a95 / #8f80b0 */
  --dgr-line:#5c3034; --lk-hover:#9cc4ee; --accent-wash-h:#4a2530;
  --sh-1:0 1px 2px rgba(0,0,0,.4);
  --sh-2:0 2px 4px rgba(0,0,0,.35), 0 8px 18px -8px rgba(0,0,0,.6);
  --sh-3:0 10px 34px -10px rgba(0,0,0,.75);
  --sh-ctl:0 1px 1px rgba(0,0,0,.3), 0 1px 2.5px rgba(0,0,0,.35);
  --sh-ctl-h:0 1px 2px rgba(0,0,0,.4), 0 3px 6px -1px rgba(0,0,0,.5);
  --sh-pri:0 1px 2px rgba(0,0,0,.4), 0 3px 8px -2px rgba(211,56,79,.45);
}}
:root[data-theme="dark"]{
  --ground:#101319; --surface:#1c202b; --raised:#222835; --sunken:#151924; /* hue-rotated 2026-09-04, was #131019/#201c2b/#282235/#191524 */
  /* Lifted from #332c42 / #2a2438. --line-soft sat 1.0 L* from --raised, and --raised IS the row
     hover colour, so mousing over a table row erased that row's own divider (1.03:1). Both rungs
     moved up together to keep the two-weight border ladder: soft is now 4.3 L* clear of a hovered
     row, and --line stays 3.7 L* above soft. */
  --line:#323a4d; --line-soft:#2b3140; /* hue-rotated 2026-09-04, was #3a324d/#312b40 */
  --ink:#eff1f6; --ink-2:#a8afc0; --ink-3:#8a91a2; /* hue-rotated 2026-09-04, was #f2eff6/#b3a8c0/#948aa2 — re-measured: ink-2 on ground 8.32->8.46, ink-3 on raised 4.68->4.68 (unchanged), ink-3 on surface 5.08->5.15 */
  /* accent-wash stays DARK, unlike the semantic washes. Those were lifted so a tinted chip keeps an
     edge against a hovered table row; --accent-wash is never used in a row (apps menu, bottom bar),
     and lifting it dropped accent-on-its-own-wash to 4.35:1. The constraint did not apply here. */
  --accent:#ef5f78; --accent-2:#d3384f; --accent-wash:#3a1e27;
  --pri-hi:#8fadff; --pri-lo:#6f91ff; --pri-2:#6f91ff; --on-pri:#171a20;
  --sh-action:0 1px 2px rgba(0,0,0,.4), 0 3px 8px -2px rgba(111,145,255,.45);
  /* Dark ink on the accent, not white. The dark-theme accent is a deliberately LIGHT coral, so
     white on it measured 3.19:1. Near-black reads 5.6-6.5:1 and keeps the fill vivid. */
  --accent-ink:#1b1720; --accent-hi:#f4738a; --accent-lo:#e85068;
  /* Amber DOWN and red UP, on purpose. Measured on the card, warn was the loudest colour in the
     palette (7.77:1) and danger the quietest (5.56:1) — "In review" optically outshouted "Grant
     failed". Now danger 7.02 leads and warn 6.00 sits under ok and info.
     The washes all rose ~3.5 L* above --raised too: at 1.00:1 against a hovered row a tinted chip
     had no edge left and became floating coloured text. */
  --warn:#d68b1f; --warn-wash:#392a0f;
  --danger:#f5898f; --danger-wash:#442325;
  --ok:#4fbb85; --ok-wash:#163221;
  --info:#6ba6e2; --info-wash:#1a2d46;
  --on-danger:#1b1720; --on-info:#1b1720;
  --pic-bg:linear-gradient(150deg,#2c3342,#222835); --pic-ink:#c2c9d8; /* was #332c42,#282235 / #cdc2d8 */
  --hero-bg:linear-gradient(160deg,#33270f,#2b2110); --hero-line:#4a3a17;
  --push-bg:linear-gradient(150deg,#222835,#1d222f); /* was #282235,#221d2f */
  --scroll:#353d50; --scroll-h:#434d64; /* was #3d3550 / #4d4364 */
  --chart-bar:#6a7795; --chart-bar-h:#808eb0; /* was #776a95 / #8f80b0 */
  --dgr-line:#5c3034; --lk-hover:#9cc4ee; --accent-wash-h:#4a2530;
  --sh-1:0 1px 2px rgba(0,0,0,.4);
  --sh-2:0 2px 4px rgba(0,0,0,.35), 0 8px 18px -8px rgba(0,0,0,.6);
  --sh-3:0 10px 34px -10px rgba(0,0,0,.75);
  --sh-ctl:0 1px 1px rgba(0,0,0,.3), 0 1px 2.5px rgba(0,0,0,.35);
  --sh-ctl-h:0 1px 2px rgba(0,0,0,.4), 0 3px 6px -1px rgba(0,0,0,.5);
  --sh-pri:0 1px 2px rgba(0,0,0,.4), 0 3px 8px -2px rgba(211,56,79,.45);
}
*{box-sizing:border-box}
@media (prefers-reduced-motion:reduce){*,*::before,*::after{transition-duration:.001ms!important;animation-duration:.001ms!important}}

html,body{margin:0;height:100%}
body{
  background:var(--ground); color:var(--ink);
  font:400 13.5px/1.5 'IBM Plex Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  -webkit-font-smoothing:antialiased;
}
.mono{font-family:'IBM Plex Sans',system-ui,sans-serif}
/* Reachable by a screen reader, invisible on screen. Not display:none, which removes it from the
   accessibility tree along with everything else. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.num{font-variant-numeric:tabular-nums}
/* color:inherit matters as much as font-family. A <button> does NOT inherit color — the UA
   default is `buttontext` (black), so any button that did not set its own color rendered BLACK
   ON THE DARK GROUND. That is what made the list-view page title nearly invisible in dark mode. */
button{font-family:inherit;color:inherit}
.ico{width:16px;height:16px;flex:0 0 auto;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.ico-s{width:13px;height:13px}
.ico-f{fill:currentColor;stroke:none}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* ============ FRAME ============ */
.app{
  display:grid;height:100vh;overflow:hidden;
  grid-template-columns:var(--rail-w) 1fr var(--rstrip-w);
  grid-template-areas:"rail shell rstrip";
}
.app.rail-collapsed{grid-template-columns:60px 1fr var(--rstrip-w)}
.rail{grid-area:rail}
.shell{grid-area:shell}
.rstrip{grid-area:rstrip}

/* ============ RAIL ============ */
.rail{background:var(--rail);display:flex;flex-direction:column;height:100%;overflow:hidden;position:relative}
/* Six of fourteen nav items (Support, Trust & safety, Deleted accounts, Reports,
   Audit log, Admins) sat below the fold with no scrollbar visible against the
   dark rail background -- they read as missing, not scrollable. This fade is
   the only cue that the list continues. */
.rail-fade{position:absolute;left:0;right:0;bottom:76px;height:26px;
  background:linear-gradient(to bottom,transparent,var(--rail));pointer-events:none}
.app.rail-collapsed .rail-fade{display:none}
.rail-brand{display:flex;align-items:center;gap:11px;padding:15px 14px 14px;flex:0 0 auto}
.rail-logo{
  width:32px;height:32px;border-radius:9px;flex:0 0 auto;
  background:linear-gradient(150deg,var(--rail-active),var(--accent-2));
  display:grid;place-items:center;color:#fff;
  box-shadow:0 2px 8px -2px rgba(239,95,120,.55);
}
.rail-logo svg{width:18px;height:18px;stroke-width:2.3}
.rail-word{font-size:var(--t-h3);font-weight:700;letter-spacing:-.022em;color:var(--rail-ink);white-space:nowrap}
.rail-word small{display:block;font-size:var(--t-micro);font-weight:600;letter-spacing:.09em;color:var(--rail-ink-3);text-transform:uppercase;margin-top:-1px}
.app.rail-collapsed .rail-word,.app.rail-collapsed .rail-sec-label,.app.rail-collapsed .nav-txt,
.app.rail-collapsed .nav-count,.app.rail-collapsed .nav-caret,.app.rail-collapsed .subnav{display:none}
.app.rail-collapsed .rail-brand{padding:14px 0 12px;justify-content:center}
.app.rail-collapsed .nav-a{justify-content:center;padding:9px 0}

/* ---- collapsed-rail tooltips — this state existed with zero indication of what
   any icon meant; hover/focus now surfaces the label via data-tip, the same real
   left-nav pattern Zoho's own product uses (an icon strip, not a labeled list). ---- */
/* Collapsed-rail tooltip + flyout are driven from JS (see the `railTip`/
   `railFlyout` block near the rail-collapse listener in app.js), not CSS
   ::after — .rail is `overflow:hidden` on purpose (it's what makes .rail-fade
   work) and a child positioned absolute inside it is clipped along with
   everything else, so this has to render as a position:fixed element appended
   to <body> instead, computed from the hovered icon's real rect. */
#railTip{
  position:fixed;z-index:70;background:var(--ink);color:var(--ground);
  font:600 12px 'IBM Plex Sans',system-ui,sans-serif;padding:5px 10px;border-radius:6px;
  white-space:nowrap;box-shadow:var(--sh-2);pointer-events:none;display:none;
}
#railTip.on{display:block}
/* the one tree item (Helpers) flies its real subnav out as position:fixed —
   same DOM node, no re-parenting, so its existing click handlers still work */
.subnav.flyout{
  display:flex!important;flex-direction:column;gap:1px;position:fixed;min-width:196px;
  background:var(--rail-2);border:1px solid var(--rail-line);border-radius:var(--r-sm);
  box-shadow:var(--sh-3);padding:6px;z-index:70;
}
.subnav.flyout .nav-a{justify-content:flex-start;padding:8px 9px}
.subnav.flyout .nav-txt,.subnav.flyout .nav-count{display:inline}

.rail-scroll{flex:1 1 auto;overflow-y:auto;padding:4px 8px 10px}
.rail-scroll::-webkit-scrollbar{width:8px}
.rail-scroll::-webkit-scrollbar-thumb{background:var(--rail-3);border-radius:8px}
.rail-sec-label{font-size:var(--t-micro);font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--rail-ink-3);padding:14px 8px 5px}
.nav-a{
  display:flex;align-items:center;gap:10px;width:100%;
  padding:8px 9px;border:0;background:none;border-radius:var(--r-xs);cursor:pointer;
  color:var(--rail-ink-2);font-size:var(--t-body);font-weight:500;text-align:left;
  transition:background .13s var(--ease),color .13s var(--ease);
}
.nav-a:hover{background:var(--rail-2);color:var(--rail-ink)}
.nav-a.on{background:var(--rail-active-bg);color:var(--rail-active);font-weight:600}
.nav-a:focus-visible{outline:2px solid var(--rail-active);outline-offset:-2px}
.nav-txt{flex:1 1 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nav-count{font-family:'IBM Plex Sans',system-ui,sans-serif;font-variant-numeric:tabular-nums;font-size:var(--t-label);color:var(--rail-ink-3)}
.nav-a.on .nav-count{color:var(--rail-active)}
.nav-caret{transition:transform .15s;color:var(--rail-ink-3)}
.nav-a[aria-expanded="true"] .nav-caret{transform:rotate(90deg)}
.subnav{display:none;padding:2px 0 4px}
.subnav.open{display:block}
.subnav button{
  display:flex;align-items:center;justify-content:space-between;width:100%;
  padding:6px 9px 6px 35px;border:0;background:none;border-radius:6px;cursor:pointer;
  color:var(--rail-ink-3);font-size:var(--t-meta);text-align:left;
}
.subnav button{transition:background .13s var(--ease),color .13s var(--ease)}
.subnav button:hover{background:var(--rail-2);color:var(--rail-ink-2)}
.subnav button.on{color:var(--rail-active);background:var(--rail-active-bg);font-weight:600}
.subnav .nav-count{font-size:var(--t-micro)}
.rail-promo{flex:0 0 auto;padding:8px 10px 4px}
.promo-pill{
  display:flex;align-items:center;justify-content:center;gap:8px;width:100%;
  height:34px;padding:0 10px;border:1px solid var(--rail-line);border-radius:20px;
  background:var(--rail-2);color:var(--rail-ink-2);cursor:pointer;
  font-size:var(--t-label);font-weight:700;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;
  transition:background .13s var(--ease),color .13s var(--ease);
}
.promo-pill:hover{background:var(--rail-3);color:var(--rail-ink)}
.promo-dot{width:7px;height:7px;border-radius:50%;background:var(--rail-active);flex:0 0 auto;box-shadow:0 0 0 3px rgba(239,95,120,.18)}
.app.rail-collapsed .rail-promo{padding:8px 6px 4px}
.app.rail-collapsed .promo-pill{padding:0}
.rail-foot{flex:0 0 auto;border-top:1px solid var(--rail-line);padding:8px}
.rail-collapse{
  display:flex;align-items:center;gap:9px;width:100%;padding:8px 9px;
  border:0;background:none;border-radius:7px;color:var(--rail-ink-3);cursor:pointer;font-size:var(--t-meta);
}
.rail-collapse:hover{background:var(--rail-2);color:var(--rail-ink-2)}
.app.rail-collapsed .rail-collapse svg{transform:rotate(180deg)}

/* ============ TOPBAR ============ */
.shell{display:flex;flex-direction:column;min-width:0;overflow:hidden}
.topbar{
  height:var(--top-h);flex:0 0 auto;display:flex;align-items:center;gap:10px;
  padding:0 14px;background:var(--surface);border-bottom:1px solid var(--line);
  position:sticky;top:0;z-index:30;
}
.omni{
  flex:1 1 auto;max-width:440px;display:flex;align-items:center;gap:9px;
  height:var(--h-ctl);padding:0 11px;border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--raised);color:var(--ink-3);cursor:pointer;font-size:var(--t-meta);
  transition:background .13s var(--ease),border-color .13s var(--ease),box-shadow .13s var(--ease);
}
.omni:hover{background:var(--surface);border-color:var(--ink-3);box-shadow:var(--sh-ctl)}
.omni .lbl{flex:1 1 auto;text-align:left}
.kbd{
  font-family:'IBM Plex Sans',system-ui,sans-serif;font-size:var(--t-micro);color:var(--ink-3);
  border:1px solid var(--line);border-radius:5px;padding:2px 5px;background:var(--surface);line-height:1;
}
.top-right{margin-left:auto;display:flex;align-items:center;gap:5px}
.org{
  display:flex;align-items:center;gap:7px;height:var(--h-ctl);padding:0 11px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);
  color:var(--ink);font-size:var(--t-meta);font-weight:600;cursor:pointer;white-space:nowrap;
  box-shadow:var(--sh-ctl);
  transition:background .13s var(--ease),box-shadow .13s var(--ease),transform .10s var(--ease);
}
.org:hover{background:var(--raised);box-shadow:var(--sh-ctl-h)}
.org:active{transform:translateY(.5px);box-shadow:var(--sh-ctl)}
.org svg{color:var(--ink-3)}
.icon-btn{
  position:relative;width:var(--h-ctl);height:var(--h-ctl);display:grid;place-items:center;
  border:1px solid transparent;border-radius:var(--r-sm);background:none;color:var(--ink-2);cursor:pointer;
  transition:background .13s var(--ease),color .13s var(--ease),transform .10s var(--ease);
}
.icon-btn:hover{background:var(--sunken);color:var(--ink)}
.icon-btn:active{transform:translateY(.5px)}
.icon-btn.accent{
  background:linear-gradient(180deg,#e04156,var(--accent));color:#fff;border-color:var(--accent-2);
  box-shadow:var(--sh-pri);
}
.icon-btn.accent:hover{background:linear-gradient(180deg,var(--accent),var(--accent-2));color:#fff}
.dot-badge{
  position:absolute;top:1px;right:1px;min-width:16px;height:16px;padding:0 4px;
  border-radius:9px;background:var(--danger);color:var(--on-danger);font-size:var(--t-micro);font-weight:700;
  display:grid;place-items:center;border:2px solid var(--surface);line-height:1;
}
.me{
  width:var(--h-ctl);height:var(--h-ctl);border-radius:50%;border:0;cursor:pointer;
  background:linear-gradient(150deg,var(--accent-hi),var(--accent-lo));color:var(--accent-ink);
  font-size:var(--t-meta);font-weight:700;display:grid;place-items:center;
  box-shadow:var(--sh-ctl);transition:transform .10s var(--ease),box-shadow .13s var(--ease);
}
.me:hover{box-shadow:var(--sh-ctl-h)}
.me:active{transform:translateY(.5px)}
.sep{width:1px;height:20px;background:var(--line);margin:0 5px}

/* ============ CONTENT ============ */
.body{flex:1 1 auto;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--scroll) transparent}
.body::-webkit-scrollbar{width:11px}
.body::-webkit-scrollbar-track{background:transparent}
.body::-webkit-scrollbar-thumb{background:var(--scroll);border-radius:8px;border:3px solid var(--ground)}
.body::-webkit-scrollbar-thumb:hover{background:var(--scroll-h)}
.tw{scrollbar-width:thin}
.view{display:none}
.view.on{display:block}

/* greeting */
.hello{
  background:var(--surface);border-bottom:1px solid var(--line);
  padding:20px 26px 0;position:relative;overflow:hidden;
}
.hello::after{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.55;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='210' height='150' viewBox='0 0 210 150' fill='none' stroke='%23ddd5e4' stroke-width='1.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='22' cy='22' r='6'/%3E%3Cpath d='M14 38c0-4.4 3.6-7 8-7s8 2.6 8 7'/%3E%3Cpath d='M62 14h20v16H62z'/%3E%3Cpath d='M62 22h20'/%3E%3Cpath d='M112 30l5 5 9-11'/%3E%3Cpath d='M156 16l9 5v10c0 6-4 9-9 11-5-2-9-5-9-11V21z'/%3E%3Cpath d='M188 30V16M182 22h12'/%3E%3Cpath d='M30 74h18v13H30z'/%3E%3Cpath d='M34 74v-3h10v3'/%3E%3Ccircle cx='84' cy='80' r='7'/%3E%3Cpath d='M96 118l5 5 9-11'/%3E%3Cpath d='M128 74h16v12h-16z'/%3E%3Cpath d='M128 79h16'/%3E%3Ccircle cx='178' cy='80' r='6'/%3E%3Cpath d='M170 96c0-4.4 3.6-7 8-7s8 2.6 8 7'/%3E%3Cpath d='M22 118l5 5 9-11'/%3E%3Cpath d='M56 112h16v13H56z'/%3E%3Cpath d='M60 112v-3h8v3'/%3E%3Ccircle cx='140' cy='118' r='6.5'/%3E%3Cpath d='M186 110l7 4v8c0 5-3 7-7 8-4-1-7-3-7-8v-8z'/%3E%3C/svg%3E");
  background-size:210px 150px;
  -webkit-mask-image:linear-gradient(100deg,transparent 38%,#000 100%);
  mask-image:linear-gradient(100deg,transparent 38%,#000 100%);
}
.hello-row{display:flex;align-items:center;gap:14px;position:relative;z-index:1}
.org-tile{
  width:48px;height:48px;border-radius:var(--r);border:1px solid var(--line);
  background:var(--surface);display:grid;place-items:center;flex:0 0 auto;box-shadow:var(--sh-1);
}
.org-tile svg{width:26px;height:26px;color:var(--accent);stroke-width:2.2}
.hello h1{margin:0;font-size:var(--t-h2);font-weight:700;letter-spacing:-.02em}
.hello .sub{margin:1px 0 0;font-size:var(--t-meta);color:var(--ink-2)}
.hello-act{margin-left:auto;display:flex;gap:8px;position:relative;z-index:1}
.tabs{display:flex;gap:2px;margin-top:16px;position:relative;z-index:1}
.tab{
  border:0;background:none;cursor:pointer;padding:10px 14px;font-size:var(--t-body);font-weight:500;
  color:var(--ink-2);border-bottom:2px solid transparent;margin-bottom:-1px;border-radius:var(--r-xs) var(--r-xs) 0 0;
  transition:color .13s var(--ease),background .13s var(--ease),border-color .13s var(--ease);
}
.tab:hover{color:var(--ink);background:var(--raised)}
.tab.on{color:var(--accent);border-bottom-color:var(--accent);font-weight:600}

.pad{padding:20px 26px 44px}
.grid{display:grid;grid-template-columns:1fr 344px;gap:16px;align-items:start}
.stack{display:flex;flex-direction:column;gap:16px;min-width:0}

/* card */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh-1);overflow:hidden}
.card-h{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--line-soft);min-height:52px}
/* A real <h3>, so the 14 card titles are reachable by heading navigation; the reset keeps it
   looking exactly as the span did. */
.card-t{margin:0;font-size:var(--t-lead);font-weight:650;letter-spacing:-.012em}
.card-b{padding:16px}
.card-b.flush{padding:0}
.pick{
  margin-left:auto;display:inline-flex;align-items:center;gap:6px;height:29px;
  border:1px solid var(--line);background:var(--surface);border-radius:var(--r-xs);
  padding:0 9px 0 11px;font-size:var(--t-meta);font-weight:500;color:var(--ink-2);
  cursor:pointer;white-space:nowrap;box-shadow:var(--sh-ctl);
  transition:background .13s var(--ease),border-color .13s var(--ease),box-shadow .13s var(--ease),transform .10s var(--ease);
}
.pick:hover{background:var(--raised);border-color:var(--ink-3);color:var(--ink);box-shadow:var(--sh-ctl-h)}
.pick:active{transform:translateY(.5px);box-shadow:var(--sh-ctl)}
.pick svg{color:var(--ink-3)}
/* Segmented control. This had a JS click handler and NO CSS at all, so it rendered as three raw
   UA buttons — grey `buttonface` chrome with black text, on both grounds. A sunken track with a
   raised pill for the active option, matching .pick's control language. */
.seg{
  display:inline-flex;align-items:center;height:29px;padding:2px;gap:2px;
  background:var(--sunken);border:1px solid var(--line);border-radius:var(--r-xs);
}
.seg button{
  flex:1 0 auto;height:100%;display:inline-flex;align-items:center;justify-content:center;
  border:0;background:none;cursor:pointer;white-space:nowrap;padding:0 11px;
  border-radius:calc(var(--r-xs) - 1px);font-size:var(--t-meta);font-weight:500;
  color:var(--ink-2);transition:background .13s var(--ease),color .13s var(--ease);
}
.seg button:hover{color:var(--ink)}
.seg button.on{background:var(--surface);color:var(--ink);font-weight:600;box-shadow:var(--sh-ctl)}
.mini-add{
  display:flex;align-items:center;gap:5px;border:0;background:none;cursor:pointer;
  color:var(--accent);font-size:var(--t-meta);font-weight:600;padding:5px 8px;border-radius:var(--r-xs);
  transition:background .13s var(--ease);
}
.mini-add:hover{background:var(--accent-wash)}

/* ---- headline: the one thing that matters today ---- */
.headline{
  display:flex;align-items:stretch;gap:0;margin-bottom:16px;
  background:var(--surface);border:1px solid var(--line);border-left:4px solid var(--warn);
  border-radius:var(--r);box-shadow:var(--sh-2);overflow:hidden;
}
.hl-fig{
  flex:0 0 auto;display:flex;flex-direction:column;justify-content:center;
  padding:20px 26px;background:var(--hero-bg);border-right:1px solid var(--hero-line);
}
.hl-num{font-size:var(--t-hero);font-weight:700;letter-spacing:-.03em;color:var(--warn);line-height:1}
.hl-cap{font-size:var(--t-label);font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--warn);margin-top:6px;white-space:nowrap}
.hl-body{flex:1 1 auto;padding:18px 22px;display:flex;flex-direction:column;justify-content:center;min-width:0}
.hl-t{font-size:var(--t-lead);font-weight:650;letter-spacing:-.012em;margin-bottom:3px}
.hl-s{font-size:var(--t-meta);color:var(--ink-2);line-height:1.5}
.hl-s b{color:var(--ink);font-weight:600}
.hl-act{flex:0 0 auto;display:flex;align-items:center;padding:0 20px 0 8px}
@media (max-width:820px){
  .headline{flex-direction:column}
  .hl-fig{border-right:0;border-bottom:1px solid var(--hero-line);padding:16px 20px}
  .hl-act{padding:0 20px 18px 20px}
}

/* metric tiles */
.tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line-soft);border-radius:var(--r);overflow:hidden;border:1px solid var(--line);box-shadow:var(--sh-1)}
.tile{background:var(--surface);padding:14px 16px;min-width:0;position:relative}
.tile-k{font-size:var(--t-label);font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-3)}
.tile-v{font-size:var(--t-h2);font-weight:700;letter-spacing:-.02em;margin-top:7px}
.tile-v .u{font-size:var(--t-meta);font-weight:500;color:var(--ink-3)}
.tile-n{font-size:var(--t-meta);color:var(--ink-2);margin-top:3px}
.tile-n.warn{color:var(--warn);font-weight:500}
.spark{position:absolute;top:13px;right:14px;width:46px;height:17px}
.spark polyline{fill:none;stroke:var(--chart-bar-h);stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.spark circle{fill:var(--chart-bar-h)}

/* progress card (Books-style) */
.prog-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.prog-lbl{font-size:var(--t-meta);color:var(--ink-2)}
.prog-v{font-size:var(--t-h2);font-weight:700;letter-spacing:-.02em;margin:4px 0 12px}
.bar{height:9px;border-radius:5px;background:var(--sunken);display:flex;overflow:hidden}
.bar i{display:block;height:100%}
.bar i.a{background:var(--info)}
.bar i.b{background:var(--warn)}
.bar i.z{background:var(--sunken)}
.legend{display:flex;gap:16px;margin-top:11px;flex-wrap:wrap}
.leg{display:flex;align-items:center;gap:6px;font-size:var(--t-meta);color:var(--ink-2)}
.leg s{width:8px;height:8px;border-radius:2px;text-decoration:none;flex:0 0 auto}
.leg b{color:var(--ink);font-weight:600}

/* category cards (Top Selling Items style) */
.cats{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.cat{border:1px solid var(--line);border-radius:9px;padding:13px;background:var(--surface)}
.cat-ico{width:38px;height:38px;border-radius:9px;background:var(--accent-wash);color:var(--accent);display:grid;place-items:center;margin-bottom:10px}
.cat-ico svg{width:19px;height:19px}
.cat-n{font-size:var(--t-meta);color:var(--ink-2)}
.cat-v{font-size:var(--t-h3);font-weight:700;letter-spacing:-.02em;margin-top:2px}
.cat-v .u{font-size:var(--t-meta);font-weight:500;color:var(--ink-3)}
.trend{display:inline-flex;align-items:center;gap:3px;font-size:var(--t-meta);font-weight:600;margin-top:6px}
.trend.up{color:var(--ok)}
.trend.dn{color:var(--danger)}
.cat-empty{
  border:1px dashed var(--line);border-radius:9px;padding:13px;display:flex;
  flex-direction:column;align-items:center;justify-content:center;text-align:center;
  color:var(--ink-3);font-size:var(--t-meta);line-height:1.45;gap:8px;
}
.cat-empty svg{width:30px;height:30px;color:var(--line);stroke-width:1.5}

/* pending actions panel */
.pa-tabs{display:flex;border-bottom:1px solid var(--line-soft)}
.pa-tab{
  flex:1;border:0;background:var(--raised);cursor:pointer;padding:11px 8px;
  font-size:var(--t-meta);font-weight:600;color:var(--ink-2);border-bottom:2px solid transparent;
}
.pa-tab.on{background:var(--surface);color:var(--ink);border-bottom-color:var(--accent)}
.pa-tab:first-child{border-right:1px solid var(--line-soft)}
.pa-sec{padding:14px 16px 6px}
.pa-sec-h{display:flex;align-items:center;gap:8px;margin-bottom:4px}
.pa-sec-h svg{width:16px;height:16px}
.pa-sec-h span{font-size:var(--t-label);font-weight:700;letter-spacing:.07em;text-transform:uppercase}
.pa-sec.v .pa-sec-h{color:var(--warn)}
.pa-sec.a .pa-sec-h{color:var(--info)}
.pa-sec.m .pa-sec-h{color:var(--ok)}
.pa-row{
  display:flex;align-items:center;gap:8px;width:100%;padding:10px 8px;margin:0 -8px;
  width:calc(100% + 16px);
  border:0;background:none;border-top:1px solid var(--line-soft);cursor:pointer;
  font-size:var(--t-body);color:var(--ink);text-align:left;border-radius:var(--r-xs);
  transition:background .13s var(--ease),color .13s var(--ease);
}
.pa-row:hover{color:var(--accent);background:var(--accent-wash)}
.pa-row>.pa-c{color:var(--ink-3);flex:0 0 auto;transition:transform .13s var(--ease),color .13s var(--ease)}
.pa-row:hover>.pa-c{color:var(--accent);transform:translateX(2px)}
.pa-row .cv{color:var(--ink-3)}
.pa-row .n{margin-left:auto;font-family:'IBM Plex Sans',system-ui,sans-serif;font-weight:700;font-variant-numeric:tabular-nums}
.pa-row .n.hot{color:var(--danger)}
.pa-row .n.zero{color:var(--ink-3);font-weight:400}

/* activity feed */
.feed{padding:6px 16px 14px}
.fi{display:flex;gap:11px;padding:11px 0;border-top:1px solid var(--line-soft)}
.fi:first-child{border-top:0}
.fi-d{width:26px;height:26px;border-radius:7px;display:grid;place-items:center;flex:0 0 auto}
.fi-d svg{width:14px;height:14px}
.fi-d.ok{background:var(--ok-wash);color:var(--ok)}
.fi-d.warn{background:var(--warn-wash);color:var(--warn)}
.fi-d.info{background:var(--info-wash);color:var(--info)}
.fi-d.bad{background:var(--danger-wash);color:var(--danger)}
.fi-t{font-size:var(--t-meta);line-height:1.45}
.fi-t b{font-weight:600}
.fi-m{font-size:var(--t-label);color:var(--ink-3);margin-top:2px}

/* chart */
.chart{padding:14px 16px 16px}
.plot{
  display:flex;align-items:flex-end;gap:7px;height:132px;
  background:linear-gradient(var(--line-soft) 1px,transparent 1px);
  background-size:100% 33px;
}
.col{flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:5px;height:100%;position:relative}
.pair{display:flex;align-items:flex-end;gap:2px;width:100%;height:100%;justify-content:center}
.b1{flex:1;max-width:17px;background:var(--chart-bar);border-radius:3px 3px 0 0}
.b2{width:6px;background:var(--accent);border-radius:3px 3px 0 0;flex:0 0 auto}
.col:hover .b1{background:var(--chart-bar-h)}
.b1.hi{background:var(--warn)}
/* --ink-2, not --ink-3: this is 10px mono, the smallest text on the page, and it sits on --line-soft
   in places. Tertiary ink at micro size measured 4.14:1 there — the smallest type had the weakest
   contrast, which is backwards. */
.x{font-size:var(--t-micro);color:var(--ink-2);font-family:'IBM Plex Sans',system-ui,sans-serif}
.chart-note{
  margin:14px 0 0;padding-top:12px;border-top:1px solid var(--line-soft);
  font-size:var(--t-meta);color:var(--ink-3);line-height:1.5;
}
.chart-note b{color:var(--ink-2);font-weight:600}
.chart-note code{font-family:'IBM Plex Sans',system-ui,sans-serif;font-size:var(--t-micro);background:var(--sunken);padding:1px 5px;border-radius:4px;color:var(--ink-2)}
.flag{
  position:absolute;top:-2px;left:50%;transform:translate(-50%,-100%);
  font-size:var(--t-micro);font-weight:700;color:var(--warn);background:var(--warn-wash);
  padding:1px 5px;border-radius:4px;white-space:nowrap;
}
.keys{margin-left:auto;display:flex;gap:14px}
.key{display:flex;align-items:center;gap:5px;font-size:var(--t-meta);color:var(--ink-2)}
.key s{width:9px;height:9px;border-radius:2px;text-decoration:none}

/* ============ LIST VIEW ============ */
.lv-head{
  background:var(--surface);border-bottom:1px solid var(--line);
  padding:14px 26px;display:flex;align-items:center;gap:12px;flex-wrap:wrap;
}
.lv-title{
  display:flex;align-items:center;gap:8px;border:0;background:none;cursor:pointer;
  padding:4px 8px;margin-left:-8px;border-radius:var(--r-xs);
  transition:background .13s var(--ease);
}
.lv-title:hover{background:var(--sunken)}
.lv-title h2{margin:0;font-size:var(--t-h3);font-weight:700;letter-spacing:-.02em}
.lv-title svg{color:var(--ink-3)}
.lv-act{margin-left:auto;display:flex;align-items:center;gap:8px}
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  height:var(--h-ctl);padding:0 13px;
  border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--surface);color:var(--ink);
  font-size:var(--t-meta);font-weight:600;letter-spacing:-.005em;cursor:pointer;white-space:nowrap;
  box-shadow:var(--sh-ctl);
  transition:background .13s var(--ease),border-color .13s var(--ease),
             box-shadow .13s var(--ease),transform .10s var(--ease),color .13s var(--ease);
}
.btn:hover{background:var(--raised);border-color:var(--ink-3);box-shadow:var(--sh-ctl-h)}
.btn:active{transform:translateY(.5px);box-shadow:var(--sh-ctl);background:var(--sunken)}
.btn svg{color:var(--ink-3);transition:color .13s var(--ease)}
.btn:hover svg{color:var(--ink-2)}

.btn.pri{
  background:linear-gradient(180deg,var(--pri-hi),var(--pri-lo));
  border-color:var(--pri-2);color:var(--on-pri);box-shadow:var(--sh-action);
}
/* Hover flips the same two stops rather than reaching for a fixed third colour, same reasoning
   as the coral version this replaced 2026-09-04: a fixed stop only gets checked against one
   theme, and a flip keeps both already-verified stops in play. */
.btn.pri:hover{background:linear-gradient(180deg,var(--pri-lo),var(--pri-hi));border-color:var(--pri-2)}
.btn.pri:active{background:var(--pri-2)}
.btn.pri svg,.btn.pri:hover svg{color:var(--on-pri);opacity:.85}

.btn.qui{border-color:transparent;background:none;box-shadow:none;color:var(--ink-2);font-weight:500}
.btn.qui:hover{background:var(--sunken);border-color:transparent;box-shadow:none;color:var(--ink)}
.btn.qui:active{background:var(--line-soft)}

.btn.dgr{color:var(--danger);border-color:var(--dgr-line)}
.btn.dgr:hover{background:var(--danger-wash);border-color:var(--danger);color:var(--danger)}
.btn.dgr svg,.btn.dgr:hover svg{color:currentColor}
.btn.ico-only{width:var(--h-ctl);padding:0}

.tw{overflow-x:auto;background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh-1)}
table{width:100%;border-collapse:collapse}
thead th{
  text-align:left;font-size:var(--t-label);font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink-3);padding:10px 14px;background:var(--raised);
  border-bottom:1px solid var(--line);white-space:nowrap;
}
thead th.r{text-align:right}
thead th button{
  /* text-transform:inherit is doing real work. A <button> does not pick up the uppercasing from
     `thead th`, so every SORTABLE header rendered title case while the two plain ones ("Target",
     "Waiting on") obeyed the rule — one table, two header styles. Same trap as `color` above:
     the property the design assumed a button would inherit, it does not. */
  border:0;background:none;cursor:pointer;color:inherit;font:inherit;
  letter-spacing:inherit;text-transform:inherit;
  display:inline-flex;align-items:center;gap:4px;padding:0;
}
thead th button:hover{color:var(--ink)}
tbody td{padding:13px 14px;border-bottom:1px solid var(--line-soft);font-size:var(--t-body);vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
tbody tr{transition:background .1s var(--ease)}
tbody tr:hover{background:var(--raised)}
td.r{text-align:right;font-family:'IBM Plex Sans',system-ui,sans-serif;font-variant-numeric:tabular-nums}
td.mut{color:var(--ink-2)}
/* Date cell: absolute date over derived relative age. Two lines, but the rows already stand two
   lines tall wherever an avatar appears, so this costs no height in practice. */
.when{white-space:nowrap}
.when-abs{display:block;font-variant-numeric:tabular-nums}
.when-rel{display:block;font-size:var(--t-micro);color:var(--ink-3);margin-top:1px}
.cbx{
  appearance:none;-webkit-appearance:none;width:16px;height:16px;flex:0 0 auto;
  border:1.5px solid var(--line);border-radius:5px;background:var(--surface);cursor:pointer;
  display:inline-grid;place-items:center;vertical-align:middle;
  transition:background .12s var(--ease),border-color .12s var(--ease);
}
.cbx:hover{border-color:var(--ink-3)}
.cbx:checked{background:var(--accent);border-color:var(--accent)}
.cbx:checked::after{
  content:"";width:9px;height:5px;border:1.9px solid #fff;border-top:0;border-right:0;
  transform:rotate(-45deg) translate(.5px,-1px);
}
.lk{color:var(--info);font-weight:600;text-decoration:none;cursor:pointer;background:none;border:0;padding:0;font-size:var(--t-body);font-family:inherit;transition:color .12s var(--ease)}
.lk:hover{text-decoration:underline;text-underline-offset:2px;color:var(--lk-hover)}
.who{display:flex;align-items:center;gap:10px}
.pic{
  width:30px;height:30px;border-radius:50%;flex:0 0 auto;
  background:var(--pic-bg);color:var(--pic-ink);
  display:grid;place-items:center;font-size:var(--t-label);font-weight:700;letter-spacing:.02em;
  border:1px solid rgba(27,23,32,.05);
}
.tag{
  display:inline-flex;align-items:center;gap:5px;font-size:var(--t-label);font-weight:600;
  padding:4px 9px;border-radius:20px;white-space:nowrap;line-height:1.25;
  border:1px solid transparent;
}
.tag s{width:5px;height:5px;border-radius:50%;background:currentColor;text-decoration:none;flex:0 0 auto}
.tag.ok{background:var(--ok-wash);color:var(--ok)}
.tag.warn{background:var(--warn-wash);color:var(--warn)}
.tag.bad{background:var(--danger-wash);color:var(--danger)}
.tag.mut{background:var(--sunken);color:var(--ink-2)}
.tag.info{background:var(--info-wash);color:var(--info)}
.env{font-family:'IBM Plex Sans',system-ui,sans-serif;font-size:var(--t-micro);padding:2px 6px;border-radius:4px;border:1px solid var(--line);color:var(--ink-2)}
.env.sbx{color:var(--warn);background:var(--warn-wash);border-color:transparent}
.tfoot{display:flex;align-items:center;gap:10px;padding:12px 14px;border-top:1px solid var(--line);font-size:var(--t-meta);color:var(--ink-2);background:var(--raised)}
.tfoot .pg{margin-left:auto;display:flex;gap:6px}
.pgb{
  width:30px;height:30px;border:1px solid var(--line);background:var(--surface);border-radius:var(--r-xs);
  color:var(--ink-2);cursor:pointer;display:grid;place-items:center;box-shadow:var(--sh-ctl);
  transition:background .13s var(--ease),color .13s var(--ease),box-shadow .13s var(--ease),transform .1s var(--ease);
}
.pgb:hover:not(:disabled){background:var(--raised);color:var(--ink);box-shadow:var(--sh-ctl-h)}
.pgb:active:not(:disabled){transform:translateY(.5px);box-shadow:var(--sh-ctl)}
.pgb:disabled{opacity:.35;cursor:default;box-shadow:none}
.pgb:first-child svg{transform:rotate(180deg)}

/* ============ LIST: FILTER BAR ============ */
.filter-bar{
  display:none;align-items:center;gap:9px;padding:10px 14px;
  background:var(--raised);border-bottom:1px solid var(--line);
}
.filter-bar.on{display:flex}
.filter-bar input{
  flex:1 1 auto;min-width:0;height:32px;padding:0 11px;
  border:1px solid var(--line);border-radius:var(--r-xs);background:var(--surface);
  font:inherit;font-size:var(--t-meta);color:var(--ink);outline:0;
}
.filter-bar input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-wash)}
.filter-chip{
  display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 6px 0 10px;
  border-radius:20px;background:var(--accent-wash);color:var(--accent);
  font-size:var(--t-label);font-weight:600;white-space:nowrap;
}
.filter-chip button{border:0;background:none;cursor:pointer;color:inherit;display:grid;place-items:center;padding:2px;border-radius:50%}
.filter-chip button:hover{background:rgba(211,56,79,.14)}

/* ============ LIST: BULK BAR ============ */
.bulk-bar{
  display:none;align-items:center;gap:10px;padding:9px 14px;
  background:var(--rail);color:var(--rail-ink);border-bottom:1px solid var(--rail-line);
}
.bulk-bar.on{display:flex}
.bulk-n{font-size:var(--t-meta);font-weight:600}
.bulk-n b{color:var(--rail-active)}
.bulk-sep{width:1px;height:18px;background:var(--rail-line)}
.bulk-b{
  display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 11px;
  border:1px solid var(--rail-line);border-radius:var(--r-xs);background:var(--rail-2);
  color:var(--rail-ink-2);font-size:var(--t-meta);font-weight:500;cursor:pointer;
  transition:background .13s var(--ease),color .13s var(--ease);
}
.bulk-b:hover{background:var(--rail-3);color:var(--rail-ink)}
.bulk-b.dgr{color:#f08a94}
.bulk-b.dgr:hover{background:#3b1e27;color:#ff9ba4}
.bulk-x{margin-left:auto;border:0;background:none;color:var(--rail-ink-3);cursor:pointer;display:grid;place-items:center;padding:5px;border-radius:var(--r-xs)}
.bulk-x:hover{background:var(--rail-2);color:var(--rail-ink)}

/* ============ LIST: SORT + EMPTY ============ */
thead th button .sort-i{opacity:.35;transition:opacity .13s var(--ease),transform .13s var(--ease)}
thead th button.sorted .sort-i{opacity:1;color:var(--accent)}
thead th button.sorted.desc .sort-i{transform:rotate(180deg)}
.empty-row td{padding:44px 16px;text-align:center;color:var(--ink-3)}
.empty-row .ttl{font-size:var(--t-body);font-weight:600;color:var(--ink-2);margin-bottom:4px}
.empty-row .sub{font-size:var(--t-meta)}

/* ============ BROADCAST ============ */
.fld-l{display:block;font-size:var(--t-label);font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3);margin-bottom:6px}
.fld{
  width:100%;padding:9px 11px;margin-bottom:14px;
  border:1px solid var(--line);border-radius:var(--r-xs);background:var(--surface);
  font:inherit;font-size:var(--t-body);color:var(--ink);outline:0;resize:vertical;
  transition:border-color .13s var(--ease),box-shadow .13s var(--ease);
}
.fld:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-wash)}
.fld-help{display:flex;justify-content:space-between;gap:10px;font-size:var(--t-meta);color:var(--ink-3);margin-top:-6px}
#bcAud button{flex:1}
.push{
  display:flex;gap:11px;padding:13px;border-radius:var(--r);
  background:var(--push-bg);border:1px solid var(--line);
}
.push-ico{
  width:34px;height:34px;border-radius:9px;flex:0 0 auto;display:grid;place-items:center;color:#fff;
  background:linear-gradient(150deg,#e0566c,var(--accent-2));box-shadow:var(--sh-ctl);
}
.push-ico svg{width:19px;height:19px}
.push-app{font-size:var(--t-micro);font-weight:700;letter-spacing:.07em;color:var(--ink-3);margin-bottom:3px}
.push-t{font-size:var(--t-body);font-weight:650;letter-spacing:-.01em;margin-bottom:2px;overflow-wrap:anywhere}
.push-b{font-size:var(--t-meta);color:var(--ink-2);line-height:1.45;overflow-wrap:anywhere}

/* ============ RECORD DRAWER ============ */
.drawer-scrim{
  display:none;position:fixed;inset:0;z-index:130;background:rgba(27,23,32,.34);
}
.drawer-scrim.on{display:block}
.drawer{
  position:fixed;top:0;right:0;bottom:0;z-index:140;width:min(420px,92vw);
  background:var(--surface);border-left:1px solid var(--line);box-shadow:var(--sh-3);
  display:flex;flex-direction:column;transform:translateX(100%);
  transition:transform .22s var(--ease);
}
.drawer.on{transform:none}
.dr-head{display:flex;align-items:flex-start;gap:13px;padding:18px 18px 16px;border-bottom:1px solid var(--line-soft)}
.dr-pic{
  width:46px;height:46px;border-radius:50%;flex:0 0 auto;display:grid;place-items:center;
  background:var(--pic-bg);color:var(--pic-ink);
  font-size:var(--t-body);font-weight:700;border:1px solid rgba(27,23,32,.05);
}
.dr-name{font-size:var(--t-h3);font-weight:700;letter-spacing:-.02em}
.dr-sub{font-size:var(--t-meta);color:var(--ink-2);margin-top:2px}
.dr-x{margin-left:auto;border:1px solid var(--line);background:var(--surface);border-radius:var(--r-xs);width:30px;height:30px;display:grid;place-items:center;color:var(--ink-2);cursor:pointer;flex:0 0 auto}
.dr-x:hover{background:var(--raised);color:var(--ink)}
.dr-acts{display:flex;gap:8px;padding:14px 18px;border-bottom:1px solid var(--line-soft);flex-wrap:wrap}
.dr-body{flex:1 1 auto;overflow-y:auto;padding:4px 18px 20px}
.dr-sec{font-size:var(--t-label);font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-3);padding:16px 0 8px}
.dr-kv{display:flex;align-items:baseline;gap:12px;padding:8px 0;border-top:1px solid var(--line-soft);font-size:var(--t-body)}
.dr-kv .k{flex:0 0 128px;color:var(--ink-3);font-size:var(--t-meta)}
.dr-kv .v{flex:1 1 auto;min-width:0}
.dr-dl{margin:0}
.dr-kv dt,.dr-kv dd{margin:0}
.dr-note{
  margin-top:10px;padding:11px 13px;border-radius:var(--r-xs);
  background:var(--danger-wash);color:var(--danger);font-size:var(--t-meta);line-height:1.5;
  display:flex;gap:9px;
}
@media (max-width:520px){ .drawer{width:100vw} }

/* ============ OMNI / PALETTE ============ */
.scrim{display:none;position:fixed;inset:0;z-index:100;background:rgba(27,23,32,.4);padding-top:11vh;justify-content:center}
.scrim.on{display:flex}
.pal{width:100%;max-width:552px;max-height:62vh;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--sh-3);display:flex;flex-direction:column;overflow:hidden}
.pal-in{display:flex;align-items:center;gap:10px;padding:13px 16px;border-bottom:1px solid var(--line-soft)}
.pal-in svg{color:var(--ink-3)}
.pal-in input{flex:1;border:0;outline:0;background:none;font:inherit;font-size:var(--t-lead);color:var(--ink)}
.pal-res{overflow-y:auto;padding:6px}
.pal-g{font-size:var(--t-micro);font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);padding:9px 10px 4px}
.pal-i{display:flex;align-items:center;gap:11px;padding:9px 10px;border-radius:8px;cursor:pointer;font-size:var(--t-body)}
.pal-i svg{color:var(--ink-3)}
.pal-i .meta{margin-left:auto;font-size:var(--t-meta);color:var(--ink-3)}
.pal-i.sel{background:var(--accent-wash);color:var(--accent)}
.pal-i.sel svg,.pal-i.sel .meta{color:var(--accent)}
.pal-none{padding:28px;text-align:center;color:var(--ink-3);font-size:var(--t-body)}

.toast{
  position:fixed;left:50%;bottom:24px;transform:translateX(-50%);z-index:200;
  /* --ink is the INVERTED surface here, so the text on it has to invert too. With color:#fff the
     toast was white-on-#f2eff6 in dark mode — a completely unreadable notification. --ground is
     --ink's opposite in both themes, so this pair stays legible either way. */
  background:var(--ink);color:var(--ground);font-size:var(--t-meta);padding:10px 17px;border-radius:9px;
  box-shadow:var(--sh-3);opacity:0;pointer-events:none;transition:opacity .2s;max-width:88vw;text-align:center;
}
.toast.on{opacity:1}

/* ============ RIGHT UTILITY STRIP ============ */
.rstrip{
  background:var(--surface);border-left:1px solid var(--line);
  display:flex;flex-direction:column;align-items:center;gap:3px;padding:9px 0;overflow:hidden;
}
.rs-btn{
  position:relative;width:32px;height:32px;display:grid;place-items:center;flex:0 0 auto;
  border:0;border-radius:var(--r-xs);background:none;color:var(--ink-2);cursor:pointer;
  transition:background .13s var(--ease),color .13s var(--ease);
}
.rs-btn:hover{background:var(--sunken);color:var(--ink)}
.rs-btn.hi{
  background:linear-gradient(150deg,#e0566c,var(--accent-2));color:#fff;border-radius:50%;
  width:30px;height:30px;box-shadow:0 2px 6px -1px rgba(184,41,70,.45);
}
.rs-btn.hi:hover{filter:brightness(1.07);background:linear-gradient(150deg,#e0566c,var(--accent-2))}
.rs-btn.hi svg{width:15px;height:15px}
.rs-dot{position:absolute;top:4px;right:4px;width:7px;height:7px;border-radius:50%;background:var(--danger);border:1.5px solid var(--surface)}
.rs-sep{width:20px;height:1px;background:var(--line);margin:6px 0;flex:0 0 auto}

/* ============ STATUS PILL (was the bottom bar) ============
   Pins/Chats/Channels/Threads/People/"What's new" were a Slack-style bottom
   bar with zero click handlers behind any of them -- found and called out
   2026-09-04. Same judgment already made for .rstrip below (see that
   comment): permanent chrome that does nothing teaches people to ignore it.
   The one real thing it held, #srcState (live/sample + environment +
   signed-in-as), moved into the topbar; .bb is its style now, not a bar. */
.bb{
  display:flex;align-items:center;gap:6px;height:28px;padding:0 9px;
  border:0;background:none;border-radius:var(--r-xs);
  color:var(--ink-2);font-size:var(--t-meta);font-weight:500;white-space:nowrap;
}
.bb svg{width:14px;height:14px;color:var(--ink-3)}

/* ============ APPS LAUNCHER ============ */
.apps-pop{
  display:none;position:fixed;z-index:120;width:296px;padding:10px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh-3);
}
.apps-pop.on{display:block}
.apps-t{font-size:var(--t-micro);font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);padding:4px 6px 8px}
.apps-g{display:grid;grid-template-columns:repeat(3,1fr);gap:4px}
.app-c{
  display:flex;flex-direction:column;align-items:center;gap:7px;padding:11px 4px;
  border:0;background:none;border-radius:var(--r-sm);cursor:pointer;
  color:var(--ink);font-size:var(--t-meta);font-weight:500;text-align:center;
  transition:background .13s var(--ease);
}
.app-c:hover{background:var(--sunken)}
.app-c i{
  width:36px;height:36px;border-radius:10px;display:grid;place-items:center;
  color:#fff;box-shadow:var(--sh-ctl);
}
.app-c i svg{width:19px;height:19px}
.app-c.cur{background:var(--accent-wash);color:var(--accent);font-weight:600}

/* ============ LIST CHROME ============ */
.th-tool{
  width:26px;height:26px;display:grid;place-items:center;border:0;border-radius:var(--r-xs);
  background:none;color:var(--ink-3);cursor:pointer;transition:background .13s var(--ease),color .13s var(--ease);
}
.th-tool:hover{background:var(--sunken);color:var(--ink)}
.th-tool.on{background:var(--accent-wash);color:var(--accent)}
thead th.tool-l,thead th.tool-r{padding:6px 8px;width:40px}
thead th.tool-r{text-align:right}
.kebab-pop{
  display:none;position:fixed;z-index:120;min-width:206px;padding:5px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);box-shadow:var(--sh-3);
}
.kebab-pop.on{display:block}
.kebab-pop button{
  display:flex;align-items:center;gap:9px;width:100%;padding:8px 9px;border:0;background:none;
  border-radius:var(--r-xs);cursor:pointer;font-size:var(--t-meta);color:var(--ink);text-align:left;
  transition:background .13s var(--ease);
}
.kebab-pop button:hover{background:var(--sunken)}
.kebab-pop button svg{color:var(--ink-3)}
.kebab-pop hr{border:0;border-top:1px solid var(--line-soft);margin:5px 0}
.kebab-pop button.dgr{color:var(--danger)}
.kebab-pop button.dgr svg{color:var(--danger)}

/* ============ CATEGORY THUMBNAILS ============ */
.cat-thumb{
  width:100%;height:88px;border-radius:var(--r-sm);margin-bottom:11px;
  display:grid;place-items:center;position:relative;overflow:hidden;
  border:1px solid rgba(27,23,32,.06);
}
.cat-thumb svg{width:34px;height:34px;color:#fff;opacity:.95;stroke-width:1.7;position:relative;z-index:1}
.cat-thumb::after{
  content:"";position:absolute;inset:0;
  background-image:radial-gradient(rgba(255,255,255,.22) 1.2px,transparent 1.2px);
  background-size:13px 13px;
}
.th-a{background:linear-gradient(140deg,#e0566c,#b8294a)}
.th-b{background:linear-gradient(140deg,#7d6a9b,#4d3f6b)}
.th-c{background:linear-gradient(140deg,#3f7fa8,#255a7d)}

/* ============ SPLIT CARDS ============ */
.split{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.mini-list{padding:6px 16px 14px}
.ml{display:flex;align-items:center;gap:11px;padding:10px 0;border-top:1px solid var(--line-soft)}
.ml:first-child{border-top:0}
.ml-r{width:26px;height:26px;border-radius:7px;background:var(--sunken);color:var(--ink-2);display:grid;place-items:center;font-size:var(--t-label);font-weight:700;flex:0 0 auto}
.ml-n{flex:1 1 auto;font-size:var(--t-meta);min-width:0}
.ml-n b{display:block;font-weight:500}
.ml-n s{display:block;text-decoration:none;font-size:var(--t-label);color:var(--ink-3);margin-top:1px}
.ml-v{font-family:'IBM Plex Sans',system-ui,sans-serif;font-size:var(--t-meta);font-weight:700;font-variant-numeric:tabular-nums}
.ml-bar{width:64px;height:5px;border-radius:3px;background:var(--sunken);overflow:hidden;flex:0 0 auto}
.ml-bar i{display:block;height:100%;background:var(--accent);border-radius:3px}
.donut-wrap{display:flex;align-items:center;gap:18px;padding:18px 16px}
.donut{width:112px;height:112px;flex:0 0 auto}
.donut-key{display:flex;flex-direction:column;gap:9px;font-size:var(--t-meta);min-width:0}
.dk{display:flex;align-items:center;gap:8px}
.dk s{width:9px;height:9px;border-radius:3px;text-decoration:none;flex:0 0 auto}
.dk b{margin-left:auto;font-family:'IBM Plex Sans',system-ui,sans-serif;font-weight:700;font-variant-numeric:tabular-nums}
.dk span{color:var(--ink-2)}

/* ============ RESPONSIVE ============ */
.burger{display:none}
@media (max-width:1100px){
  .app{grid-template-columns:var(--rail-w) 1fr;grid-template-areas:"rail shell"}
  .app.rail-collapsed{grid-template-columns:60px 1fr}
  .rstrip{display:none}
}
@media (max-width:900px){
  .app{grid-template-columns:1fr;grid-template-areas:"shell"}
  .app.rail-collapsed{grid-template-columns:1fr}
  .rail{position:fixed;left:0;top:0;z-index:60;width:250px;height:100vh;transform:translateX(-100%);transition:transform .2s var(--ease);box-shadow:var(--sh-3)}
  .rail.open{transform:none}
  .rail-scrim{display:block;position:fixed;inset:0;z-index:55;background:rgba(10,7,14,.42);
    opacity:0;pointer-events:none;transition:opacity .2s var(--ease)}
  .rail-scrim.on{opacity:1;pointer-events:auto}
  .burger{display:grid}
  .split{grid-template-columns:1fr}
  .donut-wrap{flex-direction:column;align-items:flex-start}
  .grid{grid-template-columns:1fr}
  .tiles{grid-template-columns:repeat(2,1fr)}
  .cats{grid-template-columns:1fr}
  .prog-grid{grid-template-columns:1fr}
  .omni .lbl,.omni .kbd{display:none}
  .omni{max-width:none;flex:0 0 33px;width:33px;justify-content:center;padding:0}
  .org{max-width:120px;overflow:hidden}
  .org b{overflow:hidden;text-overflow:ellipsis}
  .hello,.lv-head{padding-left:16px;padding-right:16px}
  .pad{padding:16px}
  /* 38, not 36. With the +4px hit extension below this lands on a measured 44px hit box — checked
     with elementFromPoint rather than by adding the numbers up, because the pseudo-element reaches
     about 3px past the edge, not the 4px its `inset` implies. */
  .icon-btn,.me{width:38px;height:38px}

  /* The icon-scatter behind the greeting is masked `transparent 38% -> opaque`, which on a wide
     header keeps it in the empty space to the RIGHT of the text. 38% of a phone is directly under
     the greeting and the tab row, so the decoration ran behind the words. It is decoration and
     there is no spare space for it here. */
  .hello::after{display:none}

  /* Three tabs do not fit at 375px. Scroll them sideways rather than let them wrap and collide. */
  .tabs{overflow-x:auto;flex-wrap:nowrap;scrollbar-width:none}
  .tabs::-webkit-scrollbar{display:none}
  .tab{flex:0 0 auto;white-space:nowrap;min-height:44px}

  /* 44px touch minimum. In the drawer and the rail there is room to simply grow the row. The
     topbar and bottom bar are fixed-height chrome (56px / 42px), so there the HIT AREA is pushed
     past the painted bounds instead — the control stays visually compact and still catches a
     thumb. Insets are half the surrounding gap, so neighbours meet without overlapping. */
  .nav-a,.subnav button{min-height:44px}
  .icon-btn,.me,.burger,.bb,.bb-chat{position:relative}
  /* The gap has to be at least twice the extension or neighbouring hit areas overlap and the
     wrong button answers the tap. At the desktop gap of 5px a 4px extension overlapped by 3px —
     measured, not assumed. 8px is the smallest gap that lets a 36px control reach 44px cleanly. */
  .top-right{gap:8px}
  .icon-btn::after,.me::after,.burger::after{
    content:"";position:absolute;inset:-4px;border-radius:inherit;
  }
  .bb::after,.bb-chat::after{content:"";position:absolute;left:0;right:0;top:-3px;bottom:-3px}

  /* Controls with room around them simply grow to 44px. This is deliberately a NAMED list rather
     than a blanket `button{min-height:44px}`: menu items and table-row links sit closer together
     than 44px, so growing every control would make neighbouring hit areas overlap and steal each
     other's taps — a worse bug than the one being fixed. */
  .btn,.pick,.pa-tab,.promo-pill,.rail-collapse{min-height:44px}
  /* These must stay visually small (a 33px topbar square, a 25px inline "+ Record"), so they get
     the hit-area treatment instead of growing. */
  .omni,.mini-add{position:relative}
  .omni::after{content:"";position:absolute;inset:-5px;border-radius:inherit}
  .mini-add::after{content:"";position:absolute;left:0;right:0;top:50%;height:44px;transform:translateY(-50%)}
}
@media (max-width:520px){
  .tiles{grid-template-columns:1fr}
  .hide-s{display:none}

  /* Queue rows grow instead of being extended: they are stacked with no gap, so a hit area pushed
     past the row would sit on its neighbour. Growing the row moves the neighbour out of the way. */
  .pa-row{min-height:44px}

  .dr-x{position:relative;width:36px;height:36px}
  .dr-x::after{content:"";position:absolute;inset:-5px;border-radius:inherit}
  .omni{flex-basis:38px;width:38px;height:38px}
}
