/**
 * ActionStudio — Full UI stylesheet
 * Three display modes: light, dusk, dark.
 * Overrides WP admin chrome when actionstudio-app body class is present.
 */

/* ═══ WP ADMIN CHROME OVERRIDE ═══ */
body.actionstudio-app #wpadminbar,
body.actionstudio-app #adminmenumain,
body.actionstudio-app #adminmenuback,
body.actionstudio-app #adminmenuwrap,
body.actionstudio-app #wpfooter,
body.actionstudio-app .notice,
body.actionstudio-app .update-nag,
body.actionstudio-app .updated,
body.actionstudio-app .error:not(.as-error) { display: none !important; }
body.actionstudio-app #wpcontent { margin-left: 0 !important; padding-left: 0 !important; }
body.actionstudio-app #wpbody-content { padding-bottom: 0 !important; }
body.actionstudio-app .wrap { margin: 0 !important; padding: 0 !important; }
html.wp-toolbar { padding-top: 0 !important; }
body.actionstudio-app { margin-top: 0 !important; }
/* AS-0180: WP core's own @media(max-width:600px) responsive-admin CSS
 * (wp-admin/css/common.css, not part of this plugin) sets
 * `#wpbody { padding-top: 46px }` — space it reserves for its mobile
 * admin-bar toolbar. We hide #wpadminbar above but never neutralized this
 * WP-core #wpbody padding, so on any real phone width (<=600px) a 46px
 * gray (#f0f0f1) band from #wpbody's own background showed above the
 * ActionStudio app header — confirmed live via getComputedStyle + reading
 * the matched CSS rule's cssText at a real 390px iframe viewport. */
body.actionstudio-app #wpbody { padding-top: 0 !important; }
/* v0.1.79: WP 7.0 defensive overrides */
body.actionstudio-app .wp-header-end { display: none !important; }
body.actionstudio-app #screen-meta, body.actionstudio-app #screen-meta-links { display: none !important; }
body.actionstudio-app #wp-admin-bar-root-default { display: none !important; }
body.actionstudio-app .is-fullscreen-mode { /* WP 7.0 fullscreen editor class — no conflict */ }
body.actionstudio-app [class*="dataviews"] { display: none !important; }
body.actionstudio-app .wp-admin-bar-appearance { display: none !important; }
body.actionstudio-app #adminmenu { display: none !important; }

/* ═══ HIDE SCROLLBARS (keep scroll) ═══ */
#as-app *::-webkit-scrollbar { display: none; }
#as-app * { -ms-overflow-style: none; scrollbar-width: none; }

/* ═══ LIGHT MODE (default) ═══ */
/* v0.3.5: Mirror AS palette to :root so modal/overlay elements appended to
 * document.body (e.g. .as-g-modal-backdrop, palette popover) inherit the
 * tokens. Pre-v0.3.5 these overlays were outside #as-app's scope, so
 * var(--s) and var(--b) resolved to nothing, making modals see-through.
 * When #as-app.as-dark is active we re-emit the dark values onto :root
 * so body-scoped overlays switch palette with the app. */
:root {
    --bg:#f8f6f1;--s:#fff;--sa:#f0ece4;--b:#e7e3da;--b2:#eeeae2;
    --t1:#1a1d23;--t2:#4b5563;--t3:#8a909a;
    --ac:#D4740E;--acl:#fbeee2;--ach:#B8630B;
    --bl:#3949ab;--bll:#eaecf7;
    --gn:#2e9e5b;--gnl:#e6f4ec;
    --rd:#c0392b;--rdl:#fbe9e9;
    --am:#b8860b;--aml:#fbf3df;
    --pu:#7c5cbf;--pul:#f0ecf8;
    /* AS-0127 (v0.10.238): --zebra was #eceff1 and --row-hover #dfe3e6 — both
     * COOL blue-grays (R-B of -5 and -7) sitting in an otherwise entirely WARM
     * light palette (--s #fff, --bg #f8f6f1 +7, --sa #f0ece4 +12, --b #e7e3da
     * +13). The un-striped inbox row had no background of its own, so it
     * painted --bg; the pair therefore straddled neutral, and adjacent bands
     * on opposite sides of neutral produce simultaneous contrast — the warm
     * band reads pink, the cool band reads gray. Now warm-family, and the row
     * base is pinned to --s in as-email.css so the pair is actually defined.
     * See tests/as-0127-inbox-zebra-smoke.js for the measured proof; do not
     * recolor either of these without re-running it green. */
    --head:#faf6ee;--zebra:#f9f6ef;--row-hover:#ece7de;
    --card-sh:0 1px 2px rgba(20,24,31,.05),0 2px 5px rgba(20,24,31,.06);
    --card-sh-h:0 3px 8px rgba(20,24,31,.10),0 6px 18px rgba(20,24,31,.09);
    --sb:#1A1A1A;--sb2:#2A2A2A;--sb3:#555;--sbt:#A0998F;--sbh:#DDD;
    --inp-bg:#FFF;--r:0;--rs:0;
    --err:#c0392b;--ok:#2e9e5b;
    --serif:Georgia,'Times New Roman',serif;
}
:root:has(#as-app.as-dark) {
    --bg:#16181d;--s:#1f2228;--sa:#262a31;--b:#2c3038;--b2:#31353d;
    --t1:#e8eaed;--t2:#a7adb7;--t3:#727884;
    --ac:#E8943A;--acl:#3a2a14;--ach:#F0A84E;
    --bl:#8f9ee6;--bll:#20242e;
    --gn:#5cbd82;--gnl:#173026;
    --rd:#e0655a;--rdl:#33191a;
    --am:#d8b24a;--aml:#312812;
    --pu:#b39ae0;--pul:#241f30;
    --head:#232830;--zebra:#262b33;--row-hover:#2f3540;
    --card-sh:0 1px 2px rgba(0,0,0,.3),0 2px 6px rgba(0,0,0,.24);
    --card-sh-h:0 4px 12px rgba(0,0,0,.42),0 8px 22px rgba(0,0,0,.36);
    --sb:#0D0C0B;--sb2:#181716;--sb3:#444;--sbt:#706A63;--sbh:#BBB;
    --inp-bg:#222120;
    --err:#e0655a;--ok:#5cbd82;
}
#as-app {
    --bg:#f8f6f1;--s:#fff;--sa:#f0ece4;--b:#e7e3da;--b2:#eeeae2;
    --t1:#1a1d23;--t2:#4b5563;--t3:#8a909a;
    --ac:#D4740E;--acl:#fbeee2;--ach:#B8630B;
    --bl:#3949ab;--bll:#eaecf7;
    --gn:#2e9e5b;--gnl:#e6f4ec;
    --rd:#c0392b;--rdl:#fbe9e9;
    --am:#b8860b;--aml:#fbf3df;
    --pu:#7c5cbf;--pul:#f0ecf8;
    /* AS-0127 (v0.10.238): --zebra was #eceff1 and --row-hover #dfe3e6 — both
     * COOL blue-grays (R-B of -5 and -7) sitting in an otherwise entirely WARM
     * light palette (--s #fff, --bg #f8f6f1 +7, --sa #f0ece4 +12, --b #e7e3da
     * +13). The un-striped inbox row had no background of its own, so it
     * painted --bg; the pair therefore straddled neutral, and adjacent bands
     * on opposite sides of neutral produce simultaneous contrast — the warm
     * band reads pink, the cool band reads gray. Now warm-family, and the row
     * base is pinned to --s in as-email.css so the pair is actually defined.
     * See tests/as-0127-inbox-zebra-smoke.js for the measured proof; do not
     * recolor either of these without re-running it green. */
    --head:#faf6ee;--zebra:#f9f6ef;--row-hover:#ece7de;
    --card-sh:0 1px 2px rgba(20,24,31,.05),0 2px 5px rgba(20,24,31,.06);
    --card-sh-h:0 3px 8px rgba(20,24,31,.10),0 6px 18px rgba(20,24,31,.09);
    --sb:#1A1A1A;--sb2:#2A2A2A;--sb3:#555;--sbt:#A0998F;--sbh:#DDD;
    --inp-bg:#FFF;--r:0;--rs:0;
    --serif:Georgia,'Times New Roman',serif;
}
/* Dusk removed in v0.1.48 — light/dark only */
#as-app.as-dark {
    --bg:#16181d;--s:#1f2228;--sa:#262a31;--b:#2c3038;--b2:#31353d;
    --t1:#e8eaed;--t2:#a7adb7;--t3:#727884;
    --ac:#E8943A;--acl:#3a2a14;--ach:#F0A84E;
    --bl:#8f9ee6;--bll:#20242e;
    --gn:#5cbd82;--gnl:#173026;
    --rd:#e0655a;--rdl:#33191a;
    --am:#d8b24a;--aml:#312812;
    --pu:#b39ae0;--pul:#241f30;
    --head:#232830;--zebra:#262b33;--row-hover:#2f3540;
    --card-sh:0 1px 2px rgba(0,0,0,.3),0 2px 6px rgba(0,0,0,.24);
    --card-sh-h:0 4px 12px rgba(0,0,0,.42),0 8px 22px rgba(0,0,0,.36);
    --sb:#0D0C0B;--sb2:#181716;--sb3:#444;--sbt:#706A63;--sbh:#BBB;
    --inp-bg:#222120;
}

/* ═══ RESET ═══ */
/* v0.10.179: `*:not(.btn)` — see the v0.10.179 note at the BUTTONS block
 * below for why .btn is excluded from this reset outright, rather than
 * re-fighting it with more selector specificity on the button rules (as
 * v0.10.178 did). Only elements literally carrying the .btn class are
 * skipped; anything nested INSIDE a .btn (e.g. an icon span) still matches
 * `#as-app *:not(.btn)` and still gets reset normally. */
#as-app, #as-app *:not(.btn) { margin:0; padding:0; box-sizing:border-box; }
#as-app {
    font-family:'Source Sans 3','Source Sans Pro',system-ui,-apple-system,sans-serif;
    background:var(--bg); color:var(--t1); display:flex; min-height:100vh;
    font-size:13px; transition:background .3s,color .3s; position:relative;
    overflow-x:hidden; max-width:100vw;
}

/* ═══ SIDEBAR ═══ */
#as-app .side { width:210px; background:var(--sb); position:fixed; top:0; left:0; bottom:0; display:flex; flex-direction:column; z-index:100; transition:background .3s, width .2s ease; }
#as-app .brand { padding:20px 16px; border-bottom:1px solid var(--sb2); }
#as-app .brand h1 { font-family:'Fraunces',Georgia,serif; font-size:17px; color:#FFF; font-weight:700; }
#as-app .brand small { font-size:9px; color:var(--sb3); text-transform:uppercase; letter-spacing:1.5px; display:block; margin-top:2px; }
#as-app .snav { flex:1; padding:10px 8px; overflow-y:auto; }
#as-app .slbl { display:flex; align-items:center; gap:8px; font-size:9px; text-transform:uppercase; letter-spacing:1.5px; padding:12px 10px 4px; margin-top:4px; font-weight:700; border-top:1px solid var(--sb2); }
/* Phase 6: group dot, ported from the prototype's GROUPS[].dc — squared (no
   border-radius), matching the prototype's "squared, NO radius" design note. */
#as-app .slbl i { width:7px; height:7px; flex:0 0 auto; display:block; background:var(--slc,var(--sb3)); }
/* v0.10.54: label text now takes the same per-group accent (--slc, set inline
   per .slbl alongside the dot) instead of a flat gray, plus the border-top
   above as a section divider — both per Glenn's live feedback session. */
#as-app .slbl span { color:var(--slc,var(--sb3)); }
#as-app .si { display:flex; align-items:center; gap:8px; padding:8px 10px; border-radius:var(--rs); color:var(--sbt); cursor:pointer; font-size:13px; font-weight:500; transition:all .12s; }
/* Phase 6: colored hover, ported from the prototype's per-row --onc custom
   property (GROUPS[].c / SURF[].c: --ac/--bl/--gn by section) — a deliberate
   extension beyond the prototype's own flat .si:hover{background:var(--side2)}
   (which doesn't vary by section), per Glenn's explicit "the hover state as
   well" requirement this session. Falls back to --ac for any .si with no
   --onc set (matches the prototype's own Dashboard/Engage default). */
#as-app .si:hover { background:color-mix(in srgb, var(--onc, var(--ac)) 18%, transparent); color:var(--sbh); }
#as-app .si.on { background:var(--onc, var(--ac)); color:#FFF; }
#as-app .si .ct { margin-left:auto; background:var(--sb2); color:var(--sbt); font-size:10px; padding:1px 6px; border-radius:8px; font-weight:600; }
#as-app .si.on .ct { background:rgba(255,255,255,.25); color:#FFF; }
#as-app .sfoot { padding:14px 16px; border-top:1px solid var(--sb2); display:flex; align-items:center; gap:8px; }
#as-app .av { width:28px; height:28px; border-radius:50%; background:var(--ac); display:flex; align-items:center; justify-content:center; color:#FFF; font-weight:700; font-size:11px; }
#as-app .sfoot .nm { color:var(--sbh); font-size:12px; font-weight:600; }
#as-app .sfoot .rl { color:var(--sb3); font-size:10px; }

/* ═══ BACK TO ADMIN + ESCAPE LINKS ═══ */
#as-app .as-back-admin { display:flex; align-items:center; gap:6px; margin:0 8px; padding:6px 10px; color:var(--sb3); opacity:.5; transition:opacity .15s, color .15s; text-decoration:none; font-size:11px; border-radius:var(--rs); }
#as-app .as-back-admin:hover { opacity:1; color:var(--sbh); background:var(--sb2); }
#as-app .as-escape-links { border-top:1px solid var(--sb2); padding:6px 8px; display:flex; flex-direction:column; gap:2px; }
#as-app .as-escape-link { display:flex; align-items:center; gap:4px; padding:5px 10px; font-size:10px; font-weight:600; color:var(--sb3); text-decoration:none; text-transform:uppercase; letter-spacing:.6px; opacity:.45; transition:opacity .15s, color .15s; border-radius:var(--rs); }
#as-app .as-escape-link:hover { opacity:.85; color:var(--sbh); background:var(--sb2); }

/* ═══ SIDEBAR COLLAPSE ═══ */
/* INTAKE-095: ActionStudio product icon doubles as the collapse control
   (replaces the standalone chevron). The mark is always visible; clicking it
   toggles the sidebar. Expanded = icon + text; collapsed = icon only. */
#as-app .brand { position:relative; display:flex; align-items:center; gap:10px; }
#as-app .as-brand-mark { flex:0 0 auto; background:none; border:none; padding:0; cursor:pointer; color:var(--sbh); display:flex; align-items:center; justify-content:center; width:28px; height:28px; transition:opacity .15s, transform .15s; }
#as-app .as-brand-mark svg { width:28px; height:28px; }
#as-app .as-brand-mark:hover { opacity:.8; }
#as-app .as-brand-text { min-width:0; }
#as-app.as-collapsed .side { width:48px; }
#as-app.as-collapsed .as-main { margin-left:48px; max-width:calc(100vw - 48px); }
#as-app.as-collapsed .brand h1,
#as-app.as-collapsed .brand small,
#as-app.as-collapsed .as-brand-text,
#as-app.as-collapsed .as-side-label,
#as-app.as-collapsed .slbl,
#as-app.as-collapsed .si .ct { display:none; }
#as-app.as-collapsed .brand { padding:14px 8px; justify-content:center; }
#as-app.as-collapsed .snav { padding:6px 4px; }
#as-app.as-collapsed .si { justify-content:center; padding:8px; font-size:0; overflow:hidden; }
#as-app.as-collapsed .si .as-icon { margin:0; font-size:13px; }
#as-app.as-collapsed .sfoot { padding:10px 4px; justify-content:center; }
#as-app.as-collapsed .sfoot .as-side-label { display:none; }
#as-app.as-collapsed .as-escape-links { padding:4px; gap:2px; }
#as-app.as-collapsed .as-escape-link { width:26px; height:26px; }
#as-app.as-collapsed .as-brand-mark { margin:0 auto; }

/* Phase 6 (Sidebar cosmetics): removed the v0.10.9 "collapsed-default rail,
   hover-peek, pin" block that used to live here (#as-app.as-collapsed
   .side:hover { width:210px; ... } + its child display:revert rules). Root
   cause of Glenn's "the collapse is broken, it doesn't collapse" report
   (2026-08-15): the collapse toggle button lives INSIDE .side, so clicking it
   to collapse leaves the mouse hovering over .side — the hover rule
   immediately re-expanded it back to 210px while .as-main's margin stayed at
   the collapsed 48px (by design, "nothing reflows"), producing a visibly
   full-width sidebar over a shifted, gapped content pane. That's the old
   "pin" concept's hover-peek mechanic, already supposed to have been retired
   in v0.10.14 (which removed the pin GLYPH/rotate animation but left this
   CSS behind) — removing it here finishes that and matches the current
   mandate: plain click-to-open/close, no pin, no hover magic. */

#as-app .si .lb { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* v0.10.14: plain open/close toggle — no "pinned" visual language (Glenn
   removed the pin concept entirely; the icon is now the same glyph as the
   Dashboard nav row, not a pin, so a rotate-on-pin effect no longer applies). */
#as-app .as-brand-mark svg { transition:color .15s; }
#as-app:not(.as-collapsed) .as-brand-mark { color:var(--ac); }

/* ═══ MOBILE BOTTOM TAB BAR (AS-0028) ═══
   Fixed-position primary-nav tab bar shown only at @media(max-width:768px)
   (see the 768px block below) — hidden by default so it never appears at
   desktop widths, where the sidebar itself is the primary nav. It
   SUPPLEMENTS the existing .as-hamburger/.side slide-in overlay rather than
   replacing it: the sidebar and asToggleSidebar() are untouched, and the
   overlay is still reachable both from the (still-present) hamburger and
   from this bar's own "More" tab, so no markup/JS the hamburger already
   depended on had to move. Holds the 5 most-used destinations per the
   existing nav's own top-to-bottom order/grouping (Dashboard, Communications
   as "Comms" (AS-0189), Priorities as "Tasks", Opportunities as "Pipeline", Projects)
   plus a 6th "More" tab that opens the same .side overlay for the remaining
   8 (Engage, People, Processes, Performance, Reports, Display, plus the
   already-hidden Drive). asBottomNav() (actionstudio.js) delegates to the
   existing asNav() router so badges/gating/loaders are unchanged — it just
   also keeps this bar's own .on state and the sidebar's .si.on state in
   sync in both directions. */
#as-app .as-tabbar { display:none; }
/* AS-0221: hidden at desktop widths same as .as-tabbar above — only ever
   opened via .as-tabbar-more, itself only reachable inside the
   @media(max-width:768px) tab bar. Without this, the sheet/scrim markup
   (siblings of #as-app's main content, admin-app.php) would render as plain
   flow content at the bottom of the desktop page instead of staying inert. */
#as-app .as-more-scrim, #as-app .as-more-sheet { display:none; }

/* ═══ TOOLBAR DOCTRINE v0.10.9 — uniform 30px controls ═══
   Scoped utility: add class="as-toolbar" onto a view's existing toolbar row
   (its own flex/justify-content/margin inline style is left alone) to pull
   every .btn / select / search-ish input inside it down to the prototype's
   30px control height, without hand-editing each control. Doesn't touch
   .tab/.lens height — those already read fine at their current size and
   aren't part of this pass's confirmed gaps. */
#as-app .as-toolbar .btn,
#as-app .as-toolbar select,
#as-app .as-toolbar input[type="search"],
#as-app .as-toolbar input[type="text"],
#as-app .as-toolbar input[type="month"] { height:30px; min-height:0; box-sizing:border-box; }

/* v0.10.12: page-specific control classes that aren't .btn/select/input —
 * each needs its own override the same way .as-comm-filters did (see the
 * v0.10.11 fix note above the Commissions rule). Scoped to .as-toolbar so
 * these classes stay their original size anywhere else they're reused. */
#as-app .as-toolbar .as-toolbar-btn,
#as-app .as-toolbar .as-drive-vbtn { width:30px; height:30px; min-height:0; box-sizing:border-box; }
#as-app .as-toolbar .as-compose-btn { height:30px; min-height:0; box-sizing:border-box; }

/* ═══ DARK MODE TOGGLE ═══ */
#as-app .as-mode-toggle { background:none; border:1px solid var(--b); border-radius:var(--rs); padding:6px; cursor:pointer; color:var(--t3); display:flex; align-items:center; justify-content:center; transition:color .15s, border-color .15s; width:34px; height:34px; box-sizing:border-box; }
#as-app .as-mode-toggle:hover { color:var(--t1); border-color:var(--t3); }

/* ═══ MAIN ═══ */
#as-app .as-main { margin-left:210px; flex:1; min-height:100vh; min-width:0; max-width:calc(100vw - 210px); overflow-x:hidden; transition:background .3s, margin-left .2s ease, max-width .2s ease; }
#as-app .top { padding:11px 22px; display:flex; align-items:center; justify-content:space-between; gap:16px; border-bottom:1px solid var(--b); background:var(--s); position:sticky; top:0; z-index:50; transition:background .3s,border-color .3s; }
/* v0.10.255: pairs with the viewport-fit=cover meta tag (class-as-router.php
 * output_pwa_head()) — on an iPhone home-screen install (manifest
 * display:standalone), this pushes the sticky header down below the
 * status-bar/notch instead of leaving that area a bare white gap above it.
 * env() resolves to 0 without viewport-fit=cover, so this is a no-op on
 * desktop/non-notch/regular-tab contexts. Same pairing as the tabbar's
 * existing safe-area-inset-bottom padding, just for the opposite edge. */
#as-app .top { padding-top:calc(11px + env(safe-area-inset-top)); }
#as-app .top h2 { font-family:'Fraunces',Georgia,serif; font-size:20px; font-weight:700; color:var(--t1); }
#as-app .top p { font-size:11.5px; color:var(--t3); margin-top:1px; }
#as-app .btns { display:flex; gap:6px; align-items:center; }
#as-app .cnt { padding:20px 28px; }

/* ═══ BUTTONS ═══ */
/* v0.10.172 (AS-0010): de-scoped from #as-app to a bare selector so the base
 * button rule is mount-point-agnostic. .as-g-modal-backdrop (the Google-
 * connect wizard, as-google-wizard.js openModal()) mounts on document.body,
 * outside #as-app, so it never matched these #as-app-scoped rules — it
 * previously fell back to a hand-duplicated copy in as-funnels.css
 * (.as-g-wiz-foot .btn*) that had already drifted out of sync (missing the
 * .btn.sm/.btn-plus variants below) and had no mechanism to stay in sync.
 * Safe to de-scope: actionstudio.css (handle 'actionstudio-app') is
 * unconditionally enqueued first, ahead of every other AS stylesheet, on
 * every load of the AS admin page (see class-as-router.php
 * enqueue_app_assets) — so these bare rules are always present wherever
 * #as-app or a body-mounted AS overlay can exist. :root already mirrors the
 * --ac/--t1/--rs/etc. tokens for exactly this class of overlay (see the
 * v0.3.5 comment above). Every other .btn override in the codebase uses a
 * higher-specificity compound selector (e.g. `.as-pd-panel .btn`, `#as-app
 * .as-toolbar .btn`), so lowering this base rule's own specificity doesn't
 * change which rule wins anywhere else.
 *
 * v0.10.178 fix (SUPERSEDED by v0.10.179 below — kept for history): that
 * "doesn't change which rule wins" claim missed the
 * `#as-app, #as-app * { margin:0; padding:0; ... }` reset near the top of
 * this file (~:109). That reset's `#as-app *` selector carries an ID
 * (specificity 1-0-0), which beats the bare `.btn`/`.btn.sm` selectors
 * (0-1-0 / 0-2-0) below now that they lost their own `#as-app` prefix —
 * so every plain-text .btn INSIDE #as-app silently rendered with zero
 * padding (reported: the What's New modal's "Got it" button squished
 * flush against its own edges). v0.10.178 re-added `#as-app .btn` /
 * `#as-app .btn.sm` as an extra selector on just the two padding-bearing
 * rules to restore enough specificity to beat the reset inside #as-app.
 *
 * v0.10.179 fix: v0.10.178's own fix was itself a third-order regression.
 * `.btn, #as-app .btn { ... }` is ONE rule with TWO selectors — every
 * property it declares (not just padding) now carries the elevated
 * `#as-app .btn` specificity (1 ID + 1 class = 1-1-0), including font-size
 * and color, which this rule also sets. That's higher than any bare
 * single-class modifier declared after it — `.btn-plus` (font-size:0,
 * padding:0), `.btn-p` (color:#FFF), `.btn-g` (color:var(--t2)) — all
 * 0-1-0. Per normal CSS, specificity beats source order, so those
 * modifiers silently lost on font-size/color no matter where they sit in
 * the file: icon-only +Compose/+Add-contact buttons rendered their full
 * text label instead of collapsing to the "+" glyph, and the What's New
 * modal's "Got it" button (.btn.btn-p) rendered var(--t1) dark text
 * instead of #FFF.
 *
 * Root fix: stop fighting this with more specificity stacking (that's
 * what caused both prior regressions) and remove the actual conflict
 * instead — .btn is now excluded from the `#as-app *` reset itself (see
 * the RESET block, ~:109: `#as-app *:not(.btn)`), so the base button rule
 * never needs an `#as-app`-scoped escape hatch at all. With the reset out
 * of the way, .btn/.btn.sm go back to bare single/double-class selectors,
 * and .btn-plus/.btn-p/.btn-g naturally win on the properties they
 * override via normal same-specificity source-order tie-breaking —
 * restoring the original pre-v0.10.172 cascade behavior while keeping
 * v0.10.172's benefit (bare `.btn` still matches the body-mounted
 * Google-wizard buttons, which sit outside #as-app and were never touched
 * by the #as-app-scoped reset to begin with). */
.btn { padding:7px 14px; border-radius:var(--rs); font-size:12px; font-weight:600; border:none; cursor:pointer; display:inline-flex; align-items:center; gap:5px; transition:all .12s; font-family:inherit; color:var(--t1); height:34px; box-sizing:border-box; }
.btn-p { background:var(--ac); color:#FFF; }
.btn-p:hover { background:var(--ach); }
.btn-g { background:transparent; color:var(--t2); border:1px solid var(--b); }
.btn-g:hover { background:var(--sa); }
.btn:disabled { opacity:.4; cursor:not-allowed; }
.btn.sm { height:28px; padding:0 10px; font-size:11px; }
/* v0.10.39: icon-only primary "create" button — every module's +New/+Add
 * button collapses to just this glyph, leftmost in its toolbar. Text stays
 * in the DOM (font-size:0, not display:none) so screen readers still get
 * the label; sighted users get it via title= instead. */
.btn-plus { width:34px; padding:0; justify-content:center; font-size:0; flex:0 0 auto; gap:0; }
.btn-plus::before { content:'+'; font-size:20px; font-weight:400; line-height:1; }

/* ═══ SUB-HEADER TOOLBAR — v0.10.14: shared component ported 1:1 from the
 * as-integrated prototype's shared.css. This is the canonical sub-header shell
 * every surface should use going forward (Dashboard and Display are the two
 * documented exceptions — see HANDOFF-NEXT-SESSION-sidebar-redo.md). Additive
 * only: nothing existing references these classes yet, so this cannot regress
 * any page already shipped. Surfaces adopt it one at a time as their own phase
 * lands, replacing the old hand-inlined `.as-toolbar style="display:flex;..."`
 * pattern. ═══ */
/* v0.10.15: .toolbar lives inside .cnt, which already carries its own 20px/28px
 * padding (unlike the prototype's zero-padding page shell) — cancel that out
 * with a negative margin so the toolbar still bleeds edge-to-edge under the
 * header, matching the prototype exactly, without touching .cnt's padding
 * globally (used by every view, most not yet on this component). */
#as-app .toolbar { display:flex; align-items:center; gap:12px; flex-wrap:wrap; padding:11px 22px; background:var(--s); border-bottom:1px solid var(--b); margin:-20px -28px 20px; }
#as-app .toolbar + .toolbar { margin-top:-20px; }
#as-app .toolbar .grow { flex:1; }
#as-app .toolbar .spacer { flex:1; }
/* v0.10.255: Tasks toolbar's search/filter/view-swap icon buttons, wrapped in
 * one row so mobile's flex-direction:column (below) stacks this as ONE group
 * instead of three separate full-width rows — matches how they sat side by
 * side as plain .toolbar children before the wrap. */
#as-app .as-task-icon-row { display:flex; align-items:center; gap:12px; }

/* segmented lens/tab group — the prototype's People/Companies, Opportunities-lens style */
#as-app .lenses { display:flex; border:1px solid var(--b); background:var(--bg); }
#as-app .lens { height:30px; padding:0 15px; font-size:12px; font-weight:600; color:var(--t3); display:flex; align-items:center; gap:7px; background:none; border:none; cursor:pointer; font-family:inherit; }
#as-app .lens+.lens { border-left:1px solid var(--b); }
#as-app .lens .dot { width:6px; height:6px; border-radius:50%; background:var(--ac); }
/* AS-0239: base (all widths) row for the Queue group + All / This week
 * group. AS-0229 added this wrapper but only styled it inside the 768px
 * media query, so on desktop it was a block div and the two groups stacked.
 * The later mobile rules (768px block, display:contents block) still win on
 * phones by source order. */
#as-app .as-task-scope-row { display:flex; align-items:center; gap:0; flex:0 0 auto; }
@media (min-width:769px) {
    #as-app .as-task-scope-row > .lenses + .lenses { border-left:0; }
}
#as-app .lens:hover { color:var(--t1); }
#as-app .lens.on { background:var(--t1); color:#fff; }
#as-app.as-dark .lens.on { background:var(--ac); color:#16181d; }
#as-app .lens.on .dot { background:#fff; }
#as-app .lens .n { font-size:10px; font-weight:700; opacity:.6; }

/* icon-button Cards/List segmented toggle */
#as-app .viewseg { display:inline-flex; border:1px solid var(--b); background:var(--s); }
#as-app .viewseg button { width:32px; height:30px; display:flex; align-items:center; justify-content:center; color:var(--t3); border:none; background:none; cursor:pointer; }
#as-app .viewseg button+button { border-left:1px solid var(--b); }
#as-app .viewseg button.on { background:var(--ac); color:#fff; }
#as-app .viewseg svg { width:15px; height:15px; }

#as-app .osearch { display:flex; align-items:center; gap:7px; height:30px; padding:0 10px; border:1px solid var(--b); background:var(--bg); color:var(--t3); min-width:170px; }
#as-app .osearch input { border:none; background:none; outline:none; color:var(--t1); font-size:12px; width:100%; font-family:inherit; }
#as-app .osearch svg { width:14px; height:14px; flex:0 0 auto; }
#as-app .iconbtn { width:32px; height:32px; display:flex; align-items:center; justify-content:center; border:1px solid var(--b); background:var(--s); color:var(--t2); cursor:pointer; }
#as-app .iconbtn:hover { background:var(--sa); color:var(--t1); }
#as-app .iconbtn svg { width:16px; height:16px; }
#as-app .seg { display:inline-flex; border:1px solid var(--b); background:var(--s); height:34px; box-sizing:border-box; }
/* v0.10.54: height:34px + flex-centering added to match .btn's fixed 34px
   header-bar height — previously unset here, so .seg rendered shorter than
   an adjacent .btn/.btn-plus in the same toolbar row (Glenn, live feedback). */
/* v0.10.58: gap between the icon and label — matches .si's icon/label gap.
   Previously relied on the single literal space character between </svg> and
   the label text in the markup, which read as too tight (Glenn, live
   feedback on the Email/Calendar toggle). */
#as-app .seg button { height:100%; box-sizing:border-box; display:inline-flex; align-items:center; gap:8px; padding:0 12px; font-size:12px; font-weight:600; color:var(--t2); border-right:1px solid var(--b); border-left:none; border-top:none; border-bottom:none; background:none; cursor:pointer; font-family:inherit; }
#as-app .seg button:last-child { border-right:none; }
#as-app .seg button.on { background:var(--ac); color:#fff; }
#as-app .search { flex:1; min-width:120px; max-width:280px; height:30px; padding:0 11px; font-size:12px; border:1px solid var(--b); background:var(--s); color:var(--t1); font-family:inherit; }

/* v0.10.17: labeled-select toolbar control (prototype's Health filter on
 * Projects) — ported 1:1 from shared.css alongside the rest of the sub-header
 * component set. */
#as-app .selctl { display:flex; align-items:center; gap:6px; font-size:12px; color:var(--t2); }
#as-app .selctl label { color:var(--t3); font-size:11px; }
#as-app .sel { height:30px; border:1px solid var(--b); background:var(--bg); color:var(--t1); font-size:12px; padding:0 8px; font-family:inherit; }
/* toolbar-doctrine-v2 (2026-08-16): funnel/campaign picker moved into the
 * shared Opportunities toolbar (was inside its own .as-funnels-pickbar row,
 * which had generic ".as-toolbar select{height:30px}" sizing) — its
 * generated <select> (as-funnels.js's renderFunnelPicker()) keeps its own
 * class name, so give it the same toolbar-appropriate sizing as .sel
 * directly rather than editing the string-returning function. */
#as-app .toolbar .as-funnels-pick-sel { height:30px; border:1px solid var(--b); background:var(--bg); color:var(--t1); font-size:12px; padding:0 8px; font-family:inherit; max-width:260px; }

/* v0.10.16: expanding search — icon button by default; opens into an inline
 * input on click, collapses again on blur if left empty. Sits at the far
 * right of a toolbar (after .grow), per Glenn's explicit direction — a
 * deliberate departure from the prototype's own always-open .osearch. */
#as-app .osearch-toggle { display:flex; align-items:center; }
#as-app .osearch-expand-input { width:0; height:30px; padding:0; margin:0; border:1px solid transparent; background:var(--bg); color:var(--t1); font-size:12px; font-family:inherit; opacity:0; overflow:hidden; transition:width .16s ease, opacity .12s, padding .16s, margin .16s, border-color .12s; }
#as-app .osearch-toggle.open .osearch-expand-input { width:200px; opacity:1; padding:0 10px; margin-right:6px; border-color:var(--b); }
/* AS-0188 desktop (2026-09-18): the shared cross-surface search icon
 * (#as-comms-search-wrap, AS-0069 — visible in every Communications mode's
 * toolbar row, Split/Email/Calendar alike) is a plain .iconbtn (32px) same
 * as every other .iconbtn in the app. Grown 2px to 34px here specifically —
 * NOT a base .iconbtn change, that stays 32px everywhere else — so it
 * matches Compose/mode-seg/sync/nav-arrows/Today in this one toolbar row. */
#as-app #as-comms-search-btn { width:34px; height:34px; }

#as-app .pill { display:inline-flex; align-items:center; gap:6px; font-size:10.5px; font-weight:700; padding:2px 8px; background:var(--sa); border:1px solid var(--b); color:var(--t2); }
#as-app .pill .dot { width:7px; height:7px; border-radius:50%; }
#as-app .flag { font-size:9.5px; font-weight:700; padding:1px 6px; text-transform:uppercase; display:inline-block; }
#as-app .flag.warn { background:var(--rdl); color:var(--rd); }
#as-app .flag.ok { background:var(--gnl); color:var(--gn); }
#as-app .flag.mut { background:var(--sa); color:var(--t3); }
#as-app .flag.info { background:var(--bll); color:var(--bl); }
#as-app .flag.amber { background:var(--aml); color:var(--am); }
#as-app .chipf { display:inline-flex; align-items:center; gap:6px; padding:5px 11px; font-size:11.5px; font-weight:600; color:var(--t2); background:var(--s); border:1px solid var(--b); cursor:pointer; }
#as-app .chipf.on { background:var(--acl); border-color:var(--ac); color:var(--ach); }
#as-app .chipf .ct { background:var(--sa); color:var(--t3); font-size:10px; font-weight:700; padding:0 5px; }
#as-app .chipf.on .ct { background:var(--ac); color:#fff; }

/* ═══ KPI TILES ═══ */
#as-app .kpirow { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:13px; }
#as-app .kpi { background:var(--s); border:1px solid var(--b); border-top:2px solid var(--ac); box-shadow:var(--card-sh); padding:13px 15px; }
#as-app .kpi .n { font-family:'Fraunces',Georgia,serif; font-size:26px; font-weight:700; line-height:1; }
#as-app .kpi .l { font-size:10.5px; color:var(--t3); margin-top:5px; text-transform:uppercase; letter-spacing:.4px; }
#as-app .kpi .d { font-size:11px; font-weight:700; margin-top:4px; }
#as-app .kpi .up { color:var(--gn); }
#as-app .kpi .dn { color:var(--rd); }

/* ═══ PERSON/COMPANY CARD GRID — v0.10.15: ported 1:1 from the as-integrated
 * prototype's surfaces/people.html for pixel-perfect People re-polish. Used
 * by contactCard/companyCard (as-v-crm.js / as-companies.js). */
#as-app .pcards { display:grid; grid-template-columns:repeat(auto-fill,minmax(238px,1fr)); gap:13px; }
#as-app .pcard { background:var(--s); border:1px solid var(--b); box-shadow:var(--card-sh); padding:14px 15px; cursor:pointer; transition:box-shadow .14s; }
#as-app .pcard:hover { box-shadow:var(--card-sh-h); }
#as-app .pcard .ph { display:flex; align-items:center; gap:11px; }
#as-app .pcard .ph .av { width:38px; height:38px; border-radius:50%; flex:0 0 auto; display:flex; align-items:center; justify-content:center; color:#fff; font-weight:700; font-size:13px; }
#as-app .pcard h4 { font-size:14px; font-weight:700; line-height:1.2; }
#as-app .pcard .rl { font-size:11.5px; color:var(--t3); margin-top:1px; }
#as-app .pcard .pm { display:flex; align-items:center; justify-content:space-between; margin-top:13px; }
#as-app .pcard .pm b { font-weight:700; font-size:13px; }
#as-app .pcard .last { font-size:11px; color:var(--t3); margin-top:9px; border-top:1px solid var(--b2); padding-top:8px; }

/* ═══ CARDS ═══ */

/* ⚠ DO NOT DELETE — WORDPRESS CORE OVERRIDE. Verified live 2026-07-20.
 * `.card` is a WP CORE admin class, shipped in wp-admin/load-styles.php:
 *   .card{position:relative;margin-top:20px;padding:.7em 2em 1em;min-width:255px;
 *         max-width:520px;border:1px solid #c3c4c7;box-shadow:0 1px 1px rgba(0,0,0,.04);
 *         background:#fff;box-sizing:border-box}
 * ActionStudio reuses the same class name inside the wp-admin shell, so core's
 * rule applies to EVERY AS card. It will NEVER show up in a repo grep and a
 * fixture without wp-admin styles will render fine — that false negative is
 * exactly why this reset was wrongly removed once already (v0.9.55). The
 * 520px cap is the root cause of "cards in 2 columns don't fill the space".
 * Reset only what core imposes and AS does not intend; AS's own look is set
 * in the rule directly below. `#as-app` beats core's `.card` on specificity,
 * so no !important is needed. */
#as-app .card {
    max-width:none;      /* core 520px — WAS leaking; capped every card. The actual bug. */
    min-width:0;         /* core 255px — WAS leaking; would blow out narrow cells/480px. */
    box-shadow:none;     /* core 0 1px 1px — WAS leaking; SimpleSuite cards are flat. */
    /* margin-top (core 20px) and padding (core .7em 2em 1em) were measured as
     * already neutral: the `#as-app, #as-app *` reset at ~:91 outranks core on
     * specificity, and AS pads via .ch/.cb and spaces via margin-bottom:16px.
     * Restated here belt-and-braces so the intent survives if :91 ever changes. */
    margin-top:0;
    padding:0;
    /* deliberately NOT reset: position:relative (harmless, absolute children
     * may rely on it) and box-sizing:border-box (AS wants it anyway). */
}
#as-app .card { background:var(--s); border:1px solid var(--b); border-radius:var(--r); overflow:hidden; margin-bottom:16px; transition:background .3s,border-color .3s; }
#as-app .ch { padding:12px 16px; display:flex; justify-content:space-between; align-items:center; border-bottom:1px solid var(--b); background:var(--s); color:var(--t1); }
#as-app .ch h3 { font-size:13px; font-weight:700; color:var(--t1); }
#as-app .ch .lnk { font-size:11px; color:var(--ac); font-weight:600; cursor:pointer; }
/* AS-0143/AS-0149: the ~30 modal close controls moved from a bare <span class="lnk">
   to a real <button class="lnk as-modal-close"> for keyboard/AT accessibility
   (AS_Router::modal_close_button(), templates/admin-app.php). A <button> carries
   browser-default border/background/padding/font that a <span> never had — this
   restates the same look the plain .lnk rule above already gave the span (rather
   than relying on cascade order against that rule) so the rendered result is
   unchanged. Two classes on the element (.lnk.as-modal-close) keep this specific
   enough to always win over the plain .lnk rule regardless of source order. */
#as-app .ch .lnk.as-modal-close { background:none; border:0; margin:0; padding:0; font:inherit; font-size:11px; font-weight:600; color:var(--ac); cursor:pointer; }
/* v0.9.67: small "Activity history" button in the Today's Focus header — squared, tokenized. */
#as-app .as-history-btn { font-size:11px; font-weight:600; color:var(--ac); background:var(--s); border:1px solid var(--b); padding:3px 9px; cursor:pointer; line-height:1.4; font-family:inherit; }
#as-app .as-history-btn:hover { background:var(--sa); }
#as-app .cb { padding:14px 16px; }

/* ═══ TABS ═══ */
#as-app .tabs { display:flex; gap:2px; background:var(--sa); border-radius:var(--rs); padding:2px; }
#as-app .tab { padding:4px 10px; font-size:11px; font-weight:600; border-radius:0; cursor:pointer; color:var(--t3); transition:all .12s; }
#as-app .tab:hover { color:var(--t1); }
#as-app .tab.on { background:var(--s); color:var(--t1); box-shadow:0 1px 3px rgba(0,0,0,.06); }
/* v0.10.266: inline count badge inside a .tab — same treatment as .lens .n /
 * .as-kb-pill .n — used by the filter popover's new Board/Done quick switch
 * (#as-task-board-status-filter's Done tab). */
#as-app .tab .n { margin-left:4px; font-size:9.5px; font-weight:800; opacity:.7; }

/* ═══ GRID ═══ */
#as-app .g2 { display:grid; grid-template-columns:1fr 1fr; gap:16px; margin-bottom:16px; }
#as-app .g4 { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; }

/* v0.9.55: one vertical rhythm for grid rows and full-width cards.
 * `.card` carries margin-bottom:16px, but inside a grid the `gap` already
 * supplies the row spacing — the two stacked, so a multi-row grid sat on 32px
 * while a run of full-width cards sat on 16px. Zero the card margin inside
 * grids and let the grid's own margin-bottom close the row instead. */
#as-app .g2 > .card, #as-app .g2 > div > .card,
#as-app .g3 > .card, #as-app .g3 > div > .card,
#as-app .g4 > .card, #as-app .g4 > div > .card { margin-bottom:0; }

/* v0.9.55: role-gate collapse. as-role-gates.js hides admin-gated nodes with
 * inline display:none — the node stays in the DOM, so the surviving sibling
 * kept its single grid column and left dead space beside it, breaking
 * alignment with the full-width cards above and below. (`:only-child` cannot
 * help: a display:none sibling is still a child.) The JS counts VISIBLE
 * children after the hiding pass and stamps .g-collapsed-N so the survivors
 * fill the row flush with the full-width cards. */
#as-app .g2.g-collapsed-1,
#as-app .g3.g-collapsed-1 { grid-template-columns:1fr; }
/* 2-of-3 only makes sense while .g3 is still multi-column — below 768px the
 * responsive rule takes .g3 to a single column and must keep winning. */
@media(min-width:769px) {
    #as-app .g3.g-collapsed-2 { grid-template-columns:1fr 1fr; }
}

/* ═══ METRICS ═══ */
#as-app .mc { background:var(--s); border:1px solid var(--b); border-radius:var(--r); padding:16px; transition:background .3s,border-color .3s; }
#as-app .mc .ml { font-size:11px; color:var(--t3); text-transform:uppercase; letter-spacing:.6px; font-weight:600; margin-bottom:6px; }
#as-app .mc .mv { font-family:'Fraunces',Georgia,serif; font-size:28px; font-weight:700; line-height:1; color:var(--t1); }
#as-app .mc .md { font-size:11px; margin-top:4px; font-weight:600; }
#as-app .up { color:var(--gn); } #as-app .dn { color:var(--rd); } #as-app .nt { color:var(--t3); }

/* ═══ CONTACTS ═══ */
#as-app .crow { display:flex; align-items:center; padding:8px 0; border-bottom:1px solid var(--sa); gap:10px; }
#as-app .crow:last-child { border-bottom:none; }
#as-app .cav { width:30px; height:30px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-weight:700; font-size:10px; color:#FFF; flex-shrink:0; }
#as-app .cinfo { flex:1; min-width:0; }
#as-app .cname { font-weight:600; font-size:12px; }
#as-app .csub { font-size:11px; color:var(--t3); }
#as-app .cbadge { font-size:9px; padding:2px 7px; border-radius:10px; font-weight:600; text-transform:uppercase; letter-spacing:.3px; flex-shrink:0; }

/* ═══ TASKS ═══ */
#as-app .trow { display:flex; align-items:center; padding:7px 0; border-bottom:1px solid var(--sa); gap:8px; }
#as-app .trow:last-child { border-bottom:none; }
#as-app .tcheck { width:16px; height:16px; border:2px solid var(--b); border-radius:0; cursor:pointer; flex-shrink:0; transition:all .12s; display:flex; align-items:center; justify-content:center; position:relative; }
#as-app .tcheck:hover { border-color:var(--ac); }
#as-app .tcheck.done { background:var(--gn); border-color:var(--gn); }
#as-app .tcheck.done::after { content:'✓'; color:#FFF; font-size:9px; font-weight:700; }
#as-app .tdot { width:5px; height:5px; border-radius:50%; flex-shrink:0; }
#as-app .pri-hi { background:var(--rd); } #as-app .pri-md { background:var(--ac); } #as-app .pri-lo { background:var(--gn); }
#as-app .tinfo { flex:1; }
#as-app .ttitle { font-size:12px; font-weight:500; }
#as-app .ttitle.struck { text-decoration:line-through; color:var(--t3); }
#as-app .tmeta { font-size:10px; color:var(--t3); margin-top:1px; }
#as-app .towner { font-size:10px; background:var(--sa); padding:1px 6px; border-radius:8px; font-weight:600; flex-shrink:0; color:var(--t2); }
#as-app .tdue { font-size:10px; color:var(--t3); flex-shrink:0; }
#as-app .tdue.over { color:var(--rd); font-weight:600; }

/* ═══ PIPELINE ═══ */
#as-app .pipe { display:flex; gap:2px; margin-bottom:14px; }
#as-app .pstage { flex:1; text-align:center; padding:8px 6px; border-radius:var(--rs); cursor:pointer; transition:all .12s; }
#as-app .pstage:hover { opacity:.85; }
#as-app .pstage .pc { font-family:'Fraunces',Georgia,serif; font-size:20px; font-weight:700; display:block; }
#as-app .pstage .pl { font-size:9px; text-transform:uppercase; letter-spacing:.6px; font-weight:600; margin-top:1px; display:block; }
#as-app .ps1 { background:var(--bll); color:var(--bl); }
#as-app .ps2 { background:var(--acl); color:var(--ac); }
#as-app .ps3 { background:var(--pul); color:var(--pu); }
#as-app .ps4 { background:var(--gnl); color:var(--gn); }
#as-app .ps5 { background:var(--rdl); color:var(--rd); }

/* ═══ QUICK BAR ═══ */
#as-app .qbar { display:flex; gap:16px; padding:10px 16px; background:var(--sa); border-radius:var(--rs); margin-bottom:16px; align-items:center; flex-wrap:wrap; transition:background .3s; }
#as-app .qstat { display:flex; align-items:center; gap:5px; }
#as-app .qdot { width:7px; height:7px; border-radius:50%; }
#as-app .qlbl { font-size:11px; color:var(--t3); }
#as-app .qval { font-size:11px; font-weight:700; }
/* v0.10.39: inline variant — sits inside a .toolbar next to tabs instead of
 * as its own full-width row (Priorities' Open/Done-this-week). Additive
 * modifier, not a rewrite of .qbar — Nurture's pipeline summary (as-v-crm.js)
 * still uses the base block form. */
#as-app .qbar.qbar-inline { display:inline-flex; gap:10px; padding:0; background:transparent; margin-bottom:0; }
#as-app .qbar-inline .qlbl, #as-app .qbar-inline .qval { font-size:10px; }
#as-app .qbar-inline .qdot { width:6px; height:6px; }

/* ═══ PROGRESS ═══ */
#as-app .pbar { width:100%; height:5px; background:var(--sa); border-radius:3px; overflow:hidden; margin-top:5px; }
#as-app .pfill { height:100%; border-radius:3px; transition:width .4s; }

/* ═══ GOOGLE ACTIONS ═══ */
#as-app .gact { display:inline-flex; align-items:center; gap:4px; padding:4px 8px; border-radius:4px; font-size:10px; font-weight:600; cursor:pointer; border:1px solid var(--b); background:var(--s); transition:all .12s; color:var(--t2); font-family:inherit; }
#as-app .gact:hover { background:var(--sa); }
#as-app .gact:disabled { opacity:.4; cursor:not-allowed; }
#as-app .gact.email { border-color:#DB4437; color:#DB4437; }
#as-app .gact.cal { border-color:#4285F4; color:#4285F4; }
#as-app .gact.meet { border-color:#00897B; color:#00897B; }
#as-app .gact.drive { border-color:#F4B400; color:#F4B400; }

/* ═══ SEARCH ═══ */

/* ═══ DROPZONE ═══ */
#as-app .dropzone { border:2px dashed var(--b); border-radius:var(--r); padding:28px; text-align:center; cursor:pointer; transition:all .2s; }
#as-app .dropzone:hover { border-color:var(--ac); background:var(--acl); }
#as-app .dropzone p { font-size:13px; color:var(--t2); margin-top:4px; }
#as-app .dropzone .big { font-size:15px; font-weight:600; color:var(--t1); }

/* ═══ MISC ═══ */
#as-app .field-tag { font-size:10px; padding:3px 8px; background:var(--sa); border-radius:4px; font-weight:600; color:var(--t2); }
#as-app .as-empty {
    /* v0.7.2: centering survives inside flex parents that don't span full width.
     * Was just text-align:center which fails when the parent itself shrinks to content. */
    display:flex; flex-direction:column; align-items:center; justify-content:center;
    text-align:center; padding:24px 16px; width:100%; grid-column:1 / -1;
}
#as-app .as-empty-icon { font-size:28px; margin-bottom:8px; color:var(--t3); }
#as-app .as-empty-title { font-size:14px; font-weight:600; color:var(--t1); margin-bottom:4px; }
#as-app .as-empty-desc { font-size:12px; color:var(--t3); line-height:1.5; }
/* v0.1.100: centered-large variant for page-level empty states (Opportunities, etc.)
   — vertically centers content, gives generous breathing room so it doesn't look dumpy. */
#as-app .as-empty.as-empty-page {
    display:flex; flex-direction:column; align-items:center; justify-content:center;
    min-height:420px; padding:60px 32px; gap:6px;
    /* v0.4.7: when this empty state lives inside a flex container (e.g. the
     * Opportunities kanban which is display:flex), it would shrink to its
     * content width and pin to the left. flex:1 + width:100% makes it span. */
    flex:1; width:100%;
}
#as-app .as-empty.as-empty-page .as-empty-icon { font-size:48px; margin-bottom:16px; opacity:.5; }
#as-app .as-empty.as-empty-page .as-empty-title { font-size:18px; margin-bottom:8px; }
#as-app .as-empty.as-empty-page .as-empty-desc { font-size:13px; max-width:460px; margin-bottom:20px; }
#as-app .as-placeholder { padding:40px; text-align:center; color:var(--t3); }
#as-app .as-phase-tag { font-size:11px; color:var(--ac); font-weight:600; }
#as-app .wrow { display:flex; align-items:center; padding:7px 0; border-bottom:1px solid var(--sa); gap:10px; }
#as-app .wrow:last-child { border-bottom:none; }
#as-app .wk { font-size:10px; font-weight:700; color:var(--ac); width:50px; flex-shrink:0; }
#as-app .winfo { flex:1; }
#as-app .wtitle { font-size:12px; font-weight:500; }
#as-app .wgoal { font-size:10px; color:var(--t3); margin-top:1px; }

/* ═══ MODALS ═══ */
#as-app .as-modal-bg { display:none; position:fixed; inset:0; background:rgba(0,0,0,.5); z-index:200; align-items:center; justify-content:center; }
#as-app .as-modal-bg.show { display:flex; }
#as-app .as-modal { background:var(--s); border-radius:var(--r); width:480px; max-height:80vh; overflow-y:auto; box-shadow:0 20px 60px rgba(0,0,0,.2); }
/* v0.6.0: Task modal needs more breathing room — Title + Desc + Project/Category + Pri/Status + Assign/Due + Milestone + Documents stack and force internal scroll at 480/80vh. Bump to 620 wide / 88vh so most edits fit without scrolling. */
#as-app #as-m-task .as-modal { width:620px; max-height:88vh; }
/* v0.10.133: Compose Email + Calendar Event modals were cramped in the generic
   480px .as-modal — widen them the same way #as-m-task was widened above.
   Compose gets a bit more room than the task modal since it carries a
   rich-text body plus attachments; Event matches the task modal's width. */
#as-app #as-m-compose .as-modal { width:680px; max-height:88vh; }
#as-app #as-m-event .as-modal { width:620px; max-height:88vh; }
#as-app .as-modal .ch { border-radius:var(--r) var(--r) 0 0; }
#as-app .as-modal .cb { padding:20px; }
#as-app .as-modal label { display:block; font-size:11px; font-weight:600; color:var(--t2); margin-bottom:4px; text-transform:uppercase; letter-spacing:.5px; }
#as-app .as-modal input, #as-app .as-modal select, #as-app .as-modal textarea { width:100%; padding:8px 10px; border:1px solid var(--b); border-radius:var(--rs); font-family:inherit; font-size:13px; margin-bottom:12px; background:var(--inp-bg); color:var(--t1); }
#as-app .as-modal textarea { height:60px; resize:vertical; }
#as-app .as-modal input:focus, #as-app .as-modal select:focus, #as-app .as-modal textarea:focus { outline:none; border-color:var(--ac); }
#as-app .as-modal .row { display:flex; gap:12px; }
#as-app .as-modal .row > * { flex:1; }
#as-app .as-modal .actions { display:flex; gap:8px; justify-content:flex-end; margin-top:8px; }

/* ═══ COMMISSIONS FILTER STRIP (v0.9.66; height→30px in v0.10.10) ═══
 * The Commissions view's Status / Agent / Period filters had no class and no
 * inline style, and there is no global `#as-app select` rule, so they rendered
 * as raw native OS controls that clashed with the .btn controls beside them.
 * Scope a rule to the filter container ONLY (`.as-comm-filters`) — never a
 * blanket select restyle — so the row reads as one coherent control strip:
 * same border/background/text tokens as `.as-modal select`. Squared
 * (var(--rs) = 0 in every theme). v0.10.10: height dropped from the original
 * 34px (matching `.btn`) to 30px — this toolbar is now `.as-toolbar`-scoped
 * (30px doctrine), and this rule's equal-but-later specificity was winning
 * over `.as-toolbar select{height:30px}`, so it needs to state 30px itself
 * rather than relying on the toolbar rule to override it. */
#as-app .as-comm-filters select,
#as-app .as-comm-filters input[type=month] {
    height:30px; min-height:0; box-sizing:border-box; padding:4px 10px;
    border:1px solid var(--b); border-radius:var(--rs);
    background:var(--inp-bg); color:var(--t1);
    font-family:inherit; font-size:12px;
}
#as-app .as-comm-filters select:focus,
#as-app .as-comm-filters input[type=month]:focus { outline:none; border-color:var(--ac); }

/* ═══ v0.1.1 — TASK ACTIONS ═══ */
#as-app .trow:hover { background: var(--sa); border-radius: var(--rs); }
#as-app .trow [onclick] { cursor: pointer; }
#as-app .as-pri-hi { background: var(--rd); }
#as-app .as-pri-md { background: var(--ac); }
#as-app .as-pri-lo { background: var(--gn); }

/* ═══ v0.1.3 — CONTACT DETAIL PANEL ═══ */
#as-app .as-detail-panel {
    position: fixed; top: 0; right: 0; bottom: 0; width: 480px;
    background: var(--s); border-left: 1px solid var(--b);
    z-index: 9998; overflow-y: auto; box-shadow: -4px 0 20px rgba(0,0,0,.1);
    transition: transform .2s;
}
#as-app .as-detail-header {
    padding: 14px 20px; display: flex; justify-content: space-between; align-items: center;
    border-bottom: 1px solid var(--b); position: sticky; top: 0; background: var(--s); z-index: 1;
}
#as-app .as-detail-section { padding: 16px; border-bottom: 1px solid var(--sa); }
#as-app .as-detail-name { font-family: 'Fraunces', serif; font-size: 20px; font-weight: 700; margin-bottom: 4px; }
#as-app .as-detail-field { margin-bottom: 8px; }
#as-app .as-detail-label { font-size: 9px; text-transform: uppercase; letter-spacing: .6px; color: var(--t3); font-weight: 600; margin-bottom: 2px; }
#as-app .as-detail-value { font-size: 13px; }
#as-app .as-activity-item { padding: 6px 0; border-bottom: 1px solid var(--sa); font-size: 12px; }
#as-app .as-activity-item:last-child { border-bottom: none; }
#as-app .as-activity-time { font-size: 10px; color: var(--t3); }

/* ═══ v0.1.3 — IMPORT MAPPING ═══ */
#as-app .as-map-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; border-bottom: 1px solid var(--sa); }
#as-app .as-map-row:last-child { border-bottom: none; }
#as-app .as-map-label { font-size: 11px; font-weight: 600; min-width: 100px; color: var(--t1); }
#as-app .as-map-arrow { color: var(--t3); font-size: 12px; }
#as-app .as-map-select { flex: 1; }
#as-app .as-map-select select { width: 100%; padding: 5px 8px; border: 1px solid var(--b); border-radius: var(--rs); font-size: 12px; background: var(--inp-bg); color: var(--t1); }
#as-app .as-import-sample { max-height: 200px; overflow: auto; margin: 12px 0; }
#as-app .as-import-sample table { width: 100%; font-size: 11px; border-collapse: collapse; }
#as-app .as-import-sample th { background: var(--sa); padding: 4px 8px; text-align: left; font-weight: 600; position: sticky; top: 0; }
#as-app .as-import-sample td { padding: 4px 8px; border-bottom: 1px solid var(--sa); }
#as-app .as-import-result { padding: 16px; text-align: center; }
#as-app .as-import-result .big { font-family: 'Fraunces', serif; font-size: 32px; font-weight: 700; color: var(--gn); }

/* ═══ v0.1.4 — PIPELINE KANBAN ═══ */
#as-app .as-pipe-col { min-height: 250px; }
#as-app .as-pipe-card {
    background: var(--s); border: 1px solid var(--b); border-radius: var(--rs);
    padding: 10px 12px; cursor: pointer; transition: box-shadow .15s, border-color .15s;
    margin-bottom: 6px;
}
#as-app .as-pipe-card:hover { border-color: var(--ac); box-shadow: 0 2px 8px rgba(0,0,0,.08); }
#as-app .as-pipe-card .name { font-size: 12px; font-weight: 600; margin-bottom: 2px; }
#as-app .as-pipe-card .sub { font-size: 10px; color: var(--t3); }
#as-app .as-pipe-card .deals { font-size: 10px; color: var(--ac); font-weight: 600; margin-top: 4px; }
#as-app .as-pipe-move { display: flex; gap: 3px; margin-top: 6px; }
#as-app .as-pipe-move button {
    font-size: 9px; padding: 2px 6px; border-radius: 4px;
    border: 1px solid var(--b); background: var(--s); cursor: pointer;
    color: var(--t2); font-weight: 600; transition: all .12s;
}
#as-app .as-pipe-move button:hover { background: var(--ac); color: #FFF; border-color: var(--ac); }
#as-app .as-deal-card { padding: 10px 12px; }
#as-app .as-deal-card .value { font-family: 'Fraunces', serif; font-size: 16px; font-weight: 700; color: var(--gn); }
#as-app .as-deal-card .contact { font-size: 10px; color: var(--bl); font-weight: 600; }

/* ═══ v0.1.6 — EVENTS ═══ */
#as-app .as-event-card {
    display: flex; align-items: center; gap: 14px; padding: 12px;
    border-bottom: 1px solid var(--b); cursor: pointer; transition: background .12s;
}
/* AS-0215: AS-0194's listCardSwipeHTML wraps this card in .as-swipe-wrap
 * with an absolutely-positioned .as-swipe-actions Delete layer behind it
 * (as-email.css ~L139-140) — the same structure Email mode's own
 * .as-email-row already sits in front of (as-email.css), where that row's
 * base rule bakes in position:relative + an opaque var(--s) background so
 * it covers the actions layer at rest. .as-event-card had neither at rest
 * (only :hover/.as-evl-now/.as-evl-next below ever set position/background),
 * so the actions layer painted on top of EVERY card, not just a swiped-open
 * one — every row showed a live "Delete" button. Scoped to the wrap so
 * List/Today's own cards (the only ones AS-0194 ever wraps) get this,
 * without touching Split's separate Today mini-list or Month/Week's mobile
 * agenda, which reuse the same .as-event-card markup unwrapped.
 * Specificity is (1,2,0), same as :hover/.as-evl-now/.as-evl-next just
 * below — declared BEFORE them so those still win on their own state,
 * exactly the "declared after, so both still win cleanly" pattern
 * as-email.css's own .as-email-row comment documents. No z-index needed:
 * listCardSwipeHTML renders .as-swipe-actions BEFORE this card in the DOM
 * (see as-v-events.js), so once both are positioned, this card — the later
 * sibling at the same (auto) z-index — paints on top, same mechanism
 * .as-email-row already relies on. */
#as-app .as-swipe-wrap > .as-event-card { position: relative; background: var(--s); }
#as-app .as-event-card:hover { background: var(--sa); }
#as-app .as-event-card:last-child { border-bottom: none; }
/* v0.10.85 (item 12): flag-as-important toggle on event cards. */
#as-app .as-event-flag-on { color: var(--ac) !important; border-color: var(--ac) !important; background: var(--acl) !important; }
/* v0.10.85 (item 3): List view's equivalent of Week/Day's "now" line —
 * highlights the current/next-upcoming event in Today's list.
 * v0.10.142: was one class ("Now") applied to whichever event was simply
 * NEXT in line, even a meeting 45+ minutes away with a gap before it —
 * genuinely misleading. Split into two: .as-evl-now (the JS confirmed we're
 * actually inside its start-end window right now) keeps the original "Now"
 * label; .as-evl-next (found, but hasn't started yet) gets the same
 * highlight treatment with an honest "Next" label instead. */
#as-app .as-event-card.as-evl-now, #as-app .as-event-card.as-evl-next { background: var(--acl); border-left: 3px solid var(--ac); padding-left: 9px; position: relative; }
#as-app .as-event-card.as-evl-now::before { content: 'Now'; position: absolute; top: 6px; right: 12px; font-size: 9px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ac); }
#as-app .as-event-card.as-evl-next::before { content: 'Next'; position: absolute; top: 6px; right: 12px; font-size: 9px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ac); }
#as-app .as-event-date {
    width: 48px; height: 52px; text-align: center; border-radius: 6px;
    background: var(--sa); border-top: 3px solid var(--ac); flex-shrink: 0;
    display: flex; flex-direction: column; justify-content: center;
}
#as-app .as-event-month { font-size: 10px; font-weight: 700; text-transform: uppercase; color: var(--t3); }
#as-app .as-event-day { font-size: 20px; font-weight: 800; color: var(--t1); line-height: 1; }
#as-app .as-event-info { flex: 1; min-width: 0; }
#as-app .as-event-title { font-size: 13px; font-weight: 600; margin-bottom: 2px; }
#as-app .as-event-meta { font-size: 11px; color: var(--t3); }
/* v0.10.101 (punchlist #4): margin-top bumped 4px→8px — read as too
   tight against the event title/meta line above it on the List/Split event
   card (eventCardHTML). */
#as-app .as-meet-link {
    display: inline-block; margin-top: 8px; font-size: 11px; font-weight: 600;
    color: var(--bl); text-decoration: none; padding: 2px 8px;
    background: var(--bll); border-radius: 4px;
}
#as-app .as-meet-link:hover { background: var(--bl); color: #FFF; }

/* ═══ v0.1.6 — ACTIVITY ═══ */
#as-app .as-activity-item { padding: 8px 0; border-bottom: 1px solid var(--b); font-size: 12px; }
#as-app .as-activity-item:last-child { border-bottom: none; }
#as-app .as-activity-time { font-size: 10px; color: var(--t3); white-space: nowrap; }

/* ═══ DRIVE VIEW ═══ */
#as-app .as-drive-toolbar { display:flex; align-items:center; gap:8px; margin-bottom:12px; }
#as-app .as-drive-toolbar input { flex:1; max-width:360px; padding:8px 12px; border:1px solid var(--b); background:var(--inp-bg); color:var(--t1); font-family:inherit; font-size:13px; }
#as-app .as-drive-toolbar input:focus { outline:none; border-color:var(--ac); box-shadow:0 0 0 2px color-mix(in srgb, var(--ac) 12%, transparent); }
#as-app .as-drive-create-tray { display:flex; align-items:center; gap:8px; margin-bottom:16px; padding:10px 18px; background:var(--sa); border:1px solid var(--b); }
#as-app .as-drive-create-label { font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.5px; color:var(--t3); margin-right:4px; }
#as-app .as-drive-create-btn { display:inline-flex; align-items:center; gap:5px; padding:5px 10px; font-size:11px; font-weight:600; color:var(--t2); text-decoration:none; border:1px solid var(--b); background:var(--s); transition:all .12s; }
#as-app .as-drive-create-btn:hover { border-color:var(--ac); color:var(--ac); background:var(--bg); }
#as-app .as-drive-tabs { display:flex; gap:2px; margin-bottom:16px; }
#as-app .as-drive-tab { padding:6px 16px; font-size:12px; font-weight:600; color:var(--t3); cursor:pointer; border:none; background:transparent; border-bottom:2px solid transparent; transition:all .12s; font-family:inherit; }
#as-app .as-drive-tab:hover { color:var(--t1); }
#as-app .as-drive-tab.as-dt-on { color:var(--ac); border-bottom-color:var(--ac); }
#as-app .as-drive-view-toggle { display:flex; gap:2px; margin-left:auto; }
#as-app .as-drive-vbtn { width:30px; height:30px; border:1px solid var(--b); background:var(--s); display:flex; align-items:center; justify-content:center; cursor:pointer; color:var(--t3); transition:all .12s; padding:0; }
#as-app .as-drive-vbtn:hover { color:var(--t1); border-color:var(--ac); }
#as-app .as-drive-vbtn.as-dv-on { color:var(--ac); border-color:var(--ac); background:var(--sa); }
#as-app .as-drive-body { min-height:200px; }
#as-app .as-drive-empty { display:flex; flex-direction:column; align-items:center; justify-content:center; padding:48px 20px; color:var(--t3); text-align:center; }
#as-app .as-drive-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(260px, 1fr)); gap:8px; padding:2px; }
#as-app .as-drive-item { display:flex; align-items:center; gap:12px; padding:12px 14px; background:var(--s); border:2px solid var(--b); cursor:pointer; transition:all .12s; }
#as-app .as-drive-item:hover { border-color:var(--ac); box-shadow:0 2px 8px rgba(0,0,0,.06); }
#as-app .as-drive-item-icon { flex-shrink:0; width:36px; height:36px; display:flex; align-items:center; justify-content:center; background:var(--sa); color:var(--t3); }
#as-app .as-drive-item:hover .as-drive-item-icon { color:var(--ac); }
#as-app .as-drive-item-info { flex:1; min-width:0; }
#as-app .as-drive-item-name { font-size:13px; font-weight:500; color:var(--t1); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#as-app .as-drive-item-meta { font-size:11px; color:var(--t3); margin-top:2px; }
/* List view */
#as-app .as-drive-list { display:flex; flex-direction:column; padding:2px; }
#as-app .as-drive-list-header { display:flex; align-items:center; gap:10px; padding:8px 14px; border-bottom:2px solid var(--b); font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.5px; color:var(--t3); }
#as-app .as-drive-list-header span { cursor:pointer; display:flex; align-items:center; gap:3px; }
#as-app .as-drive-list-header span:hover { color:var(--t1); }
#as-app .as-dl-name { flex:1; min-width:0; }
#as-app .as-dl-type { width:100px; flex:0 0 100px; }
#as-app .as-dl-date { width:100px; flex:0 0 100px; text-align:right; }
#as-app .as-dl-icon { width:36px; flex:0 0 36px; display:flex; align-items:center; justify-content:center; }
#as-app .as-drive-list-row { display:flex; align-items:center; gap:10px; padding:10px 14px; border-bottom:1px solid var(--b); cursor:pointer; transition:all .12s; background:var(--s); }
#as-app .as-drive-list-row:hover { background:var(--sa); }
#as-app .as-drive-list-row .as-dl-name { font-size:13px; font-weight:500; color:var(--t1); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#as-app .as-drive-list-row .as-dl-type { font-size:11px; color:var(--t3); }
#as-app .as-drive-list-row .as-dl-date { font-size:11px; color:var(--t3); }

/* ═══ RESPONSIVE ═══ */
@media(max-width:1100px) {
    #as-app .g2 { grid-template-columns:1fr; }
    #as-app .g4 { grid-template-columns:repeat(2,1fr); }
}

/* ═══ v0.1.5 — SVG ICONS ═══ */
#as-app .as-icon { display:inline-block; vertical-align:middle; flex-shrink:0; }
#as-app .si .as-icon { opacity:.7; }
#as-app .si.on .as-icon { opacity:1; }
#as-app .as-icon-btn { padding:3px 6px !important; font-size:10px !important; display:inline-flex; align-items:center; justify-content:center; }
#as-app .as-icon-danger { color:var(--rd); }
#as-app .as-icon-danger:hover { background:var(--rdl); }

/* ═══ v0.1.7 — IMPORT TARGET TABS ═══ */
#as-app #as-import-target-tabs { margin-bottom:0; }

/* ═══ v0.1.7 — EMAIL TEMPLATE SEND MODAL ═══ */
#as-app #as-m-sendemail .as-modal { width:520px; }
#as-app #as-m-sendemail label { display:block; font-size:11px; font-weight:600; color:var(--t2); margin-bottom:4px; text-transform:uppercase; letter-spacing:.5px; }
#as-app #as-m-emailtpl code { font-size:10px; background:var(--sa); padding:1px 4px; border-radius:3px; }

/* ═══ v0.1.8 — TOAST NOTIFICATIONS ═══ */
/* v0.10.227 (AS-0009): bumped 9999 -> 10010, above .as-g-modal-backdrop's
 * 10000 (assets/css/as-google-wizard.css). The wizard backdrop is appended
 * directly to <body>, a sibling of this container rather than a descendant,
 * so raw z-index decided paint order — a connect-init failure toast
 * (e.g. "Team Google credentials not configured…") was rendering BEHIND the
 * wizard's dark overlay, invisible, making the wizard look like it silently
 * reverted from Step 3 to Step 2 with no explanation. */
#as-toast-container { position:fixed; top:16px; right:16px; z-index:10010; display:flex; flex-direction:column; gap:8px; pointer-events:none; }
#as-app .as-toast { padding:10px 16px; border-radius:var(--rs); font-size:12px; font-weight:600; color:#FFF; pointer-events:auto; transition:opacity .3s; min-width:200px; max-width:360px; box-shadow:0 4px 12px rgba(0,0,0,.15); }
#as-app .as-toast-success { background:var(--gn); }
#as-app .as-toast-error { background:var(--rd); }
#as-app .as-toast-info { background:var(--bl); }
/* AS-0238: optional action button inside a toast (e.g. Reconnect). */
#as-app .as-toast .as-toast-action { margin-left:10px; padding:2px 8px; font:inherit; font-size:11px; color:inherit; background:transparent; border:1px solid currentColor; border-radius:0; cursor:pointer; }
/* AS-0238: calendar Filters popover row when the personal token is dead. */
#as-app .as-cal-reconnect { display:flex; flex-direction:column; gap:6px; margin:0 0 8px; padding:8px 10px; background:var(--rdl); border-left:3px solid var(--rd); border-radius:0; }
#as-app .as-cal-reconnect-msg { font-size:12px; font-weight:600; color:var(--rd); }
#as-app .as-cal-reconnect-btn { align-self:flex-start; font-size:11px; height:26px; padding:0 10px; border-radius:0; }

/* ═══ v0.1.8 — DEADLINE COLORS ═══ */
#as-app .due-overdue { color:var(--rd) !important; font-weight:700 !important; }
#as-app .due-today { color:var(--ac) !important; font-weight:700 !important; }
#as-app .due-urgent { color:#D4740E !important; font-weight:700 !important; }
#as-app .due-week { color:#E8943A !important; font-weight:600 !important; }
#as-app .due-future { color:var(--gn) !important; }

/* v0.1.98.1: urgency left-borders removed. Visual cue now lives on a due-proximity dot next to the title
   (see .as-due-dot). Overdue still applies a background tint, which persists here for kanban contrast. */
#as-app .as-kb-card.as-overdue { background:var(--rdl); }

/* v0.10.266 (AS-0054 [stale id — see AS-0159-0166, not AS-0054/55/56/57] correction): Priorities/Tasks toolbar quick popovers —
 * Queue and the Filter-tasks control (Done folded into the latter). Direct
 * correction from Glenn reviewing the live v0.10.257 build: both used to be
 * full-height .as-opp-tray side drawers; he wants "a drop down quick and
 * easy filter, not a full side bar." Mirrors the .as-notif-wrap/.as-notif-
 * panel anchored-dropdown pattern immediately below — position:relative
 * wrap + position:absolute panel + outside-click close (as-v-tasks.js) —
 * reusing that existing dropdown language rather than inventing a new one.
 * .as-tray-head/.as-tray-body inside these panels are the same shared
 * classes every .as-opp-tray already uses (padding/typography unchanged). */
#as-app .as-qp-anchor { position:relative; }
#as-app .as-quickpop { display:none; position:absolute; top:calc(100% + 8px); left:0; width:300px; max-width:90vw; max-height:420px; overflow-y:auto; background:var(--s); border:1px solid var(--b); border-radius:var(--r); box-shadow:0 8px 24px rgba(0,0,0,.12); z-index:300; }
#as-app .as-quickpop.as-tray-open { display:block; }
#as-app #as-task-filter-wrap .as-quickpop { left:auto; right:0; }

/* ═══ v0.1.8 — NOTIFICATION BELL (fixed v0.1.14) ═══ */
#as-app .as-notif-wrap { position:relative; display:inline-flex; align-items:center; }
#as-app .as-notif-bell { position:relative; width:34px; height:34px; padding:0 !important; display:inline-flex; align-items:center; justify-content:center; box-sizing:border-box; }
#as-app .as-notif-bell svg { width:16px; height:16px; display:block; flex-shrink:0; }
#as-app .as-notif-badge { position:absolute; top:-2px; right:-2px; background:var(--rd); color:#FFF; font-size:9px; font-weight:700; min-width:16px; height:16px; border-radius:50%; display:inline-flex; align-items:center; justify-content:center; padding:0 3px; line-height:1; }
#as-app .as-notif-panel { position:absolute; top:calc(100% + 8px); right:0; width:340px; max-height:420px; overflow-y:auto; background:var(--s); border:1px solid var(--b); border-radius:var(--r); box-shadow:0 8px 24px rgba(0,0,0,.12); z-index:300; }
#as-app .as-notif-header { padding:10px 14px; font-weight:700; font-size:12px; border-bottom:1px solid var(--b); }
#as-app .as-notif-group { padding:4px 0; border-bottom:1px solid var(--sa); }
#as-app .as-notif-group:last-child { border-bottom:none; }
#as-app .as-notif-group-title { padding:6px 14px 2px; font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.5px; }
#as-app .as-notif-item { display:flex; align-items:center; gap:6px; padding:6px 14px; font-size:12px; cursor:pointer; transition:background .1s; }
#as-app .as-notif-item:hover { background:var(--sa); }
#as-app .as-notif-due { margin-left:auto; font-size:10px; flex-shrink:0; }

/* ═══ v0.9.59 — BELL: "Happened" (event log) + "Needs attention" ═══
 * Two sections in one panel. The event rows are taller than the due-date rows
 * on purpose: each carries a headline, an optional sub-line and an actor/time
 * meta line, where a due-date row is a single title. Squared throughout —
 * --r/--rs are 0 and the only literal radius below is on .as-notif-dot, which
 * is a 6px circular indicator, not a box. The event_count chip is a BOX and is
 * therefore squared like everything else. */
#as-app .as-notif-section { border-bottom:1px solid var(--b); }
#as-app .as-notif-section:last-child { border-bottom:none; }
#as-app .as-notif-section-title { display:flex; align-items:center; gap:8px; padding:8px 14px 4px; font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.5px; color:var(--t3); }
/* Plain count, deliberately NOT badge-styled — standing state does not badge. */
#as-app .as-notif-section-count { font-weight:600; color:var(--t3); text-transform:none; letter-spacing:0; }
#as-app .as-notif-readall { margin-left:auto; background:none; border:none; padding:0; font-size:10px; font-weight:600; color:var(--ac); cursor:pointer; text-transform:none; letter-spacing:0; }
#as-app .as-notif-readall:hover { text-decoration:underline; }
#as-app .as-notif-quiet { padding:10px 14px 12px; font-size:11px; color:var(--t3); }

#as-app .as-notif-event { display:flex; align-items:flex-start; gap:6px; padding:8px 14px; border-top:1px solid var(--sa); }
#as-app .as-notif-event:hover { background:var(--sa); }
#as-app .as-notif-event.is-unread { border-left:2px solid var(--ac); padding-left:12px; }
#as-app .as-notif-event-main { flex:1; min-width:0; }
#as-app .as-notif-event.is-clickable .as-notif-event-main { cursor:pointer; }
#as-app .as-notif-event-title { display:flex; align-items:center; gap:6px; font-size:12px; font-weight:600; color:var(--t1); }
#as-app .as-notif-event.is-unread .as-notif-event-title { font-weight:700; }
#as-app .as-notif-event-sub { margin-top:2px; font-size:11px; color:var(--t2); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
#as-app .as-notif-event-meta { margin-top:3px; font-size:10px; color:var(--t3); }
#as-app .as-notif-dot { width:6px; height:6px; border-radius:50%; background:var(--ac); flex-shrink:0; }
/* event_count > 1. A collapsed row is N events; the pill makes N visible even
 * when the headline is scanned rather than read. */
#as-app .as-notif-count { margin-left:auto; flex-shrink:0; min-width:16px; padding:0 5px; border-radius:var(--rs); background:var(--sa); border:1px solid var(--b); font-size:9px; font-weight:700; line-height:14px; text-align:center; color:var(--t2); }
#as-app .as-notif-dismiss { flex-shrink:0; background:none; border:none; padding:0 2px; font-size:14px; line-height:1; color:var(--t3); cursor:pointer; }
#as-app .as-notif-dismiss:hover { color:var(--t1); }

/* ═══ v0.1.8 — PROJECT DOT ═══ */
#as-app .as-proj-dot { width:8px; height:8px; border-radius:50%; flex-shrink:0; display:inline-block; }
#as-app .as-project-card { cursor:pointer; transition:border-color .12s; }
#as-app .as-project-card:hover { border-color:var(--ac); }
#as-app .as-company-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(260px,1fr)); gap:12px; }
#as-app .as-company-card-g { cursor:pointer; transition:border-color .12s; }
#as-app .as-company-card-g:hover { border-color:var(--ac); }

/* ═══ v0.1.8 — COLOR PICKER ═══ */
#as-app .as-color-dot { width:24px; height:24px; border-radius:50%; cursor:pointer; border:2px solid transparent; transition:all .12s; }
#as-app .as-color-dot:hover { transform:scale(1.15); }
#as-app .as-color-dot.on { border-color:var(--t1); box-shadow:0 0 0 2px var(--s); }

/* ═══ v0.1.9 — USER MANAGEMENT ═══ */
#as-app .as-user-role-sel { font-family:inherit; cursor:pointer; }
#as-app .as-user-role-sel:focus { outline:none; border-color:var(--ac); }

/* ═══ v0.1.9 — TASK KANBAN BOARD ═══ */
/* NOTE (AS-0060, v0.10.206): .as-kanban/.as-kb-col/.as-kb-header/.as-kb-count/
 * .as-kb-body are NOT exclusive to the Tasks board — Funnels' bucket columns
 * (as-funnels.js, `.as-kb-col.as-ft-bucket`) and Pipeline's stage columns
 * (as-v-crm.js, `.as-kb-col.as-opp-col`) reuse the same shared shell classes.
 * .as-kb-card/.as-kb-title/.as-kb-meta/.as-kb-pri/.as-kb-owner/.as-kb-due/
 * .as-kb-actions ARE Tasks-board-only (grepped: no other JS emits them), so
 * those are safe to touch directly. The column min-width is NOT touched
 * here for that reason — see the #as-kanban-board-scoped override below,
 * which narrows only the Tasks board's own columns and leaves Funnels/
 * Pipeline at their original 180px floor, untouched, per the ticket's
 * "board only" scope. */
#as-app .as-kanban { display:flex !important; flex-wrap:nowrap !important; gap:12px; overflow-x:auto; padding-bottom:8px; }
#as-app .as-kb-col { flex:1 1 0%; min-width:180px; max-width:none; background:var(--sa); border-radius:var(--r); overflow:hidden; }
/* v0.10.257 (AS-0054 [stale id — see AS-0159-0166, not AS-0054/55/56/57] follow-on): Priorities — a mobile one-column-at-a-time
 * pill switcher. Desktop is unchanged (pills hidden, every .as-kb-col shows,
 * same flex row as always); the 768px block below flips this to one column
 * visible at a time.
 * v0.10.266: the Queue/Done tray-trigger row that used to render above the
 * board (.as-kb-trayrow/.as-kb-tray-btn/.as-kb-tray-dot/.as-kb-tray-n) is
 * gone — Queue moved into the toolbar (.lenses next to +Add task, see
 * .as-quickpop below) and Done folded into the filter popover, both direct
 * corrections from Glenn reviewing the live v0.10.257 build. Removed rather
 * than left dead since nothing renders these classes anymore. */
#as-app .as-kb-pills { display:none; gap:6px; overflow-x:auto; margin-bottom:10px; padding-bottom:2px; }
#as-app .as-kb-pill { flex:0 0 auto; font-size:11.5px; font-weight:700; padding:6px 12px; border:1px solid var(--b); background:var(--s); color:var(--t2); white-space:nowrap; cursor:pointer; }
#as-app .as-kb-pill .n { margin-left:5px; font-size:9.5px; font-weight:800; opacity:.7; }
#as-app .as-kb-header { padding:10px 12px; font-size:12px; font-weight:700; display:flex; justify-content:space-between; align-items:center; border-bottom:3px solid var(--ac); }
#as-app .as-kb-count { font-size:10px; background:var(--s); padding:1px 6px; border-radius:8px; font-weight:600; color:var(--t3); }
#as-app .as-kb-body { padding:8px; min-height:120px; }
#as-app .as-kb-card { background:var(--s); border:1px solid var(--b); border-radius:var(--rs); padding:10px 12px; margin-bottom:6px; cursor:pointer; transition:border-color .12s,box-shadow .12s; }
#as-app .as-kb-card:hover { border-color:var(--ac); box-shadow:0 2px 8px rgba(0,0,0,.08); }
#as-app .as-kb-title { font-size:12px; font-weight:600; margin-bottom:4px; }
#as-app .as-kb-meta { display:flex; align-items:center; gap:6px; font-size:10px; color:var(--t3); flex-wrap:wrap; }
#as-app .as-kb-pri { width:6px; height:6px; border-radius:50%; flex-shrink:0; }
#as-app .as-kb-owner { font-size:10px; }
#as-app .as-kb-due { font-size:10px; }
#as-app .as-kb-actions { display:flex; gap:3px; margin-top:6px; }
#as-app .as-kb-actions button { font-size:9px; padding:2px 6px; border-radius:0; border:1px solid var(--b); background:var(--s); cursor:pointer; color:var(--t2); font-weight:600; transition:all .12s; font-family:inherit; }
#as-app .as-kb-actions button:hover { background:var(--ac); color:#FFF; border-color:var(--ac); }

/* AS-0060 (v0.10.206): reclaim the ambient .cnt padding for the BOARD panel
 * only — List view (#as-task-panel-list) keeps the normal 20px/28px .cnt
 * gutter untouched. .cnt's own padding is declared once, globally (~:259:
 * `#as-app .cnt { padding:20px 28px; }`), and .toolbar already cancels it
 * with `margin:-20px -28px 20px` (~:345 and its comment) to bleed edge to
 * edge under the header. #as-task-panel-board is a sibling of .toolbar, not
 * a descendant, so giving it the same -28px left/right margin only widens
 * the board's own content — it does not touch .cnt's padding declaration
 * (which the toolbar and every other view still use) and does not shift or
 * resize .toolbar itself. The board's edges end up flush with the toolbar's
 * already-flush edges above it, so nothing misaligns. */
#as-app #as-task-panel-board { margin:0 -28px; }

/* AS-0060 (v0.10.206): column floor cut from 180px to 144px (180*0.8, a 20%
 * reduction), scoped to `#as-kanban-board .as-kb-col` (ID + class beats the
 * bare `#as-app .as-kb-col` rule above on specificity, so this wins only
 * inside the Tasks board's own DOM — Funnels/Pipeline's `.as-kb-col` stays
 * at the shared 180px floor). 4 cols * 144 + 3 gaps * 12 = 612px, down from
 * 4*180+3*12=756px. Combined with the padding reclaim above, this drops the
 * total viewport width needed before the board's bare CSS floor forces
 * horizontal scroll from ~1022px (210 sidebar + 56 .cnt padding + 756 floor)
 * to ~822px (210 + 0 reclaimed padding + 612 floor) — see the ticket for the
 * full before/after math. List view (.as-task-cols/.trow) is untouched. */
#as-app #as-kanban-board .as-kb-col { min-width:144px; }

/* AS-0060 (v0.10.206): below ~1100px the 4 columns (still side-by-side —
 * the existing @media(max-width:768px) block below is what switches them to
 * a stacked column layout, see #as-app .as-kanban { flex-direction:column }
 * at ~:1598) get noticeably tight even at the new 144px floor once real
 * card content (a long owner name, a long title) pushes a column past its
 * CSS minimum. Scoped to (max-width:1100px) and (min-width:769px) so it
 * only covers the still-side-by-side range and never overlaps or fights the
 * 768px/480px mobile blocks' own .as-kb-card padding rules (~:1617, ~:1774)
 * — those already replace this panel's padding via normal cascade order
 * (they're declared later in the file at equal specificity), so this rule
 * simply stops applying once a narrower block's rule takes over.
 * Owner name truncates with an ellipsis (title attribute added in
 * kanbanCard(), as-v-tasks.js, keeps the full name available on hover)
 * rather than being hidden outright — knowing WHO owns a card is more
 * useful at a glance than not, and it's the least essential piece of
 * .as-kb-meta compared to the priority dot and due-date badge, which stay
 * full-size and untouched per the ticket. */
@media(max-width:1100px) and (min-width:769px) {
    #as-app .as-kb-card { padding:8px 9px; }
    #as-app .as-kb-owner { max-width:64px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; display:inline-block; vertical-align:bottom; }
}

/* ═══ v0.1.9 — WEEK PLAN VIEW ═══ */
#as-app .as-wp-week { margin-bottom:16px; background:var(--s); border:1px solid var(--b); border-radius:var(--r); overflow:hidden; }
#as-app .as-wp-header { display:flex; align-items:center; gap:10px; padding:10px 16px; border-bottom:1px solid var(--b); background:var(--sa); }
#as-app .as-wp-label { font-size:12px; font-weight:700; color:var(--ac); min-width:50px; }
#as-app .as-wp-bar { flex:1; height:5px; background:var(--b); border-radius:3px; overflow:hidden; }
#as-app .as-wp-fill { height:100%; background:var(--gn); border-radius:3px; transition:width .4s; }
#as-app .as-wp-pct { font-size:11px; font-weight:700; min-width:32px; text-align:right; }
#as-app .as-wp-body { padding:6px 16px; }
#as-app .as-wp-unassigned { margin-top:16px; }
#as-app .as-wp-unassigned-label { font-size:11px; font-weight:600; color:var(--t3); text-transform:uppercase; letter-spacing:.5px; margin-bottom:4px; }

/* ═══ v0.1.10 — DRAG AND DROP ═══ */
#as-app .as-dragging { opacity:0.5; transform:rotate(1deg); }
#as-app .as-drag-over { background:var(--acl) !important; outline:2px dashed var(--ac); outline-offset:-2px; border-radius:var(--r); }
/* AS-0118: floating drop-time preview that follows the cursor during Day/
 * Week-timegrid/Month drag-drop (as-v-events.js's _asDragPreviewShow/Hide).
 * Fixed-position + pointer-events:none so it never intercepts the drag's own
 * dragover/drop targeting. */
#as-app .as-drag-ghost { position:absolute; left:2px; right:2px; z-index:6; box-sizing:border-box; border:2px dashed var(--ac); background:color-mix(in srgb,var(--ac) 18%,transparent); border-radius:var(--rs); pointer-events:none; font-size:11px; font-weight:700; color:var(--t1); padding:2px 6px; overflow:hidden; } /* AS-INBOX-046 */
#as-app .as-drag-preview { position:fixed; z-index:10005; background:var(--t1); color:var(--s); font-size:11px; font-weight:700; padding:3px 8px; border-radius:var(--r); pointer-events:none; box-shadow:0 2px 8px rgba(0,0,0,.2); white-space:nowrap; }
/* AS-0173: highlighted span shown inside a Day/Week time-grid column while
 * dragging out a new meeting (as-v-events.js's enableDragToCreate). Absolute
 * within the column (which is already position:relative), pointer-events:none
 * so it never itself becomes a mouse target mid-drag. */
#as-app .as-drag-create-ghost { position:absolute; left:2px; right:2px; background:var(--acl); border:1px dashed var(--ac); border-radius:var(--r); pointer-events:none; z-index:4; }
#as-app .as-kb-card[draggable="true"],
#as-app .as-pipe-card[draggable="true"],
#as-app .as-deal-card[draggable="true"] { cursor:grab; }
#as-app .as-kb-card[draggable="true"]:active,
#as-app .as-pipe-card[draggable="true"]:active,
#as-app .as-deal-card[draggable="true"]:active { cursor:grabbing; }

/* ═══ v0.1.10 — PRELOADER ═══ */
#as-app .as-preloader { display:flex; flex-direction:column; align-items:center; justify-content:center; padding:40px 20px; }
#as-app .as-spinner { width:24px; height:24px; border:2px solid var(--sa); border-top-color:var(--t2); border-radius:50%; animation:as-spin 1.1s linear infinite; } /* v0.8.50: slower + muted (Band A #4) */
/* v0.10.91: AS.miniBusy()'s corner spinner — a repeat-navigation feedback
   affordance (calendar/Split prev-next), smaller and more muted than the
   full .as-spinner used for first-load states. */
#as-app .as-mini-busy { position:absolute; top:6px; right:6px; z-index:6; pointer-events:none; }
#as-app .as-spinner-xs { width:13px; height:13px; border-width:2px; }
@keyframes as-spin { to { transform:rotate(360deg); } }

/* v0.10.146: shared "working" affordance — AS.coldState(), three dots
 * cycling through the app's existing blue/orange/green triad (reused here
 * as Know/Do/Measure). One primitive app-wide instead of the mix of
 * spinners, bars, and bare "Loading…" text that grew up view by view. */
#as-app .as-kdm-loading { gap:10px; padding:36px 20px; }
#as-app .as-kdm-dots { display:inline-flex; gap:6px; }
#as-app .as-kdm-dot { width:7px; height:7px; border-radius:50%; animation:as-kdm-pulse 1.35s ease-in-out infinite; }
#as-app .as-kdm-dot:nth-child(1) { background:var(--bl); animation-delay:0s; }
#as-app .as-kdm-dot:nth-child(2) { background:var(--ac); animation-delay:.18s; }
#as-app .as-kdm-dot:nth-child(3) { background:var(--gn); animation-delay:.36s; }
/* AS-0299: dots inline at the right edge of the Communications search box, and the Searching row. */
#as-app .as-search-dots { position:absolute; right:40px; top:50%; transform:translateY(-50%); pointer-events:none; display:inline-flex; }
#as-app .as-search-state { display:flex; align-items:center; gap:8px; border-radius:0; }
@keyframes as-kdm-pulse { 0%,80%,100% { opacity:.28; transform:scale(.72); } 40% { opacity:1; transform:scale(1); } }

/* ═══ v0.1.13 — STAGE DRAG REORDER ═══ */
#as-app .as-stage-grip { cursor:grab; font-size:14px; color:var(--t3); flex-shrink:0; user-select:none; padding:0 4px; line-height:1; }
#as-app .as-stage-grip:active { cursor:grabbing; }
#as-app .as-stage-row { transition:background .12s; }
#as-app .as-stage-row.as-dragging { opacity:.4; }
#as-app .as-stage-row.as-drag-insert { position:relative; }
#as-app .as-stage-row.as-drag-insert::before { content:''; position:absolute; left:0; right:0; height:2px; background:var(--ac); z-index:1; }
#as-app .as-stage-row.as-drag-insert[style*="--insert: top"]::before,
#as-app .as-stage-row.as-drag-insert[style*="--insert:top"]::before { top:0; }
#as-app .as-stage-row.as-drag-insert[style*="--insert: bottom"]::before,
#as-app .as-stage-row.as-drag-insert[style*="--insert:bottom"]::before { top:auto; bottom:0; }

/* ═══ v0.1.13 — CONTACT CARD VIEW ═══ */
#as-app .as-contact-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); gap:12px; padding:4px 0; }
#as-app .as-ccard {
    background:var(--s); border:1px solid var(--b); border-radius:var(--r); padding:14px;
    cursor:pointer; transition:border-color .12s,box-shadow .12s;
}
#as-app .as-ccard:hover { border-color:var(--ac); box-shadow:0 2px 8px rgba(0,0,0,.08); }
#as-app .as-ccard-top { display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:10px; }
#as-app .as-ccard-actions { display:flex; gap:3px; opacity:0; transition:opacity .12s; }
#as-app .as-ccard:hover .as-ccard-actions { opacity:1; }
#as-app .as-ccard-name { font-size:13px; font-weight:600; margin-bottom:2px; }
#as-app .as-ccard-co { font-size:11px; color:var(--t3); margin-bottom:6px; }
#as-app .as-ccard-badges { display:flex; gap:4px; flex-wrap:wrap; margin-bottom:6px; }
#as-app .as-ccard-email { font-size:10px; color:var(--t3); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* ═══ v0.1.14 — DASHBOARD SCHEDULE ═══ */
#as-app .as-dash-event { display:flex; align-items:center; gap:10px; padding:8px 0; border-bottom:1px solid var(--sa); cursor:pointer; transition:background .1s; }
#as-app .as-dash-event:last-child { border-bottom:none; }
#as-app .as-dash-event:hover { background:var(--sa); border-radius:var(--rs); }
#as-app .as-dash-event-time { font-size:11px; font-weight:700; color:var(--ac); min-width:60px; flex-shrink:0; }
#as-app .as-dash-event-info { flex:1; min-width:0; }

/* ═══ v0.1.14 — TASK COLUMNS ═══ */
/* v0.1.98: removed full 1px border on .as-task-cols > .trow — side borders cluttered the grid.
   Rows now separated by bottom border only; stale state shows via background tint + left accent. */
#as-app .as-task-cols { display:grid; grid-template-columns:1fr 1fr; gap:4px 16px; align-items:start; }
/* AS-0221 (Stage 3): each `>` direct-child selector below also matches
 * `.as-task-cols > .as-swipe-wrap > .trow` — taskRowSwipe() (as-v-tasks.js)
 * now wraps every row in .as-swipe-wrap for the swipe-to-Done gesture,
 * which pushes .trow one level deeper as a GRID CHILD (the wrap itself, an
 * ordinary block box, becomes the direct grid child instead). Without this
 * broadening, .trow would silently lose every one of these rules at desktop
 * widths — invisible in testing on a touch device (where the grid is
 * already single-column) but a real regression on desktop's 2/3-column
 * board. The wrap itself needs no grid-specific CSS: a block box is a
 * perfectly ordinary grid item, same as .trow was on its own before. */
#as-app .as-task-cols > .trow, #as-app .as-task-cols > .as-swipe-wrap > .trow { background:var(--s); border:none; border-bottom:1px solid var(--sa); padding:8px 12px; margin:0; flex-wrap:wrap; overflow:hidden; }
#as-app .as-task-cols > .trow .tinfo, #as-app .as-task-cols > .as-swipe-wrap > .trow .tinfo { min-width:0; overflow:hidden; }
#as-app .as-task-cols > .trow .ttitle, #as-app .as-task-cols > .as-swipe-wrap > .trow .ttitle { overflow:hidden; text-overflow:ellipsis; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
#as-app .as-task-cols > .trow .towner, #as-app .as-task-cols > .as-swipe-wrap > .trow .towner { max-width:120px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
@media(min-width:1400px) { #as-app .as-task-cols { grid-template-columns:1fr 1fr 1fr; } }
@media(max-width:900px) { #as-app .as-task-cols { grid-template-columns:1fr; } }

/* ═══ v0.1.98.1 — DUE-PROXIMITY DOT + OVERDUE ROW ═══ */
/* Replaces the old "STALE" text pill and red left-border system.
   Single small pill-sized dot next to the title signals due proximity; overdue tasks also get a red row bg. */
#as-app .as-due-dot {
    display:inline-block; width:8px; height:8px; border-radius:50%;
    margin-right:6px; vertical-align:middle; flex-shrink:0;
}
#as-app .as-due-dot-y { background:#E8B33A; }  /* yellow — more than 3 days out */
#as-app .as-due-dot-o { background:#D4740E; }  /* orange — 2–3 days out */
#as-app .as-due-dot-r { background:var(--rd); } /* red — 1 day or less, or overdue */

/* Overdue row/card: red background tint (only when past due date and not done) */
#as-app .trow.as-overdue,
#as-app .as-task-cols > .trow.as-overdue,
#as-app .as-task-cols > .as-swipe-wrap > .trow.as-overdue { background:var(--rdl); }

/* AS-0221 (Stage 3): List view's own swipe-left reveal — a single green
 * "Done" action (var(--gn), same as-swipe-act/.as-swipe-wrap/.as-swipe-
 * actions engine Comms/Events already use, see as-email.css's own
 * .as-swipe-resolve/.as-swipe-followup comments for the shared markup).
 * Green matches the approved mobile-forward prototype's Priorities
 * swipe-reveal color exactly (distinct from Comms' amber Follow-up —
 * colors are deliberately per-screen, not a shared palette). */
#as-app .as-swipe-done{background:var(--gn)}
#as-app .as-kb-card.as-overdue { background:var(--rdl); }

/* AS-0221 (Stage 4): Commissions ledger row — previously an ad hoc
 * all-inline-style flex row with fixed 90/80/220px columns that simply
 * overflowed a phone width (no CSS file backed it at all). Desktop layout
 * unchanged from the original inline values, now just expressed as classes
 * so a mobile breakpoint can actually target them. Swipe-left reveals
 * Void/Reopen (gray, .as-swipe-void) — the closest real analog to a
 * "Pause/Resume" toggle this ledger has (no pause-able state exists on a
 * commission entry); the desktop action-button column (.comm-row-acts)
 * hides at mobile widths since the same actions are reachable via swipe +
 * the new #as-performance-detail panel (as-v-commissions.js). */
#as-app .comm-row { display:flex; align-items:center; gap:12px; padding:10px 14px; border-bottom:1px solid var(--sa); }
#as-app .comm-row-main { flex:1; min-width:0; cursor:pointer; }
#as-app .comm-row-amt { font-size:14px; font-weight:700; min-width:90px; text-align:right; }
#as-app .comm-row-status { min-width:80px; }
#as-app .comm-row-acts { display:flex; gap:6px; flex-wrap:wrap; justify-content:flex-end; min-width:220px; }
#as-app .as-swipe-void{background:var(--t2)}
@media(max-width:768px) {
    #as-app .comm-row { flex-wrap:wrap; padding:10px 12px; }
    #as-app .comm-row-main { flex:1 1 100%; order:1; }
    #as-app .comm-row-amt { order:2; min-width:0; text-align:left; }
    #as-app .comm-row-status { order:3; }
    #as-app .comm-row-acts { display:none; }
}

/* AS-0221 (Stage 5): People — swipe-left "Log activity" mock (amber, matching
 * the approved prototype's People/Companies swipe color) and the contact
 * detail panel's real tel:/sms:/mailto: colored-circle affordances (call
 * green / text purple / email blue — same three-color convention as the
 * approved prototype's own row-acts, Glenn's explicit request). */
#as-app .as-swipe-log{background:var(--am)}
#as-app .as-contact-acts{display:flex;gap:7px;flex-shrink:0}
#as-app .as-contact-act{width:29px;height:29px;border-radius:50%;border:1px solid var(--b);display:flex;align-items:center;justify-content:center;color:#fff;text-decoration:none;flex-shrink:0}
#as-app .as-contact-act.call{background:var(--gn);border-color:var(--gn)}
#as-app .as-contact-act.sms{background:var(--pu);border-color:var(--pu)}
#as-app .as-contact-act.mailto{background:var(--bl);border-color:var(--bl)}

/* Legacy .as-stale — kept as no-op alias so any external callers don't error; visuals handled by dot/overdue. */
#as-app .as-stale { }
#as-app .as-kb-card.as-stale { }

/* ═══ v0.1.14 — SETTINGS TABS ═══ */
#as-app .as-stab { }

/* ═══ v0.1.14 — ZOOM LINK ═══ */
/* v0.10.101 (punchlist #4): matches .as-meet-link's own margin-top bump. */
#as-app .as-zoom-link {
    display:inline-block; margin-top:8px; margin-left:4px; font-size:11px; font-weight:600;
    color:#2D8CFF; text-decoration:none; padding:2px 8px;
    background:#EBF3FF; border-radius:4px;
}
#as-app .as-zoom-link:hover { background:#2D8CFF; color:#FFF; }

/* ═══ v0.1.13 — MOBILE RESPONSIVE ═══ */
#as-app .as-hamburger { display:none; }

/* ═══ DASHBOARD v0.1.15 — Metric Cards ═══ */
#as-app .as-metrics { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:20px; }
#as-app .as-mc { background:var(--s); border:1px solid var(--b); border-radius:var(--r); padding:16px; }
#as-app .as-mc-label { font-size:10px; color:var(--t3); text-transform:uppercase; letter-spacing:.6px; font-weight:600; margin-bottom:6px; display:flex; align-items:center; gap:6px; }
#as-app .as-mc-dot { width:7px; height:7px; border-radius:50%; }
#as-app .as-mc-value { font-family:Georgia,serif; font-size:28px; font-weight:700; line-height:1; }
#as-app .as-mc-event-title { font-size:14px; font-weight:600; line-height:1.3; }
#as-app .as-mc-detail { font-size:11px; color:var(--t3); margin-top:4px; font-weight:500; }
#as-app .as-mc-pbar { width:100%; height:5px; background:var(--sa); border-radius:3px; margin-top:6px; overflow:hidden; }
#as-app .as-mc-pfill { height:100%; border-radius:3px; transition:width .4s ease; }
/* v0.9.30: clickable metric cards (hover shows a → arrow, no View button) */
#as-app .as-mc-click { cursor:pointer; position:relative; transition:border-color .12s, box-shadow .12s, transform .12s; }
#as-app .as-mc-click:hover { border-color:#d9dce2; box-shadow:0 2px 8px rgba(0,0,0,.06); transform:translateY(-1px); }
#as-app .as-mc-go { position:absolute; top:13px; right:14px; color:var(--t3); font-size:14px; opacity:0; transition:opacity .12s; }
#as-app .as-mc-click:hover .as-mc-go { opacity:1; }
/* v0.9.30: Today's Focus card — accent + section groups + appointments line */
#as-app .as-focus-card { border-top:2px solid var(--ac); }
#as-app .as-focus-grp { font-size:9px; font-weight:700; text-transform:uppercase; letter-spacing:.6px; color:var(--t3); margin:12px 0 2px; }
#as-app .cb > .as-focus-grp:first-child { margin-top:0; }
#as-app .as-focus-tag { font-size:8.5px; font-weight:700; text-transform:uppercase; letter-spacing:.3px; padding:1px 6px; margin-left:2px; }
#as-app .as-focus-appts { display:flex; align-items:center; gap:8px; padding:11px 0 3px; margin-top:8px; border-top:1px solid var(--sa); font-size:12px; color:var(--t2); cursor:pointer; }
#as-app .as-focus-appts:hover { color:var(--ac); }
#as-app .as-focus-appts .as-focus-appts-arr { margin-left:auto; color:var(--t3); font-size:14px; }
#as-app .as-focus-appts:hover .as-focus-appts-arr { color:var(--ac); }
#as-app .as-focus-appts-empty { cursor:default; color:var(--t3); }
#as-app .as-focus-appts-empty:hover { color:var(--t3); }

/* ═══ DASHBOARD v0.1.15 — Schedule ═══ */
#as-app .as-sched-row { display:flex; align-items:center; gap:12px; padding:8px 0; border-bottom:1px solid var(--sa); }
#as-app .as-sched-row:last-child { border-bottom:none; }
#as-app .as-sched-time { font-size:11px; font-weight:700; color:var(--ac); min-width:64px; flex-shrink:0; }
#as-app .as-sched-info { flex:1; min-width:0; }
#as-app .as-sched-title { font-size:12px; font-weight:600; }
#as-app .as-sched-meta { font-size:10px; color:var(--t3); }
#as-app .as-sched-divider { border:none; border-top:1px dashed var(--b); margin:8px 0; }
#as-app .as-sched-divider-label { font-size:9px; color:var(--t3); text-transform:uppercase; letter-spacing:.5px; font-weight:600; }
#as-app .as-meet-btn { font-size:9px; font-weight:600; color:var(--bl); background:var(--bll); padding:3px 8px; border-radius:4px; text-decoration:none; flex-shrink:0; }
#as-app .as-meet-btn:hover { background:var(--bl); color:#FFF; }
#as-app .as-zoom-btn { font-size:9px; font-weight:600; color:#2D8CFF; background:#EBF3FF; padding:3px 8px; border-radius:4px; text-decoration:none; flex-shrink:0; }
#as-app .as-zoom-btn:hover { background:#2D8CFF; color:#FFF; }
#as-app .as-dash-more { font-size:11px; color:var(--t3); padding:8px 0; }

/* ═══ DASHBOARD v0.1.15 — Team Snapshot ═══ */
#as-app .as-snap-section-label { font-size:10px; font-weight:600; color:var(--t3); text-transform:uppercase; letter-spacing:.5px; margin-bottom:8px; }
#as-app .as-team-row { display:flex; align-items:center; gap:10px; padding:6px 0; }
#as-app .as-team-av { width:24px; height:24px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:9px; font-weight:700; color:#FFF; flex-shrink:0; }
#as-app .as-team-name { font-size:12px; font-weight:500; width:80px; }
#as-app .as-team-count { font-size:10px; color:var(--t3); width:50px; text-align:right; }
#as-app .as-team-bar { flex:1; height:8px; background:var(--sa); border-radius:4px; overflow:hidden; }
#as-app .as-team-fill { height:100%; border-radius:4px; transition:width .4s ease; }

/* ═══ DASHBOARD v0.1.15 — Pipeline Shape ═══ */
#as-app .as-pipe-shape { display:flex; gap:4px; margin-top:4px; }
#as-app .as-pipe-stage { flex:1; text-align:center; padding:8px 4px; border-radius:var(--rs); }
#as-app .as-pipe-num { font-family:Georgia,serif; font-size:16px; font-weight:700; display:block; }
#as-app .as-pipe-lbl { font-size:7px; text-transform:uppercase; letter-spacing:.5px; font-weight:600; display:block; margin-top:1px; }

/* ═══ DASHBOARD v0.1.15 — Quick Actions ═══ */
#as-app .as-quick-actions { display:flex; gap:8px; justify-content:center; margin-top:16px; padding:12px 0; }

/* ═══ DASHBOARD v0.1.15 — Pipeline Alerts ═══ */
#as-app .as-alert-row { display:flex; align-items:center; gap:8px; padding:5px 0; cursor:pointer; border-bottom:1px solid var(--sa); transition:background .1s; }
#as-app .as-alert-row:last-child { border-bottom:none; }
#as-app .as-alert-row:hover { background:var(--sa); border-radius:var(--rs); }
#as-app .as-alert-dot { width:6px; height:6px; border-radius:50%; flex-shrink:0; }
#as-app .as-alert-info { flex:1; min-width:0; }
#as-app .as-alert-name { font-size:12px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#as-app .as-alert-meta { font-size:10px; color:var(--t3); }

/* ═══ DASHBOARD v0.1.15 — Weekly Progress ═══ */
#as-app .as-streak { font-size:12px; font-weight:700; color:var(--ac); margin-bottom:8px; }
#as-app .as-streak-fire { font-size:14px; }
#as-app .as-wp-mini { display:flex; align-items:center; gap:6px; padding:3px 0; }
#as-app .as-wp-mini-label { font-size:10px; font-weight:600; color:var(--t2); width:36px; flex-shrink:0; }
#as-app .as-wp-mini-bar { flex:1; height:6px; background:var(--sa); border-radius:3px; overflow:hidden; }
#as-app .as-wp-mini-fill { height:100%; border-radius:3px; transition:width .4s ease; }
#as-app .as-wp-mini-pct { font-size:10px; font-weight:700; width:28px; text-align:right; flex-shrink:0; }
#as-app .as-wp-mini-count { font-size:9px; color:var(--t3); width:30px; flex-shrink:0; }

/* ═══ THREE-COLUMN GRID ═══ */
#as-app .g3 { display:grid; grid-template-columns:1fr 1fr 1fr; gap:16px; margin-bottom:16px; align-items:stretch; }
#as-app .g3 > div { display:flex; flex-direction:column; }
#as-app .g3 > .card { display:flex; flex-direction:column; }
#as-app .g3 > div > .card { flex:1; display:flex; flex-direction:column; }
#as-app .g3 > .card > .cb, #as-app .g3 > div > .card > .cb { flex:1; overflow-y:auto; max-height:500px; }

/* ═══ CALENDAR — Month View (toolbar-doctrine-v2 pixel-match pass,
   2026-08-16, against _prototypes/as-communications/index.html's .mgrid/
   .mdow/.mcell/.mev — see that file's <style> block for the source values).
   Event-chip border-radius dropped to 0 everywhere below, not just to match
   the mock — the app's own tokens are --r:0;--rs:0 (square, no radius) and
   these rules were hardcoding a radius in violation of that doctrine. ═══ */
/* AS-0222: month grid cell padding/row-height/typography brought up to the
   same breathing-room scale AS-0221 established for the mobile shell/More
   sheet and Comms (assets/css/actionstudio.css ~1916-1950 pre-existing —
   16px outer / 13-14px row padding / 12px gaps / 10-11px section labels,
   .as-more-row etc.) — this grid was still on the old dense v0.10-era
   values (5px/6px cell padding, 9-9.5px event type, 1px/4px "+more"). Values
   below are the closest matches ALREADY IN USE elsewhere in this file
   (.as-more-hd padding 6px 16px 10px, .as-dash-more font-size:11px, task/
   list row padding patterns), not new invented tokens — this app has no
   --sp* or --gap* spacing-token scale (confirmed: grep for one across
   mia/dev-os + mia/spl/symphony and this repo turned up nothing), so
   "reuse the scale" means reuse these existing literal values consistently. */
#as-app .as-cal-header { display:grid; grid-template-columns:repeat(7,1fr); background:var(--sa); border-radius:var(--rs) var(--rs) 0 0; }
#as-app .as-cal-hcell { padding:10px 6px; text-align:center; font-size:10px; font-weight:700; color:var(--t3); text-transform:uppercase; letter-spacing:.5px; border-bottom:1px solid var(--b); border-right:1px solid var(--b2); }
#as-app .as-cal-hcell:last-child { border-right:none; }
#as-app .as-cal-body { display:grid; grid-template-columns:repeat(7,1fr); border:1px solid var(--b); border-top:none; border-radius:0 0 var(--rs) var(--rs); overflow:hidden; }
#as-app .as-cal-cell { min-height:112px; padding:8px 8px; border-right:1px solid var(--b2); border-bottom:1px solid var(--b); background:var(--s); transition:background .1s; }
#as-app .as-cal-cell:nth-child(7n) { border-right:none; }
#as-app .as-cal-cell:hover { background:var(--sa); }
#as-app .as-cal-other { opacity:.4; }
#as-app .as-cal-day { font-size:12px; font-weight:700; color:var(--t2); margin-bottom:5px; }
/* AS-0184 (2026-09-18): the filled circle read too close to a "selected"
   state and was easy to miss at a glance, especially small — Glenn's
   direction: bold accent-colored number, no fill/circle/ring, plus a small
   caret pointing at it. Same treatment at every other place "today" is
   marked — see .as-cal-ws-day.as-cal-ws-today (week mobile day-strip) and
   .asd-cal-today (List/Split mini-cal) below. */
#as-app .as-cal-today .as-cal-day { background:none; color:var(--ac); display:inline-block; position:relative; padding-bottom:5px; }
#as-app .as-cal-today .as-cal-day::after { content:''; position:absolute; bottom:0; left:50%; transform:translateX(-50%); width:0; height:0; border-style:solid; border-width:4px 3.5px 0 3.5px; border-color:var(--ac) transparent transparent transparent; }
#as-app .as-cal-evt { font-size:10.5px; font-weight:600; color:var(--t1); padding:3px 6px; margin-bottom:3px; border-radius:0; background:var(--sa); border-left:2px solid var(--ac); cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#as-app .as-cal-evt:hover { background:var(--b); }
#as-app .as-cal-evt-time { font-weight:700; color:var(--ac); }
/* AS-0222: was a bare 9px/1px-4px afterthought line — brought up to the same
   "+N more"/overflow-affordance treatment as .as-dash-more elsewhere in this
   file (font-size:11px, color:var(--t3), breathing padding) plus a hover
   state since, like .as-cal-evt above it, it's a click target (opens that
   day). */
#as-app .as-cal-more { font-size:11px; color:var(--t3); padding:3px 6px; margin-top:1px; font-weight:600; cursor:pointer; border-radius:0; }
#as-app .as-cal-more:hover { background:var(--b); color:var(--t2); }

/* ═══ CALENDAR — List view mini calendar (v0.10.49, per
   _prototypes/as-communications/index.html's .callist/.calleft/.calright/
   .cal-* — the List view previously had no calendar companion at all). ═══ */
#as-app .as-evl-wrap { display:flex; gap:16px; align-items:flex-start; }
#as-app .as-evl-side { flex:0 0 288px; }
#as-app .as-evl-main { flex:1; min-width:0; }

/* AS-0055 [stale id — see AS-0159-0166, not AS-0054/55/56/57] (mobile Communications build, 2026-09-11): mobile-only 7-day
   week-strip, hidden on desktop where the month mini-cal above still shows —
   flipped by the 768px block below. Pill styling matches the mobile-audit
   prototype's .cal-week/.cal-day (day-of-week letter + date number, the
   selected day filled solid), scaled to this app's --ac/--t tokens instead of
   the prototype's placeholder palette. */
#as-app .as-cal-weekstrip-card { display:none; }
#as-app .as-cal-ws-hd { display:flex; align-items:center; justify-content:space-between; padding:2px 2px 8px; }
#as-app .as-cal-ws-month { font-size:12px; font-weight:700; }
#as-app .as-cal-ws-days { display:flex; gap:4px; }
#as-app .as-cal-ws-day { flex:1; display:flex; flex-direction:column; align-items:center; gap:2px; padding:6px 0; border:none; background:none; cursor:pointer; }
#as-app .as-cal-ws-day .dn { font-size:9px; font-weight:700; text-transform:uppercase; color:var(--t3); }
#as-app .as-cal-ws-day .dd { font-size:13px; font-weight:700; color:var(--t1); width:24px; height:24px; line-height:24px; border-radius:50%; }
#as-app .as-cal-ws-day.as-cal-ws-today .dd { color:var(--ac); }
#as-app .as-cal-ws-day.as-cal-ws-on .dd { background:var(--t1); color:#fff; }
#as-app .as-cal-ws-day.as-cal-ws-on.as-cal-ws-today .dd { background:var(--ac); }
/* AS-0184: caret under today's number, same idea as the Month grid above.
   .as-cal-ws-day is already flex-direction:column, so this ::after just
   becomes another stacked item below .dd — no absolute positioning needed. */
#as-app .as-cal-ws-day.as-cal-ws-today::after { content:''; width:0; height:0; border-style:solid; border-width:4px 3.5px 0 3.5px; border-color:var(--ac) transparent transparent transparent; margin-top:1px; }

/* v0.10.56: AI "Suggested — from email" sidebar box (punch-list item 8),
   per _prototypes/as-communications/index.html's .calbox/.sug/.sgb — reuses
   the app's own .card/.cb shell (identical shape to the mock's .calbox)
   rather than a second copy of that container. */
#as-app .as-ai-sug-h { display:flex; align-items:center; gap:5px; font-size:9.5px; letter-spacing:.8px; text-transform:uppercase; color:var(--t3); font-weight:700; margin-bottom:10px; }
#as-app .as-ai-sug-h svg { color:var(--ac); flex-shrink:0; }
#as-app .as-ai-sug { padding:10px 0; border-top:1px solid var(--b2); }
#as-app .as-ai-sug:first-child { border-top:none; padding-top:0; }
#as-app .as-ai-sug-t { font-size:12px; font-weight:700; color:var(--t1); }
#as-app .as-ai-sug-w { font-size:10.5px; color:var(--t3); margin-top:2px; line-height:1.4; }
#as-app .as-ai-sug-a { display:flex; gap:6px; margin-top:8px; }
#as-app .as-ai-sug-btn { height:26px; padding:0 11px; font-size:10.5px; font-weight:600; border:1px solid var(--b); border-radius:var(--rs); background:var(--s); color:var(--t2); cursor:pointer; transition:all .12s; font-family:inherit; }
#as-app .as-ai-sug-btn.p { background:var(--ac); color:#fff; border-color:var(--ac); }
#as-app .as-ai-sug-btn:hover { border-color:var(--ac); color:var(--ac); }
#as-app .as-ai-sug-btn.p:hover { background:var(--ach); color:#fff; }
#as-app .as-mcal-nav { display:flex; align-items:center; justify-content:space-between; margin-bottom:8px; }
#as-app .as-mcal-nav .asd-cal-hd { margin-bottom:0; flex:1; }
#as-app .as-mcal-nav button { line-height:1; }
/* v0.10.113: quiet "Go to today" escape hatch under the mini-cal grid — a
   fast way back to the current month/day without paging through months. */
#as-app .as-mcal-today-link { display:block; width:100%; margin-top:6px; padding:5px 0; border:none; background:none; color:var(--t3); font-size:11px; font-weight:600; text-align:center; cursor:pointer; border-radius:var(--rs); }
#as-app .as-mcal-today-link:hover { color:var(--ac); background:var(--sa); }
/* v0.10.90: also matched under #as-comms-panel-triage — Split's mini-cal
   (loadSplitMiniCal(), as-v-events.js) paints the exact same .asd-cal-*
   markup as List view's, just into a different DOM id, so its styling is
   shared here rather than duplicated. */
#as-app #as-comms-panel-cal .asd-cal-hd, #as-app #as-comms-panel-triage .asd-cal-hd { font-weight:700; font-size:13px; text-align:center; display:block; }
#as-app #as-comms-panel-cal .asd-cal-grid, #as-app #as-comms-panel-triage .asd-cal-grid { display:grid; grid-template-columns:repeat(7,1fr); gap:2px; text-align:center; }
#as-app #as-comms-panel-cal .asd-cal-dow, #as-app #as-comms-panel-triage .asd-cal-dow { font-size:9px; color:var(--t3); font-weight:700; padding-bottom:4px; display:block; }
#as-app #as-comms-panel-cal .asd-cal-c, #as-app #as-comms-panel-triage .asd-cal-c { position:relative; padding:6px 0; font-size:11px; color:var(--t2); cursor:pointer; display:block; border-radius:0; }
#as-app #as-comms-panel-cal .asd-cal-c:hover, #as-app #as-comms-panel-triage .asd-cal-c:hover { background:var(--sa); }
/* AS-0184: same "no fill, bold accent number + caret" treatment as the
   Month grid/week-strip above. The old filled-circle version needed a
   dedicated :hover override (removed below) and flipped .asd-cal-dot white
   for contrast against the fill (removed too) — neither is needed once
   there's no fill; .asd-cal-c:hover's plain var(--sa) already applies. */
#as-app #as-comms-panel-cal .asd-cal-today, #as-app #as-comms-panel-triage .asd-cal-today { background:none; color:var(--ac); font-weight:700; }
#as-app #as-comms-panel-cal .asd-cal-today::after, #as-app #as-comms-panel-triage .asd-cal-today::after { content:''; position:absolute; bottom:1px; left:50%; transform:translateX(-50%); width:0; height:0; border-style:solid; border-width:4px 3.5px 0 3.5px; border-color:var(--ac) transparent transparent transparent; }
#as-app #as-comms-panel-cal .asd-cal-dot, #as-app #as-comms-panel-triage .asd-cal-dot { position:absolute; bottom:2px; left:50%; transform:translateX(-50%); width:3px; height:3px; border-radius:50%; background:var(--gn); }
/* Nudge the "has events" dot up so it clears the today-caret above when a
   day is both. */
#as-app #as-comms-panel-cal .asd-cal-today .asd-cal-dot, #as-app #as-comms-panel-triage .asd-cal-today .asd-cal-dot { bottom:7px; }
#as-app #as-comms-panel-cal .asd-cal-x, #as-app #as-comms-panel-triage .asd-cal-x { visibility:hidden; cursor:default; }
/* v0.10.55: "selected" (day-filtered) is a distinct state from "today" —
   an outline ring rather than a filled background, so both can be visibly
   different when the same cell is both today and selected. */
#as-app #as-comms-panel-cal .asd-cal-selected { box-shadow:inset 0 0 0 1.5px var(--ac); font-weight:700; }
/* v0.10.78: dropped the "Full day view"/"Clear" action buttons this header
   used to carry — the mini-cal's own day-click toggle covers "Clear", and
   Day view is one click away via the view-tabs above. Today gets a small
   accent + a secondary date line so the default landing state reads as an
   intentional "today" card rather than a generic filtered-date header.
   v0.10.101 (punchlist #3): the solid background fill read as a "strong
   color band" spanning the full row — dropped in favor of the border-bottom
   already present (a plain, subtle line does the same "separates header
   from list" job without the block-of-color weight). "Today" bumped to a
   real heading size; the date sub-label stays at its existing smaller size
   (unchanged) so the two stay proportional to each other. */
#as-app #as-comms-panel-cal .as-evl-filter-head { display:flex; align-items:baseline; gap:8px; padding:10px 12px; border-bottom:1px solid var(--b); font-size:13px; }
#as-app #as-comms-panel-cal .as-evl-filter-head-today b { color:var(--ac); font-size:17px; }
#as-app #as-comms-panel-cal .as-evl-filter-sub { color:var(--t3); font-size:11.5px; }

/* ═══ Communications — Split triage mode (v0.10.90), third mode alongside
   Email/Calendar. Left = "Needs your response" priority list; right = the
   mini-cal + a notes stub (row 1), a day-nav'd Today list (row 2). Internal
   identifier is "triage" — data-comms-mode="triage", #as-comms-panel-triage
   — to avoid colliding with the unrelated asToggleSplit()/
   .as-split-horizontal concept (the email list/preview pane split within
   Email mode itself); visible label stays "Split". Per
   _prototypes/as-communications/index.html §6. ═══ */
/* Edge-to-edge margin cancel + its own padding-back live in as-email.css
   (v0.10.31's established convention for #as-comms-panel-email/-cal) —
   this just adds the fixed-height, independently-scrolling-columns part
   Split shares with Email's own .as-email-wrap. */
#as-app #as-comms-panel-triage { height:calc(100vh - 52px); box-sizing:border-box; overflow:hidden; }
#as-app .as-triage-wrap { display:flex; gap:16px; align-items:stretch; height:100%; }
#as-app .as-triage-left { flex:0 0 400px; display:flex; flex-direction:column; background:var(--s); border:1px solid var(--b); border-radius:var(--r); overflow:hidden; }
/* v0.10.94: left column split into two stacked sections (Inbox, Follow-up)
 * — replaces the old single Priority/Starred/All-filtered list. Inbox is
 * capped, not flex:1, so Follow-up is always visible below it without
 * scrolling past a long inbox first (Glenn: "top should be inbox... maybe
 * there's a scroll there... below that should be another one that is
 * flagged"); ~340px comfortably shows the "5 or 6, 8 messages" he described
 * before its own internal scrollbar kicks in. */
#as-app .as-triage-section { display:flex; flex-direction:column; min-height:0; }
/* v0.10.95: Glenn — the boundary between Inbox and Follow-up was too subtle
 * when Inbox has fewer rows than its 340px cap (the common case): the
 * section's own border-bottom sat flush against the last row with no
 * breathing room, and var(--b2) is a deliberately faint token (label
 * hairlines), easy to miss entirely. Padding above/below + the stronger
 * var(--b) token (this column's own outer border) make it read as a real
 * divider rather than a rendering artifact. */
#as-app .as-triage-section-inbox { flex:0 0 auto; max-height:340px; border-bottom:1px solid var(--b); padding-bottom:8px; }
#as-app .as-triage-section-followup { flex:1; min-height:0; margin-top:8px; }
#as-app .as-triage-hd { padding:14px 16px 11px; border-bottom:1px solid var(--b2); flex:0 0 auto; }
#as-app .as-triage-hd h4 { font-size:15px; font-weight:700; margin-bottom:0; }
/* AS-0187: chevron icon markup exists on both Inbox/Follow-up headers at
   every width (templates/admin-app.php), but stays hidden here by default
   — desktop has no collapse behavior, so nothing about its header should
   look or act any different than before. The 768px mobile block below
   turns it back on, alongside the actual collapse/tap-affordance rules. */
#as-app .as-triage-chev { display:none; }
/* v0.10.113: quiet inline count next to a section title (Split's Follow-up
   header here; Email mode's own Follow-up box reuses the same class) —
   Glenn: "we don't need a big red badge... just the number, quietly." */
#as-app .as-count-quiet { font-size:12px; font-weight:600; color:var(--t3); }
#as-app .as-triage-list { flex:1; overflow-y:auto; }
/* Triage rows reuse .as-email-row/.as-email-avatar/etc. (as-email.css) as-is
   — only the narrow-column wrap treatment is borrowed from
   .as-split-vertical's own 360px-column rules (as-email.css), the closest
   existing "compact inbox row" precedent, rather than inventing a new one. */
#as-app .as-triage-list .as-email-row { flex-wrap:wrap; padding:6px 10px; }
#as-app .as-triage-list .as-email-subject { width:100%; order:10; padding-left:38px; margin-top:2px; font-size:11px; }
#as-app .as-triage-list .as-email-from { flex:1; width:auto; }
#as-app .as-triage-list .as-email-snippet { display:none; }
/* v0.10.113: quiet "View all" hand-off at the bottom of Split's (capped,
   see fetchSplitAll()) Inbox list, over to the full Email view's own
   completely-paginated inbox (v0.10.112).
   v0.10.147: sticky to the bottom of the scrollable list (Glenn: it should
   stay "always visible", not require scrolling to the true end) — needs its
   own opaque background (var(--s), the card surface token) so rows don't
   show through underneath it while scrolling.
   v0.10.205 (AS-0097): "View all" is now a real child of .as-split-listfoot
   (fixed a DOM-nesting bug that made it render as a sibling and wrap onto
   its own line — see as-email.js) sharing ONE row with the unread toggle
   and "View more". The sticky/opaque "always visible" treatment moved up
   to .as-split-listfoot itself below, since that's now the element pinned
   to the bottom of the scrollable list — this button no longer needs its
   own sticky positioning or opaque background, just enough padding to stay
   comfortably clickable at its natural (no longer full-width) size. */
#as-app .as-split-viewall-btn { display:inline-block; width:auto; margin:0; padding:6px 2px; border:none; background:transparent; color:var(--t3); font-size:11px; font-weight:600; text-align:center; cursor:pointer; white-space:nowrap; }
#as-app .as-split-viewall-btn:hover { color:var(--ac); }
/* v0.10.164 (AS-0072): "Unread only" toggle, relocated out of the Inbox
   panel's header row (was a bordered checkbox+label there — Glenn: "a big
   checkbox is a little unsightly") down next to the "View all" hand-off.
   v0.10.205 (AS-0097): now shares ONE row with "View more" and "View all"
   (was stacked above them) via flex on .as-split-listfoot; that container
   carries the sticky/opaque "always visible without scrolling to the true
   end" treatment that used to live on .as-split-viewall-btn alone
   (v0.10.147) — the whole row is pinned now, not just View all, since all
   three controls share it. The `> * + *` rule draws a "|" divider only
   between controls that are actually present as DOM children (adjacent-
   sibling selector), so the empty-state case (unread toggle alone, no
   viewMore/viewAll — see as-email.js ~line 374) and the "nothing left to
   page in" case (toggle + View all, no View more) never show a stray
   divider next to a missing control. */
/* v0.10.217 (AS-0102): dropped the checkbox+label markup entirely — Glenn
   wanted all three listfoot controls to look visually consistent, not just
   co-located. Now a plain clickable word matching .as-split-viewmore-btn/
   .as-split-viewall-btn's exact box model, same base color (var(--t3)).
   Since there's no checkbox left to show on/off state, .is-active (toggled
   in as-email.js alongside splitFilterUnread) tints it with the accent
   color while the filter is on — the only remaining "is this active"
   signal, so don't drop it without replacing it with something else. */
#as-app .as-split-unread-toggle { display:inline-block; width:auto; margin:0; padding:6px 2px; border:none; background:transparent; color:var(--t3); font-size:11px; font-weight:600; text-align:center; cursor:pointer; white-space:nowrap; }
#as-app .as-split-unread-toggle:hover { color:var(--ac); }
#as-app .as-split-unread-toggle.is-active { color:var(--ac); }
/* v0.10.193 (AS-0068): "View more" — deliberately distinct from "View all"
   next to it: it grows the in-place list (see as-email.js), while View all
   hands off to the full Email view.
   v0.10.205 (AS-0097): now an inline control in the shared listfoot row
   rather than its own full-width block — see .as-split-listfoot above.
   v0.10.217 (AS-0102): was color:var(--ac) (orange accent), making it look
   like the odd one out next to the now-gray unread toggle and the
   already-gray View all — changed to var(--t3) so all three match. */
#as-app .as-split-viewmore-btn { display:inline-block; width:auto; margin:0; padding:6px 2px; border:none; background:transparent; color:var(--t3); font-size:11px; font-weight:600; text-align:center; cursor:pointer; white-space:nowrap; }
#as-app .as-split-viewmore-btn:hover { text-decoration:underline; }
/* v0.10.218 (AS-0102 follow-up, found during its own live-walk): moved
   below all three listfoot controls so this divider rule's border-left
   consistently wins same-specificity source-order against every control's
   own border:none reset — previously only View all (positioned before
   this rule) got its divider; Unread-toggle and View-more, positioned
   after, had their border:none win instead, silently dropping the bar. */
/* v0.10.221 (AS-0107): Glenn — the row (Unread/View more/View all) read as
   left-aligned under the Inbox column and its own box felt "a little bit
   too thick." justify-content:center centers the row itself (the controls'
   own internal gap/dividers are unchanged); padding trimmed 6px->4px
   top/bottom only — a small reduction, not the drastic full removal that
   would make the row feel cramped against the list above it. Left/right
   padding (10px) untouched; it isn't part of what Glenn flagged. A
   hover-to-reveal treatment was floated live but explicitly as an unsure
   idea ("that might mess it up or make it worse") — not implemented. */
#as-app .as-split-listfoot { display:flex; align-items:center; justify-content:center; gap:0; padding:4px 10px; position:sticky; bottom:0; z-index:1; background:var(--s); border-radius:var(--rs); }
#as-app .as-split-listfoot > * + * { margin-left:10px; padding-left:10px; border-left:1px solid var(--b); }
#as-app .as-triage-right { flex:1; min-width:0; display:flex; flex-direction:column; gap:16px; overflow-y:auto; }
#as-app .as-triage-row1 { display:flex; gap:14px; flex:0 0 auto; }
#as-app .as-triage-row1 > .card { margin-bottom:0; }
#as-app .as-triage-mini { flex:0 0 320px; }
#as-app .as-triage-notes { flex:1; min-width:0; }
#as-app .as-triage-row2 { flex:1; min-width:0; display:flex; flex-direction:column; min-height:0; }
#as-app .as-triage-row2 > .card { margin-bottom:0; }
/* v0.10.94: Glenn — "too much space between the arrows for today and the
 * list below." Was margin-bottom:10px on the bar + the .cb card's own
 * 14px top padding underneath = 24px of dead vertical space before the
 * first event card. min-width:130px on the label (below) existed to keep
 * the ‹ › arrows from jumping around as the label text changed length —
 * dropped now that the label never carries a redundant date (just "Today"/
 * "Tomorrow"/weekday), so it can hug the arrows instead of padding the bar. */
#as-app .as-triage-daybar { display:flex; align-items:center; gap:10px; margin-bottom:2px; flex:0 0 auto; }
#as-app .as-triage-daytitle { font-size:14px; font-weight:700; }
#as-app .as-triage-today { flex:1; overflow-y:auto; padding-top:2px; }
#as-app .as-triage-note-empty { padding:20px 4px; text-align:center; color:var(--t3); font-size:12px; line-height:1.5; }
/* v0.10.91: "Recent notes & meetings" cards — real Gemini/Fireflies recap
   emails (window.asLoadSplitNotes, as-email.js), styled after the prototype's
   own .note/.ic/.bd/.tt/.wt/.sm/.lk shape (_prototypes/as-communications/
   index.html §6) rather than a new pattern. */
#as-app #as-split-notes { max-height:260px; overflow-y:auto; }
#as-app .as-triage-note { display:flex; gap:10px; padding:10px 0; border-top:1px solid var(--b2); cursor:pointer; }
#as-app .as-triage-note:first-child { border-top:none; padding-top:0; }
#as-app .as-triage-note-ic { width:28px; height:28px; flex:0 0 auto; background:var(--gnl); color:var(--gn); border-radius:var(--rs); display:flex; align-items:center; justify-content:center; }
#as-app .as-triage-note-bd { flex:1; min-width:0; }
#as-app .as-triage-note-tt { font-size:12px; font-weight:700; color:var(--t1); }
#as-app .as-triage-note-wt { font-size:10.5px; color:var(--t3); margin-top:1px; }
#as-app .as-triage-note-sm { font-size:10.5px; color:var(--t2); margin-top:4px; line-height:1.4; overflow:hidden; text-overflow:ellipsis; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
#as-app .as-triage-note-lk { font-size:10.5px; color:var(--ac); font-weight:600; margin-top:5px; display:inline-block; }
#as-app .as-triage-note:hover .as-triage-note-lk { color:var(--ach); }
@media (max-width:1150px) { #as-app .as-triage-left { flex:0 0 320px; } #as-app .as-triage-row1 { flex-direction:column; } #as-app .as-triage-mini { flex:0 0 auto; } }

/* ═══ CALENDAR — Toolbar (v0.10.103, punch-list item 9; redesigned AS-0065) ═══
 * Concept C ("minimal command bar") layout pass: borderless icon nav +
 * a single Filters popover in the subheader (built dynamically by
 * asCalToggleFilter() in as-v-events.js — reuses .as-email-dropdown, no new
 * popover CSS needed) replacing the 3 duplicated inline checkbox+select
 * bars this block used to style. Stays inside the existing type system
 * (Source Sans 3, existing --t1/--t2/--t3/--b tokens) — no new fonts.
 *
 * AS-0065 (2026-08-30): nav/label/Today moved out of their own row
 * (#as-cal-nav) into the shared subheader (#as-comms-cal-nav, in
 * templates/admin-app.php next to #as-comms-mode-seg). #as-comms-toolbar
 * gets position:relative so #as-cal-label can center against the WHOLE
 * toolbar width via absolute positioning, independent of the nav
 * cluster's own width on either side — see the mobile override below for
 * why that trick is turned off at narrow widths. */
#as-app #as-comms-toolbar { position:relative; }
#as-app .as-cal-nav-group { display:flex; align-items:center; gap:1px; }
/* .as-cal-nav-btn still styles Split's day-nav buttons (.as-triage-daybar,
 * asSplitDayNav) — that pair wasn't part of this pass, keep its padding. */
#as-app .as-cal-nav-btn { padding:4px 8px; }
/* AS-0188 desktop (2026-09-18): was 26x26px — the shortest control in this
 * subheader row, sitting well under the Compose/mode-seg/sync neighbors'
 * 34px. Grown to match; same borderless icon-only look, just a bigger box. */
#as-app .as-cal-nav-arrow { width:34px; height:34px; display:flex; align-items:center; justify-content:center; border:none; background:none; color:var(--t3); cursor:pointer; border-radius:var(--rs); }
#as-app .as-cal-nav-arrow:hover { background:var(--sa); color:var(--ac); }
/* AS-0188 (2026-09-18): text "Today" (was a square showing just today's
 * date number, AS-0065) — an icon/number wasn't clear enough for a "jump
 * back to today" navigation action once you're months or years away. Height
 * now matches the rest of the subheader row (34px) instead of the old
 * 28px square; width goes auto to fit the word. */
#as-app .as-cal-nav-today-sq { height:34px; padding:0 14px; display:flex; align-items:center; justify-content:center; border:1px solid var(--b); border-radius:var(--rs); background:var(--s); color:var(--t1); font-size:12px; font-weight:700; cursor:pointer; white-space:nowrap; }
#as-app .as-cal-nav-today-sq:hover { background:var(--ac); color:#fff; border-color:var(--ac); }
/* AS-0188 desktop: Calendar's own view-tabs/filter instances of the shared
 * .viewseg/.iconbtn components (both also used elsewhere at their original
 * 32/30px and 32px — untouched there) grown to the same 34px so this one
 * subheader row reads as one height throughout. */
#as-app #as-event-view-tabs button { width:34px; height:34px; }
#as-app #as-cal-filter-btn { width:34px; height:34px; }
/* AS-0065: centered against #as-comms-toolbar, not the nav cluster — a
 * given label's own width no longer affects anything else in the row. */
/* AS-0237: the absolute centering above let the range title slide under
 * the Today button whenever the left cluster (Compose, mode switch, search,
 * arrows, Today) reached past the middle of the toolbar minus half the
 * title: narrow desktop widths and the long Day and Week titles. The title
 * is now an in-flow flex sibling after Today with its own gap, so the two
 * can never overlap; a title that does not fit is truncated, never covered. */
#as-app #as-comms-cal-nav { gap:12px; min-width:0; }
#as-app #as-cal-label { position:static; transform:none; top:auto; left:auto; flex:0 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; font-size:15px; font-weight:700; color:var(--t1); white-space:nowrap; pointer-events:none; }
#as-app .as-cal-nav-today-sq { flex:0 0 auto; }
#as-app .as-mcal-navbtn { padding:2px 6px; }
#as-app .as-cal-filter-dot { pointer-events:none; }

/* ═══ CALENDAR — Selector (Settings) ═══ */
#as-app .as-cal-check { display:flex; align-items:center; gap:8px; padding:5px 0; cursor:pointer; font-size:12px; }
#as-app .as-cal-check input { margin:0; }
#as-app .as-cal-swatch { width:12px; height:12px; border-radius:3px; flex-shrink:0; }

/* ═══ CALENDAR — Week View ═══ */
#as-app .as-wk-grid { display:grid; grid-template-columns:repeat(7,1fr); gap:8px; }
#as-app .as-wk-col { background:var(--s); border:1px solid var(--b); border-radius:var(--rs); overflow:hidden; min-height:200px; }
#as-app .as-wk-today { border-color:var(--ac); }
#as-app .as-wk-header { padding:8px 10px; border-bottom:1px solid var(--b); display:flex; justify-content:space-between; align-items:center; }
#as-app .as-wk-dn { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.5px; color:var(--t2); }
#as-app .as-wk-dd { font-size:11px; color:var(--t3); }
#as-app .as-wk-dd-today { color:var(--ac); font-weight:700; }
#as-app .as-wk-body { padding:6px; }
#as-app .as-wk-evt { padding:6px 8px; margin-bottom:6px; border-radius:var(--rs); background:var(--sa); border-left:3px solid var(--ac); cursor:pointer; transition:background .1s; }
#as-app .as-wk-evt:hover { background:var(--b); }
#as-app .as-wk-evt:last-child { margin-bottom:0; }
#as-app .as-wk-evt-time { font-size:10px; font-weight:700; color:var(--ac); }
#as-app .as-wk-evt-title { font-size:12px; font-weight:600; margin-top:2px; }
#as-app .as-wk-evt-meta { font-size:10px; color:var(--t3); margin-top:1px; }

/* v0.1.79: Week time-grid view */
#as-app .as-wk-tg { border:1px solid var(--b); border-radius:var(--rs); overflow:hidden; background:var(--s); }
#as-app .as-wk-tg-head { display:grid; grid-template-columns:56px repeat(7,1fr); border-bottom:1px solid var(--b); position:sticky; top:0; z-index:2; background:var(--s); }
#as-app .as-wk-tg-head .as-wk-tg-gutter { border-right:1px solid var(--b); background:var(--sa); }
#as-app .as-wk-tg-hcell { padding:8px 4px; text-align:center; border-right:1px solid var(--b); }
#as-app .as-wk-tg-hcell:last-child { border-right:none; }
/* AS-0234: the weekday and date are adjacent inline spans with no whitespace between them ("MONOct 5"); give the weekday a gap. Scoped to the time-grid header so .as-wk-header (flex, space-between) is untouched; the <=768px rule below hides .as-wk-dd so the mobile strip is unchanged. */
#as-app .as-wk-tg-hcell .as-wk-dn { margin-right:4px; }
#as-app .as-wk-tg-today { background:rgba(212,116,14,0.04); }
#as-app .as-wk-tg-scroll { overflow-y:auto; max-height:calc(100vh - 220px); }
#as-app .as-wk-tg-body { display:grid; grid-template-columns:56px repeat(7,1fr); position:relative; }
#as-app .as-wk-tg-body > .as-wk-tg-gutter { border-right:1px solid var(--b); background:var(--sa); }
#as-app .as-wk-tg-hlabel { display:flex; align-items:flex-start; justify-content:flex-end; padding:2px 6px 0 0; font-size:9px; color:var(--t3); font-weight:600; box-sizing:border-box; }
#as-app .as-wk-tg-col { border-right:1px solid var(--b); position:relative; }
#as-app .as-wk-tg-col:last-child { border-right:none; }
#as-app .as-wk-tg-today-col { background:rgba(212,116,14,0.02); }
#as-app .as-wk-tg-hline { position:absolute; left:0; right:0; height:1px; background:var(--b); pointer-events:none; }
/* v0.4.4: Apple-style tile sizing rewritten end-to-end. The previous comment
 * (v0.1.100) said "short events visually extend past their time slot" — that
 * was the bug Glenn reported (overlap + hidden text). The new model:
 *   - Box conforms to actual duration (height = endMin - startMin in pixels).
 *   - Min-height is 18px purely so a 5-min event remains clickable.
 *   - Sub-36-min events get .as-wk-tg-evt-short / .as-day-evt-short which
 *     collapses to a single row of "time · title" with ellipsis.
 *   - Column-packing in JS (layoutDayEvents) places overlapping events
 *     side-by-side using a real cluster + greedy column-pack algorithm. */
#as-app .as-wk-tg-evt { position:absolute; background:var(--sa); padding:4px 6px; font-size:10px; cursor:pointer; overflow:hidden; z-index:1; transition:box-shadow 0.12s; border-radius:0; min-height:18px; border:1px solid var(--b); /* v0.10.76: same-tinted back-to-back events had no visible seam — box-sizing:border-box (app-wide reset) keeps this from growing past the slot. v0.4.5: removed border-left:3px solid var(--ac); v0.4.4 clickability floor only. toolbar-doctrine-v2 (2026-08-16): radius dropped to 0, same app-wide --r:0;--rs:0 token fix as Month/Day. */ }
#as-app .as-wk-tg-evt:hover { box-shadow:0 2px 8px rgba(0,0,0,.18); z-index:3; }
/* v0.10.85 (item 2): bottom-edge resize handle — a thin strip, only visible
 * on hover so it doesn't add visual clutter to every event tile. */
#as-app .as-wk-tg-resize { position:absolute; left:0; right:0; bottom:0; height:6px; cursor:ns-resize; z-index:4; }
#as-app .as-wk-tg-evt:hover .as-wk-tg-resize { background:var(--cal-color,var(--ac)); opacity:.35; }
#as-app .as-wk-tg-resize-label { position:absolute; bottom:2px; right:4px; font-size:8px; font-weight:700; color:var(--t2); background:var(--s); padding:1px 4px; border-radius:2px; pointer-events:none; z-index:5; }
/* v0.4.4: short-slot adaptive style — mirrors .as-day-evt-short. Sub-36-min
 * events render time + title on one ellipsised row so they never exceed
 * their actual height. */
#as-app .as-wk-tg-evt-short {
    padding:2px 5px;
    display:flex;
    flex-direction:row;
    align-items:center;
    gap:4px;
    line-height:1.1;
}
#as-app .as-wk-tg-evt-short > div:first-child { font-size:8px !important; flex-shrink:0; }
#as-app .as-wk-tg-evt-short .as-wk-tg-evt-title {
    -webkit-line-clamp:1; line-clamp:1; margin-top:0;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
    flex:1; min-width:0; font-size:10px;
}
#as-app .as-wk-tg-evt-short .as-meet-btn,
#as-app .as-wk-tg-evt-short .as-evt-del { display:none; }

/* v0.10.174 (AS-0021): Week timegrid all-day lane — same 56px-gutter +
 * 7-column grid as .as-wk-tg-head/.as-wk-tg-body so columns line up, but
 * flows to content height instead of the fixed hour-grid height. Only
 * inserted into the DOM when the week actually has an all-day event (see
 * loadCalWeek's paint()).
 * AS-0179: grid-template-rows is now set inline per paint (one row per
 * lane layoutAllDayWeekEvents() actually used) since the lane's row count
 * is dynamic — see loadCalWeek()'s paint(). max-height+overflow-y bounds
 * the LANE as a whole (was previously bounded per .as-wk-tg-allday-col
 * column below, back when each day scrolled independently) now that
 * banners share one row-space across the whole week instead of stacking
 * inside a single day's own column. */
#as-app .as-wk-tg-allday { display:grid; grid-template-columns:56px repeat(7,1fr); row-gap:3px; border-bottom:1px solid var(--b); background:var(--s); max-height:96px; overflow-y:auto; }
#as-app .as-wk-tg-allday-gutter { position:sticky; top:0; border-right:1px solid var(--b); background:var(--sa); font-size:8px; color:var(--t3); font-weight:600; text-transform:uppercase; letter-spacing:.4px; display:flex; align-items:center; justify-content:center; padding:4px 2px; text-align:center; }
/* AS-0179: the 7 day columns are now plain background/drop-target cells
 * (border lines for the grid + drop zones for enableWeekAlldayDragDrop)
 * spanning every row via inline grid-row:1/-1 — the banners themselves
 * (siblings in the same grid, see .as-allday-banner below) carry the
 * actual content and stacking, not these columns. */
#as-app .as-wk-tg-allday-col { border-right:1px solid var(--b); }
#as-app .as-wk-tg-allday-col:last-child { border-right:none; }

/* v0.10.174 (AS-0021): all-day chip — Day-view lane only (see
 * allDayChipHTML's comment in as-v-events.js; Week's own spanning banner
 * is .as-allday-banner below). Deliberately NOT positioned/sized like
 * .as-wk-tg-evt/.as-day-evt (no absolute top/height) — it's a plain flow
 * pill, since all-day events never carry a time slot to lay out against. */
/* AS-0112: min-width:0 fixes a classic flex-column overflow trap — with
 * white-space:nowrap on the label and no min-width override, a flex item's
 * default auto min-width is its unwrapped CONTENT width, which can force
 * its container wider than its track instead of letting overflow:hidden/
 * text-overflow:ellipsis do their job — the actual mechanism behind the
 * original AS-0112 ticket's "block overflows layout" report once a long
 * title is involved. text-overflow:ellipsis now truncates correctly
 * because the chip can no longer force its container to grow. */
#as-app .as-allday-chip { position:relative; display:flex; align-items:center; gap:6px; background:var(--sa); border:1px solid var(--b); border-left:3px solid var(--cal-color,var(--ac)); padding:2px 8px; font-size:10px; font-weight:600; cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; max-width:100%; box-sizing:border-box; transition:box-shadow .12s; }
#as-app .as-allday-chip:hover { box-shadow:0 1px 6px rgba(0,0,0,.15); }
#as-app .as-allday-chip-personal { background:var(--gnl); }
#as-app .as-allday-chip .as-evt-del { display:none; margin-left:auto; flex-shrink:0; }
#as-app .as-allday-chip:hover .as-evt-del { display:inline-flex; }

/* AS-0179: Week view's spanning all-day banner — ONE element per (multi-)
 * day event, positioned via inline grid-column/grid-row (see
 * allDayBannerHTML in as-v-events.js) instead of being repeated once per
 * day it covers. Shares .as-allday-chip-personal for the personal-event
 * background tint and .as-allday-resize/-l/-r for its edge handles (same
 * absolutely-positioned handles, now anchored to this single element
 * instead of to whichever chip instance used to be the event's true
 * edge), but is otherwise its own rule rather than reusing .as-allday-chip
 * directly — a banner spans grid tracks and needs its own margin/
 * box-sizing to sit correctly inside the shared .as-wk-tg-allday grid. */
#as-app .as-allday-banner { position:relative; display:flex; align-items:center; gap:6px; background:var(--sa); border:1px solid var(--b); border-left:3px solid var(--cal-color,var(--ac)); border-radius:3px; margin:0 2px; padding:2px 8px; font-size:10px; font-weight:600; cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; box-sizing:border-box; transition:box-shadow .12s; }
#as-app .as-allday-banner:hover { box-shadow:0 1px 6px rgba(0,0,0,.15); }
/* AS-0112 (kept for the banner, AS-0179): draggable whole-event move — see
 * enableWeekAlldayDragDrop in as-v-events.js. */
#as-app .as-allday-banner[draggable="true"] { cursor:grab; }
#as-app .as-allday-banner[draggable="true"]:active { cursor:grabbing; }
#as-app .as-allday-banner.as-allday-chip-personal { background:var(--gnl); }
#as-app .as-allday-banner .as-evt-del { display:none; margin-left:auto; flex-shrink:0; }
#as-app .as-allday-banner:hover .as-evt-del { display:inline-flex; }

/* AS-0112 (resize, follow-up; AS-0179: retargeted to the spanning banner):
 * edge handles, rendered only on the banner's TRUE start/end (see
 * allDayBannerHTML's comment in as-v-events.js) — position:relative on the
 * chip/banner above is what anchors these. Kept invisible until hover/drag
 * so the lane doesn't gain visual noise on every event; width is generous
 * enough to grab without overlapping the delete "x" (which is on the
 * opposite, right side and only shown on hover too, so the two never
 * compete for the same pixels — the end handle sits ON TOP, z-index above
 * .as-evt-del, since resizing an event from its own last day takes
 * priority over deleting it from that spot). */
#as-app .as-allday-resize { position:absolute; top:0; bottom:0; width:7px; cursor:ew-resize; z-index:3; }
#as-app .as-allday-resize-l { left:0; }
#as-app .as-allday-resize-r { right:0; z-index:6; }
#as-app .as-allday-chip:hover .as-allday-resize,
#as-app .as-allday-banner:hover .as-allday-resize { background:var(--cal-color,var(--ac)); opacity:.35; }
#as-app .as-allday-resize:hover { opacity:.7 !important; }

/* v0.1.51: Section divider labels (Migration page) */
#as-app .as-section-label { display:flex; align-items:center; gap:10px; margin:24px 0 14px; font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:1.2px; color:var(--t3); }
#as-app .as-section-label::after { content:''; flex:1; height:1px; background:var(--b); }
/* v0.9.25: Configure summary cards — clickable, open the config tray */
#as-app .as-cfg-card { cursor:pointer; transition:border-color .12s, box-shadow .12s; }
#as-app .as-cfg-card:hover { border-color:#d9dce2; box-shadow:0 1px 0 rgba(0,0,0,.03); }
#as-app .as-cfg-card .ch .lnk { margin-left:auto; }
/* v0.9.26: compact + paginated Team members list (replaces heavy tiles) */
#as-app .as-umini-list { display:flex; flex-direction:column; }
#as-app .as-umini { display:flex; align-items:center; gap:9px; padding:6px 0; border-bottom:1px solid var(--sa); }
#as-app .as-umini:last-child { border-bottom:none; }
#as-app .as-umini-nm { flex:1; min-width:0; font-size:12px; font-weight:600; color:var(--t1); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#as-app .as-umini-actions { display:flex; gap:2px; flex:none; }
#as-app .as-umini.as-user-inactive { opacity:.5; }
#as-app .as-umini-pager { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-top:10px; padding-top:8px; border-top:1px solid var(--sa); }
/* v0.9.27: Settings — template icon tiles + tray sub-headings */
#as-app .as-tpl-grid { display:grid; grid-template-columns:repeat(4,1fr); gap:10px; }
#as-app .as-tpl-tile { border:1px solid var(--b); padding:14px 10px; text-align:center; cursor:pointer; display:flex; flex-direction:column; align-items:center; gap:8px; }
#as-app .as-tpl-tile:hover { border-color:var(--ac); background:var(--sa); }
#as-app .as-tpl-ic { width:34px; height:34px; display:flex; align-items:center; justify-content:center; background:var(--acl); color:var(--ac); font-size:17px; }
#as-app .as-tpl-nm { font-size:12px; font-weight:600; }
#as-app .as-set-sub, #as-app .as-cfg-sub { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.5px; color:var(--t3); margin:20px 0 8px; padding-top:16px; border-top:1px solid var(--b); }
/* first sub-heading in a panel shouldn't carry a divider above it */
#as-app .as-set-panel > .as-set-sub:first-child, #as-app .as-cfg-panel > .as-cfg-sub:first-child { margin-top:0; padding-top:0; border-top:none; }
/* CORRECTION to the v0.9.55 note that stood here: the removed
 * `#as-app .as-tpl-card { max-width:none !important }` was NOT dead. The
 * `.card { max-width:520px }` cap it fought is real — it comes from WORDPRESS
 * CORE (wp-admin/load-styles.php), which is why a repo grep found nothing and
 * a fixture without wp-admin styles showed no difference. Removing it did
 * regress .as-tpl-card to 520px. The special case is no longer needed only
 * because the general core reset now lives on `#as-app .card` (see ~:171) —
 * if that reset is ever removed, this card breaks again. */
@media (max-width:640px){ #as-app .as-tpl-grid { grid-template-columns:1fr 1fr; } }
/* v0.1.51: Checkbox styling */
#as-app input[type=checkbox] { width:16px; height:16px; accent-color:var(--ac); cursor:pointer; flex-shrink:0; }
/* v0.1.51: Meet Now header button */
#as-app .as-meet-now-btn { background:none; border:1px solid var(--b); border-radius:var(--rs); cursor:pointer; color:var(--t3); display:inline-flex; align-items:center; justify-content:center; gap:5px; transition:color .15s, border-color .15s, background .15s; height:34px; padding:0 12px; font-size:12px; font-weight:600; font-family:inherit; box-sizing:border-box; text-decoration:none; }
#as-app .as-meet-now-btn:hover { color:var(--gn); border-color:var(--gn); background:rgba(91,140,90,.08); }
/* v0.1.51: Escape links as icon-only row */
#as-app .as-escape-links { border-top:1px solid var(--sb2); padding:8px; display:flex; flex-direction:row; gap:4px; justify-content:center; }
#as-app .as-escape-link { display:flex; align-items:center; justify-content:center; width:30px; height:30px; padding:0; font-size:0; color:var(--sb3); text-decoration:none; opacity:.6; transition:opacity .15s, color .15s, background .15s; border-radius:var(--rs); }
#as-app .as-escape-link:hover { opacity:1; color:var(--sbh); background:var(--sb2); }
#as-app .as-escape-link svg { opacity:1 !important; }

/* ═══ RESPONSIVE — 768px ═══ */

/* ═══ v0.1.85 — Reports filters + visual upgrades ═══ */
#as-app .as-rpt-filters { display:flex; gap:8px; align-items:center; margin-bottom:16px; }
#as-app .as-rpt-filters select { padding:6px 10px; font-size:11px; border:1px solid var(--b); background:var(--s); color:var(--t1); font-family:inherit; }
#as-app .as-rpt-flabel { font-size:10px; color:var(--t3); font-weight:600; text-transform:uppercase; letter-spacing:.5px; }
#as-app .sparkline { display:flex; align-items:flex-end; gap:1px; height:20px; }
#as-app .spark-bar { flex:1; min-width:3px; }
#as-app .dv-table { width:100%; border-collapse:collapse; }
#as-app .dv-table th { font-size:9px; font-weight:700; text-transform:uppercase; letter-spacing:.5px; color:var(--t3); text-align:left; padding:6px 8px; border-bottom:2px solid var(--b); }
#as-app .dv-table td { font-size:12px; padding:8px; border-bottom:1px solid var(--sa); }
#as-app .dv-table tr:hover td { background:var(--sa); }
#as-app .dv-table .num { text-align:right; font-variant-numeric:tabular-nums; font-weight:600; }

@media(max-width:768px) {
    /* — Sidebar overlay — */
    #as-app .side { transform:translateX(-100%); transition:transform .25s ease; z-index:200; width:210px !important; }
    #as-app .side.as-side-open { transform:translateX(0); box-shadow:4px 0 20px rgba(0,0,0,.3); }
    #as-app .as-main { margin-left:0 !important; max-width:100vw !important; }
    #as-app .as-brand-mark { display:none; }
    #as-app.as-collapsed .as-side-label,
    #as-app.as-collapsed .slbl,
    #as-app.as-collapsed .as-brand-text,
    #as-app.as-collapsed .brand h1,
    #as-app.as-collapsed .brand small { display:revert; }
    #as-app.as-collapsed .si { font-size:13px; justify-content:flex-start; }
    /* Glenn, 2026-09-11: the desktop 48px collapsed-rail treatment for the
       shared SimpleSuite app tray (#as-app.as-collapsed .ss-shell-sidebar-
       footer/.ss-shell-app-tray/.ss-shell-version, ~line 2396 below) has no
       viewport awareness — if the desktop sidebar is set to collapsed, that
       same narrow-rail CSS was still winning inside the mobile drawer once
       it's manually opened (.side.as-side-open), squeezing the tray icons
       into a vertical column even though the open drawer is a full 210px
       wide, not a 48px rail. Same class of bug the labels/brand-text/.si
       restores just above already fixed for the rest of the sidebar when
       AS-0034-era mobile support was added — the app-tray primitive arrived
       later and never got the equivalent restore. Mirrors those rules'
       `display:revert` pattern exactly. */
    #as-app.as-collapsed .ss-shell-sidebar-footer { display:revert; flex-direction:revert; align-items:revert; padding:12px 16px 8px; }
    #as-app.as-collapsed .ss-shell-app-tray { flex-direction:revert; }
    #as-app.as-collapsed .ss-shell-version { display:revert; }

    /* — Hamburger — */
    #as-app .as-hamburger { display:inline-flex; align-items:center; justify-content:center; width:36px; height:36px; border:1px solid var(--b); border-radius:var(--rs); cursor:pointer; background:transparent; color:var(--t1); font-size:18px; flex-shrink:0; }

    /* — Bottom tab bar (AS-0028) — */
    #as-app .as-tabbar { display:flex; position:fixed; left:0; right:0; bottom:0; z-index:150; background:var(--s); border-top:1px solid var(--b); padding:4px 2px calc(4px + env(safe-area-inset-bottom)); box-shadow:0 -2px 10px rgba(0,0,0,.06); }
    /* Sits under .side (z-index:200 when open, set above) so the slide-in
       overlay's own shadow still reads as "on top" while it's open; hidden
       outright rather than just covered so its shadow/border don't show
       through beside the overlay's own 210px width at the bottom-left
       corner. */
    #as-app .side.as-side-open ~ .as-tabbar { display:none; }
    /* v0.10.253: Engage dropped from the tray (down to 4 destinations + More
       — see the template comment above this bar's markup), which freed up
       width per item; used it to size icons up from 18px to 22px per
       Glenn's request rather than just widening the idle flex gaps. min-
       height bumped 48px -> 52px to give the bigger icon + label room to
       breathe instead of feeling cramped against the old ceiling. */
    #as-app .as-tabbar-item { flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px; padding:6px 2px; min-height:52px; color:var(--t3); cursor:pointer; border-radius:var(--rs); transition:color .12s; }
    #as-app .as-tabbar-item .as-icon { width:22px; height:22px; }
    #as-app .as-tabbar-item span { font-size:9.5px; font-weight:600; line-height:1; }
    #as-app .as-tabbar-item:hover { color:var(--t1); }
    #as-app .as-tabbar-item.on { color:var(--ac); }
    /* AS-0221: "Priorities" (10 chars) doesn't fit this tab's width at the
       normal 9.5px single-line size — matches the approved
       as-mobile-shell-v1 prototype's `.tab.long`, which Glenn reviewed and
       said explicitly to leave as-is rather than abbreviate or shrink the
       other four labels to make room. */
    #as-app .as-tabbar-item.long span { font-size:8px; line-height:1.15; white-space:normal; text-align:center; max-width:62px; }

    /* — Mobile "More" bottom sheet (AS-0221) — */
    /* z-index above .side's mobile open state (200, set above) so the sheet
       always sits on top of the slide-in overlay if both were ever briefly
       in the DOM at once; below .as-quickpop/.as-notif-panel (300, desktop-
       only surfaces this sheet never coexists with). */
    #as-app .as-more-scrim { position:fixed; inset:0; background:rgba(15,18,23,.38); z-index:219; opacity:0; pointer-events:none; transition:opacity .2s; }
    #as-app .as-more-scrim.open { opacity:1; pointer-events:auto; }
    #as-app .as-more-sheet { position:fixed; left:0; right:0; bottom:0; background:var(--s); border-radius:18px 18px 0 0; z-index:220; box-shadow:0 -10px 30px rgba(0,0,0,.2); transform:translateY(100%); transition:transform .25s ease; max-height:72%; display:flex; flex-direction:column; }
    #as-app .as-more-sheet.open { transform:translateY(0); }
    #as-app .as-more-grabber { width:36px; height:4px; background:var(--b); border-radius:2px; margin:9px auto 4px; flex:0 0 auto; }
    #as-app .as-more-hd { display:flex; align-items:center; justify-content:space-between; padding:6px 16px 10px; border-bottom:1px solid var(--b2); flex:0 0 auto; }
    #as-app .as-more-hd h4 { font-size:14px; font-weight:700; color:var(--t1); }
    #as-app .as-more-hd button { font-size:12px; font-weight:700; color:var(--ac); background:none; border:none; cursor:pointer; }
    #as-app .as-more-body { overflow-y:auto; flex:1; padding:10px 14px calc(16px + env(safe-area-inset-bottom)); }
    #as-app .as-more-sec { padding:14px 4px 6px; font-size:10px; font-weight:800; text-transform:uppercase; letter-spacing:.5px; color:var(--t3); }
    #as-app .as-more-sec:first-child { padding-top:2px; }
    #as-app .as-more-row { display:flex; align-items:center; gap:12px; padding:13px 4px; border-bottom:1px solid var(--b2); cursor:pointer; }
    #as-app .as-more-row:last-child { border-bottom:none; }
    #as-app .as-more-row .ic { width:30px; height:30px; border-radius:50%; background:var(--sa); color:var(--t2); display:flex; align-items:center; justify-content:center; flex:0 0 auto; }
    #as-app .as-more-row .lbl { flex:1; font-size:13px; font-weight:600; color:var(--t1); }
    #as-app .as-more-row .chev { color:var(--t3); flex:0 0 auto; display:flex; }
    /* Un-hides the base display:none set above (desktop default) — .open
       (JS-toggled) then drives actual visibility via opacity/transform. */
    #as-app .as-more-scrim { display:block; }
    #as-app .as-more-sheet { display:flex; }

    /* — Header bar — */
    #as-app .top { padding:10px 12px; padding-top:calc(10px + env(safe-area-inset-top)); }
    #as-app .top h2 { font-size:16px; }
    #as-app .top p { font-size:10px; }
    #as-app .top .btns { gap:4px; }
    #as-app .as-meet-now-btn { padding:0 8px; font-size:0; gap:0; width:34px; justify-content:center; }
    #as-app .as-meet-now-btn svg { margin:0; }

    /* — Content area — */
    /* Extra bottom padding clears the fixed .as-tabbar (~58px incl. its own
       padding) added above, plus the iOS home-indicator safe area, so the
       last row of every view isn't hidden under the tab bar. */
    #as-app .cnt { padding:12px 12px calc(70px + env(safe-area-inset-bottom)); }
    /* AS-MOBILE-GUTTER (v0.10.345): .toolbar's `margin:-20px -28px` cancels the
     * DESKTOP 28px .cnt gutter. With .cnt at 12px the toolbar was 40px wider
     * than its parent (left -20 / right +20) and its 22px side padding left
     * content 2px from the glass: Priorities/Comms/Calendar headers flush
     * to the edge and clipped (measured live 390px). Re-match to the gutter. */
    #as-app .toolbar { margin:-12px -12px 12px; padding:10px 12px; gap:8px; }
    #as-app .toolbar + .toolbar { margin-top:-12px; }

    /* — Grids — */
    #as-app .g2 { grid-template-columns:1fr; }
    #as-app .g3 { grid-template-columns:1fr; }
    #as-app .g4 { grid-template-columns:repeat(2,1fr); }
    #as-app .as-metrics { grid-template-columns:repeat(2,1fr); gap:8px; }

    /* — Dashboard metric cards — */
    #as-app .as-mc { padding:12px; }
    #as-app .as-mc-value { font-size:22px; }
    #as-app .as-mc-event-title { font-size:12px; }

    /* — Dashboard schedule — */
    #as-app .as-sched-time { min-width:52px; font-size:10px; }

    /* — Dashboard cards — */
    #as-app .g3 > .card > .cb,
    #as-app .g3 > div > .card > .cb { max-height:300px; }

    /* — Tabs — */
    #as-app .tabs { flex-wrap:wrap; gap:1px; }
    #as-app .tab { padding:4px 8px; font-size:10px; }

    /* — Kanban / Pipeline — */
    #as-app .as-kanban { flex-direction:column; }
    #as-app .as-kb-col { min-width:100%; }
    #as-app .as-pipe-col { min-width:100% !important; min-height:auto !important; }
    /* v0.10.257 (AS-0054 [stale id — see AS-0159-0166, not AS-0054/55/56/57] follow-on): Priorities board only (#as-kanban-board
     * ID-scoped, same reason #as-kanban-board .as-kb-col{min-width:144px}
     * above is ID-scoped — .as-kb-col is shared with Pipeline/CRM/Funnels
     * boards via as-funnels.js/as-v-crm.js, don't touch those). One column
     * visible at a time via the pill switcher instead of every column
     * stacked full-width — avoids the "tasks run off the right and left"
     * problem a stacked multi-section board had at phone width. */
    #as-app .as-kb-pills { display:flex; }
    #as-app #as-kanban-board.as-kanban { flex-direction:row; overflow-x:hidden; }
    #as-app #as-kanban-board .as-kb-col { display:none; min-width:100%; }
    #as-app #as-kanban-board .as-kb-col.as-kb-col-active { display:block; }
    /* AS-0229: #as-task-panel-board's own `margin:0 -28px` (~:1088) cancels
     * .cnt's DESKTOP 28px gutter to bleed the board edge to edge — but .cnt's
     * own horizontal padding shrinks to 12px at this breakpoint (~:2038) and
     * the board's margin never followed it down, so the single active column
     * (and every task card/title inside it) bled 16px off BOTH edges of the
     * real viewport — exactly the "tasks run off the right and left" case
     * this block's own pill-switcher comment above describes, just caused a
     * different way than the stacked-columns scenario it was written to
     * avoid. Same fix pattern as as-email.css's AS-0229 panels. */
    #as-app #as-task-panel-board { margin-left:-12px; margin-right:-12px; }

    /* — Task view toolbar — */
    #as-app #as-v-tasks > div:first-child { flex-direction:column; gap:8px; align-items:stretch !important; }
    #as-app #as-v-tasks > div:first-child > div:first-child { flex-wrap:wrap; gap:6px; }
    #as-app #as-v-tasks > div:first-child > .btns { flex-wrap:wrap; gap:6px; justify-content:flex-start; }
    /* AS-0229: same stretch-every-child problem the v0.10.255 fix below
     * solved for the icon row — Queue and All/This-week (siblings of
     * .as-task-icon-row, each its own `.lenses`) landed as two separate
     * full-width stacked bars instead of sharing one row ("Queue/All/This
     * week filter buttons don't stay on one row", Glenn, live, iPhone
     * 15/16, 2026-10-01). Markup now wraps both in .as-task-scope-row
     * (templates/admin-app.php) — force that wrapper back to a row, and
     * its two `.lenses` children to size to content instead of stretching,
     * so Queue sits next to All/This-week as one compact group. */
    #as-app .as-task-scope-row { display:flex; flex-wrap:wrap; gap:6px; align-items:center; }
    #as-app .as-task-scope-row .lenses { flex:0 0 auto; }
    /* v0.10.255: without this, .as-task-icon-row's search/filter/view-swap
     * buttons — plain children of the now-column .toolbar above — each ended
     * up as their own full-width stacked row (stretch applies to every child
     * alike). Force this one group back to a row so the three sit together. */
    #as-app #as-v-tasks > div:first-child > .as-task-icon-row { flex-direction:row; gap:6px; align-self:flex-start; }
    #as-app #as-task-project-filter,
    #as-app #as-task-owner-filter,
    #as-app #as-task-priority-filter { flex:1; min-width:0; font-size:10px !important; }
    /* AS-MOBILE-GUTTER (v0.10.345) — Priorities toward actionstudio__as-priorities-v1-apple-style.html:
     * 16px side gutters, inset 8px-radius cards, "+" inline with the Queue/scope
     * row instead of on its own row, no empty .grow gap, no right-edge clip.
     * The 12px .as-kanban gap was being applied after the empty .as-kb-pills
     * flex item, shoving the active column 12px right (measured live: col
     * 12..387 inside a 375 board = clipped at the right edge). */
    #as-app #as-v-tasks > div:first-child { flex-direction:row; flex-wrap:wrap; align-items:center !important; gap:8px; padding:10px 16px; }
    #as-app #as-v-tasks > div:first-child > .grow { display:none; }
    #as-app #as-v-tasks > div:first-child > .as-task-scope-row { flex:1 1 0; min-width:0; }
    #as-app #as-v-tasks > div:first-child > #as-task-summary { flex:1 1 100%; }
    #as-app #as-v-tasks > div:first-child > .as-task-icon-row { flex:1 1 100%; align-self:stretch; }
    #as-app #as-kanban-board.as-kanban { gap:0; }
    #as-app #as-kanban-board .as-kb-header { padding-left:16px; padding-right:16px; }
    #as-app #as-kanban-board .as-kb-body { padding:8px 16px 12px; }
    #as-app #as-kanban-board .as-kb-card { border-radius:8px; }

    /* — Task list — */
    #as-app .as-task-cols { grid-template-columns:1fr; }
    #as-app .trow { gap:6px; }
    #as-app .towner { display:none; }
    #as-app .ttitle { font-size:12px; }

    /* — Quick-complete tap target (fix, 2026-08-30) — the visual .tcheck box
       stays small (16px, 14px at 480px) to match the desktop-established
       look, but a transparent ::before expands the actual clickable/thumb
       area to the 44x44px minimum. Absolutely positioned so it doesn't
       affect .trow's flex layout or push neighboring elements. */
    #as-app .tcheck::before { content:''; position:absolute; top:50%; left:50%; width:44px; height:44px; transform:translate(-50%,-50%); }

    /* — Task kanban cards — */
    #as-app .as-kb-card { padding:8px 10px; }
    #as-app .as-kb-title { font-size:11px; }
    /* v0.10.255: the nudge/move-arrow buttons (.as-kb-actions button) stayed
     * at the desktop 9px-font/2px-6px-padding size at every mobile breakpoint
     * — never enlarged for touch, unlike .tcheck/.as-mode-toggle etc, which
     * already use an invisible 44px ::before hit-area. That exact technique
     * would overlap here (2-3 buttons sit 3px apart in one row), so this is
     * a direct visible-size bump instead — smaller win, but no ambiguous
     * overlapping tap zones between adjacent buttons. */
    #as-app .as-kb-actions { gap:6px; }
    #as-app .as-kb-actions button { font-size:11px; padding:6px 10px; }

    /* — Week plan — */
    #as-app .as-wp-header { padding:8px 12px; }
    #as-app .as-wp-body { padding:4px 12px; }
    #as-app .as-wp-label { font-size:11px; min-width:40px; }

    /* — Modals — */
    #as-app .as-modal { width:calc(100vw - 24px) !important; max-height:90vh; }
    #as-app .as-modal .row { flex-direction:column; gap:0; }
    #as-app .as-modal .cb { padding:14px; }

    /* — Detail panels — */
    #as-app .as-detail-panel { width:100% !important; }
    #as-app .as-detail-name { font-size:17px; }
    #as-app .as-detail-section { padding:12px; }

    /* — Contacts — */
    #as-app .as-contact-grid { grid-template-columns:repeat(auto-fill,minmax(160px,1fr)); gap:8px; }
    #as-app #as-v-contacts > div:first-child { flex-direction:column; gap:8px; align-items:stretch !important; }
    #as-app #as-v-contacts > div:first-child > div:first-child { flex-wrap:wrap; }
    #as-app #as-v-contacts > div:first-child > .btns { justify-content:flex-start; }

    /* — Pipeline toolbar — */
    #as-app #as-v-pipeline > div:first-child { flex-direction:column; gap:8px; align-items:stretch !important; }
    #as-app #as-v-pipeline > div:first-child > div:first-child { flex-wrap:wrap; gap:6px; }

    /* — Events toolbar — */
    #as-app #as-v-events > div:first-child { flex-direction:column; gap:8px; align-items:stretch !important; }
    #as-app #as-v-events > div:first-child > div:last-child { flex-wrap:wrap; gap:6px; }

    /* — Calendar grids — */
    #as-app .as-wk-grid { grid-template-columns:repeat(3,1fr); gap:6px; }
    #as-app .as-wk-col { min-height:120px; }
    #as-app .as-wk-tg-head { grid-template-columns:40px repeat(7,1fr); }
    #as-app .as-wk-tg-body { grid-template-columns:40px repeat(7,1fr); }
    #as-app .as-wk-tg-hlabel { font-size:8px; padding-right:3px; }
    #as-app .as-wk-tg-hcell .as-wk-dn { font-size:8px; }
    #as-app .as-wk-tg-hcell .as-wk-dd { display:none; }
    #as-app .as-cal-cell { min-height:70px; }
    #as-app .as-cal-hcell { padding:6px 2px; font-size:9px; }
    #as-app .as-cal-day { font-size:10px; }
    #as-app .as-cal-evt { font-size:9px; padding:1px 3px; }

    /* — Calendar — Month, mobile-first redesign (AS-0131) — root-cause was
       that .as-cal-cell/.as-cal-hcell above only ever shrank the SAME
       desktop-clone 7-col grid at this breakpoint and the 480px one below
       (cosmetic, never a real restructure), while #as-app's .as-main
       (~line 149/283) clips overflow-x — Tuesday-Saturday and any events on
       them were unreachable below ~600px with no scroll affordance at all.
       Below 768px, loadCalMonth() (as-v-events.js) now builds a fully
       different cell: day number + up to 3 small colored dots, never event
       title text, so a cell can never overflow/truncate. The 7-column grid
       itself stays (native-calendar-app pattern, not a desktop clone) — only
       what's INSIDE each cell changes. Tapping a cell paints that day's full
       agenda in #as-cal-month-agenda below the grid, via the same
       renderFilteredDayList()/eventCardHTML()/.as-event-card markup List
       view already ships (see paintCalMobileAgenda(), as-v-events.js) —
       no new row component. */
    #as-app .as-cal-cell-mobile { min-height:44px; display:flex; flex-direction:column; align-items:center; padding:6px 2px 4px; cursor:pointer; }
    #as-app .as-cal-cell-mobile .as-cal-day { margin-bottom:3px; }
    #as-app .as-cal-cell-mobile:hover,
    #as-app .as-cal-cell-mobile:active { background:var(--sa); }
    #as-app .as-cal-cell-selected { box-shadow:inset 0 0 0 1.5px var(--ac); }
    #as-app .as-cal-dots { display:flex; gap:3px; justify-content:center; }
    #as-app .as-cal-dot { width:5px; height:5px; border-radius:50%; flex-shrink:0; }
    #as-app .as-cal-mobile-agenda { margin-top:12px; }
    #as-app .as-cal-mobile-agenda:empty::before { content:'Tap a day to see its schedule'; display:block; padding:20px 8px; text-align:center; font-size:12px; color:var(--t3); }

    /* — Calendar — Week, mobile-first redesign (AS-0131) — root cause was
       the same shrink-not-restructure pattern: .as-wk-tg-head/-body's
       "56px repeat(7,1fr)" narrowed to "40px repeat(7,1fr)" just above
       (line ~1954/1955), still rendering all 7 day columns side by side —
       at 390px they crushed to 55-90px each (Saturday measured 18px live),
       event titles truncated to 5-6 characters. Below 768px, loadCalWeek()
       abandons the column-grid approach entirely instead of squeezing it
       further — .as-wk-tg is never built at all here — and renders this
       compact day-of-week strip instead (same visual weight as Month's own
       .as-cal-header/.as-cal-hcell row above), tapping a day painting its
       agenda in #as-cal-week-agenda via the identical
       paintCalMobileAgenda() path Month's mobile cells use. */
    #as-app .as-wk-mobile-strip { display:flex; background:var(--sa); border:1px solid var(--b); border-radius:var(--rs); overflow:hidden; }
    #as-app .as-wk-mobile-day { flex:1; display:flex; flex-direction:column; align-items:center; gap:3px; padding:8px 2px; cursor:pointer; border-right:1px solid var(--b2); min-width:0; }
    #as-app .as-wk-mobile-day:last-child { border-right:none; }
    #as-app .as-wk-mobile-day:hover,
    #as-app .as-wk-mobile-day:active { background:var(--b); }
    #as-app .as-wk-mobile-dn { font-size:9px; font-weight:700; color:var(--t3); text-transform:uppercase; letter-spacing:.5px; }
    #as-app .as-wk-mobile-dd { font-size:13px; font-weight:700; color:var(--t2); }
    #as-app .as-wk-mobile-today .as-wk-mobile-dd { color:var(--ac); }
    #as-app .as-wk-mobile-selected { background:var(--ac); }
    #as-app .as-wk-mobile-selected .as-wk-mobile-dn,
    #as-app .as-wk-mobile-selected .as-wk-mobile-dd,
    #as-app .as-wk-mobile-selected.as-wk-mobile-today .as-wk-mobile-dd { color:#fff; }
    #as-app .as-wk-mobile-dot { width:4px; height:4px; border-radius:50%; background:var(--ac); }
    #as-app .as-wk-mobile-selected .as-wk-mobile-dot { background:#fff; }
    #as-app .as-wk-mobile-agenda { margin-top:12px; }
    #as-app .as-wk-mobile-agenda:empty::before { content:'Tap a day to see its schedule'; display:block; padding:20px 8px; text-align:center; font-size:12px; color:var(--t3); }

    /* — Notification panel — */
    #as-app .as-notif-panel { width:calc(100vw - 24px); right:-60px; }

    /* AS-0221 (Priorities re-architecture): Queue/Filter — real mobile
     * bottom sheets, replacing the v0.10.266 "constrain to viewport, anchor
     * stays put" treatment (which kept them anchored under their toolbar
     * trigger, still fundamentally the desktop-popover shape just narrower
     * — on a short phone screen with the trigger near the top of the
     * toolbar, a 420px-tall anchored popover could still run off-screen or
     * crowd the content below). .as-quickpop has exactly these two
     * consumers app-wide (confirmed — #as-task-queue-tray/#as-task-filter-
     * tray only), so this overrides the class directly rather than adding
     * a third marker class. Same fixed-bottom/rounded-top/full-width shape
     * .as-opp-tray's own mobile treatment already uses just below, for
     * visual consistency across every tray family in this shell. No JS
     * changes needed: the open/close state is still the same
     * .as-tray-open class toggle (asToggleTaskQueuePop/asOpenTaskFilters/
     * asCloseTrays, as-v-tasks.js/as-v-crm.js, untouched), and the existing
     * outside-tap-closes listener (as-v-tasks.js) already treats a tap on
     * the newly-added scrim below as "outside the tray". */
    #as-app .as-quickpop {
        position:fixed; top:auto; left:0; right:0; bottom:0;
        width:100%; max-width:100%; max-height:75vh;
        border-radius:12px 12px 0 0; border-bottom:none;
        box-shadow:0 -4px 20px rgba(0,0,0,.18);
    }
    #as-app #as-task-filter-wrap .as-quickpop { left:0; right:0; }
    /* Dims the page behind an open bottom sheet. body.as-tray-active is
     * already set/cleared by every tray opener + the shared asCloseTrays()
     * (as-v-crm.js) — previously an inert class with no CSS consumer at
     * all; this is the first one, scoped to mobile only so desktop's
     * anchored popovers (still just popovers there) don't suddenly gain a
     * full-page dim. */
    body.as-tray-active::after { content:''; position:fixed; inset:0; background:rgba(0,0,0,.35); z-index:299; }

    /* — Quick bar — */
    #as-app .qbar { flex-wrap:wrap; gap:8px; }

    /* — Pipeline stages — */
    #as-app .pipe { flex-wrap:wrap; gap:4px; }
    #as-app .pstage { flex:1 1 calc(50% - 2px); min-width:0; padding:6px 4px; }
    #as-app .pstage .pc { font-size:16px; }
    #as-app .pstage .pl { font-size:8px; }

    /* — Pipe shape (dashboard) — */
    #as-app .as-pipe-shape { flex-wrap:wrap; }
    #as-app .as-pipe-stage { flex:1 1 calc(33% - 3px); min-width:0; padding:6px 2px; }
    #as-app .as-pipe-num { font-size:13px; }
    #as-app .as-pipe-lbl { font-size:6px; }

    /* — Projects toolbar — */
    #as-app #as-v-projects > div:first-child { flex-direction:column; gap:8px; align-items:stretch !important; }
    /* AS-0231: that column rule stacked every toolbar child on its own row (New, All/Mine, then
     * search, filter and swap each alone, measured at 390px). Same row model as Priorities
     * (AS-MOBILE-GUTTER): one wrapping row, the scope tabs take the free space, icons sit on the right. */
    #as-app #as-v-projects > div.toolbar:first-child { flex-direction:row; flex-wrap:wrap; align-items:center !important; gap:8px; }
    #as-app #as-v-projects > div.toolbar:first-child > .grow { display:none; }
    #as-app #as-v-projects > div.toolbar:first-child > #as-projects-scope-tabs { flex:1 1 0; min-width:0; }
    #as-app #as-v-projects > div.toolbar:first-child > #as-projects-summary:empty { display:none; }
    #as-app #as-v-projects > div.toolbar:first-child > #as-projects-summary { flex:1 1 100%; order:9; }
    /* AS-0231: List-view project rows: name and meta get their own full-width line, progress, status
     * and the edit and delete buttons share the line below (they squeezed the meta text into ~100px). */
    #as-app .as-project-card > .cb { flex-wrap:wrap; gap:8px; }
    #as-app .as-project-card > .cb > div:first-child { flex:1 1 100%; min-width:0; overflow-wrap:anywhere; }
    #as-app .as-project-card > .cb > div:last-child { flex:1 1 100%; justify-content:space-between; }

    /* — Drive — */
    #as-app .as-drive-toolbar { flex-direction:column; gap:6px; }
    #as-app .as-drive-toolbar input { max-width:100% !important; }
    #as-app .as-drive-grid { grid-template-columns:1fr; }

    /* — User tiles — */
    #as-app .as-user-tile { width:100% !important; }

    /* — Toast — */
    #as-toast-container { right:8px; left:8px; }
    #as-app .as-toast { max-width:100%; min-width:0; }

    /* — Split/Triage (AS-0034) — .as-triage-wrap/-left/-right had NO mobile
       breakpoint at all before this (only the >@media(max-width:1150px)
       rule above, which just narrows the left column from 400px to 320px —
       still side-by-side). At phone widths that leaves a fixed 320-400px
       left pane fighting a squeezed right pane instead of stacking. Mirrors
       .as-email-inbox-split's own flex-direction:column!important collapse
       for Email/List mode's split view (as-email.css) — the closest
       existing precedent for this same two-pane-to-one-column move.
       #as-comms-panel-triage's fixed height:calc(100vh - 52px)/overflow:hidden
       (set for desktop's independently-scrolling columns) is relaxed to
       auto/visible so the now-stacked content scrolls with the page instead
       of being clipped to one screen's worth of height with two competing
       internal scrollbars. */
    #as-app #as-comms-panel-triage { height:auto; overflow:visible; }
    #as-app .as-triage-wrap { flex-direction:column; height:auto; gap:12px; }
    #as-app .as-triage-left { flex:0 0 auto; width:100%; }
    #as-app .as-triage-right { flex:0 0 auto; width:100%; overflow-y:visible; }
    #as-app .as-triage-row1 { flex-direction:column; }
    /* AS-0055 [stale id — see AS-0159-0166, not AS-0054/55/56/57] (mobile Communications build, 2026-09-11): approved mobile-audit
       prototype order is Inbox → Follow-up → day-nav'd Today list → "Recent
       notes & meetings" at the very bottom (Glenn: "the ai summaries should
       be below inbox and today"), with the month mini-cal dropped entirely —
       same "no month grid on mobile" call already made for Split's own
       day-nav (asSplitDayNav) and for Priorities' Queue/Done trays. No markup
       change needed: .as-triage-right is already flex-direction:column (base
       rule, untouched by this block), so reordering its two direct children
       via `order` is enough — row2 (day-nav+Today, id=as-triage-row2) first,
       row1 (mini-cal+notes, id=as-triage-row1) second with the mini-cal
       itself hidden, leaving only the notes card. loadSplitMiniCal() still
       fires and paints #as-split-mini-cal even though it's hidden here —
       harmless (same "hidden but still fetched" precedent as List view's own
       nav-row hide in showCalView()), not worth branching the fetch on
       viewport width for a purely cosmetic mobile hide. */
    #as-app .as-triage-mini { display:none; }
    #as-app .as-triage-row1 { order:2; }
    #as-app .as-triage-row2 { order:1; }
    /* Glenn, real-device walk 2026-09-11: Follow-up's header rendered with
       ZERO rows visible under it, jumping straight to the Today day-nav —
       confirmed root cause: .as-triage-left's max-height:55vh (just removed
       above) forced Inbox (its own separate max-height:340px, desktop-sized)
       and Follow-up to fight over a shared, capped flex column. Follow-up's
       flex:1 section (base rule, ~line 1403) got whatever tiny remainder was
       left after Inbox's fixed 340px + the resize handle — often collapsing
       its own flex:1 list (~line 1410, overflow-y:auto) to a sliver too
       short to show even one row without an internal scroll the user would
       never think to try. Fix: Follow-up gets its OWN natural height on
       mobile (flex:0 0 auto, not fighting Inbox for space) and its list
       stops being an internal-scroll box (matches how #as-comms-panel-
       triage itself was already converted to whole-page scroll, AS-0034) —
       Inbox keeps its own max-height/internal-scroll untouched, since it can
       genuinely hold dozens of messages and still needs one. */
    #as-app .as-triage-section-followup { flex:0 0 auto; }
    #as-app .as-triage-section-followup .as-triage-list { flex:0 0 auto; overflow-y:visible; }

    /* — Split/Triage collapsible sections (AS-0187) — mobile-only, per
       Glenn's Option C pick off the prototype (_prototypes/
       actionstudio__as-0187-split-mobile-prototype.html, .sp-acc-hd/-body).
       Inbox and Follow-up headers become independently tappable — either
       can be open or closed in any combination, no fixed ratio. Reuses the
       exact is-collapsed/chevron-rotate convention Funnels' own Know/Do/
       Measure cards already established (.as-cd-collapsible, as-funnels.css)
       rather than inventing a new one: a `.is-collapsed` modifier toggled
       (asToggleTriageSection(), as-email.js) on the parent .as-triage-section
       hides that section's own .as-triage-list and rotates its chevron;
       absent the class (the default — both sections start open per Glenn,
       not the prototype's Follow-up-collapsed default which was tuned for
       its own 3-section mock) everything renders exactly as it did before
       this ticket. Collapsing doesn't need to survive as-email.js's
       renderSplitInboxList()/renderSplitFollowupList() re-renders — see
       their own comments in as-email.js — they only ever replace
       .as-triage-list's innerHTML, never touching .as-triage-hd or the
       .is-collapsed class sitting on their shared parent.
       Note: .as-triage-resize-handle (v0.10.151/v0.10.254) already sits
       between these two sections on mobile and stays fully functional,
       unrelated to and untouched by this collapse feature — see this
       ticket's own build notes for the known visual overlap between the
       two affordances, flagged for Glenn rather than resolved here. */
    #as-app .as-triage-hd { cursor:pointer; min-height:44px; display:flex; align-items:center; justify-content:space-between; gap:8px; }
    #as-app .as-triage-chev { display:flex; align-items:center; justify-content:center; flex:0 0 auto; color:var(--t3); transition:transform .15s ease; }
    #as-app .as-triage-section.is-collapsed .as-triage-chev { transform:rotate(-90deg); }
    #as-app .as-triage-section.is-collapsed .as-triage-list { display:none; }

    /* — Split mobile density toggle (AS-0226 follow-on) — replaces the
       non-functional gray gap between the stacked Inbox/Follow-up column
       (.as-triage-left) and the Today/Calendar column (.as-triage-right)
       with a real tappable control. Default/balanced state (neither
       .as-density-mail nor .as-density-cal on .as-triage-wrap) renders
       exactly as before this ticket — untouched. Chevron-up button expands
       Inbox/collapses Calendar to a short strip; chevron-down does the
       reverse; tapping the active one again (asToggleTriageDensity(),
       as-email.js) returns to balanced. 56px strip height is a judgment
       call — tall enough to keep the collapsed section's own header
       ("Inbox"/"Today") visible as a re-entry point, short enough to read
       as clearly de-emphasized next to the expanded column. */
    #as-app .as-triage-vdivider { display:flex; align-items:center; justify-content:center; gap:2px; min-height:40px; margin:2px 0; background:var(--s); border:1px solid var(--b); border-radius:var(--rs); }
    #as-app .as-triage-vdiv-btn { flex:1; display:flex; align-items:center; justify-content:center; min-height:38px; border-radius:var(--rs); }
    #as-app .as-triage-vdiv-grip { display:block; width:1px; align-self:stretch; margin:8px 0; background:var(--b); }
    #as-app .as-triage-wrap.as-density-mail .as-triage-right { flex:0 0 56px; max-height:56px; overflow:hidden; }
    #as-app .as-triage-wrap.as-density-mail .as-triage-right .as-triage-row1 { display:none; }
    #as-app .as-triage-wrap.as-density-mail .as-triage-left { flex:1 1 auto; }
    #as-app .as-triage-wrap.as-density-cal .as-triage-left { flex:0 0 56px; max-height:56px; overflow:hidden; }
    #as-app .as-triage-wrap.as-density-cal .as-triage-right { flex:1 1 auto; }

    /* — Calendar · List view (AS-0055 [stale id — see AS-0159-0166, not AS-0054/55/56/57]) — .as-evl-wrap/-side had NO mobile
       breakpoint at all before this (same gap Split/Triage had before
       AS-0034): the 288px-fixed sidebar sat side-by-side with the agenda at
       every width, squeezing it into a narrow column on a phone. Stacks full-
       width, same collapse pattern as .as-triage-wrap above. Swaps the month
       mini-cal for the week-strip control (both already in the DOM — see
       renderCalWeekStrip()/#as-cal-weekstrip-card). */
    #as-app .as-evl-wrap { flex-direction:column; align-items:stretch; }
    #as-app .as-evl-side { flex:0 0 auto; width:100%; }
    #as-app #as-cal-mini-card { display:none; }
    #as-app .as-cal-weekstrip-card { display:block; }
    #as-app .as-triage-mini { flex:0 0 auto; }

    /* — Calendar header (AS-0065, superseded by AS-0188 below) — the desktop
       layout floats #as-cal-label centered against the FULL toolbar width
       via absolute positioning, which only reads cleanly when there's
       enough clearance on both sides for a long Day-view label ("Wednesday,
       August 26, 2026") not to overlap the create-button/mode-seg on the
       left or the view-tabs/filter/sync/search cluster on the right. At
       phone widths there isn't — AS-0065 dropped the label to its own line
       below the arrows/Today to avoid the collision. */
    /* AS-0188 mobile (2026-09-18): "same icons, real tap sizes" — approved
       mockup. #as-comms-cal-nav and #as-comms-actions-cal each get
       flex:1 1 100%, so they land as two full-width rows inside
       #as-comms-toolbar's own flex-wrap (each still wraps below the
       Compose/mode-seg/search row above it, same as before — only what's
       INSIDE each of these two rows changes). Confirmed in the actual CSS:
       neither row had a centering/stretch rule at all before this, so they
       just left-aligned and left dead space on the right. */
    #as-app #as-comms-cal-nav { flex:1 1 100%; gap:8px; } /* AS-0237: was the inline 6px */
    #as-app #as-comms-actions-cal { flex:1 1 100%; }
    /* Row 1 (#as-comms-cal-nav): arrows — label (centered, flex:1) — Today.
       Real flex siblings now instead of AS-0065's absolute-centered label,
       so nothing can overlap regardless of label length — it just gets
       tighter, never collides. */
    #as-app #as-cal-label { position:static; transform:none; top:auto; left:auto; flex:1; text-align:center; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
    #as-app .as-cal-nav-group { border:1px solid var(--b); }
    #as-app .as-cal-nav-group .as-cal-nav-arrow + .as-cal-nav-arrow { border-left:1px solid var(--b); }
    #as-app .as-cal-nav-arrow { width:40px; height:40px; }
    #as-app .as-cal-nav-arrow svg { width:16px; height:16px; }
    #as-app .as-cal-nav-today-sq { height:40px; }
    /* Row 2 (#as-comms-actions-cal): view-tabs share the row evenly instead
       of sitting as a small fixed-width cluster; filter/sync match height. */
    #as-app #as-event-view-tabs { flex:1; }
    #as-app #as-event-view-tabs button { flex:1; width:auto; height:40px; }
    #as-app #as-event-view-tabs svg { width:17px; height:17px; }
    #as-app #as-cal-filter-btn { width:40px; height:40px; flex:0 0 auto; }
    #as-app #as-event-sync-btn { width:40px; height:40px; flex:0 0 auto; }

    /* AS-0185: touch-target audit — Month/Week/Day prev/next
       (.as-cal-nav-arrow, 26x26px), the week-strip/Split day-nav
       (.as-cal-nav-btn, .btn's 34px height but only 4px/8px padding), and
       both List/Split mini-calendar prev/next (.as-mcal-navbtn, 2px/6px
       padding) all sit well under the 44px touch-target minimum with no
       mobile override at all. Same invisible ::before hit-area technique as
       .tcheck/.as-mode-toggle (AS-0098/AS-0148, see the "Quick-complete tap
       target" rule above) — visual size is untouched, only the tappable
       area grows. None of these had position:relative already (.as-cal-nav-
       btn/.as-mcal-navbtn combine with the base .btn rule, which has none;
       .as-cal-nav-arrow has none of its own either), so it's added here
       alongside the ::before rather than assumed. */
    #as-app .as-cal-nav-arrow,
    #as-app .as-cal-nav-btn,
    #as-app .as-mcal-navbtn { position:relative; }
    #as-app .as-cal-nav-arrow::before,
    #as-app .as-cal-nav-btn::before,
    #as-app .as-mcal-navbtn::before { content:''; position:absolute; top:50%; left:50%; width:44px; height:44px; transform:translate(-50%,-50%); }
}

/* ═══ RESPONSIVE — 480px ═══ */
@media(max-width:480px) {
    /* — Header — */
    #as-app .top { padding:8px 10px; padding-top:calc(8px + env(safe-area-inset-top)); }
    #as-app .top h2 { font-size:14px; }
    #as-app .top p { display:none; }
    #as-app .as-mode-toggle { width:30px; height:30px; position:relative; }
    #as-app .as-notif-bell { width:30px !important; height:30px !important; }
    #as-app .as-sysmenu-btn { width:30px !important; height:30px !important; position:relative; }
    #as-app .as-meet-now-btn { width:30px; height:30px; position:relative; }
    #as-app .as-hamburger { width:32px; height:32px; font-size:16px; position:relative; }
    /* AS-0148: below the 44px touch-target minimum at this width — same
       invisible ::before hit-area technique already proven on .tcheck
       (see the "Quick-complete tap target" rule above). .as-notif-bell
       already has position:relative from its base rule (line ~891). */
    #as-app .as-mode-toggle::before,
    #as-app .as-notif-bell::before,
    #as-app .as-sysmenu-btn::before,
    #as-app .as-meet-now-btn::before,
    #as-app .as-hamburger::before { content:''; position:absolute; top:50%; left:50%; width:44px; height:44px; transform:translate(-50%,-50%); }

    /* — Bottom tab bar (AS-0028) — v0.10.254: this used to shrink the
       icon/label back down at the narrowest width to fit 6 items (5
       destinations + More). v0.10.253 already dropped Engage from the tray
       (5 items total) specifically to free up room for BIGGER icons/tap
       targets (22px icon, 52px min-height, set in the 768px block above) —
       but this override was never removed, so it silently undid that fix on
       every real phone (all ≤480px). With one fewer item there's no
       crowding to solve here anymore; let the 768px block's sizes carry
       through unchanged. */

    /* — Content — */
    /* Re-asserts the 768px block's bottom clearance (this block otherwise
       overrides #as-app .cnt's padding shorthand entirely at this width). */
    #as-app .cnt { padding:10px 8px calc(66px + env(safe-area-inset-bottom)); }
    #as-app .toolbar { margin:-10px -8px 10px; padding:10px 12px; }
    #as-app .toolbar + .toolbar { margin-top:-10px; }
    /* AS-0229: .cnt's horizontal padding tightens again to 8px at this
     * width — keep the Priorities board's edge-to-edge cancel (~:2086, this
     * file's own 768px block) in sync, same reasoning as there. Every real
     * phone (iPhone 15/16 included, 390-430px) is ≤480px, so this is the
     * value that actually applies on device. */
    #as-app #as-task-panel-board { margin-left:-8px; margin-right:-8px; }

    /* — Split/Triage (AS-0034) — this 50vh re-assert is REMOVED (AS-0055 [stale id — see AS-0159-0166, not AS-0054/55/56/57],
       2026-09-11): it re-imposed the exact cap the 768px block above just
       dropped, on every real phone (all <=480px are also <=768px, so this
       rule always fired on top of it) — silently undoing that fix the same
       way the tabbar-icon override above already did once before. See the
       "Follow-up rendered with zero rows visible" comment in the 768px
       block for the full root-cause writeup. */

    /* — Grids — */
    #as-app .g4 { grid-template-columns:1fr; }
    #as-app .as-metrics { grid-template-columns:1fr; }

    /* — Dashboard metrics — */
    #as-app .as-mc { padding:10px; }
    #as-app .as-mc-value { font-size:20px; }
    #as-app .as-mc-label { font-size:9px; }

    /* — Dashboard cards — */
    #as-app .g3 > .card > .cb,
    #as-app .g3 > div > .card > .cb { max-height:250px; }
    #as-app .card { margin-bottom:10px; }
    /* v0.9.55: grids follow the tightened mobile card rhythm too (the
     * grid-child margin reset above keeps the cards themselves at 0). */
    #as-app .g2, #as-app .g3 { gap:10px; margin-bottom:10px; }
    #as-app .ch { padding:10px 12px; }
    #as-app .ch h3 { font-size:12px; }
    #as-app .cb { padding:10px 12px; }

    /* — Tasks — */
    #as-app .trow { padding:6px 0; }
    #as-app .ttitle { font-size:11px; }
    #as-app .tmeta { font-size:9px; }
    #as-app .tdue { font-size:9px; }
    #as-app .tcheck { width:14px; height:14px; }
    #as-app .tdot { width:4px; height:4px; }

    /* — Kanban — */
    #as-app .as-kb-header { padding:8px 10px; font-size:11px; }
    #as-app .as-kb-body { padding:6px; min-height:80px; }
    #as-app .as-kb-card { padding:7px 9px; margin-bottom:4px; }
    #as-app .as-kb-title { font-size:11px; margin-bottom:2px; }
    #as-app .as-kb-meta { font-size:9px; }
    #as-app .as-kb-actions { gap:6px; }
    #as-app .as-kb-actions button { font-size:11px; padding:6px 10px; }

    /* — Week plan — */
    #as-app .as-wp-header { padding:6px 10px; gap:6px; }
    #as-app .as-wp-body { padding:4px 10px; }

    /* — Calendar — */
    #as-app .as-wk-grid { grid-template-columns:1fr; }
    #as-app .as-wk-col { min-height:auto; }
    #as-app .as-cal-cell { min-height:50px; padding:3px 4px; }
    #as-app .as-cal-hcell { font-size:8px; padding:4px 2px; }
    /* AS-0131: re-assert the mobile Month cell's own sizing at this width —
       .as-cal-cell-mobile and .as-cal-cell above are equal specificity, so
       without this the blanket .as-cal-cell rule just above (later in
       source order) would win at <=480px and quietly widen the mobile
       cell's padding back out. 44px stays the touch-target floor (AS-0148's
       existing convention in this file) regardless of viewport. */
    #as-app .as-cal-cell-mobile { min-height:44px; padding:5px 2px 3px; }

    /* — Contacts — */
    #as-app .as-contact-grid { grid-template-columns:1fr; }
    #as-app .as-ccard { padding:10px; }
    #as-app .crow { gap:6px; }
    #as-app .cav { width:26px; height:26px; font-size:9px; }
    #as-app .cname { font-size:11px; }

    /* — Modals — */
    #as-app .as-modal { width:calc(100vw - 16px) !important; max-height:92vh; }
    #as-app .as-modal .cb { padding:12px; }
    #as-app .as-modal label { font-size:10px; }
    #as-app .as-modal input,
    #as-app .as-modal select,
    #as-app .as-modal textarea { font-size:12px; padding:7px 8px; }

    /* — Detail panel — */
    #as-app .as-detail-header { padding:10px 12px; }
    #as-app .as-detail-name { font-size:16px; }
    #as-app .as-detail-section { padding:10px; }

    /* — Notification panel — */
    #as-app .as-notif-panel { width:calc(100vw - 16px); right:-40px; max-height:70vh; }
    #as-app .as-notif-item { padding:5px 10px; font-size:11px; }

    /* AS-0221: Queue/Filter bottom sheets, tightened further to match. */
    #as-app .as-quickpop { max-height:70vh; }
    /* v0.9.59 — event rows track the due-date rows' tighter phone padding. */
    #as-app .as-notif-event { padding:6px 10px; }
    #as-app .as-notif-event.is-unread { padding-left:8px; }
    #as-app .as-notif-section-title, #as-app .as-notif-quiet { padding-left:10px; padding-right:10px; }
    #as-app .as-notif-event-title { font-size:11px; }

    /* — Pipeline stages — */
    #as-app .pstage { padding:5px 3px; }
    #as-app .pstage .pc { font-size:14px; }
    #as-app .pstage .pl { font-size:7px; }

    /* — Quick bar — */
    #as-app .qbar { padding:8px 10px; gap:6px; }
    #as-app .qlbl { font-size:10px; }
    #as-app .qval { font-size:10px; }
}


/* ── v0.1.17: Meet copy button ─────────────── */
.as-meet-copy {
    display:inline-flex;align-items:center;gap:4px;padding:4px 10px;
    font-size:11px;border:1px solid var(--b);border-radius:var(--rs);
    cursor:pointer;background:var(--sa);color:var(--bl);
}
.as-meet-copy:hover { background:color-mix(in srgb, var(--bl) 10%, transparent); }

/* ── v0.1.18: Day view ────────────────────── */
#as-app .as-day-container { border: 1px solid var(--b); border-radius: var(--rs); overflow: hidden; background: var(--s); }
/* toolbar-doctrine-v2 pixel-match (2026-08-16): gutter widened to match
   _prototypes/as-communications/index.html's .hlbl (78px). */
#as-app .as-day-gutter { width: 78px; flex-shrink: 0; border-right: 1px solid var(--b); background: var(--sa); }
#as-app .as-day-hour-label { display: flex; align-items: flex-start; justify-content: flex-end; padding: 2px 8px 0 0; font-size: 10px; color: var(--t3); font-weight: 600; box-sizing: border-box; }
#as-app .as-day-col { position: relative; }
#as-app .as-day-hour-line { position: absolute; left: 0; right: 0; height: 1px; background: var(--b); pointer-events: none; }
#as-app .as-day-hour-line:nth-child(odd) { background: color-mix(in srgb, var(--b) 50%, transparent); }
#as-app .as-day-now { position: absolute; left: 0; right: 0; height: 2px; background: var(--rd); z-index: 5; pointer-events: none; }
#as-app .as-day-now::before { content: ''; position: absolute; left: -4px; top: -3px; width: 8px; height: 8px; border-radius: 50%; background: var(--rd); }
#as-app .as-day-evt {
    position: absolute; left: 2px; right: 2px; padding: 5px 10px; border-radius: 0;
    /* toolbar-doctrine-v2 (2026-08-16): radius dropped to 0 — the app's own
       tokens are --r:0;--rs:0, this rule was hardcoding a radius against
       that doctrine (independent of the mock, which is also square). */
    border: 1px solid var(--b); /* v0.10.76: same-tinted back-to-back events had no visible seam */
    background: var(--sa); cursor: pointer; /* v0.4.5: removed border-left:3px solid var(--ac). The 8% color-mix background tint conveys calendar source without competing with title text. P/T pill also gone (kept on month view only). Kept in this pixel-match pass — a deliberate improvement over the mock's static left-border, not reverted. */
    font-size: 11px; overflow: hidden; z-index: 2; transition: box-shadow .15s;
    box-sizing: border-box; min-height: 18px; /* v0.4.4: was 76px — Apple-style. The box now conforms to actual time slot. 18px is purely a clickability floor for sub-15-min events. */
}
#as-app .as-day-evt:hover { box-shadow: 0 2px 10px rgba(0,0,0,.18); z-index: 3; }
#as-app .as-day-evt-time { font-size: 10px; font-weight: 700; color: var(--ac); }
/* v0.4.4: Short-slot adaptive style. Events under ~36 minutes get this class
 * applied in JS. Padding collapses, time + title fold into one row, title
 * truncates to a single ellipsised line so a 30-min slot never bleeds past
 * its own height. The Meet button and × del are hidden (still reachable via
 * hover-grow on focus, and via clicking through to the modal). */
#as-app .as-day-evt-short {
    padding: 2px 6px;
    font-size: 10px;
    line-height: 1.15;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 6px;
}
#as-app .as-day-evt-short .as-day-evt-time { font-size: 9px; flex-shrink: 0; }
#as-app .as-day-evt-short .as-day-evt-title {
    -webkit-line-clamp: 1; line-clamp: 1; margin-top: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    flex: 1; min-width: 0;
}
#as-app .as-day-evt-short .as-meet-btn,
#as-app .as-day-evt-short .as-evt-del { display: none; }

/* v0.10.174 (AS-0021): Day view all-day lane — sits above .as-day-container,
 * gutter width matches .as-day-gutter (78px) so the "All day" label lines up
 * visually with the hour labels beneath it. Only rendered when the day
 * actually has an all-day event (see renderDayGrid). */
#as-app .as-day-allday-row { display:flex; border:1px solid var(--b); border-bottom:none; border-radius:var(--rs) var(--rs) 0 0; background:var(--s); }
#as-app .as-day-allday-gutter { width:78px; flex-shrink:0; border-right:1px solid var(--b); background:var(--sa); font-size:9px; color:var(--t3); font-weight:600; text-transform:uppercase; letter-spacing:.4px; display:flex; align-items:center; justify-content:flex-end; padding:4px 8px; box-sizing:border-box; }
/* AS-0112: same max-height/overflow-y constraint as the Week lane's
 * .as-wk-tg-allday-col (see its comment) — a day with several stacked
 * all-day/multi-day chips now scrolls within the strip instead of growing
 * the row unboundedly. */
#as-app .as-day-allday-strip { flex:1; padding:5px 8px; display:flex; flex-wrap:wrap; align-content:flex-start; gap:5px; max-height:80px; overflow-y:auto; }
#as-app .as-day-allday-row + .as-day-container { border-radius:0 0 var(--rs) var(--rs); }

/* ── v0.1.18: Drag feedback ───────────────── */
#as-app .as-dragging { opacity: .4 !important; }
#as-app .as-drag-over { background: color-mix(in srgb, var(--ac) 8%, var(--s)) !important; }
#as-app .as-wk-evt[draggable="true"] { cursor: grab; }
#as-app .as-wk-evt[draggable="true"]:active { cursor: grabbing; }
#as-app .as-cal-evt[draggable="true"] { cursor: grab; }
#as-app .as-day-evt[draggable="true"] { cursor: grab; }

/* ═══ User tile grid (v0.1.31) ═══ */
#as-app .as-user-grid{display:flex;flex-wrap:wrap;gap:12px;padding:4px 0}
#as-app .as-user-tile{width:calc(50% - 6px);border:1px solid var(--b);background:var(--s);padding:14px;display:flex;flex-direction:column;gap:10px;box-sizing:border-box}
#as-app .as-user-tile.as-user-inactive{opacity:.5}
#as-app .as-user-tile-top{display:flex;align-items:center;gap:10px}
#as-app .as-user-tile-info{flex:1;min-width:0}
#as-app .as-user-tile-name{font-size:13px;font-weight:600;color:var(--t1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#as-app .as-user-you{font-size:9px;font-weight:400;color:var(--t3)}
#as-app .as-user-tile-email{font-size:11px;color:var(--t3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#as-app .as-user-tile-meta{display:flex;gap:6px;flex-wrap:wrap}
#as-app .as-user-pill{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.3px;background:var(--sa);padding:2px 8px}
#as-app .as-user-tile-foot{display:flex;justify-content:space-between;font-size:10px;color:var(--t3)}
#as-app .as-user-tile-actions{display:flex;gap:4px;justify-content:flex-end;border-top:1px solid var(--b);padding-top:8px;margin-top:2px}
#as-app .as-user-icon-btn{width:28px;height:28px;border:1px solid var(--b);background:var(--s);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0;transition:all .12s}
#as-app .as-user-icon-btn:hover{background:var(--sa);border-color:currentColor}
@media(max-width:900px){#as-app .as-user-tile{width:100%}}

/* v0.1.36: Multi-assign picker */
#as-app .as-multi-assign{display:flex;flex-wrap:wrap;gap:4px;padding:4px 0}
#as-app .as-multi-assign label{display:flex;align-items:center;gap:4px;font-size:11px;padding:3px 8px;background:var(--sa);cursor:pointer;white-space:nowrap;transition:background .15s}
#as-app .as-multi-assign label:hover{background:var(--b)}
#as-app .as-multi-assign input[type=checkbox]{margin:0;width:13px;height:13px}
#as-app .as-multi-assign label.as-ma-checked{background:var(--acl);font-weight:600}

/* v0.1.79: Done archive toggle button */
#as-app .as-kb-archive-btn { background:none; border:none; color:var(--t3); cursor:pointer; padding:2px 4px; margin-left:auto; opacity:0.6; transition:opacity 0.15s; }
#as-app .as-kb-archive-btn:hover { opacity:1; color:var(--bl); }

/* v0.1.79: Nudge button and notification styling */
#as-app .as-nudge-btn { background:none; border:none; color:var(--t3); cursor:pointer; padding:2px 4px; opacity:0.5; transition:opacity 0.15s,color 0.15s; }
#as-app .as-nudge-btn:hover { opacity:1; color:#D4740E; }
#as-app .as-notif-nudge { background:rgba(212,116,14,0.06); border-left:2px solid #D4740E; }

/* v0.1.79: Nudge button styling */
#as-app .as-nudge-btn { color:var(--t3) !important; transition:color 0.15s; }
#as-app .as-nudge-btn:hover { color:#D4740E !important; }
#as-app .as-notif-nudge { background:rgba(212,116,14,0.05); display:flex; align-items:center; gap:6px; }

/* v0.1.93: Delete icon on calendar event tiles (month/week/day) — shows on hover */
#as-app .as-evt-del {
    position:absolute; top:2px; right:3px; width:14px; height:14px; display:none;
    align-items:center; justify-content:center; cursor:pointer;
    color:var(--rd); background:var(--bg); border:1px solid var(--b); border-radius:50%;
    font-size:9px; font-weight:700; line-height:1; z-index:4;
}
#as-app .as-cal-evt { position:relative; }
#as-app .as-cal-evt:hover .as-evt-del,
#as-app .as-wk-tg-evt:hover .as-evt-del,
#as-app .as-day-evt:hover .as-evt-del { display:flex; }
#as-app .as-evt-del:hover { background:var(--rd); color:#fff; }

/* ═══ v0.1.98 — P/T PREFIX PILLS + PERSONAL TINT ═══ */
/* Replaces border-based personal/team distinction + diagonal-stripe pattern.
   One token system used across calendar tiles (month/week/day), dashboard Tomorrow list, dashboard Today list. */
#as-app .as-pt-pill {
    display:inline-block; font-size:10px; font-weight:700; line-height:1;
    padding:3px 6px; margin-right:6px; border-radius:3px;
    text-transform:uppercase; letter-spacing:.4px; color:#FFF !important;
    vertical-align:baseline; flex-shrink:0;
    min-width:18px; text-align:center;
}
/* v0.2.6: Ensure pill is visible on task list rows + kanban cards — prevents
   accidental text-color inheritance from row state classes from hiding white label. */
#as-app .crow .as-pt-pill,
#as-app .as-kb-card .as-pt-pill,
#as-app .as-task-cols .as-pt-pill { color:#FFF !important; }
#as-app .as-pt-p { background:var(--gn); }
#as-app .as-pt-t { background:var(--bl); }

/* v0.2.2 — TASK STATUS PILLS
 * Extends the P/T pill system for task status. Same geometry (.as-pt-pill,
 * above); background color now comes entirely inline from AS.statusPill()
 * (as-utils.js, v0.10.258) — the team's actual configured column color (or
 * red when overdue), not a fixed per-key class. .as-pt-td/.as-pt-ip/
 * .as-pt-pn/.as-pt-dn/.as-pt-overdue all removed as dead CSS once nothing
 * emitted those classes anymore. */

/* Personal event tiles — subtle bg tint (replaces diagonal stripes) */
#as-app .as-cal-evt-personal,
#as-app .as-wk-tg-evt-personal,
#as-app .as-day-evt-personal { background:var(--gnl); }

/* Calendar tile title — allow full title on week/day, stay compact on month */
/* Month: tile is short, title is already JS-truncated to 18 chars + ellipsis — leave behavior alone */
/* Week + day: title wraps up to 3 lines (v0.1.100 — Apple-style, no clamp dance on hover). */
#as-app .as-wk-tg-evt-title {
    font-size:11px; font-weight:600; margin-top:2px; line-height:1.3;
    overflow:hidden; text-overflow:ellipsis;
    display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical;
    white-space:normal; word-break:break-word;
}
#as-app .as-day-evt-title {
    font-size:12.5px; font-weight:600; margin-top:2px; line-height:1.3;
    overflow:hidden; text-overflow:ellipsis;
    display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical;
    white-space:normal; word-break:break-word;
}


/* ═══════════════════════════════════════════════════════════════════
 * v0.3.2: Calendar color painting
 * ═══════════════════════════════════════════════════════════════════ */

/* 8% tint via color-mix when --cal-color is set. Falls back to the existing
 * flat var(--sa) / var(--gnl) backgrounds if the browser doesn't support it. */
#as-app .as-day-evt[style*="--cal-color"],
#as-app .as-wk-tg-evt[style*="--cal-color"],
#as-app .as-cal-evt[style*="--cal-color"] {
    background: color-mix(in srgb, var(--cal-color) 8%, var(--bg));
}

/* Time strip inside painted events uses the cal-color for stronger affordance */
#as-app .as-day-evt[style*="--cal-color"] .as-day-evt-time,
#as-app .as-cal-evt[style*="--cal-color"] .as-cal-evt-time {
    color: var(--cal-color);
}

/* Hover lifts to a slightly higher tint */
#as-app .as-day-evt[style*="--cal-color"]:hover,
#as-app .as-wk-tg-evt[style*="--cal-color"]:hover,
#as-app .as-cal-evt[style*="--cal-color"]:hover {
    background: color-mix(in srgb, var(--cal-color) 14%, var(--bg));
}

/* Manage-modal swatch: interactive affordance without breaking SS flat-UI spec */
#as-app .as-g-cal-swatch {
    cursor: pointer;
    transition: box-shadow 0.12s;
}
#as-app .as-g-cal-swatch:hover,
#as-app .as-g-cal-swatch:focus {
    box-shadow: 0 0 0 2px var(--bg), 0 0 0 3px var(--t2);
    outline: none;
}

/* Palette popover chip */
.as-g-palette-chip {
    transition: transform 0.08s;
}
.as-g-palette-chip:hover {
    transform: scale(1.08);
}

/* v0.10.199 (AS-0063): the .as-cal-legend* top-bar strip these rules styled
 * is gone — per-calendar toggles moved into the Filters popover (reuses the
 * existing .as-email-dropdown/.as-email-dd-checkbox styling, inline dot
 * styling for the color swatch — no new classes needed). */


/* v0.3.2: Task privacy pill. Muted so it doesn't compete with status badges. */
#as-app .as-pill-private {
    display: inline-block;
    padding: 1px 5px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.5px;
    color: var(--t3);
    background: var(--sa);
    border: 0.5px solid var(--b);
    margin-right: 6px;
    vertical-align: 1px;
}

/* v0.3.5: muted version string under sidebar footer.
 * Rendered by admin-app.php after #as-sfoot. Hidden when sidebar is collapsed
 * so the 44px-wide rail doesn't get noisy. */
#as-app .as-side-ver {
    font-size: 9px;
    color: var(--sb3);
    text-align: center;
    padding: 6px 0 10px;
    letter-spacing: 0.5px;
    font-family: 'SF Mono', Menlo, Consolas, monospace;
    opacity: 0.7;
    user-select: none;
}
#as-app.as-collapsed .as-side-ver {
    display: none;
}

/* ═══════════════════════════════════════════════════════════════════
 * v0.9.68 / HUB-0023 Phase 2 — shared Hub app-tray primitive, AS-scoped
 * restores + collapsed-rail variants.
 *
 * The tray markup and base look come from the Hub's dependency-free
 * ss-app-tray.css (enqueued in AS_Router::on_load). NOTHING here restyles
 * it — do not add colors, borders or sizes. Two narrow jobs only:
 *
 *   1. RESTORE the padding the Hub sheet declares. actionstudio.css opens
 *      with `#as-app, #as-app * { margin:0; padding:0; box-sizing:border-box; }`
 *      — specificity (1,0,0) — which OUTRANKS the primitive's single-class
 *      selectors (0,1,0) no matter which sheet loads last. Without these two
 *      rules the footer and version stamp collapse to zero padding and the
 *      tray jams against the nav. The values are copied verbatim from
 *      ss-app-tray.css; if that sheet's padding ever changes, change these.
 *   2. COLLAPSED RAIL parity: AS's 48px collapsed sidebar needs the tray to
 *      stack vertically, mirroring the Hub's own
 *      `.ss-shell--collapsed .ss-shell-app-tray` rules (which live in the
 *      Hub-only ss-admin.css and so never reach ActionStudio).
 * ═══════════════════════════════════════════════════════════════════ */
#as-app .ss-shell-sidebar-footer { padding: 12px 16px 8px; }
#as-app .ss-shell-version { padding: 6px 0 0; }

/* Collapsed rail: icons stack, version stamp hides (same treatment the
   legacy .as-side-ver got above — a 48px rail can't show "v0.9.68"). */
#as-app.as-collapsed .ss-shell-sidebar-footer {
    padding: 8px 0;
    display: flex;
    flex-direction: column;
    align-items: center;
}
#as-app.as-collapsed .ss-shell-app-tray {
    flex-direction: column;
    gap: 4px;
}
#as-app.as-collapsed .ss-shell-version {
    display: none;
}

/* The Hub stamp inherits the legacy line's click-for-What's-new affordance
   (wired in as-whatsnew.js). Make that discoverable. */
#as-app .ss-shell-version { cursor: pointer; user-select: none; }

/* ═══════════════════════════════════════════════════════════════════
 * v0.4.6: Opportunities — filter row, kanban cards, list view, tray,
 * contact picker modal.
 *
 * The page model is single-list-of-opportunities (the entity formerly
 * known as deals). Segment is a filter dimension, not navigation.
 * Edit goes to a slide-in tray (right panel desktop / bottom sheet
 * mobile); create stays modal. Contact picker is a search modal that
 * replaces the broken 25-row dropdown.
 * ═══════════════════════════════════════════════════════════════════ */

/* ── Filter row ─────────────────────────────────────────────────── */
/* v0.4.8: utility class with stronger specificity than the kanban's
 * display:flex !important. Used by the Opportunities view toggle so
 * Kanban/List actually hide each other. */
#as-app .as-hidden { display:none !important; }
#as-app .as-opp-filter-row {
    display:flex; flex-wrap:wrap; gap:8px; align-items:center;
    margin-bottom:12px; padding:10px 12px;
    background:var(--s); border:1px solid var(--b);
}
#as-app .as-opp-filter {
    padding:6px 10px; border:1px solid var(--b); background:var(--inp-bg);
    color:var(--t1); font-size:12px; min-width:120px; cursor:pointer;
}
#as-app .as-opp-revchk {
    display:inline-flex; align-items:center; gap:6px;
    font-size:11px; color:var(--t2); margin:0; padding:4px 8px;
    cursor:pointer; user-select:none;
}
#as-app .as-opp-revchk input { margin:0; cursor:pointer; }
#as-app .as-opp-search {
    flex:1; min-width:180px; padding:6px 10px;
    border:1px solid var(--b); background:var(--inp-bg);
    color:var(--t1); font-size:12px;
}
#as-app .as-opp-view-toggle {
    display:inline-flex; gap:0; margin-left:auto;
    border:1px solid var(--b); overflow:hidden;
}
#as-app .as-opp-view-btn {
    padding:6px 14px; background:var(--s); color:var(--t2);
    border:none; cursor:pointer; font-size:11px; font-weight:600;
    border-right:1px solid var(--b);
}
#as-app .as-opp-view-btn:last-child { border-right:none; }
#as-app .as-opp-view-btn.on {
    background:var(--ac); color:#fff;
}
#as-app .as-opp-view-btn:hover:not(.on) { background:var(--sa); }

/* ── Kanban card refinements (v0.4.6) ──────────────────────────── */
#as-app .as-opp-col { min-width:240px; max-width:280px; flex:0 0 260px; }
#as-app .as-opp-col-empty {
    padding:14px; text-align:center; color:var(--t3);
    font-size:11px; font-style:italic;
}
#as-app .as-opp-card {
    position:relative;
    background:var(--s); border:1px solid var(--b);
    padding:10px 12px; margin-bottom:8px; cursor:grab;
    transition:box-shadow .12s, transform .08s;
}
#as-app .as-opp-card:hover { box-shadow:0 2px 8px rgba(0,0,0,.10); }
#as-app .as-opp-card:active { cursor:grabbing; }
#as-app .as-opp-card-owner {
    position:absolute; top:8px; right:8px;
    width:22px; height:22px; border-radius:50%;
    background:var(--ac); color:#fff;
    display:flex; align-items:center; justify-content:center;
    font-size:10px; font-weight:700;
}
#as-app .as-opp-card-title {
    font-size:13px; font-weight:600; color:var(--t1);
    line-height:1.3; margin-bottom:4px; padding-right:28px;
}
#as-app .as-opp-card-contact {
    font-size:11px; color:var(--t3); margin-bottom:6px;
}
#as-app .as-opp-card-company {
    font-size:11px; font-weight:600; color:var(--t2); margin-top:-4px; margin-bottom:6px;
}
#as-app .as-opp-card-close {
    font-size:10px; color:var(--t3); margin-top:4px;
}
#as-app .as-opp-seg-chip {
    display:inline-block; font-size:9px; font-weight:600;
    padding:2px 6px; background:var(--sa); color:var(--t2);
    text-transform:uppercase; letter-spacing:.4px;
    margin-top:4px;
}
#as-app .as-opp-card-foot {
    display:flex; gap:4px; margin-top:8px;
    padding-top:6px; border-top:1px solid var(--sa);
    align-items:center;
}
#as-app .as-opp-card-foot button {
    padding:2px 6px; font-size:11px; background:var(--sa);
    color:var(--t2); border:none; cursor:pointer;
}
#as-app .as-opp-card-foot button:hover { background:var(--b); color:var(--t1); }

/* Phase 7 (Opportunities pixel-parity): "one signal chip" per card, ported
   1:1 from _prototypes/as-crm-redesign/index.html's .sig classes. */
#as-app .sig { display:inline-flex; align-items:center; gap:5px; font-size:10.5px; font-weight:600; padding:2px 7px; }
#as-app .sig.warn { background:var(--rdl); color:var(--rd); }
#as-app .sig.ok { background:var(--gnl); color:var(--gn); }
#as-app .sig.mut { background:var(--sa); color:var(--t3); border:1px solid var(--b); }
#as-app .sig.val { background:var(--acl); color:var(--ach); }

/* Phase 7: hover-reveal action rail — same buttons/handlers as before
   (.as-ft-actions: Capture+Sustain boards and Sustain's table; .as-opp-card-
   foot: Nurture board), just hidden until the card is hovered or keyboard-
   focused. Nothing live did hover-reveal before this; scoped to .as-opp-card
   and .as-funnels-table specifically so nothing outside those two contexts
   is affected. */
#as-app .as-opp-card .as-ft-actions,
#as-app .as-opp-card .as-opp-card-foot {
    opacity:0; transition:opacity .12s;
}
#as-app .as-opp-card:hover .as-ft-actions,
#as-app .as-opp-card:focus-within .as-ft-actions,
#as-app .as-opp-card:hover .as-opp-card-foot,
#as-app .as-opp-card:focus-within .as-opp-card-foot {
    opacity:1;
}
#as-app .as-funnels-table .as-ft-actions { opacity:0; transition:opacity .12s; }
#as-app .as-funnels-table tbody tr:hover .as-ft-actions,
#as-app .as-funnels-table tbody tr:focus-within .as-ft-actions {
    opacity:1;
}
#as-app .as-opp-make-proj {
    margin-left:auto; font-size:10px; color:var(--gn);
    font-weight:600; cursor:pointer; padding:2px 6px;
    text-decoration:none;
}
#as-app .as-opp-make-proj:hover {
    background:var(--gnl); color:var(--gn);
}

/* ── List view (AS-0221 Stage 7: rebuilt off <table> onto a div-row
   layout so a swipe gesture is structurally possible — see as-v-crm.js's
   oppListRowHtml/oppListRowSwipe header comment) ─────────────────────── */
#as-app .as-opp-list { background:var(--s); border:1px solid var(--b); font-size:12px; }
#as-app .as-opp-list-row {
    display:flex; align-items:center; gap:12px; padding:10px 12px;
    border-bottom:1px solid var(--sa); cursor:pointer; transition:background .08s;
}
#as-app .as-opp-list-row:hover { background:color-mix(in srgb, var(--ac) 4%, var(--s)); }
#as-app .as-opp-list-row:last-child { border-bottom:none; }
#as-app .as-opp-list-main { flex:1; min-width:0; }
#as-app .as-opp-list-title { font-weight:600; color:var(--t1); }
#as-app .as-opp-list-meta { font-size:10px; color:var(--t3); margin-top:2px; }
#as-app .as-opp-list-stage { flex-shrink:0; }
#as-app .as-opp-list-val { flex-shrink:0; min-width:70px; text-align:right; font-weight:600; color:var(--t1); }
#as-app .as-swipe-won{background:var(--gn)}
@media(max-width:768px) {
    #as-app .as-opp-list-row { flex-wrap:wrap; }
    #as-app .as-opp-list-main { flex:1 1 100%; order:1; }
    #as-app .as-opp-list-stage { order:2; }
    #as-app .as-opp-list-val { order:3; text-align:left; }
}

/* ── Edit Tray (slide-in) ──────────────────────────────────────── */
/* Right-anchored 380px panel on desktop. Bottom-anchored 80vh sheet
 * on mobile. Hidden by default; .as-tray-open slides it into view. */
#as-app .as-opp-tray {
    position:fixed; top:0; right:0; bottom:0;
    width:420px; max-width:100vw;
    background:var(--bg); border-left:1px solid var(--b);
    box-shadow:-4px 0 20px rgba(0,0,0,.12);
    transform:translateX(100%);
    transition:transform .25s ease;
    z-index:1000; overflow-y:auto;
    display:flex; flex-direction:column;
}
#as-app .as-opp-tray.as-tray-open {
    transform:translateX(0);
}
#as-app .as-tray-head {
    display:flex; justify-content:space-between; align-items:center;
    padding:14px 18px; border-bottom:1px solid var(--b);
    background:var(--s);
    position:sticky; top:0; z-index:1;
}
#as-app .as-tray-head h3 { margin:0; font-size:14px; color:var(--t1); }
#as-app .as-tray-actions { display:flex; gap:6px; }
#as-app .as-tray-actions .btn { font-size:11px; padding:5px 12px; }
#as-app .as-tray-body { padding:16px 18px; flex:1; }
#as-app .as-tray-body label {
    display:block; font-size:10px; font-weight:700;
    text-transform:uppercase; letter-spacing:.4px;
    color:var(--t3); margin-bottom:4px; margin-top:12px;
}
#as-app .as-tray-body label:first-child { margin-top:0; }
#as-app .as-tray-body input[type=text],
#as-app .as-tray-body input[type=number],
#as-app .as-tray-body input[type=date],
#as-app .as-tray-body input[type=datetime-local],
#as-app .as-tray-body select,
#as-app .as-tray-body textarea {
    width:100%; padding:7px 10px; border:1px solid var(--b);
    background:var(--inp-bg); color:var(--t1); font-size:12px;
    box-sizing:border-box;
}
#as-app .as-tray-body textarea { resize:vertical; min-height:80px; }
/* v0.10.29 (Communications, Phase 8): .fld — Add Event tray's field wrapper,
 * per the mock's own class name. Purely a spacing wrapper; label/input
 * styling already comes from the .as-tray-body rules above. */
#as-app .as-tray-body .fld { margin-bottom:4px; }
#as-app .as-tray-body .row {
    display:flex; gap:10px;
}
#as-app .as-tray-body .row > div { flex:1; }
#as-app .as-tray-contact-pick {
    display:flex; gap:6px; align-items:stretch;
}
#as-app .as-tray-contact-display {
    flex:1; padding:7px 10px; border:1px solid var(--b);
    background:var(--inp-bg); color:var(--t1); font-size:12px;
    display:flex; align-items:center; min-height:32px;
    cursor:pointer; transition:border-color .12s, background .12s;
}
/* v0.7.06: empty state reads as a click target, not a disabled input.
 * Dashed border + hover state cue the user that this opens the picker.
 * Pre-v0.7.06 the empty state looked identical to a normal input — users
 * tried to type a name and were confused when the field rejected input.
 * The "Add" / "Choose" button next to it remains the primary affordance;
 * this change makes the display surface itself a redundant click target. */
#as-app .as-tray-contact-display.is-empty {
    border-style:dashed; color:var(--t3); font-style:italic;
}
#as-app .as-tray-contact-display:hover {
    border-color:var(--ac);
}
#as-app .as-tray-contact-pick .btn {
    font-size:11px; padding:5px 10px; flex-shrink:0;
}
#as-app .as-tray-make-proj {
    margin-top:18px; padding:12px 14px;
    background:color-mix(in srgb, var(--gn) 8%, var(--bg));
    border-left:3px solid var(--gn);
    font-size:12px; color:var(--t1);
}
/* v0.10.115: Campaign origin panel — same info-card doctrine as
   .as-tray-make-proj above, accent instead of green since this is
   provenance, not a completed/won state. */
#as-app .as-tray-campaign-origin {
    margin-bottom:18px; padding:12px 14px;
    background:color-mix(in srgb, var(--ac) 8%, var(--bg));
    border-left:3px solid var(--ac);
    font-size:12px; color:var(--t1);
}
#as-app .as-tray-make-proj button[disabled] {
    opacity:.6; cursor:not-allowed;
}
#as-app .as-tray-foot {
    margin-top:20px; padding-top:14px; border-top:1px solid var(--sa);
    display:flex; justify-content:flex-end; gap:8px; flex-wrap:wrap;
}
/* v0.4.7: promote button on the contact tray sits left of Save changes */
#as-app .as-tray-promote {
    margin-right:auto; font-size:11px;
}

/* Mobile: tray becomes bottom sheet */
@media (max-width: 720px) {
    #as-app .as-opp-tray {
        top:auto; left:0; right:0; bottom:0;
        width:100%; max-width:100%;
        height:80vh; max-height:80vh;
        border-left:none; border-top:1px solid var(--b);
        transform:translateY(100%);
        box-shadow:0 -4px 20px rgba(0,0,0,.18);
    }
    #as-app .as-opp-tray.as-tray-open {
        transform:translateY(0);
    }
}

/* ── Contact picker modal ──────────────────────────────────────── */
/* v0.4.7: explicit z-index bump on the picker container so it appears
 * ABOVE the slide-in tray (which is z:1000). Pre-v0.4.7 the picker
 * inherited the generic .as-modal-bg z:200 and got hidden behind the
 * tray on Opportunities create flows. */
#as-app #as-m-contact-picker { z-index:1100; }
#as-app .as-cp-modal {
    width:480px; max-width:92vw;
    height:560px; max-height:80vh;
    display:flex; flex-direction:column;
}
/* v0.7.4: locked modal height so typing into the picker doesn't make
 * the dialog grow/shrink with the result count. Pre-v0.7.4 the modal
 * sized to its content — every keystroke that changed result count
 * caused a visible jump and made the search box hard to follow.
 * Fixed height + scrollable results = stable target. */
/* v0.4.8: picker .cb keeps padding:0 because the input + results provide
 * their own padding, but we add padding to the inner sections so content
 * doesn't crash into modal edges. */
#as-app .as-cp-modal .cb {
    padding:0; flex:1; display:flex; flex-direction:column;
    overflow:hidden;
}
#as-app .as-cp-input {
    margin:20px 24px 14px 24px; padding:11px 14px;
    border:1px solid var(--b); background:var(--inp-bg);
    color:var(--t1); font-size:13px;
    flex-shrink:0;
    /* v0.7.06: explicit box-sizing + width:auto override the inherited
     * `.as-modal input { width:100% }` which combined with the 40px horizontal
     * margin pushed the input past the modal edge. width:auto + the parent
     * flex column's content box gives correct sizing.
     * v0.7.07: bumped margin 20→24 horizontal, 18→20 top to match the new
     * row padding and give the input visible breathing room from modal edge. */
    box-sizing:border-box; width:auto;
}
#as-app .as-cp-input:focus {
    outline:none; border-color:var(--ac);
}
#as-app .as-cp-results {
    flex:1; overflow-y:auto;
    padding:4px 0 16px 0;
}
#as-app .as-cp-row {
    padding:12px 24px; cursor:pointer;
    border-top:1px solid var(--sa);
    transition:background .08s;
    /* v0.7.07: padding bumped 11px 20px → 12px 24px to match the wider input
     * inset, giving the picker rows visible left/right breathing room from the
     * modal edges and matching the input's horizontal alignment. */
}
#as-app .as-cp-row:first-child { border-top:none; }
#as-app .as-cp-row:hover {
    background:color-mix(in srgb, var(--ac) 6%, var(--s));
}
#as-app .as-cp-name {
    font-size:13px; font-weight:600; color:var(--t1);
}
#as-app .as-cp-sub {
    font-size:11px; color:var(--t3); margin-top:2px;
}
#as-app .as-cp-no-contact .as-cp-name {
    color:var(--t3); font-style:italic; font-weight:500;
}
#as-app .as-cp-create {
    background:color-mix(in srgb, var(--gn) 6%, var(--s));
}
#as-app .as-cp-create .as-cp-name {
    color:var(--gn);
}
#as-app .as-cp-empty {
    padding:30px 16px; text-align:center;
    color:var(--t3); font-size:12px; font-style:italic;
}

/* ── Segment manager modal (v0.4.8) ────────────────────────────── */
/* Opened from "Manage segments..." sentinel in the filter-row segment
 * dropdown. Lists current segments with rename/remove + an inline add. */
#as-app #as-m-seg-manager { z-index:1100; }
#as-app .as-seg-modal {
    width:520px; max-width:92vw;
    max-height:80vh;
    display:flex; flex-direction:column;
}
#as-app .as-seg-modal .cb {
    padding:18px 20px; flex:1;
    overflow-y:auto;
    display:flex; flex-direction:column; gap:12px;
}
#as-app .as-seg-list {
    display:flex; flex-direction:column;
    border:1px solid var(--b);
}
#as-app .as-seg-row {
    display:flex; align-items:center; gap:10px;
    padding:10px 14px;
    border-bottom:1px solid var(--sa);
    background:var(--s);
}
#as-app .as-seg-row:last-child { border-bottom:none; }
#as-app .as-seg-name {
    flex:1; font-size:13px; font-weight:600; color:var(--t1);
}
#as-app .as-seg-count {
    font-size:11px; color:var(--t3);
    padding:2px 8px; background:var(--sa);
}
#as-app .as-seg-row .btn { font-size:11px; padding:4px 10px; }
#as-app .as-seg-add {
    display:flex; gap:8px;
    padding-top:6px; border-top:1px solid var(--sa);
}
#as-app .as-seg-add input {
    flex:1; padding:8px 12px;
    border:1px solid var(--b); background:var(--inp-bg);
    color:var(--t1); font-size:13px;
}
#as-app .as-seg-add input:focus { outline:none; border-color:var(--ac); }
#as-app .as-seg-add .btn { font-size:12px; padding:7px 14px; flex-shrink:0; }

/* v0.8.04: Role-blocked UI state.
 *
 * Per role contract §4.2: manager/member gates DISABLE (visible but
 * obviously inert + tooltip-explained), admin gates HIDE (set via inline
 * style in as-role-gates.js). The class below paints the disabled state.
 *
 * pointer-events:none stops mouse clicks; the JS layer also captures
 * keyboard activations defensively. */
#as-app .as-role-blocked,
.as-role-blocked {
  opacity: 0.45;
  pointer-events: none;
  cursor: not-allowed;
  filter: grayscale(0.4);
}

/* ───────────────────────────────────────────────────────────────────────────
 * Background-activity indicator (#as-netbar)
 * INTAKE-096 retired the full-width animated sweeping stripe; v0.9.12 shrank
 * it to a quiet 14px ring. v0.10.146 (Glenn, live feedback — this exact
 * signal had already been toned down once and was still "a waste... should
 * just update in the background, you should never even know"): retired the
 * ring entirely for routine activity — .is-active carries no styling
 * anymore, netBusy/netIdle keep toggling the class for harmless bookkeeping
 * but nothing renders. The only thing #as-netbar shows now is .is-offline —
 * a real "Account offline" pill, set via as-ui.js netFailure()/netSuccess(),
 * that only appears after a genuine run of unreachable-server failures, not
 * for normal traffic or routine HTTP error responses.
 * ──────────────────────────────────────────────────────────────────────────*/
.as-netbar{display:inline-flex;align-items:center;align-self:center;height:22px;opacity:0;width:0;overflow:hidden;pointer-events:none;transition:opacity .2s ease,width .2s ease;white-space:nowrap;}
.as-netbar.is-offline{opacity:1;width:auto;pointer-events:auto;background:var(--rdl);color:var(--rd);font-size:11px;font-weight:600;padding:3px 10px;border-radius:20px;gap:6px;}
.as-netbar.is-offline::before{content:"";width:6px;height:6px;flex:0 0 6px;border-radius:50%;background:var(--rd);animation:as-netbar-pulse 1.4s ease-in-out infinite;}
@keyframes as-netbar-pulse{0%,100%{opacity:1;}50%{opacity:0.35;}}

/* v0.9.17: Engage view content (top-bar button removed v0.10.14 — see
 * templates/admin-app.php; Phase 9: promoted from a right-side tray to a
 * full routed view, #as-v-engage — these rules re-scoped from the retired
 * #as-engage-tray selector, content/sizing unchanged). Cards stack
 * full-width; heat-map stays compact. */
#as-app #as-v-engage .engage-card,#as-app #as-performance-panel-engage .engage-card{width:100%;}
#as-app #as-v-engage .heatmap-table th,#as-app #as-v-engage .heatmap-table td,#as-app #as-performance-panel-engage .heatmap-table th,#as-app #as-performance-panel-engage .heatmap-table td{padding:4px 2px;}
#as-app #as-v-engage .heatmap-table,#as-app #as-performance-panel-engage .heatmap-table{font-size:11px;}

/* v0.9.19: dashboard bottom row — Campaign Performance chart + Sales Funnel /
 * Campaign rings (two tabbed cards). Ported from the locked prototype. */
#as-app .as-dc-row{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:16px;align-items:start;}
#as-app .as-dc-head{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;padding:11px 15px;border-bottom:1px solid var(--b);}
#as-app .as-dc-head h3{font-size:13px;font-weight:600;}
#as-app .as-dc-switch{display:flex;flex-shrink:0;}
#as-app .as-dc-switch button{font-family:inherit;font-size:10px;padding:5px 10px;border:1px solid var(--b);background:var(--s);color:var(--t2);cursor:pointer;margin-left:-1px;white-space:nowrap;}
#as-app .as-dc-switch button.on{background:var(--t1);border-color:var(--t1);color:#fff;font-weight:600;}
#as-app .as-dc-body{padding:14px 16px;}
#as-app .as-dc-legend{display:flex;flex-wrap:wrap;gap:14px;margin-bottom:6px;}
#as-app .dc-lg{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--t2);cursor:pointer;}
#as-app .dc-lg.off{opacity:.35;}
#as-app .dc-lg b{font-weight:700;color:var(--t1);}
#as-app .dc-chip{width:12px;height:3px;}
#as-app #as-dc-chart{width:100%;height:auto;display:block;}
#as-app .dc-gl{stroke:var(--sa);stroke-width:1;}
#as-app .dc-ax{font-size:9px;fill:var(--t3);}
#as-app .dc-ln{fill:none;stroke-width:2.2;}
#as-app .dc-empty{padding:24px;text-align:center;color:var(--t3);font-size:12px;}
#as-app .dc-cmp{display:flex;align-items:center;gap:11px;padding:9px 2px;border-bottom:1px solid var(--sa);cursor:pointer;}
#as-app .dc-cmp:last-child{border-bottom:none;}
#as-app .dc-ring{width:42px;height:42px;flex-shrink:0;}
#as-app .dc-cmp-n{font-size:12px;font-weight:600;}
#as-app .dc-cmp:hover .dc-cmp-n{color:var(--ac);}
#as-app .dc-cmp-s{font-size:10px;color:var(--t3);margin-top:2px;}
#as-app .dc-flag{display:inline-block;font-size:8px;font-weight:700;text-transform:uppercase;padding:1px 5px;margin-left:5px;}
#as-app .dc-flag.win{background:var(--gnl);color:var(--gn);}
#as-app .dc-flag.need{background:var(--rdl);color:var(--rd);}
#as-app .dc-fn-svg{width:100%;height:auto;display:block;max-height:230px;}
#as-app .dc-fn-l{font-size:11px;fill:var(--t2);}
#as-app .dc-fn-r{font-family:Georgia,serif;font-weight:700;fill:var(--t1);font-size:13px;}
@media(max-width:768px){#as-app .as-dc-row{grid-template-columns:1fr;}}


/* v0.8.53: Send-email surface rendered as a right-side tray (matches the
   opportunity/contact edit tray) instead of a centered modal. CSS-only — the
   asShowModal('sendemail') / asHideModals() plumbing is unchanged. Backdrop is
   transparent + click-through so the rest of the UI stays usable, like the
   other trays. On mobile it becomes a bottom sheet. */
#as-app #as-m-sendemail { background:transparent; pointer-events:none; justify-content:flex-end; align-items:stretch; }
#as-app #as-m-sendemail .as-modal {
    pointer-events:auto;
    width:520px; max-width:100vw; height:100vh; max-height:100vh;
    border-radius:0; overflow-y:auto;
    border-left:1px solid var(--b);
    box-shadow:-4px 0 20px rgba(0,0,0,.12);
    transform:translateX(100%); transition:transform .25s ease;
    display:flex; flex-direction:column;
}
#as-app #as-m-sendemail.show .as-modal { transform:translateX(0); }
#as-app #as-m-sendemail .as-modal .cb { flex:1; overflow-y:auto; }
@media (max-width: 720px) {
    #as-app #as-m-sendemail { align-items:flex-end; }
    #as-app #as-m-sendemail .as-modal {
        width:100%; max-width:100%; height:85vh; max-height:85vh;
        border-left:none; border-top:1px solid var(--b);
        transform:translateY(100%); box-shadow:0 -4px 20px rgba(0,0,0,.18);
    }
    #as-app #as-m-sendemail.show .as-modal { transform:translateY(0); }
}

/* ───────────────────────────────────────────────────────────────────────────
 * AS-UI007 — Shared dropdown/menu component.
 * Replaces one-off inline style + onmouseover/onmouseout background-swap on the
 * Quick-add menu (and any future popover) with token-driven classes. Hover comes
 * from :hover (var(--sa)), not inline JS, so spacing/hover/color stay consistent
 * with the rest of the shell. Zero radius per suite UI contract.
 * ──────────────────────────────────────────────────────────────────────────*/
#as-app .as-menu {
    position:absolute; right:0; top:100%; margin-top:4px;
    background:var(--bg); border:1px solid var(--b);
    box-shadow:0 4px 12px rgba(0,0,0,.12); z-index:100; min-width:160px;
}
#as-app .as-menu-item {
    padding:6px 14px; font-size:12px; cursor:pointer;
    border-bottom:1px solid var(--sa); transition:background .12s ease;
}
#as-app .as-menu-item:last-child { border-bottom:none; }
#as-app .as-menu-item:hover { background:var(--sa); }
/* toolbar-doctrine-v2 (2026-08-16): thin divider between the sysmenu's
 * folded-in quick-add create items and its original theme/toggle items. */
#as-app .as-menu-sep { height:1px; background:var(--b); margin:4px 0; }

/* header/toolbar doctrine: ⋮ system menu trigger + toggle rows */
#as-app .as-sysmenu-btn { width:34px; height:34px; padding:0 !important; display:inline-flex; align-items:center; justify-content:center; box-sizing:border-box; color:var(--t3); }
#as-app .as-sysmenu-btn:hover { color:var(--t1); }
#as-app .as-sysmenu-btn svg { width:16px; height:16px; display:block; }
#as-app #as-sysmenu { min-width:190px; }
#as-app .as-menu-toggle { display:flex; align-items:center; justify-content:space-between; gap:18px; }
#as-app .as-menu-check { color:var(--ac); font-weight:700; font-size:13px; line-height:1; opacity:0; }
#as-app .as-menu-check::before { content:'\2713'; }
#as-app .as-menu-check.on { opacity:1; }

/* ───────────────────────────────────────────────────────────────────────────
 * v0.10.23 (Phase 5, Display): ported 1:1 from
 * _prototypes/as-integrated/surfaces/display.html's embedded <style> block.
 * Display is one of the two documented .toolbar exceptions (Dashboard is the
 * other) — this left-rail .setwrap/.setrail/.setmain layout replaces it.
 * Selectors gained the #as-app prefix (file convention); values/tokens are
 * otherwise unchanged from the prototype source.
 * ──────────────────────────────────────────────────────────────────────────*/
#as-app .setwrap { display:flex; gap:0; height:calc(100vh - 74px); margin:-20px -28px; }
#as-app .setrail { width:206px; flex:0 0 auto; border-right:1px solid var(--b); background:var(--s); overflow-y:auto; padding:10px 0; }
#as-app .setgrp { font-size:9px; letter-spacing:.9px; text-transform:uppercase; color:var(--t3); font-weight:700; padding:13px 16px 5px; }
#as-app .setlink { display:flex; align-items:center; gap:10px; width:100%; text-align:left; padding:8px 16px; font-size:12.5px; font-weight:500; color:var(--t2); background:none; border:none; cursor:pointer; font-family:inherit; }
#as-app .setlink:hover { background:var(--sa); color:var(--t1); }
#as-app .setlink.on { background:var(--acl); color:var(--ach); font-weight:600; box-shadow:inset 2px 0 0 var(--ac); }
#as-app .setlink svg { width:15px; height:15px; flex:0 0 auto; }
#as-app .setmain { flex:1; min-width:0; overflow-y:auto; padding:22px 26px 60px; }
#as-app .setmain h3 { font-family:var(--serif); font-size:19px; font-weight:700; color:var(--t1); }
#as-app .setmain .lead { font-size:12.5px; color:var(--t3); margin:3px 0 18px; line-height:1.5; }
#as-app .panel { background:var(--s); border:1px solid var(--b); box-shadow:var(--card-sh); margin-bottom:16px; }
#as-app .paneltitle { font-size:9.5px; letter-spacing:.8px; text-transform:uppercase; color:var(--t3); font-weight:700; margin:20px 0 9px; }
#as-app .paneltitle:first-child { margin-top:0; }
#as-app .frow { display:flex; align-items:center; gap:12px; padding:12px 15px; border-bottom:1px solid var(--b2); }
#as-app .frow:last-child { border-bottom:none; }
#as-app .frow .g { flex:1; min-width:0; }
#as-app .frow .g b { font-weight:600; font-size:13px; display:block; }
#as-app .frow .g span { font-size:11.5px; color:var(--t3); }
#as-app .frow .val { font-size:12.5px; color:var(--t2); font-weight:600; }
#as-app .frow.click { cursor:pointer; }
#as-app .frow.click:hover { background:var(--sa); }
#as-app .sw { width:36px; height:20px; background:var(--b); position:relative; transition:.15s; flex:0 0 auto; display:inline-block; cursor:pointer; }
#as-app .sw.on { background:var(--ac); }
#as-app .sw::after { content:""; position:absolute; top:2px; left:2px; width:16px; height:16px; background:#fff; transition:.15s; }
#as-app .sw.on::after { left:18px; }
#as-app .chip2 { font-size:10px; font-weight:700; padding:2px 8px; text-transform:uppercase; letter-spacing:.3px; }
#as-app .chip2.admin { background:var(--rdl); color:var(--rd); }
#as-app .chip2.manager { background:var(--bll); color:var(--bl); }
#as-app .chip2.operator { background:var(--gnl); color:var(--gn); }
#as-app .chip2.ambassador { background:var(--pul); color:var(--pu); }
#as-app .tbl2 { width:100%; border-collapse:collapse; font-size:12.5px; }
#as-app .tbl2 th { text-align:left; font-size:10px; letter-spacing:.5px; text-transform:uppercase; color:var(--t3); font-weight:700; padding:9px 15px; border-bottom:1px solid var(--b); background:var(--head); }
#as-app .tbl2 td { padding:10px 15px; border-bottom:1px solid var(--b2); }
#as-app .tbl2 tr:last-child td { border-bottom:none; }
#as-app .tbl2 td.num, #as-app .tbl2 th.num { text-align:right; font-variant-numeric:tabular-nums; }
#as-app .rate-in { width:64px; padding:5px 8px; font-size:12.5px; border:1px solid var(--b); background:var(--bg); color:var(--t1); text-align:right; font-family:inherit; }
#as-app .stagechip { display:inline-flex; align-items:center; gap:8px; padding:8px 12px; border:1px solid var(--b); background:var(--bg); font-size:12.5px; font-weight:600; margin:0 8px 8px 0; }
#as-app .stagechip .gr { color:var(--t3); cursor:grab; }
#as-app .cap { display:grid; grid-template-columns:1.4fr repeat(3,1fr); gap:0; }
#as-app .cap>div { padding:9px 14px; border-bottom:1px solid var(--b2); font-size:12px; }
#as-app .cap .h { font-size:10px; letter-spacing:.4px; text-transform:uppercase; color:var(--t3); font-weight:700; background:var(--head); border-bottom:1px solid var(--b); }
#as-app .cap .ck { color:var(--gn); font-weight:700; }
#as-app .cap .no { color:var(--t3); }
#as-app .av2 { width:32px; height:32px; flex:0 0 auto; display:flex; align-items:center; justify-content:center; color:#fff; font-weight:700; font-size:11px; }
#as-app .hint2 { font-size:11.5px; color:var(--t3); padding:0 15px 12px; }
#as-app .note { background:var(--acl); border:1px solid var(--ac); padding:11px 13px; font-size:12px; color:var(--t2); line-height:1.5; }
#as-app .note b { color:var(--ach); }
#as-app .role2 { font-size:9.5px; font-weight:700; text-transform:uppercase; letter-spacing:.3px; padding:1px 6px; background:var(--bll); color:var(--bl); }
/* AS-0231: Settings (Display) cancels .cnt's 28px side padding, but on mobile .cnt is 12px (8px at 480), so the settings area stuck out past the screen (measured +12px at 390). Placed after the base rule so it wins. */
@media (max-width:768px) { #as-app .setwrap { margin:-12px -12px; } }
@media (max-width:480px) { #as-app .setwrap { margin:-10px -8px; } #as-app .setmain { padding:16px 14px 60px; } }
@media (max-width:820px) {
    #as-app .setrail { width:56px; }
    #as-app .setlink span, #as-app .setgrp { display:none; }
    #as-app .setlink { justify-content:center; }
}

/* v0.10.108: shared recipient-email autocomplete dropdown (as-recipient-
 * autocomplete.js) — appended directly to document.body (not #as-app) so it
 * can position over a modal's own overflow/z-index without being clipped, so
 * these rules are deliberately unscoped. */
.as-rac-dropdown { position:absolute; background:var(--s); border:1px solid var(--b); box-shadow:0 4px 12px rgba(0,0,0,.15); z-index:100000; max-height:220px; overflow-y:auto; font-family:inherit; }
.as-rac-row { padding:6px 10px; font-size:12.5px; cursor:pointer; border-bottom:1px solid var(--b2); color:var(--t1); }
.as-rac-row:last-child { border-bottom:none; }
.as-rac-row-active, .as-rac-row:hover { background:var(--sa); }
.as-rac-name { font-weight:600; }
.as-rac-email { color:var(--t3); font-size:11.5px; }
/* AS-0096: a mail-history-derived suggestion (not a saved contact) gets a
 * quiet inline tag so it reads as "we've seen this address" rather than
 * "this is a verified contact record" — same visual weight as .as-rac-email. */
.as-rac-suggested { color:var(--t3); font-size:10px; font-style:italic; }

/* AS-0208 (v0.10.308): declined events are hidden by default; with the
 * calendar Filters popover's "Show declined" on they render dimmed. Every
 * chip/card/banner that carries data-event-id gets data-declined="1". */
#as-app [data-declined="1"]{opacity:.45}
#as-app [data-declined="1"] .as-wk-tg-evt-title,
#as-app .as-cal-evt[data-declined="1"],
#as-app .as-event-card[data-declined="1"] .as-event-title{text-decoration:line-through;text-decoration-color:var(--t3)}

/* ═══ AS-MOBILE-PROTO (v0.10.346) — phone Priorities + Communications Split brought to the approved
   prototypes: _prototypes/actionstudio__as-priorities-v1-apple-style.html and
   actionstudio__as-0187-v5-apple-style-split.html (Glenn confirmed v5 as the locked Split direction).
   Appended LAST on purpose: it re-skins rules declared earlier in this file at equal specificity.
   Every selector below is either phone-only (<=768px) or a desktop default that hides a phone-only
   element, so desktop is unchanged. Tokens only (--bg/--s/--sa/--b/--b2/--t1-3/--ac/--am/--aml/--bl/
   --gn/--pu/--rd) so warm/dark follow the Hub theme. ═══ */
#as-app .as-top-plus,
#as-app .as-task-seg,
#as-app .as-task-done-wrap,
#as-app .as-kb-pri-lead,
#as-app .as-hd-m,
#as-app .as-exp-btn,
#as-app .as-triage-calhd,
#as-app .as-event-ic { display:none; }
#as-app .as-top-plus { padding:0; }

@media(max-width:768px) {
    /* ── Priorities: header "+" (prototype: page header carries the add action) ── */
    #as-app[data-as-view="tasks"] .top .as-top-plus { display:inline-flex; align-items:center; justify-content:center; width:28px; height:28px; border-radius:50%; }
    #as-app[data-as-view="tasks"] .top .as-top-plus::before { font-size:18px; }
    #as-app #as-v-tasks > .toolbar .btn-plus { display:none; }

    /* ── Priorities toolbar: Queue chip | Know·Do·Measure segmented control | Done chip, then a slim
          row for All/This week + search/filter/view-swap (kept — function, not in the prototype) ── */
    #as-app #as-v-tasks > div:first-child { gap:8px; padding:10px 14px; }
    #as-app #as-v-tasks > div:first-child > .as-task-scope-row { display:contents; }
    #as-app #as-v-tasks > div:first-child::after { content:''; order:4; flex:0 0 100%; height:0; }
    #as-app #as-task-queue-wrap { order:1; flex:0 0 auto; border:0; background:none; padding:0; }
    #as-app #as-task-seg-mount { display:block; order:2; flex:1 1 0; min-width:0; }
    #as-app .as-task-done-wrap { display:block; order:3; flex:0 0 auto; }
    #as-app #as-task-scope-tabs { order:5; flex:0 0 auto; }
    #as-app #as-v-tasks > div:first-child > #as-task-summary { display:none; }
    #as-app #as-v-tasks > div:first-child > .as-task-icon-row { order:6; flex:1 1 0; align-self:center; justify-content:flex-end; }
    #as-app #as-task-queue-btn,
    #as-app #as-task-done-btn { display:flex; align-items:center; gap:5px; font-size:10.5px; font-weight:700; line-height:1; padding:7px 10px; min-height:32px; border:1px solid var(--b); background:var(--s); color:var(--t2); border-radius:8px; cursor:pointer; white-space:nowrap; }
    #as-app #as-task-queue-btn { color:#7a5f10; border-color:#ecd9a3; background:var(--aml); }
    #as-app #as-task-queue-btn .n,
    #as-app #as-task-done-btn .n { background:var(--sa); color:var(--t3); font-size:9px; font-weight:800; padding:1px 5px; border-radius:6px; }
    #as-app #as-task-queue-btn .n { background:rgba(184,134,11,.16); color:#7a5f10; }
    #as-app #as-task-queue-btn .n:empty,
    #as-app #as-task-done-btn .n:empty { display:none; }
    #as-app #as-task-seg-mount .as-kb-pills { display:flex; gap:0; overflow:hidden; margin:0; padding:0; border:1px solid var(--b); background:var(--bg); border-radius:8px; }
    #as-app #as-task-seg-mount .as-kb-pill { flex:1 1 0; min-width:0; font-size:11.5px; font-weight:700; line-height:1; padding:0; min-height:30px; border:0; border-radius:0; background:none; color:var(--t3); cursor:pointer; }
    #as-app #as-task-seg-mount .as-kb-pill.on { background:var(--t1); color:var(--s); }

    /* ── Priorities section header (prototype .sec-hd): serif title + "N tasks" ── */
    #as-app #as-kanban-board .as-kb-header { border-bottom:0 !important; padding:12px 16px 6px; justify-content:flex-start; gap:8px; }
    #as-app #as-kanban-board .as-kb-header > span:first-child { font-family:'Fraunces',Georgia,serif; font-size:17px; font-weight:700; color:var(--t1) !important; }
    #as-app #as-kanban-board .as-kb-count { font-size:0; background:none; padding:0 0 0 0; padding-top:2px; font-weight:400; }
    #as-app #as-kanban-board .as-kb-count::after { content:attr(data-label); font-size:10.5px; color:var(--t3); }
    #as-app #as-kanban-board .as-kb-col { background:transparent; border-radius:0; }

    /* ── Priorities rows (prototype .tk-row): flush white rows, 9px priority dot, 13px bold title,
          11.5px meta, round move buttons ── */
    #as-app #as-kanban-board .as-kb-body { padding:0; min-height:0; }
    #as-app #as-kanban-board .as-kb-card { display:grid; grid-template-columns:auto minmax(0,1fr) auto; grid-template-areas:"pri t a" "pri m a"; align-items:center; column-gap:11px; row-gap:2px; margin:0; padding:12px 16px; border:0; border-bottom:1px solid var(--b2); border-radius:0; background:var(--s); box-shadow:none; }
    #as-app #as-kanban-board .as-kb-card.as-overdue { background:var(--rdl); }
    #as-app #as-kanban-board .as-kb-card > .as-proj-dot { display:none; }
    #as-app #as-kanban-board .as-kb-pri-lead { display:block; grid-area:pri; width:9px; height:9px; border-radius:50%; }
    #as-app #as-kanban-board .as-kb-title { grid-area:t; font-size:13px; font-weight:700; margin:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
    #as-app #as-kanban-board .as-kb-title .as-pt-pill { display:none; }
    #as-app #as-kanban-board .as-kb-meta { grid-area:m; font-size:11.5px; min-width:0; flex-wrap:nowrap; overflow:hidden; }
    #as-app #as-kanban-board .as-kb-meta .as-kb-pri { display:none; }
    #as-app #as-kanban-board .as-kb-owner { max-width:none; font-size:11.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    #as-app #as-kanban-board .as-kb-due { font-size:11.5px; flex:0 0 auto; }
    #as-app #as-kanban-board .as-kb-actions { grid-area:a; margin:0; gap:4px; }
    #as-app #as-kanban-board .as-kb-actions button { width:26px; height:26px; padding:0; border-radius:50%; display:flex; align-items:center; justify-content:center; background:var(--s); color:var(--t3); font-size:0; }
    #as-app #as-kanban-board .as-kb-actions button svg { width:12px; height:12px; }
    #as-app #as-kanban-board .as-kb-actions button:hover { background:var(--s); color:var(--t1); border-color:var(--b); }

    /* ── Queue / Done bottom sheets (prototype .sheet): grabber, header + close, inset item cards ── */
    #as-app #as-task-queue-tray,
    #as-app #as-task-done-tray { border-radius:18px 18px 0 0; padding:0; max-height:72vh; }
    #as-app #as-task-queue-tray::before,
    #as-app #as-task-done-tray::before { content:''; display:block; width:36px; height:4px; background:var(--b); border-radius:2px; margin:9px auto 4px; }
    #as-app #as-task-queue-tray .as-hd-d,
    #as-app #as-task-done-tray .as-hd-d { display:none; }
    #as-app #as-task-queue-tray .as-hd-m { display:inline; }
    #as-app #as-task-queue-tray .as-tray-head h3,
    #as-app #as-task-done-tray .as-tray-head h3 { font-size:14px; font-weight:700; }
    #as-app #as-task-queue-tray .as-tray-body,
    #as-app #as-task-done-tray .as-tray-body { padding:10px 14px 16px; }
    #as-app #as-task-queue-tray .as-qt-item { background:var(--bg); border:1px solid var(--b); border-radius:10px; padding:10px 12px; margin:0 0 8px !important; display:block; }
    #as-app #as-task-queue-tray .as-qt-item .as-kb-title { white-space:normal; font-size:12.5px; font-weight:600; margin-bottom:8px; }
    #as-app #as-task-queue-tray .as-qt-item .as-kb-actions { display:flex; gap:6px; margin-top:0 !important; }
    #as-app #as-task-queue-tray .as-qt-item .as-kb-actions button { flex:1; width:auto; height:auto; font-size:10.5px; font-weight:700; padding:7px 0; border:1px solid var(--b); border-radius:7px; background:var(--s); color:var(--qc,var(--t2)); }
    #as-app #as-task-done-tray .as-kb-card { display:block; background:none; border:0; border-bottom:1px solid var(--b2); border-radius:0; padding:9px 4px; margin:0 !important; }
    #as-app #as-task-done-tray .as-kb-title { text-decoration:line-through; color:var(--t3); font-size:12.5px; font-weight:600; }

    /* ── Communications Split ── */
    /* Section headers (prototype .sec-hd): serif 18px title, "N unread" sub, expand icon at the right */
    #as-app #as-comms-panel-triage .as-triage-hd { border-bottom:0; padding:12px 16px 4px; min-height:0; gap:8px; justify-content:flex-start; cursor:default; }
    #as-app #as-comms-panel-triage .as-triage-hd h4 { font-family:'Fraunces',Georgia,serif; font-size:18px; font-weight:700; margin:0; flex:0 0 auto; margin-right:auto; display:flex; align-items:baseline; gap:8px; }
    #as-app #as-comms-panel-triage .as-triage-hd-inbox .as-triage-chev { display:none; }
    #as-app #as-comms-panel-triage .as-triage-section-followup .as-triage-hd { cursor:pointer; }
    #as-app #as-split-inbox-unread-count { font-size:0; font-family:var(--sans,inherit); }
    #as-app #as-split-inbox-unread-count[data-n]::after { content:attr(data-n) ' unread'; font-size:10.5px; font-weight:400; color:var(--t3); }
    #as-app .as-exp-btn { display:flex; align-items:center; justify-content:center; width:26px; height:26px; padding:0; flex:0 0 auto; border:1px solid var(--b); background:var(--s); border-radius:7px; color:var(--t3); cursor:pointer; }
    #as-app .as-exp-btn svg { width:13px; height:13px; }
    #as-app .as-triage-wrap.as-density-mail .as-exp-btn[data-mode="mail"],
    #as-app .as-triage-wrap.as-density-cal .as-exp-btn[data-mode="cal"] { background:var(--sa); color:var(--t1); border-color:#d3cfc4; }
    #as-app .as-triage-calhd { display:flex; align-items:center; gap:8px; padding:12px 16px 4px; }
    #as-app .as-triage-calhd .ttl { font-family:'Fraunces',Georgia,serif; font-size:18px; font-weight:700; flex:0 0 auto; }
    #as-app .as-triage-calhd .sub { font-size:10.5px; color:var(--t3); margin-right:auto; padding-top:2px; }
    /* the AS-0226 up/down divider is replaced by the per-section expand icons */
    #as-app .as-triage-vdivider { display:none; }
    /* one continuous column like the prototype: no card chrome, no inter-section gaps */
    #as-app .as-triage-wrap { gap:0; }
    #as-app .as-triage-left { border:0; border-radius:0; background:transparent; }
    #as-app .as-triage-section-inbox { max-height:none; border-bottom:0; padding-bottom:0; }
    #as-app .as-triage-section-followup { margin-top:0; }
    #as-app .as-triage-right { gap:0; }
    #as-app #as-triage-right .as-triage-row2 > .card { border:0; background:transparent; }
    #as-app #as-triage-right .as-triage-row2 > .card > .cb { padding:0; }
    /* expanded/contracted: contracted section becomes the prototype's slim summary card */
    #as-app .as-triage-wrap.as-density-mail .as-triage-right { flex:0 0 auto; max-height:none; overflow:visible; }
    #as-app .as-triage-wrap.as-density-mail .as-triage-right > :not(.as-triage-calhd) { display:none; }
    #as-app .as-triage-wrap.as-density-mail .as-triage-calhd { margin:4px 14px 8px; padding:11px 16px; background:var(--s); border-radius:10px; box-shadow:0 1px 3px rgba(0,0,0,.06); border-left:3px solid var(--bl); }
    #as-app .as-triage-wrap.as-density-mail .as-triage-calhd .ttl { font-family:var(--sans,inherit); font-size:12.5px; }
    #as-app .as-triage-wrap.as-density-cal .as-triage-left { flex:0 0 auto; max-height:none; overflow:visible; }
    #as-app .as-triage-wrap.as-density-cal .as-triage-left > :not(.as-triage-section-inbox) { display:none; }
    #as-app .as-triage-wrap.as-density-cal .as-triage-section-inbox > :not(.as-triage-hd) { display:none; }
    #as-app .as-triage-wrap.as-density-cal .as-triage-section-inbox { margin:4px 14px 8px; background:var(--s); border-radius:10px; box-shadow:0 1px 3px rgba(0,0,0,.06); border-left:3px solid var(--ac); }
    #as-app #as-comms-panel-triage .as-triage-wrap.as-density-cal .as-triage-hd-inbox { padding:11px 16px; }
    #as-app #as-comms-panel-triage .as-triage-wrap.as-density-cal .as-triage-hd-inbox h4 { font-family:var(--sans,inherit); font-size:12.5px; }
    #as-app .as-triage-wrap.as-density-cal .as-triage-right { order:0; }

    /* Two-line rows (prototype .in-row): avatar | name + time / subject / 2-line snippet. Replaces the
       one-line checkbox+kebab table row whose subject and sender truncated (flex:1 on .as-email-subject
       zeroed its flex-basis, so width:100% never wrapped it to its own line). Checkbox hidden on
       phones (bulk select is a desktop pattern); the kebab stays, vertically centered, as the row's menu. */
    #as-app #as-comms-panel-triage .as-triage-list .as-email-row { display:grid; grid-template-columns:38px minmax(0,1fr) auto auto; grid-template-areas:"av nm tm kb" "av sj sj kb" "av sn sn kb"; align-items:center; column-gap:11px; row-gap:2px; padding:12px 16px; margin:0; background:var(--s); border-bottom:1px solid var(--b2); }
    #as-app #as-comms-panel-triage .as-triage-list .as-email-row-check-wrap { display:none; }
    #as-app #as-comms-panel-triage .as-triage-list .as-email-row-check { display:none; }
    #as-app #as-comms-panel-triage .as-triage-list .as-email-avatar { grid-area:av; grid-row:1 / span 3; width:38px; height:38px; font-size:13px; margin:0; }
    #as-app #as-comms-panel-triage .as-triage-list .as-email-from { grid-area:nm; font-size:13.5px; font-weight:700; padding:0; min-width:0; width:auto; flex:none; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    #as-app #as-comms-panel-triage .as-triage-list .as-email-date { grid-area:tm; width:auto; flex:none; font-size:11px; color:var(--t3); padding:0; text-align:right; }
    #as-app #as-comms-panel-triage .as-triage-list .as-email-kebab-left { grid-area:kb; grid-row:1 / span 3; align-self:center; margin:0; }
    #as-app #as-comms-panel-triage .as-triage-list .as-email-subject { display:contents; }
    #as-app #as-comms-panel-triage .as-triage-list .as-email-subject-text { grid-area:sj; display:block; font-size:12.5px; font-weight:600; margin:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }
    #as-app #as-comms-panel-triage .as-triage-list .as-email-snippet { grid-area:sn; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; white-space:normal; font-size:12px; line-height:1.4; color:var(--t3); margin:0; min-width:0; }
    #as-app #as-comms-panel-triage .as-triage-list .as-snip-dash,
    #as-app #as-comms-panel-triage .as-triage-list .as-email-chip { display:none; }
    #as-app #as-comms-panel-triage .as-triage-list .as-split-listfoot { border-radius:0; }

    /* Balanced default: Inbox shows ~3 rows (prototype) and scrolls inside; the sticky Unread/View more/View all footer
       needs the extra 44px. Expanded Inbox (density-mail) lifts the cap. */
    #as-app .as-triage-wrap:not(.as-density-mail) .as-triage-section-inbox .as-triage-list { max-height:308px; overflow-y:auto; -webkit-overflow-scrolling:touch; }

    /* Communications mode tabs (prototype .in-tabs): text tabs with a 2px accent underline instead of the icon segmented control */
    #as-app #as-comms-toolbar > .grow { display:none; }
    #as-app #as-comms-mode-seg { display:flex; flex:1 1 0; min-width:0; gap:0; border:0; background:none; padding:0; }
    #as-app #as-comms-mode-seg button { flex:1 1 0; justify-content:center; padding:9px 0; font-size:12px; font-weight:700; color:var(--t3); background:none; border:0; border-bottom:2px solid transparent; border-radius:0; box-shadow:none; }
    #as-app #as-comms-mode-seg button svg { display:none; }
    #as-app #as-comms-mode-seg button.on { color:var(--t1); background:none; border-bottom-color:var(--ac); }

    /* Calendar rows (prototype .cal-ev-row + .cal-ic): circular type-colored icon badge replaces the
       month/day date box; edit/flag buttons hidden on the phone row (tap opens the detail popover). */
    #as-app #as-split-today-list .as-event-card,
    #as-app #as-comms-panel-cal .as-event-card { gap:11px; padding:12px 16px; border-bottom:1px solid var(--b2); background:var(--s); }
    #as-app #as-split-today-list .as-event-date,
    #as-app #as-comms-panel-cal .as-event-date { width:34px; height:34px; min-width:34px; flex:0 0 34px; padding:0; border:0; border-radius:50%; background:var(--evc,var(--ac)); color:#fff; display:flex; align-items:center; justify-content:center; }
    #as-app #as-split-today-list .as-event-date .as-event-month,
    #as-app #as-split-today-list .as-event-date .as-event-day,
    #as-app #as-comms-panel-cal .as-event-date .as-event-month,
    #as-app #as-comms-panel-cal .as-event-date .as-event-day { display:none; }
    #as-app #as-split-today-list .as-event-ic,
    #as-app #as-comms-panel-cal .as-event-ic { display:block; width:16px; height:16px; }
    #as-app #as-split-today-list .as-event-acts,
    #as-app #as-comms-panel-cal .as-event-acts { display:none !important; }
    #as-app #as-split-today-list .as-event-title,
    #as-app #as-comms-panel-cal .as-event-title { font-size:13.5px; font-weight:700; }
    #as-app #as-split-today-list .as-event-meta,
    #as-app #as-comms-panel-cal .as-event-meta { font-size:12px; color:var(--t3); }

    /* Calendar week strip (prototype .cal-strip): flat edge-to-edge white strip, 30px day circles (today = red,
       selected = sand). Also fixes the 8px internal overflow measured at 393px (content 367 in a 359 box: the
       7 day buttons had no min-width:0). */
    #as-app #as-cal-weekstrip-card { margin:0 -16px 8px; padding:10px 14px 8px; border:0; border-bottom:1px solid var(--b); border-radius:0; box-shadow:none; background:var(--s); overflow:hidden; }
    #as-app .as-cal-ws-days { gap:0; }
    #as-app .as-cal-ws-day { min-width:0; gap:5px; padding:0; }
    #as-app .as-cal-ws-day .dn { font-size:9.5px; }
    #as-app .as-cal-ws-day .dd { width:30px; height:30px; line-height:30px; font-size:14px; font-weight:600; }
    #as-app .as-cal-ws-day.as-cal-ws-today .dd { background:var(--rd); color:#fff; }
    #as-app .as-cal-ws-day.as-cal-ws-on:not(.as-cal-ws-today) .dd { background:var(--sa); color:var(--t1); }
    #as-app .as-cal-ws-day.as-cal-ws-on.as-cal-ws-today .dd { background:var(--rd); }
    #as-app .as-cal-ws-day.as-cal-ws-today::after { display:none; }
}

/* AS-0246 beta affordance: Beta features card in Display > Tools. Theme tokens only. */
#as-app #as-beta-features .as-beta-row+.as-beta-row{margin-top:14px;padding-top:14px;border-top:1px solid var(--b2)}
#as-app .as-beta-lbl{display:flex;gap:12px;align-items:flex-start;font-size:13px;color:var(--t1);cursor:pointer}
#as-app .as-beta-desc{font-size:12px;color:var(--t2)}
#as-app .as-beta-lbl input[role=switch]{appearance:none;-webkit-appearance:none;flex:0 0 auto;width:40px;height:22px;margin:0;border:1px solid var(--b);background:var(--sa);position:relative;cursor:pointer;border-radius:0}
#as-app .as-beta-lbl input[role=switch]::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;background:var(--t3);transition:transform .15s}
#as-app .as-beta-lbl input[role=switch]:checked{background:var(--ac);border-color:var(--ac)}
#as-app .as-beta-lbl input[role=switch]:checked::after{transform:translateX(18px);background:var(--bg)}
#as-app .as-beta-lbl input[role=switch]:disabled{opacity:.6;cursor:default}
#as-app #as-beta-features.as-beta-loading .cb{opacity:.55;pointer-events:none}
#as-app .as-beta-lbl input[role=switch]:focus-visible{outline:3px solid var(--ac);outline-offset:2px}

/* AS-0231 slice 2 (Split + Email mode, 390px): 44px touch targets. Appended last so these win over the base and earlier
   mobile rules at equal specificity. Icon controls use the AS-0148 invisible ::before hit area (no layout change); controls
   that own their own row (View all, Follow-up header, reading-pane actions) get real size instead so hit areas never overlap. */
@media(max-width:768px) {
    #as-app #as-comms-toolbar .btn-plus,
    #as-app #as-comms-toolbar .iconbtn,
    #as-app #as-comms-toolbar .seg button,
    #as-app .as-email-kebab-left,
    #as-app .as-exp-btn,
    #as-app .as-split-preview-close { position:relative; z-index:1; }
    #as-app #as-comms-toolbar .btn-plus::after,
    #as-app #as-comms-toolbar .iconbtn::before,
    #as-app .as-email-kebab-left::before,
    #as-app .as-exp-btn::before,
    #as-app .as-split-preview-close::before { content:''; position:absolute; top:50%; left:50%; width:44px; height:44px; transform:translate(-50%,-50%); }
    #as-app #as-comms-toolbar .seg button::before { content:''; position:absolute; top:50%; left:0; right:0; height:44px; transform:translateY(-50%); }
    #as-app .as-split-viewall-btn { min-height:44px; padding:14px 12px; }
    #as-app #as-comms-panel-triage .as-triage-section-followup .as-triage-hd { min-height:44px; }
    #as-app .pv-act { min-height:44px; min-width:44px; }
}

/* AS-0231 slice 3 (Inbox / Email mode, 390px). Fix to slice 2: .btn-plus draws its "+" glyph with ::before (base rule
   .btn-plus::before { content:'+' }), so its 44px hit area must use ::after or the glyph disappears (seen as a blank orange Compose button). */
@media(max-width:768px) {
    #as-app #as-comms-toolbar .as-toolbar-btn,
    #as-app .as-email-row .as-email-action-btn,
    #as-app .as-email-bulkbar .as-email-action-btn { position:relative; z-index:1; }
    #as-app #as-comms-toolbar .as-toolbar-btn::before,
    #as-app .as-email-row .as-email-action-btn::before,
    #as-app .as-email-bulkbar .as-email-action-btn::before { content:''; position:absolute; top:50%; left:50%; width:44px; height:44px; transform:translate(-50%,-50%); }
}

/* AS-0231 slice 4 (Calendar, 390px). Event titles and meta wrap instead of running out of the card (an unbroken title made
   the shell 802px wide inside a 374px screen); the Now/Next badge no longer sits on top of the first title line; calendar
   nav, view tabs, sync and Split day-nav buttons reach 44px with real size (the 40px mobile sizes from AS-0148 era). */
@media(max-width:768px) {
    #as-app .as-event-title,
    #as-app .as-event-meta { overflow-wrap:anywhere; min-width:0; }
    #as-app .as-event-card.as-evl-now .as-event-title,
    #as-app .as-event-card.as-evl-next .as-event-title { padding-right:44px; }
    #as-app .as-cal-nav-arrow { width:44px; height:44px; }
    #as-app .as-cal-nav-today-sq { height:44px; }
    #as-app #as-event-view-tabs button { height:44px; }
    #as-app #as-event-sync-btn { width:44px; height:44px; }
    #as-app .as-cal-nav-btn { min-width:44px; min-height:44px; }
}

/* AS-0231 slice 5 (search and filter popups, 390px). The Communications search results popup was left-anchored inside the
   narrow search wrap (130px to 550px on a 390px screen); it now spans the toolbar width. Filter popups (Email, Calendar)
   and the search input/rows reach 44px targets, and a filter popup taller than the screen scrolls instead of running off it. */
@media(max-width:768px) {
    #as-app #as-comms-search-wrap { position:static !important; }
    #as-app #as-comms-search-results { left:8px !important; right:8px !important; top:100%; min-width:0 !important; max-width:none !important; width:auto; }
    #as-app #as-comms-search-results .as-menu-item { min-height:44px; }
    #as-app .osearch-toggle.open #as-comms-search { height:44px; background:var(--s); }
    #as-app #as-comms-toolbar:has(.osearch-toggle.open) #as-comms-mode-seg { flex:0 0 0; width:0; min-width:0; overflow:hidden; visibility:hidden; }
    #as-app .as-email-dropdown { max-height:calc(100vh - 120px); overflow-y:auto; }
    #as-app .as-email-dropdown label.as-email-dd-checkbox { min-height:44px; }
    #as-app .as-email-dropdown input[type=text],
    #as-app .as-email-dropdown select { min-height:44px; }
    #as-app .as-email-dropdown .as-email-dd-item { min-height:44px; }
}
