/* ==========================================================================
   1EIGHTY Analytics — Command Center
   Design tokens: restrained near-black surfaces, violet/cyan brand energy,
   semantic color reserved for what the data actually means. Typography and
   spacing carry hierarchy — color and glow are the accent, not the argument.
   ========================================================================== */
:root{
  /* Surfaces — deep, slightly warm-neutral navy-black, not pure #000 */
  --ink-950:#06070C;
  --ink-900:#0A0C15;
  --ink-850:#0E111C;
  --ink-800:#141828;
  --ink-750:#1A1F33;

  --line:rgba(255,255,255,0.07);
  --line-strong:rgba(255,255,255,0.14);
  --surface-1:rgba(255,255,255,0.028);
  --surface-2:rgba(255,255,255,0.05);
  --surface-hover:rgba(255,255,255,0.065);

  --text-primary:#F3F4F9;
  /* Bumped up from the previous #9599AE — the old value read too low-contrast
     for secondary/body copy inside the dark cards (e.g. the IQ panel-head
     descriptions). Never pushed to pure white; hierarchy against
     --text-primary/--text-tertiary is preserved. */
  --text-secondary:#94A3B8;
  --text-tertiary:#565C74;

  /* Brand — violet primary, cyan secondary. Rose/pink from the card's own
     gradient is deliberately NOT used as dashboard chrome; it stays confined
     to the tiny logo lockup so the instrument itself reads calmer than the
     card. */
  --violet:#8B6CF7;
  --violet-dim:#6D5AC4;
  --cyan:#2FD0FF;
  --brand-gradient:linear-gradient(135deg, var(--violet) 0%, var(--cyan) 100%);
  --brand-glow:rgba(139,108,247,0.35);
  --cyan-glow:rgba(47,208,255,0.28);

  /* Semantic — only ever means what it says */
  --good:#33D69F;
  --good-dim:rgba(51,214,159,0.16);
  --warn:#F0A83E;
  --warn-dim:rgba(240,168,62,0.16);
  --bad:#F1495F;
  --bad-dim:rgba(241,73,95,0.16);
  /* Live Activity panel's own "Live" chip — a vivid premium neon green,
     distinct from the global top-right "Live Data" status (which stays red,
     see .live-indicator). Scoped to .live-badge only. */
  --live-green:#39FF88;
  --live-green-dim:rgba(57,255,136,0.16);

  /* Sidebar surface — near-black with a restrained deep-violet undertone
     (NOT the flatter navy --ink-900 it used before, which read as a
     visibly separate "purple panel" next to the pure-black dashboard).
     Marginally lighter than --ink-950 so the boundary is still legible
     (helped along by the existing border-right), but close enough that
     the rail reads as part of the same black surface, not a floating card. */
  --sidebar-bg:#0B0910;

  --radius-lg:20px;
  --radius-md:14px;
  --radius-sm:10px;
  --sidebar-w:222px;
  --sidebar-w-collapsed:50px;
  --sidebar-transition:240ms cubic-bezier(.4,0,.2,1);

  /* Type scale — deliberate, not incidental. KPI numbers and section titles
     stay put (hierarchy anchors); the smaller supporting-text sizes below
     are bumped ~7% for readability. */
  --fs-page-title:26px;
  --fs-section-title:16px;
  --fs-kpi-number:38px;
  --fs-kpi-label:13.5px;
  --fs-change:13.5px;
  --fs-body:15px;
  --fs-iq-headline:15.5px;
  --fs-iq-body:14px;
  --fs-meta:12.5px;
  --fs-nav:14px;

  /* Command-center heading face — Space Grotesk (loaded via Google Fonts in
     index.html): a clean, technical, data-driven geometric sans, not the
     previous faux-military/DIN aerospace treatment. Falls back to other
     geometric sans faces, then the body sans, if the web font is slow/
     unavailable. Used ONLY for the "Command Center" H1. */
  --font-command:'Space Grotesk','Plus Jakarta Sans',system-ui,sans-serif;

  /* --- Theming: a small set of semantic tokens that flip between dark
     (here) and light (:root[data-theme="light"] below). Dark is the
     established source of truth; light only ever overrides tokens, never
     component art direction. These few fill gaps the surface/text/line
     scale above didn't already cover. --- */
  --input-bg:rgba(255,255,255,0.04);
  --tooltip-bg:rgba(8,9,17,0.97);
  --tooltip-text:#FFFFFF;
  --scrollbar-thumb:rgba(255,255,255,0.14);
  --scrollbar-thumb-active:rgba(255,255,255,0.28);
  /* Internal canvas surface for the two heavy visualization modules
     (1EIGHTY IQ, Performance Journey). They stay dark in BOTH themes — see
     3G/3H in the theme block: their neon/plasma/brain art is authored for
     a dark ground, so in light mode they read as embedded dark consoles. */
  --viz-surface:#06070d;
  --shadow-card:0 1px 2px rgba(0,0,0,0.35);
}
:root[data-theme="light"]{
  /* Foundation — a cool lavender-pearl, never flat #fff. The scale mirrors
     the dark one's DIRECTION (950 = the most-tinted page ground, rising to
     pure white for the top raised layer) so every existing `var(--ink-*)`
     reference lands somewhere sensible. */
  --ink-950:#E9EAF3;
  --ink-900:#F1F1F8;
  --ink-850:#F6F6FB;
  --ink-800:#FAFAFD;
  --ink-750:#FFFFFF;

  /* Borders / dividers — a cool near-navy at low alpha, not gray. */
  --line:rgba(28,27,64,0.10);
  --line-strong:rgba(28,27,64,0.17);
  /* Surfaces layer by tone, separated by soft shadow + hairline rather than
     heavy gray fills. surface-1 = the primary card (white); surface-2 = a
     quiet fill (chips, icon wells, ghost buttons); surface-hover = a touch
     deeper. */
  --surface-1:#FFFFFF;
  --surface-2:#ECEDF6;
  --surface-hover:#E4E5F1;

  --text-primary:#1B1C2E;
  --text-secondary:#565C71;
  --text-tertiary:#888DA1;

  /* Brand — hues preserved; violet and the two pale accents (cyan, gold)
     deepened just enough to stay vivid AND legible on white. The bright
     originals still shine wherever they're used as glow/fill. */
  --violet:#7A55F0;
  --violet-dim:#9B86F5;
  --cyan:#0C9CCB;
  --brand-gradient:linear-gradient(135deg, #7A55F0 0%, #14A6D6 100%);
  --brand-glow:rgba(122,85,240,0.20);
  --cyan-glow:rgba(12,156,203,0.16);

  --good:#12A26D;
  --good-dim:rgba(18,162,109,0.14);
  --warn:#C27C15;
  --warn-dim:rgba(194,124,21,0.15);
  --bad:#E13A53;
  --bad-dim:rgba(225,58,83,0.13);
  --live-green:#12B265;
  --live-green-dim:rgba(18,178,101,0.15);

  /* Sidebar gets its own scoped light surface — see the
     [data-theme="light"] .sidebar block lower in this file. */

  --input-bg:#F3F3FA;
  --tooltip-bg:rgba(24,25,44,0.96);
  --tooltip-text:#FFFFFF;
  --scrollbar-thumb:rgba(28,27,64,0.22);
  --scrollbar-thumb-active:rgba(28,27,64,0.40);
  --viz-surface:#06070d;
  --shadow-card:0 1px 2px rgba(24,26,54,0.05), 0 10px 26px -14px rgba(24,26,54,0.14);
}

/* ==========================================================================
   GLASS MATERIAL SYSTEM (#14)
   Three coherent levels instead of ad-hoc per-component rgba():
     FLOAT   — dropdowns / popovers. Clearest, most transparent.
     PANEL   — Quick View / larger overlays. A little more surface + blur
               for readability over a large area; SAME glass family.
     CONTROL — closed compact selects (Card Studio). Faint tint + light blur.
   Each level exposes: -bg (base tint), -glare (top specular gradient),
   -edge (hairline border), -blur, -sat, -shadow. Neutral smoked glass —
   no violet/cyan cast. Tune here, everything follows.
   ========================================================================== */
:root{
  /* #13 — FLOAT pushed one clear step further: markedly more background
     transmission, stronger blur + saturation, a crisper specular top edge.
     Still fully readable (dark text tokens / light surface do the contrast). */
  --glass-float-bg:rgba(17,17,21,0.44);
  --glass-float-glare:linear-gradient(179deg, rgba(255,255,255,0.14) 0%, rgba(255,255,255,0.03) 26%, rgba(255,255,255,0) 52%);
  --glass-float-edge:rgba(255,255,255,0.18);
  --glass-float-blur:19px;
  --glass-float-sat:1.75;
  --glass-float-shadow:0 28px 60px -18px rgba(0,0,0,0.66), 0 2px 10px -4px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.16);

  /* #14–#18 — PANEL is NEUTRAL smoked glass (no navy/blue), and moved
     materially closer to FLOAT: lower surface alpha, high-quality blur,
     the scrim does the heavy lifting behind it. */
  --glass-panel-bg:rgba(15,15,17,0.56);
  --glass-panel-glare:linear-gradient(179deg, rgba(255,255,255,0.12) 0%, rgba(255,255,255,0.025) 24%, rgba(255,255,255,0) 46%);
  --glass-panel-edge:rgba(255,255,255,0.14);
  --glass-panel-blur:44px;
  --glass-panel-sat:1.7;
  --glass-panel-shadow:0 48px 120px -24px rgba(0,0,0,0.62), 0 3px 14px -5px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.14);

  --glass-control-bg:rgba(255,255,255,0.035);
  --glass-control-glare:linear-gradient(178deg, rgba(255,255,255,0.13), rgba(255,255,255,0.02) 40%, rgba(255,255,255,0) 60%);
  --glass-control-edge:rgba(255,255,255,0.15);
  --glass-control-blur:8px;
  --glass-control-sat:1.55;
}
:root[data-theme="light"]{
  /* #13 — LIGHT FLOAT: this is the one the user most wants to SEE change.
     Surface alpha dropped hard (0.52 → 0.34) so the page reads through it,
     compensated by a heavier neutral blur + saturation and a bright
     specular top so it still looks like a solid pane of glass, not a
     washed-out ghost. NEUTRAL white — no lavender/blue. */
  --glass-float-bg:rgba(253,253,253,0.34);
  --glass-float-glare:linear-gradient(176deg, rgba(255,255,255,0.96) 0%, rgba(255,255,255,0.28) 26%, rgba(255,255,255,0.04) 46%, rgba(255,255,255,0) 62%);
  --glass-float-edge:rgba(20,22,40,0.09);
  --glass-float-blur:28px;
  --glass-float-sat:2;
  --glass-float-shadow:0 26px 56px -18px rgba(28,27,64,0.28), 0 3px 12px -4px rgba(28,27,64,0.14), inset 0 1px 0 rgba(255,255,255,0.98);

  /* #15/#18 — LIGHT PANEL: neutral pearl-white glass, substantially more
     transparent than before, environment visibly influences it. NO blue. */
  --glass-panel-bg:rgba(252,252,252,0.52);
  --glass-panel-glare:linear-gradient(176deg, rgba(255,255,255,0.92) 0%, rgba(255,255,255,0.22) 26%, rgba(255,255,255,0.03) 46%, rgba(255,255,255,0) 60%);
  --glass-panel-edge:rgba(20,22,40,0.09);
  --glass-panel-blur:50px;
  --glass-panel-sat:1.7;
  --glass-panel-shadow:0 48px 130px -30px rgba(28,27,64,0.26), 0 4px 16px -6px rgba(28,27,64,0.14), inset 0 1px 0 rgba(255,255,255,0.9);

  --glass-control-bg:rgba(255,255,255,0.46);
  --glass-control-glare:linear-gradient(178deg, rgba(255,255,255,0.92), rgba(255,255,255,0.1) 44%, rgba(255,255,255,0) 62%);
  --glass-control-edge:rgba(28,27,64,0.12);
  --glass-control-blur:12px;
  --glass-control-sat:1.5;
}

*{ box-sizing:border-box; margin:0; padding:0; font-family:'Plus Jakarta Sans', -apple-system, sans-serif; }
html,body{ height:100%; }
body{
  background:var(--ink-950); color:var(--text-primary);
  font-size:14px; line-height:1.5; -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
a{ color:inherit; text-decoration:none; }
button{ font-family:inherit; }
/* Elements also given a `display` value below (e.g. .app, .login-screen)
   would otherwise defeat the plain [hidden] attribute, since an author rule
   of equal specificity always beats the UA default — this keeps hidden
   authoritative no matter what other display rules exist. */
[hidden]{ display:none !important; }
.mono{ font-family:'JetBrains Mono', ui-monospace, monospace; }
.tnum{ font-variant-numeric:tabular-nums; font-feature-settings:'tnum' 1; }
::-webkit-scrollbar{ width:9px; height:9px; }
::-webkit-scrollbar-track{ background:transparent; }
::-webkit-scrollbar-thumb{ background:var(--scrollbar-thumb); border-radius:999px; }
@media (prefers-reduced-motion: reduce){
  *{ animation-duration:0.01ms !important; animation-iteration-count:1 !important; transition-duration:0.01ms !important; }
}
:focus-visible{ outline:2px solid var(--cyan); outline-offset:2px; border-radius:4px; }

.glass{
  background:var(--surface-1);
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
}
.glow-static{ position:relative; }
.glow-static::before{
  content:""; position:absolute; inset:-1px; border-radius:inherit; z-index:-1; padding:1px;
  background:linear-gradient(135deg, rgba(139,108,247,0.5), rgba(47,208,255,0.35));
  -webkit-mask:linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor; mask-composite:exclude; opacity:0.6;
}

.btn{
  font-weight:700; font-size:14px; padding:12px 22px; border-radius:999px;
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  cursor:pointer; border:none; transition:transform .25s cubic-bezier(.22,1,.36,1), box-shadow .25s ease, background .2s ease;
}
.btn-primary{ background:var(--brand-gradient); color:#0A0A16; box-shadow:0 6px 20px rgba(139,108,247,0.22); width:100%; }
.btn-primary:hover{ transform:translateY(-1px); box-shadow:0 0 22px rgba(139,108,247,0.4); }
.btn-ghost{ background:var(--surface-2); border:1px solid var(--line-strong); color:var(--text-primary); width:100%; }
.btn-ghost:hover{ background:var(--surface-hover); }

.grad-text{ background:var(--brand-gradient); -webkit-background-clip:text; background-clip:text; color:transparent; }

/* ==========================================================================
   Login — Stage 3 premium polish pass. Same building blocks (.glass,
   .glow-static) the rest of the product already uses for "premium surface",
   just applied here with real composition/hierarchy instead of the previous
   bare centered card. Two soft ambient glows behind the card (decorative,
   aria-hidden) instead of a single flat radial wash.
   ========================================================================== */
/* QC#14 — auth-resolving splash. Same deep cool ground as the login screen so
   there's zero visual jump when it resolves to either app or login. */
.auth-boot{
  position:fixed; inset:0; z-index:9000; display:flex; align-items:center; justify-content:center;
  background:linear-gradient(170deg, #0A1024 0%, #0B1330 45%, #090C22 100%);
}
.auth-boot[hidden]{ display:none; }
[data-theme="light"] .auth-boot{ background:linear-gradient(170deg, #EEF2FF 0%, #E7EEFC 46%, #EAF3FB 100%); }
.auth-boot-mark{ width:68px; height:68px; display:block; animation:authBootPulse 1.6s ease-in-out infinite; }
@keyframes authBootPulse{ 0%,100%{ opacity:0.55; transform:scale(0.97); } 50%{ opacity:1; transform:scale(1); } }
@media (prefers-reduced-motion:reduce){ .auth-boot-mark{ animation:none; opacity:0.9; } }
/* QC#14 — deep-link / new-tab open: withhold the mark entirely and match the
   APP shell ground (not the login gradient), so the Full Contact Record (or
   target view) fades in over an identical background with no intermediate
   branded artifact. */
.auth-boot.is-deeplink{ background:var(--ink-950); }
[data-theme="light"] .auth-boot.is-deeplink{ background:var(--ink-50, #f6f7fb); }
.auth-boot.is-deeplink .auth-boot-mark{ display:none; }

.login-screen{
  position:relative; min-height:100vh; display:flex; flex-direction:column; align-items:center; justify-content:center;
  padding:34px 24px; overflow:hidden;
  /* QC#11 — darker near-black indigo base; the moving colour is all in the
     smoke layers below (no static coloured radials competing with them). */
  background:linear-gradient(168deg, #05060F 0%, #080B1E 46%, #04050D 100%);
}
/* QC#11 — SMOKE, not a rotating layer. Three full-bleed layers (.login-aurora
   + its ::before + ::after), each a set of soft radial "puffs" of cool colour
   (violet / indigo / electric blue / cyan) with fully transparent falloff, so
   no layer ever has a visible edge. Each drifts + scales + fades on its own
   long, prime-ish period, heavily blurred, softly masked — the colours keep
   recombining like coloured vapour behind the frosted card. NO rotate, NO
   border-radius box, NO bounded blob. */
.login-aurora{
  position:absolute; inset:-40%; z-index:0; pointer-events:none;
  filter:blur(78px) saturate(1.25);
  -webkit-mask-image:radial-gradient(ellipse 78% 70% at 50% 48%, #000 8%, #000 58%, transparent 96%);
  mask-image:radial-gradient(ellipse 78% 70% at 50% 48%, #000 8%, #000 58%, transparent 96%);
  background:
    radial-gradient(32% 40% at 26% 32%, rgba(96,86,255,0.55), transparent 70%),
    radial-gradient(30% 36% at 78% 40%, rgba(38,120,255,0.5), transparent 72%),
    radial-gradient(34% 40% at 58% 82%, rgba(120,72,255,0.45), transparent 72%);
}
.login-aurora::before, .login-aurora::after{ content:""; position:absolute; inset:-8%; }
.login-aurora::before{
  background:
    radial-gradient(30% 38% at 68% 24%, rgba(43,214,255,0.42), transparent 72%),
    radial-gradient(34% 40% at 30% 66%, rgba(74,96,255,0.5), transparent 72%),
    radial-gradient(26% 32% at 84% 78%, rgba(150,86,255,0.4), transparent 74%);
}
.login-aurora::after{
  background:
    radial-gradient(36% 42% at 44% 16%, rgba(60,110,255,0.4), transparent 74%),
    radial-gradient(30% 36% at 16% 44%, rgba(120,70,255,0.44), transparent 74%),
    radial-gradient(32% 38% at 80% 58%, rgba(43,196,255,0.36), transparent 74%);
}
@media (prefers-reduced-motion:no-preference){
  .login-aurora{ animation:loginSmokeA 42s ease-in-out infinite; }
  .login-aurora::before{ animation:loginSmokeB 55s ease-in-out infinite; }
  .login-aurora::after{ animation:loginSmokeC 67s ease-in-out infinite; }
}
@keyframes loginSmokeA{
  0%, 100%{ transform:translate3d(-3%, -2%, 0) scale(1.05); opacity:0.85; }
  33%     { transform:translate3d(4%, 3%, 0)   scale(1.22); opacity:1; }
  66%     { transform:translate3d(-2%, 4%, 0)  scale(1.1);  opacity:0.72; }
}
@keyframes loginSmokeB{
  0%, 100%{ transform:translate3d(3%, 2%, 0)   scale(1.15); opacity:0.7; }
  40%     { transform:translate3d(-4%, -3%, 0) scale(1);    opacity:1; }
  70%     { transform:translate3d(2%, -4%, 0)  scale(1.18); opacity:0.8; }
}
@keyframes loginSmokeC{
  0%, 100%{ transform:translate3d(-2%, 3%, 0)  scale(1.1);  opacity:1; }
  45%     { transform:translate3d(4%, -2%, 0)  scale(1.24); opacity:0.65; }
  75%     { transform:translate3d(-3%, -3%, 0) scale(1.05); opacity:0.9; }
}
/* QC#11 — reduced motion: a beautiful STATIC smoky composition, still dark. */
@media (prefers-reduced-motion:reduce){
  .login-aurora, .login-aurora::before, .login-aurora::after{ animation:none; }
  .login-aurora{ transform:scale(1.12); opacity:0.9; }
  .login-aurora::before{ opacity:0.8; }
  .login-aurora::after{ opacity:0.85; }
}
.login-card{
  /* QC P8 — height only: trim the excess interior glass above the logo and
     below the footer link. Width, position, branding, field/button spacing,
     lockup→form rhythm all unchanged.
     QC P12 — final pass: TOP interior padding only, 15px → 8px. Bottom (18px),
     sides (42px), everything else untouched. */
  position:relative; z-index:1; width:100%; max-width:428px; padding:8px 42px 18px; text-align:center;
  box-shadow:0 60px 150px -38px rgba(0,0,0,0.66), 0 0 0 1px rgba(255,255,255,0.05) inset;
}
/* #26 — bold, tight brand lockup. QC#10 — slightly tighter still. */
.login-lockup{ display:flex; flex-direction:column; align-items:center; margin-bottom:18px; }
.login-logo{ display:flex; flex-direction:column; align-items:center; }
/* QC#9 — transparent RGBA !e asset, sits clean over the glass, no matte. */
.login-mark{ width:80px; height:80px; margin:0 auto 5px; display:block; filter:drop-shadow(0 4px 18px rgba(150,86,255,0.3)); }
.login-word{ height:29px; width:auto; margin:0 auto; display:block; }
.login-sub{ font-size:14px; font-weight:600; letter-spacing:0.16em; color:var(--text-secondary); margin-top:6px; text-transform:uppercase; }
.login-card .field{ text-align:left; margin-bottom:13px; }
.login-card label{ font-size:12px; letter-spacing:0.02em; color:var(--text-secondary); font-weight:600; display:block; margin-bottom:7px; }
.login-card input{
  width:100%; padding:14px 15px; border-radius:11px; font-size:15px; color:var(--text-primary);
  background:var(--input-bg); border:1px solid var(--line); box-sizing:border-box;
  transition:border-color .14s ease, box-shadow .14s ease;
}
.login-card input:focus{ outline:none; border-color:var(--violet); box-shadow:0 0 0 3px color-mix(in srgb, var(--violet) 18%, transparent); }
.login-card .btn-primary{ width:100%; margin-top:10px; padding:14.5px 14px; font-size:15px; font-weight:700; box-shadow:0 14px 32px -14px color-mix(in srgb, var(--violet) 65%, transparent); }
.login-error{ margin-top:14px; font-size:13px; color:var(--bad); }
.login-hint{ margin-top:16px; font-size:12px; color:var(--text-tertiary); line-height:1.6; }

/* #13/#25 — SSO buttons sit BELOW the email/password form and its OR divider.
   Neutral surface, provider mark on the left, same radius/size as the inputs. */
.login-sso{ display:flex; flex-direction:column; gap:10px; }
.login-sso-btn{
  display:flex; align-items:center; justify-content:center; gap:10px; width:100%;
  padding:12.5px 14px; border-radius:11px; cursor:pointer;
  font:inherit; font-size:13.5px; font-weight:650; color:var(--text-primary);
  background:var(--surface-2); border:1px solid var(--line-strong);
  transition:background .14s ease, border-color .14s ease, opacity .14s ease;
}
.login-sso-btn:hover{ background:var(--surface-hover); border-color:var(--violet); }
.login-sso-btn:focus-visible{ outline:2px solid var(--violet); outline-offset:2px; }
.login-sso-btn[disabled]{ opacity:0.55; cursor:default; }
.login-sso-btn.is-loading{ opacity:0.7; }
.login-sso-btn svg{ width:17px; height:17px; flex:0 0 auto; }
.login-sso-msg{ font-size:12px; line-height:1.5; text-align:left; }
.login-divider{
  display:flex; align-items:center; gap:12px; margin:20px 0 14px;
  font-size:11px; letter-spacing:0.08em; text-transform:uppercase; color:var(--text-tertiary);
}
.login-divider::before, .login-divider::after{ content:""; flex:1; height:1px; background:var(--line); }
.login-footer{
  position:relative; z-index:1; margin-top:18px; font-size:11.5px; letter-spacing:0.04em;
  color:color-mix(in srgb, var(--text-tertiary) 80%, transparent);
  display:flex; align-items:center; justify-content:center; gap:12px;
}
/* QC#5 — day/night Easter egg. Deliberately tiny and quiet; a soft glow on
   hover is the only flourish. One icon per theme via [data-theme]. */
.login-theme{
  flex:0 0 auto; width:26px; height:26px; border-radius:8px; padding:0; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center;
  background:none; border:1px solid transparent; color:var(--text-tertiary);
  transition:color .16s ease, background .16s ease, box-shadow .16s ease, transform .12s ease;
}
.login-theme:hover{
  color:var(--text-secondary); background:color-mix(in srgb, #fff 6%, transparent);
  box-shadow:0 0 16px -4px color-mix(in srgb, var(--violet) 55%, transparent);
}
.login-theme:focus-visible{ outline:2px solid var(--violet); outline-offset:2px; }
.login-theme:active{ transform:scale(0.9); }
.login-theme svg{ width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:2; stroke-linecap:round; }
/* icon shows the destination: dark mode → sun ("go light"); light → moon. */
.login-theme-moon{ display:none; }
.login-theme-sun{ display:block; }
[data-theme="light"] .login-theme-sun{ display:none; }
[data-theme="light"] .login-theme-moon{ display:block; }

/* #2 — Forgot password link + its two panels (request / set-new-password).
   Same .login-card, swapped &lt;form&gt; visibility — no separate modal/overlay. */
.login-forgot-link{
  display:block; width:100%; margin-top:12px; padding:2px; background:none; border:none; cursor:pointer;
  font:inherit; font-size:12.5px; font-weight:600; color:var(--text-tertiary); transition:color .14s ease;
}
.login-forgot-link:hover{ color:var(--violet); }
.login-forgot-copy{ font-size:13px; color:var(--text-secondary); line-height:1.5; margin:0 0 18px; text-align:left; }
.login-msg{ margin-top:14px; font-size:12.5px; line-height:1.5; text-align:left; }
.login-msg.is-error{ color:var(--bad); }
.login-msg.is-success{ color:var(--good); }

/* #3 — tasteful secondary link back to the public site; deliberately quiet
   relative to Sign In / the form itself. */
.login-website-link{
  display:inline-flex; align-items:center; gap:5px; margin-top:11px; font-size:12px; font-weight:600;
  color:var(--text-tertiary); text-decoration:none; transition:color .14s ease;
}
.login-website-link:hover{ color:var(--cyan); }
.login-website-link svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2.2; }

@media (max-width:520px){
  .login-card{ padding:26px 22px 24px; max-width:100%; }
  .login-lockup{ margin-bottom:16px; }
  .login-mark{ width:64px; height:64px; }
  .login-word{ height:25px; }
  .login-sub{ font-size:12.5px; }
}
/* QC#11 — light mode: a cool periwinkle composition (NOT flat gray), same
   smoke layers dialled down so the form stays crisp. */
[data-theme="light"] .login-screen{
  background:
    radial-gradient(ellipse 62% 44% at 50% -6%, rgba(99,102,241,0.14), transparent 60%),
    radial-gradient(ellipse 50% 44% at 100% 104%, rgba(56,189,248,0.12), transparent 62%),
    linear-gradient(170deg, #EDF1FF 0%, #E5ECFB 46%, #E9F3FB 100%);
}
[data-theme="light"] .login-aurora{ opacity:0.42; filter:blur(80px) saturate(0.95); }

/* ==========================================================================
   App shell
   ========================================================================== */
.app{ display:flex; min-height:100vh; }

.sidebar{
  width:var(--sidebar-w); flex:0 0 auto; background:var(--sidebar-bg);
  border-right:1px solid var(--line); padding:24px 13px;
  display:flex; flex-direction:column; gap:18px; position:sticky; top:0; height:100vh;
  /* z-index so the collapsed rail's overflowing tooltips reliably float
     above .main's isolated panels (light mode especially). */
  z-index:30;
  transition:width var(--sidebar-transition), background-color .3s ease, border-color .3s ease;
  /* NB: no overflow clip here on desktop — the collapsed-rail tooltips
     render just outside the right edge (left:calc(100% + 12px)) and must
     not be clipped. The mobile drawer gets overflow-y:auto separately. */
}
.sidebar-logo{
  display:flex; flex-direction:row; align-items:center; gap:6px; padding:2px 0;
  /* Negative margin nudges the whole lockup up toward Command Center's own
     vertical level, without touching .sidebar's own padding-top — which
     would shift the profile/nav rows below it too. Raised again (was -4px)
     to bring the logo's visual center closer to the (now solid-white)
     heading's visual center — tuned by eye against a live render, not
     derived from box-model arithmetic alone (line-height/cap-height make
     that unreliable). */
  margin:-9px 0 2px;
  background:none; border:none; cursor:pointer; border-radius:12px; align-self:flex-start;
  transition:background .18s ease;
}
.sidebar-logo:hover{ background:var(--surface-1); }
/* The mark and wordmark are two INDEPENDENT raster assets (logo-mark.png
   512x512, logo-word.png 952x200 ~4.76:1), so each is sized on its own —
   the combined lockup is never scaled as one object. The wordmark is now
   the stronger element of the two (30px, up from 26px) and the mark is
   pulled back to a supporting role (38px, down from 60px) — inner content
   width is still 222 - 2*13 (sidebar padding) - 2*2 (button padding) =
   192px, and 38 + 8 (gap) + 30*4.76 (word's fixed aspect) ≈ 189px, so this
   still fits the unchanged rail with a few px to spare. One line, vertically
   centred on each other. */
.sidebar-logo .s-mark,
.sidebar-logo .s-mark-lite{ width:46px; height:46px; display:block; border-radius:12px; transition:width .2s ease, height .2s ease; }
.sidebar-logo .s-mark-lite{ display:none; }
.sidebar-logo .s-word{ height:30px; width:auto; display:block; }

.sidebar-profile-wrap{ position:relative; flex:0 0 auto; }
/* QC P4 — ROOT CAUSE of "top profile-trigger avatar never shows its ring,
   in either theme": .sidebar is `position:sticky` with an explicit
   z-index:30, so it's the nearest actual stacking-context root above
   #avatarBadge (.sidebar-profile-wrap is position:relative but z-index:auto
   — that alone does NOT create one). Within .sidebar's context, the ring
   (a z-index:-1 descendant of #avatarBadge) paints right after .sidebar's
   OWN background — but BEFORE .sidebar-profile's own opaque background,
   which is ordinary same-context content painted later and sits exactly
   over the ring, hiding it completely, in both themes. #profileMenuAvatar
   never has this problem because .profile-menu is ITSELF a tight stacking
   context (position:absolute + explicit z-index + backdrop-filter) with
   nothing else in it to paint over the ring. Giving .sidebar-profile its
   own stacking context (position:relative + z-index:0 — no visual offset,
   no change to its order among sidebar siblings) reproduces that same
   working structure: now the ring paints above THIS element's own
   background, below only its own avatar circle, exactly as designed. */
.sidebar-profile{
  width:100%; display:flex; align-items:center; gap:11px; padding:11px 12px; border-radius:14px;
  background:var(--surface-1); border:1px solid var(--line); cursor:pointer; text-align:left;
  font:inherit; color:inherit; position:relative; z-index:0;
}
.sidebar-profile:hover{ background:var(--surface-hover); border-color:var(--line-strong); }
.sidebar-profile[aria-expanded="true"]{ background:var(--surface-hover); border-color:var(--line-strong); }
.sidebar-profile-txt{ display:flex; flex-direction:column; align-items:flex-start; min-width:0; overflow:hidden; flex:1 1 auto; }
.profile-chevron{ width:14px; height:14px; flex:0 0 auto; fill:none; stroke:var(--text-tertiary); stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; transition:transform .18s ease; }
.sidebar-profile[aria-expanded="true"] .profile-chevron{ transform:rotate(180deg); }
.avatar-badge{
  width:36px; height:36px; border-radius:50%; flex:0 0 auto;
  background:var(--brand-gradient); color:#0A0A16; font-weight:800; font-size:13px;
  display:flex; align-items:center; justify-content:center;
}
.avatar-badge-lg{ width:40px; height:40px; font-size:14px; }
.profile-name{ font-size:13.5px; font-weight:700; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.profile-role{ font-size:12.5px; color:var(--text-tertiary); }

/* ---- Profile dropdown menu ---- */
.profile-menu{
  position:absolute; top:calc(100% + 8px); left:0; right:0; z-index:80;
  background:rgba(17,19,30,0.96); border:1px solid rgba(255,255,255,0.12); border-radius:14px;
  padding:6px; display:flex; flex-direction:column; gap:2px;
  box-shadow:0 22px 48px -14px rgba(0,0,0,0.6), 0 0 0 1px rgba(0,0,0,0.35), 0 0 22px -6px rgba(139,108,247,0.22);
  -webkit-backdrop-filter:blur(20px); backdrop-filter:blur(20px);
  animation:profileMenuIn .13s ease;
}
[data-theme="light"] .profile-menu{
  background:rgba(255,255,255,0.98); border-color:rgba(28,27,64,0.14);
  box-shadow:0 22px 48px -16px rgba(46,32,96,0.28), 0 0 0 1px rgba(46,32,96,0.05);
}
@keyframes profileMenuIn{ from{ opacity:0; transform:translateY(-6px); } to{ opacity:1; transform:translateY(0); } }
.profile-menu-head{ display:flex; align-items:center; gap:10px; padding:9px 10px 11px; margin-bottom:3px; border-bottom:1px solid var(--line); }
.profile-menu-id{ display:flex; flex-direction:column; min-width:0; }
.profile-menu-name{ font-size:13.5px; font-weight:800; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.profile-menu-role{ font-size:12px; color:var(--text-tertiary); }
.profile-menu-item{
  display:flex; align-items:center; gap:10px; width:100%; text-align:left;
  padding:9px 10px; border:none; border-radius:9px; background:none; cursor:pointer;
  font:inherit; font-size:13px; font-weight:600; color:var(--text-primary);
  transition:background .14s ease, color .14s ease;
}
.profile-menu-item svg{ width:15px; height:15px; flex:0 0 auto; fill:none; stroke:var(--text-secondary); stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.profile-menu-item svg use{ pointer-events:none; }
.profile-menu-item:hover{ background:var(--surface-hover); }
.profile-menu-item:hover svg{ stroke:var(--text-primary); }
.profile-menu-item-danger{ color:var(--bad); }
.profile-menu-item-danger svg{ stroke:var(--bad); }
.profile-menu-item-danger:hover{ background:var(--bad-dim); color:var(--bad); }
.profile-menu-item-danger:hover svg{ stroke:var(--bad); }
/* Super-User-Admin-only Demo Mode presentation toggle — same row shape as
   every other profile-menu item; a switch instead of a chevron. ON = hide the
   internal admin surfaces for a customer demo. */
.profile-menu-item-demo span:not(.profile-menu-demo-switch){ flex:1 1 auto; }
.profile-menu-demo-switch{
  flex:0 0 auto; width:32px; height:18px; border-radius:99px; position:relative;
  background:var(--surface-2); border:1px solid var(--line-strong); transition:background .16s ease, border-color .16s ease;
}
.profile-menu-demo-switch > span{
  position:absolute; top:1px; left:1px; width:14px; height:14px; border-radius:50%;
  background:var(--text-tertiary); transition:transform .16s ease, background .16s ease;
}
.profile-menu-item-demo[aria-checked="true"] .profile-menu-demo-switch{
  background:color-mix(in srgb, var(--cyan) 32%, transparent); border-color:color-mix(in srgb, var(--cyan) 48%, transparent);
}
.profile-menu-item-demo[aria-checked="true"] .profile-menu-demo-switch > span{ transform:translateX(14px); background:var(--cyan); }
.sidebar-company{ font-size:10.5px; letter-spacing:0.05em; font-weight:700; color:var(--good); padding:0 4px; }

.sidebar-nav{ display:flex; flex-direction:column; gap:2px; margin-top:4px; position:relative; }
.nav-item{
  display:flex; align-items:center; gap:9px; padding:9px 9px; border-radius:11px;
  font-size:var(--fs-nav); font-weight:600; color:var(--text-secondary); cursor:pointer;
  transition:background .16s ease, color .16s ease; border-left:2px solid transparent; position:relative; z-index:1;
}

/* ---- Travelling active indicator (one reusable element) ----------------
   #navThumb travels between .nav-item positions (positionNavThumb, app.js —
   distance-aware duration). The silhouette here is the RESTORED pre-navThumb
   active shape (accent left-bar + 11% tint + soft glow, 11px radius) so it
   reads as sidebar-native, not like the timeframe pill. .nav-thumb-jelly's
   ::after adds a faint multi-tone stained-glass refraction; .is-jelly runs a
   one-shot scaleY stretch->settle (amplitude via --jelly-amp, set in JS). */
.nav-thumb{
  position:absolute; left:0; right:0; top:0; height:44px; z-index:0; pointer-events:none;
  border-radius:11px; opacity:0; transform:translateY(0);
  transition:transform .34s cubic-bezier(.4,0,.15,1), height .34s cubic-bezier(.4,0,.15,1), opacity .28s ease;
}
.nav-thumb.is-ready{ opacity:1; }
.nav-thumb-jelly{
  position:absolute; inset:0; border-radius:inherit; overflow:hidden; --na:var(--violet); --jelly-amp:1.09;
  border-left:2px solid var(--na);
  background:color-mix(in srgb, var(--na) 11%, var(--surface-2));
  box-shadow:0 0 16px -7px var(--na), inset 0 0 0 1px color-mix(in srgb, var(--na) 16%, transparent);
}
/* Faint stained-glass refraction — 1EIGHTY palette only, deliberately low
   opacity so it reads as glass, never a rainbow. Screen-blended over the
   accent-tinted base; the icon (z-index:1 on .nav-item) stays sharp above. */
.nav-thumb-jelly::after{
  content:""; position:absolute; inset:-20%; border-radius:inherit; pointer-events:none;
  background:
    radial-gradient(60% 70% at 12% 0%,   rgba(139,108,247,0.30), transparent 62%),
    radial-gradient(55% 80% at 92% 20%,  rgba(47,208,255,0.22),  transparent 60%),
    radial-gradient(70% 90% at 78% 100%, rgba(240,82,158,0.16),  transparent 62%),
    radial-gradient(60% 80% at 4% 100%,  rgba(62,123,250,0.20),  transparent 58%);
  mix-blend-mode:screen; opacity:0.6;
}
.nav-thumb[data-color="cyan"]  .nav-thumb-jelly{ --na:var(--cyan); }
.nav-thumb[data-color="amber"] .nav-thumb-jelly{ --na:var(--warn); }
.nav-thumb[data-color="green"] .nav-thumb-jelly{ --na:var(--good); }
.nav-thumb-jelly.is-jelly{ animation:navThumbJelly .34s cubic-bezier(.4,0,.15,1) both; }
@keyframes navThumbJelly{
  0%{ transform:scaleY(1); } 34%{ transform:scaleY(var(--jelly-amp)); }
  62%{ transform:scaleY(calc(2 - var(--jelly-amp))); } 82%{ transform:scaleY(calc(1 + (var(--jelly-amp) - 1) * 0.22)); }
  100%{ transform:scaleY(1); }
}
.sidebar-nav.has-thumb .nav-item.is-active{
  background:none; box-shadow:none; border-left-color:transparent;
}
@media (prefers-reduced-motion:reduce){
  .nav-thumb{ transition:opacity .18s ease; }
  .nav-thumb-jelly.is-jelly{ animation:none; }
  .nav-thumb-jelly::after{ opacity:0.4; }
}
[data-theme="light"] .nav-thumb-jelly::after{ mix-blend-mode:overlay; opacity:0.45; }
.nav-item .nav-icon{
  width:30px; height:30px; border-radius:9px; display:flex; align-items:center; justify-content:center; flex:0 0 auto;
  background:var(--surface-2); transition:width .2s ease, height .2s ease, border-radius .2s ease, background .16s ease;
}
.nav-item .nav-icon svg{ width:18px; height:18px; fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; transition:width .2s ease, height .2s ease; }
/* Each nav item carries its OWN section accent in --nav-accent; the icon
   stroke uses it always, and the active-state treatment (border, tint,
   glow, icon chip) below inherits the SAME variable so selecting a section
   colours its nav box to match that section — no more one-size-fits-all
   violet. Adding a new nav item = add one --nav-accent line here. */
.nav-item[data-color="violet"]{ --nav-accent:var(--violet); }
.nav-item[data-color="cyan"]{ --nav-accent:var(--cyan); }
.nav-item[data-color="amber"]{ --nav-accent:var(--warn); }
.nav-item[data-color="green"]{ --nav-accent:var(--good); }
/* QC (this pass) — Platform Admin section colours: a cool steel-blue for
   Client Hub and a warm gold for Card Studio, deliberately distinct from the
   four client-facing accents above so the admin-only rows read as their own
   "backstage" register at a glance, not a fifth ordinary product page. */
.nav-item[data-color="steel"]{ --nav-accent:#5B7CFA; }
.nav-item[data-color="gold"]{ --nav-accent:#D9AE3E; }
.nav-item .nav-icon svg{ stroke:var(--nav-accent, var(--violet)); }
.nav-item:hover{ background:var(--surface-1); color:var(--text-primary); }
/* Restrained: coloured left border + a faint accent-tinted background + a
   soft accent glow — not a neon block. Kept subtle enough that the label
   text stays the readable focus. */
.nav-item.is-active{
  color:var(--text-primary);
  border-left-color:var(--nav-accent, var(--violet));
  background:color-mix(in srgb, var(--nav-accent, var(--violet)) 11%, var(--surface-2));
  box-shadow:0 0 16px -7px var(--nav-accent, var(--violet)), inset 0 0 0 1px color-mix(in srgb, var(--nav-accent, var(--violet)) 16%, transparent);
}
.nav-item.is-active .nav-icon{ background:color-mix(in srgb, var(--nav-accent, var(--violet)) 24%, transparent); }

.sidebar-spacer{ flex:1; }
/* ROOT CAUSE of the "upsell not displaying" bug: the collapse animation
   caps .sidebar-upsell at max-height:160px with overflow:hidden, but the
   real content (title + 3-line copy + full-width button + 16px padding) is
   ~168-175px tall — so the bottom of the "Upgrade Plan" button was being
   clipped off. Nothing JS, nothing conditional, not a collision — purely
   the max-height being a few px short of the content. Fixed by raising the
   expanded cap to a value the content actually fits inside, and trimming
   the internal padding/copy spacing a touch so it stays compact. */
.sidebar-upsell{ padding:14px; flex:0 0 auto; }
.upsell-title{ font-size:13px; font-weight:800; margin-bottom:5px; }
.upsell-copy{ font-size:12.5px; color:var(--text-tertiary); line-height:1.45; margin-bottom:10px; }
.sidebar-upsell .btn-ghost{ padding:9px 14px; }

.sidebar-utility{ display:flex; flex-direction:column; gap:1px; padding-top:2px; border-top:1px solid var(--line); }

/* Theme toggle — established here aesthetically/structurally this pass; the
   control is fully wired (click, keyboard, persisted preference) but does
   not yet repaint the app in an actual light palette. Clicking it is
   inert-safe: it only flips its own visual state and a stored preference. */
.theme-toggle{
  display:flex; align-items:center; justify-content:center; gap:9px; width:100%;
  background:none; border:none; padding:7px 10px; border-radius:10px; cursor:pointer;
  /* Nudged up (tighter own padding + the reduced .sidebar-utility padding-top)
     and given a little air beneath it so it reads as its own appearance
     control, separate from the Collapse / Settings / Log Out cluster. */
  margin-bottom:5px;
}
.theme-toggle:hover{ background:var(--surface-1); }
.theme-icon{ width:14px; height:14px; fill:none; stroke:var(--text-tertiary); stroke-width:2; stroke-linecap:round; stroke-linejoin:round; flex:0 0 auto; transition:stroke .2s ease, width .2s ease, height .2s ease; }
.theme-toggle[aria-pressed="false"] .theme-icon-moon{ stroke:var(--cyan); }
.theme-toggle[aria-pressed="true"] .theme-icon-sun{ stroke:var(--warn); }
.theme-toggle-track{
  position:relative; width:34px; height:19px; border-radius:99px; background:var(--surface-2);
  border:1px solid var(--line-strong); flex:0 0 auto; transition:background .2s ease;
}
.theme-toggle-thumb{
  position:absolute; top:2px; left:2px; width:13px; height:13px; border-radius:50%;
  background:var(--brand-gradient); transition:transform .25s cubic-bezier(.22,1,.36,1); box-shadow:0 1px 3px rgba(0,0,0,0.4);
}
.theme-toggle[aria-pressed="true"] .theme-toggle-thumb{ transform:translateX(15px); }
.sidebar-foot-item{
  display:flex; align-items:center; gap:10px;
  background:none; border:none; color:var(--text-primary); text-align:left; padding:9px 10px;
  font-size:13px; font-weight:600; border-radius:10px; cursor:pointer; width:100%;
  transition:background .16s ease, box-shadow .16s ease, transform .16s ease;
}
.sidebar-foot-item svg{ width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:2; flex:0 0 auto; transition:width .2s ease, height .2s ease; }
.sidebar-foot-item:hover{ background:var(--surface-1); color:#fff; }
/* Settings lives in the utility row, not .sidebar-nav, so it needs its own
   "currently viewing this page" treatment — same visual language as
   .nav-item.is-active (tinted background + accent bar + soft glow) but a
   single fixed violet accent rather than a per-section data-color, since
   this row has no such mapping. Works unchanged in the collapsed rail too
   (background/box-shadow scale with the element regardless of its size). */
.sidebar-foot-item.is-active{
  color:var(--text-primary);
  background:color-mix(in srgb, var(--violet) 11%, var(--surface-2));
  box-shadow:inset 2px 0 0 var(--violet), 0 0 16px -7px var(--violet);
}

/* ==========================================================================
   Collapsible sidebar (desktop/tablet only — see the ≥1025px guard below;
   the existing ≤1024px off-canvas drawer behavior is untouched and always
   wins on narrower viewports regardless of this state). Expanded stays the
   default. Only .sidebar's width is a "layout" transition — everything
   else animates opacity/max-size, which is what keeps this GPU-cheap and
   free of any new continuous animation loop.
   ========================================================================== */
.sidebar-logo .s-word{ transition:opacity .16s ease; }
.nav-label{
  display:inline-block; overflow:hidden; white-space:nowrap;
  transition:opacity .14s ease, max-width var(--sidebar-transition), margin var(--sidebar-transition);
  max-width:160px;
}
.nav-item .nav-label{ margin-left:0; }
.sidebar-profile, .sidebar-company, .sidebar-upsell{
  overflow:hidden;
  transition:opacity .16s ease, max-height var(--sidebar-transition), margin var(--sidebar-transition), padding var(--sidebar-transition), background-color .16s ease, border-color .16s ease;
}
.sidebar-profile{ max-height:70px; }
.sidebar-company{ max-height:20px; }
/* Was 160px — a few px short of the real content, which clipped the bottom
   of the Upgrade Plan button. 200px clears it with headroom while still
   animating cleanly to 0 on collapse. */
.sidebar-upsell{ max-height:200px; }

/* Collapse/expand control — lives permanently in the bottom utility group
   (both expanded AND collapsed), a plain conventional "panel" glyph whose
   inner chevron flips direction via CSS rather than swapping icons, so
   there's only ever one element to toggle. Same visual language as
   Settings/Log Out — no colored fill/background, just a brighter hover. */
.sidebar-collapse-btn{
  display:flex; align-items:center; gap:10px; width:100%;
  background:none; border:none; color:var(--text-primary); text-align:left; padding:9px 10px;
  font-size:13px; font-weight:600; border-radius:10px; cursor:pointer;
  transition:background .16s ease, box-shadow .16s ease, transform .16s ease;
}
.sidebar-collapse-btn:hover{ background:var(--surface-1); color:#fff; }
.panel-icon{
  width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round; flex:0 0 auto; transition:width .2s ease, height .2s ease, filter .2s ease;
}
.panel-icon .panel-chevron{ transition:transform .2s ease; transform-box:fill-box; transform-origin:center; }
.sidebar-collapse-btn:hover .panel-icon{ filter:drop-shadow(0 0 4px rgba(255,255,255,0.65)); }

/* Restrained white glow behind Collapse/Settings/Log Out on hover — real
   pointers only, so it never gets stuck "on" from a touch tap. Soft
   illumination + a slight lift, not a flash: a static box-shadow/transform
   pair transitioning in, no animation loop. Theme keeps its own separate
   dark/light-coded hover styling untouched. */
@media (hover:hover) and (pointer:fine){
  .sidebar-collapse-btn:hover, .sidebar-foot-item:hover{
    box-shadow:0 0 0 1px rgba(255,255,255,0.07), 0 0 20px -3px rgba(255,255,255,0.4);
    transform:translateY(-1px);
  }
}

.sidebar-divider{ display:none; height:1px; background:var(--line); margin:3px 10px; }

@media (min-width:1025px){
  /* Tight top/bottom padding + zero outer gap — the collapsed rail should
     hug its content; the individual visible pieces below add back only the
     small deliberate spacing they actually need, instead of relying on a
     blanket flex `gap` that (as the logo/nav bug below shows) also counts
     space for elements that are visually gone but still in the DOM. */
  .sidebar.is-collapsed{ width:var(--sidebar-w-collapsed); padding:14px 0 10px; gap:0; }
  .sidebar.is-collapsed .sidebar-logo{
    flex-direction:row; align-items:center;
    align-self:stretch; margin:0 0 14px; width:100%; padding:0; gap:0; justify-content:center;
  }
  .sidebar.is-collapsed .sidebar-logo .s-word{ opacity:0; width:0; }
  /* Collapsed state is the OPPOSITE emphasis from expanded: only the 1E mark
     is visible at all, so it should read as by far the most prominent icon
     in the rail (nav icons are 28px, utility icons sit in a 34px box) —
     44px against the unpadded 50px-wide collapsed rail (see
     .sidebar.is-collapsed above: padding:14px 0 10px, zero horizontal
     padding) leaves 3px clearance each side, centred. */
  /* Pushed to the practical ceiling: the collapsed rail is exactly 50px
     wide with zero horizontal padding anywhere in this chain (.sidebar,
     .sidebar-logo), so 49px leaves a bare ~0.5px safety margin each side —
     as large as the rail can hold without risking a rounding-driven clip. */
  .sidebar.is-collapsed .sidebar-logo .s-mark,
  .sidebar.is-collapsed .sidebar-logo .s-mark-lite{ width:49px; height:49px; border-radius:13px; }
  .sidebar.is-collapsed .sidebar-logo{ margin-top:-2px; }
  .sidebar.is-collapsed .sidebar-profile,
  .sidebar.is-collapsed .sidebar-company,
  .sidebar.is-collapsed .sidebar-upsell{
    opacity:0; max-height:0; margin-top:0; margin-bottom:0; padding-top:0; padding-bottom:0; border-width:0; pointer-events:none;
  }
  /* gap:0 matters here even though .nav-label is width:0 — a flex `gap`
     still reserves space between two rendered flex items regardless of
     either one's own width, so without this the icon sat ~5px left of true
     center (icon + invisible-but-still-gapped label, centered as a pair)
     instead of centered on its own. Same root cause the bottom utility row
     already avoided by zeroing its own gap. */
  .sidebar.is-collapsed .sidebar-nav{ margin-top:0; gap:4px; }
  /* border-left:2px (from the base .nav-item rule) offsets the centred icon
     2px right inside the 50px rail — that's exactly what made the glass pill
     look left-heavy. Zero it in the collapsed rail so the icon sits on the
     true rail centre and the pill is mathematically symmetric. */
  .sidebar.is-collapsed .nav-item{ justify-content:center; padding-left:0; padding-right:0; gap:0; border-left-width:0; }
  /* Collapsed rail: the travelling indicator hugs the isolated icon as a
     centred glass pill (no left border — that reads odd on a narrow chip).
     3px inset each side = a touch wider than before, equal L/R breathing
     room, and never touching the rail edges. */
  .sidebar.is-collapsed .nav-thumb{ left:3px; right:3px; border-radius:13px; }
  .sidebar.is-collapsed .nav-thumb-jelly{
    border-left-width:0;
    box-shadow:0 0 22px -6px var(--na),
               inset 0 0 0 1.5px color-mix(in srgb, var(--na) 32%, transparent),
               inset 0 1px 0 color-mix(in srgb, #fff 7%, transparent);
  }
  /* Collapsed: the MAIN nav icons get the biggest bump — clearly larger and
     more identifiable than the ~34px bottom utility controls (which are
     unchanged). 36px chip in the 50px rail leaves 7px clearance each side. */
  .sidebar.is-collapsed .nav-item .nav-icon{ width:36px; height:36px; border-radius:11px; }
  .sidebar.is-collapsed .nav-item .nav-icon svg{ width:21px; height:21px; }
  .sidebar.is-collapsed .nav-label{ opacity:0; max-width:0; margin-left:0; }
  /* Collapsed-rail hover feedback for INACTIVE items only — a restrained
     white border glow + ambient glow, no layout movement (no transform),
     no large neon effect. The active item keeps its own section-accent
     treatment (.nav-item.is-active above) untouched — this never applies
     to it. Real pointers only, same guard the utility-row glow uses. */
  @media (hover:hover) and (pointer:fine){
    .sidebar.is-collapsed .nav-item:not(.is-active):hover{
      background:var(--surface-1);
      box-shadow:0 0 0 1px rgba(255,255,255,0.12), 0 0 16px -4px rgba(255,255,255,0.4);
    }
    .sidebar.is-collapsed .nav-item:not(.is-active):hover .nav-icon{
      background:var(--surface-hover);
    }
  }

  /* Bottom utility row (collapse toggle / theme / Settings / Log Out): each
     becomes an IDENTICAL fixed-size square, auto-centered in the rail — the
     same box, centered the same way, for every icon — rather than each row
     separately centering its own differently-sized content (which is what
     let the theme toggle's icon drift off the shared axis before). This is
     the actual container/alignment fix, not a per-icon margin nudge. Extra
     vertical gap + brighter/larger icons make this row read with the same
     visual authority as the main nav instead of sitting small and muted
     beside it. */
  .sidebar.is-collapsed .sidebar-utility{ gap:9px; padding-top:8px; }
  .sidebar.is-collapsed .sidebar-collapse-btn,
  .sidebar.is-collapsed .theme-toggle,
  .sidebar.is-collapsed .sidebar-foot-item{
    width:34px; height:34px; margin:0 auto; padding:0; gap:0; justify-content:center;
    color:var(--text-primary);
  }
  .sidebar.is-collapsed .sidebar-collapse-btn:hover,
  .sidebar.is-collapsed .sidebar-foot-item:hover{ color:#fff; }
  /* QC#13 — collapsed rail: Log Out reads as the danger action it is (icon
     only, no label to signal it), using the shared danger colour. Only
     #logoutBtn — Settings stays neutral. */
  .sidebar.is-collapsed #logoutBtn{ color:var(--bad); }
  .sidebar.is-collapsed #logoutBtn svg{ stroke:var(--bad); }
  .sidebar.is-collapsed #logoutBtn:hover{ color:var(--bad); background:var(--bad-dim); }
  .sidebar.is-collapsed #logoutBtn:hover svg{ stroke:var(--bad); }
  .sidebar.is-collapsed #logoutBtn:focus-visible{ outline:2px solid var(--bad); outline-offset:2px; }
  .sidebar.is-collapsed .panel-icon,
  .sidebar.is-collapsed .sidebar-foot-item svg{ width:19px; height:19px; }
  .sidebar.is-collapsed .panel-chevron{ transform:scaleX(-1); }
  .sidebar.is-collapsed .theme-toggle-track{ display:none; }
  .sidebar.is-collapsed .theme-icon{ width:18px; height:18px; }
  /* The compact rail shows exactly ONE icon reflecting the CURRENT mode
     (moon while dark, sun while light) rather than always defaulting to the
     moon — so it still communicates real state, not just decoration. */
  .sidebar.is-collapsed .theme-toggle[aria-pressed="false"] .theme-icon-sun{ display:none; }
  .sidebar.is-collapsed .theme-toggle[aria-pressed="true"] .theme-icon-moon{ display:none; }
  .sidebar.is-collapsed .sidebar-collapse-btn .nav-label,
  .sidebar.is-collapsed .sidebar-foot-item .nav-label{ opacity:0; max-width:0; }
  .sidebar.is-collapsed .sidebar-divider{ display:block; }

  /* Collapsed-rail tooltips — CSS-only, no JS positioning loop. Only ever
     shown while collapsed, since a fully-expanded sidebar already has its
     own visible label. */
  .sidebar.is-collapsed [data-tooltip]{ position:relative; }
  .sidebar.is-collapsed [data-tooltip]:hover::after,
  .sidebar.is-collapsed [data-tooltip]:focus-visible::after{
    content:attr(data-tooltip);
    position:absolute; left:calc(100% + 12px); top:50%; transform:translateY(-50%);
    /* Premium smoked / frosted glass — ONE system in both themes (the rail
       is permanently dark). ~87% dark material + a strong backdrop blur so
       whatever sits behind it (bright light-mode content included) melts to
       an unreadable wash, + a subtle violet brand edge + crisp white text.
       Not a flat black rectangle, not near-transparent glass. */
    background:rgba(11,12,22,0.87);
    -webkit-backdrop-filter:blur(18px) saturate(1.4); backdrop-filter:blur(18px) saturate(1.4);
    border:1px solid rgba(139,108,247,0.30); color:#FFFFFF;
    font-size:12px; font-weight:600; white-space:nowrap; padding:7px 12px; border-radius:9px;
    box-shadow:0 16px 40px -8px rgba(0,0,0,0.62), 0 0 0 1px rgba(0,0,0,0.5), 0 0 20px -4px rgba(139,108,247,0.32);
    pointer-events:none; z-index:120;
    animation:sidebarTooltipIn .12s ease;
  }
}
@keyframes sidebarTooltipIn{ from{ opacity:0; transform:translateY(-50%) translateX(-4px); } to{ opacity:1; transform:translateY(-50%) translateX(0); } }

/* No explicit width/margin rule needed here for the collapse feature — .app
   is a plain flex row and .main is flex:1 1 auto, so it already reflows to
   fill whatever width .sidebar's own width transition frees up, frame by
   frame, for free. */
/* Desktop-only: top padding trimmed to near-zero so the timeframe selector's
   top border essentially kisses the viewport's top edge — "docked to the
   roof" rather than floating with normal card breathing room above it. The
   ≤1024px and ≤430px breakpoints below both re-declare the full padding
   shorthand with their own 10px top value, so this reduction never reaches
   mobile/tablet, per item 7's "DESKTOP" scope. */
.main{ flex:1 1 auto; min-width:0; padding:3px 10px 60px; }
#viewOverview{ transition:opacity .2s ease; }
#viewOverview.is-refreshing{ opacity:0.5; }
/* Final pre-live polish — Overview's own content is tall enough that the
   generic 60px .main trailing padding (sized for shorter, ordinary
   scrolling pages) reads as an oversized dead footer gutter under the
   final row. Scoped to Overview only via body.is-overview (toggled in
   switchView) — every other view keeps the untouched 60px value the
   Settings/Leads negative-margin fixes are already calibrated against. */
body.is-overview .main{ padding-bottom:26px; }

/* ==========================================================================
   Header
   ========================================================================== */
/* Desktop: tight, intentional gap between the header/subtitle and the first
   KPI row (~half the previous 28px). Mobile keeps its original breathing
   room — see the ≤1024px override below, where the topbar controls wrap and
   need the extra space. */
/* align-items:flex-start (not center) is the actual mechanism behind moving
   the timeframe controls up on desktop (item 7): .topbar-title (heading +
   subtitle) is the taller of the two row children, so under flex-start it
   sits exactly where it always did (the tallest item has zero centering
   offset either way) while .topbar-controls — shorter — now sits flush with
   the row's top instead of vertically centered ~8px down from it. Mobile
   gets its own align-items:stretch override below (≤1024px), so this is
   already desktop-only in effect. */
.topbar{ display:flex; align-items:flex-start; justify-content:space-between; gap:20px; flex-wrap:wrap; margin-bottom:14px; }
/* item 5 (+ item 10, Refinement Pass Part 2) — shared COMMAND HEADER: the
   #pageTitleGroup/#pageHeaderActions row gets contained in one compact glass
   panel. Originally Smart-Accessories-only; now the shared treatment for
   Smart Accessories, Digital Card and Contact Command via body.is-command-
   header (set in switchView()). Suppressed on an open contact record
   (:not(.is-lead-record)) — that view hides the generic header entirely.
   Overview keeps its own separate Command Center header, untouched — this
   rule never matches it. Deliberately compact (modest padding, no added
   height beyond the panel chrome) with a tighter bottom margin than the
   shared 14px default, so the panel flows straight into the page content
   instead of floating above it like a hero. */
body.is-command-header:not(.is-lead-record) .topbar{
  background:var(--surface-1); border:1px solid var(--line); border-radius:var(--radius-lg);
  padding:14px 18px; margin-bottom:10px; position:relative; overflow:hidden;
}
body.is-command-header:not(.is-lead-record) .topbar::before{
  content:""; position:absolute; inset:0; pointer-events:none; z-index:0;
  background:radial-gradient(ellipse 120% 90% at 0% 0%, color-mix(in srgb, var(--cyan) 8%, transparent), transparent 62%);
}
body.is-command-header:not(.is-lead-record) .topbar-titlegroup,
body.is-command-header:not(.is-lead-record) .topbar-controls{ position:relative; z-index:1; }
[data-theme="light"] body.is-command-header:not(.is-lead-record) .topbar::before{
  background:radial-gradient(ellipse 120% 90% at 0% 0%, color-mix(in srgb, var(--cyan) 5%, transparent), transparent 62%);
}
/* min-width:0 down this whole chain is the actual fix for a narrow-viewport
   bug where the title, instead of wrapping to a second line inside its own
   box, was overflowing straight past the edge of the screen — flex items
   default to a minimum size equal to their content's un-shrunk width unless
   told otherwise, which silently defeats normal text wrapping. */
.topbar-titlegroup{ display:flex; align-items:center; gap:12px; min-width:0; flex:1 1 auto; }
/* Phase 4 — the heading now LEFT-aligns, so it shares the same left edge as
   every other page title and reads as the left half of a proper
   title / right-controls topbar (centered, it floated as an island a touch
   left of true-centre and slightly above the date controls). */
.topbar-title{ display:flex; flex-direction:column; align-items:flex-start; gap:2px; min-width:0; padding-top:2px; }
.topbar-title h1, .topbar-title .topbar-subtitle{ text-align:left; }
/* Matched to the actual 1EIGHTY wordmark asset (assets/logo-word.png), not
   another dashboard element — the mark is a bold, geometric, squared-off
   sans (flat-cut terminals on the T/Y, uniform thick strokes, single-story
   forms), which is exactly Space Grotesk's own known character (see
   --font-command below, already loaded via Google Fonts and already used
   for this same reason before an earlier pass over-corrected it toward
   matching a different element instead). Solid white, current
   size/position unchanged — typography only. */
/* Phase 4 — a more distinctive "command interface" treatment: the command
   face set in caps with wide, even tracking at a lighter weight (600) reads
   as technical / instrument-panel, not gamer. The size drops because caps
   carry more visual weight. Baseline nudged down a hair to line up with the
   date controls on the right. */
/* Shared "Command Center" headline treatment — one reusable rule instead
   of two near-duplicate ones. Bumped from 21px (the original Command
   Center size) to 26px so the flagship page title actually reads as the
   strongest headline in the product; that resulting size/weight/tracking
   is now the standard for EVERY major page's <h1> (.page-title h1 below
   used to run its own larger-but-plain 27px/700/tight-tracking treatment —
   retired in favor of this one, so every top-level page shares one
   headline system, not four). Positioning (margin/gap/flex) stays on each
   selector's own rule since Overview's and the generic page-header's
   layouts genuinely differ. */
.topbar-title h1,
.page-title h1{
  font-family:var(--font-command);
  font-size:26px; font-weight:600; letter-spacing:0.13em; line-height:1.15;
  text-transform:uppercase;
  color:var(--text-primary);
}
.topbar-title h1{ margin-top:3px; }
/* A restrained, STATIC cool sheen on the words — same blue→cyan→white family
   the "1EIGHTY ecosystem" accent uses, but no animation and low contrast so
   it reads as quiet premium polish, not a light show. */
.topbar-title h1 .cmd-accent{
  background:linear-gradient(96deg, #CFE0FF 0%, #FFFFFF 42%, #BFEEFF 78%, #E6F6FF 100%);
  -webkit-background-clip:text; background-clip:text; color:transparent;
  text-shadow:0 0 18px rgba(120,200,255,0.18);
}
[data-theme="light"] .topbar-title h1 .cmd-accent{
  background:none; color:var(--text-primary); text-shadow:none;
}
.topbar-subtitle{ font-size:13px; color:var(--text-secondary); font-weight:500; }
/* Restrained, premium "alive" accent for just the brand phrase — same cool
   blue->cyan->white family as before, now with a second slow layer: the
   gradient itself is widened (background-size:220%) and its position drifts
   back and forth (ecosystemDrift) UNDER the existing brightness/glow pulse
   (ecosystemBreathe) — the two together read as color/energy moving inside
   the letters rather than a uniform flat pulse, without any hue leaving the
   blue/cyan/white family (no rainbow travel, no shimmer-speed motion). */
.ecosystem-accent{
  background:linear-gradient(100deg, #4A8CFF 0%, #6FA8FF 22%, #4FD8FF 45%, #FFFFFF 60%, #4FD8FF 78%, #6FA8FF 100%);
  background-size:220% 100%;
  -webkit-background-clip:text; background-clip:text; color:transparent;
  text-shadow:0 0 10px rgba(79,216,255,0.28);
  animation:ecosystemBreathe 6.5s ease-in-out infinite, ecosystemDrift 9s ease-in-out infinite;
}
@keyframes ecosystemBreathe{
  0%, 100%{ filter:brightness(0.94) saturate(0.95); text-shadow:0 0 8px rgba(79,216,255,0.2); }
  50%{ filter:brightness(1.18) saturate(1.15); text-shadow:0 0 16px rgba(79,216,255,0.5); }
}
@keyframes ecosystemDrift{
  0%, 100%{ background-position:0% 50%; }
  50%{ background-position:100% 50%; }
}
@media (prefers-reduced-motion:reduce){
  .ecosystem-accent{ animation:none; filter:brightness(1.05); text-shadow:0 0 10px rgba(79,216,255,0.3); background-position:30% 50%; }
}
/* Non-Overview page identity — left-aligned, same headline treatment as
   Command Center (see the shared .topbar-title h1, .page-title h1 rule
   above); only the layout (row of title+badge, top offset) is page-header-
   specific. Not centered / no gradient sheen on the words themselves —
   that stays unique to the Command Center span (.cmd-accent). */
.page-title{ display:flex; flex-direction:column; gap:3px; min-width:0; padding-top:3px; }
.page-title h1{
  display:flex; align-items:center; gap:11px; flex-wrap:wrap;
}
/* Tablet — the longer page titles ("Smart Accessories", "Contact Command")
   at the new 26px/uppercase/wide-tracking size need a touch more room once
   the sidebar is still full-width but the content column has narrowed;
   the ≤430px mobile step (see the responsive section) covers phones. */
@media (max-width:900px){
  .topbar-title h1, .page-title h1{ font-size:22px; letter-spacing:0.11em; }
}

/* Phase 3 — "Beta" preview badge (Card Studio). Small rounded glass pill
   with a restrained cyan/violet neon edge + glow. No star, no warning tone. */
.beta-badge{
  display:inline-flex; align-items:center; gap:4px;
  font-family:var(--font-mono, 'JetBrains Mono', ui-monospace, monospace);
  font-size:9.5px; font-weight:800; letter-spacing:0.14em; text-transform:uppercase;
  color:var(--cyan);
  padding:3px 8px 2px; border-radius:99px;
  background:color-mix(in srgb, var(--cyan) 12%, transparent);
  border:1px solid color-mix(in srgb, var(--cyan) 40%, transparent);
  box-shadow:0 0 14px -4px color-mix(in srgb, var(--cyan) 60%, transparent),
             inset 0 0 8px -4px color-mix(in srgb, var(--cyan) 50%, transparent);
  position:relative; top:-1px;
}
.beta-badge[hidden]{ display:none; }
.mock-overlay-eyebrow .beta-badge{ font-size:8.5px; padding:2px 6px 1px; letter-spacing:0.12em; top:0; vertical-align:middle; }
[data-theme="light"] .beta-badge{
  color:color-mix(in srgb, var(--cyan) 72%, #0b2b39);
  background:color-mix(in srgb, var(--cyan) 16%, #fff);
  border-color:color-mix(in srgb, var(--cyan) 46%, transparent);
  box-shadow:0 0 12px -5px color-mix(in srgb, var(--cyan) 50%, transparent);
}
@media (max-width:560px){ .beta-badge{ font-size:9px; letter-spacing:0.1em; } }
.page-title .page-desc{ margin-top:0; font-size:13px; color:var(--text-secondary); font-weight:500; line-height:1.4; }
/* §10, Revision 3 — a plain nav shortcut in the page-header's action slot
   (Smart Accessories only). Same .btn.btn-ghost pill every other secondary
   action already uses, just sized to sit in a topbar row. */
.page-header-actions{ align-self:center; }
.page-header-leads-btn{ width:auto; padding:9px 18px; font-size:13px; gap:7px; }
.page-header-leads-btn svg{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2; }
/* QC P1 — the notification-bell slot. NOT a .topbar-controls container, so it
   is not hidden by body.is-lead-record (Full Contact Record). Sits at the far
   right of the topbar on every non-Overview view; empty on Overview (the bell
   moves into #overviewControls there). */
.topbar-notif{ display:flex; align-items:center; }
/* #2 (polish pass) — Full Contact header cluster: the Call/Email/Note/
   Appointment quick actions and the notification bell are ONE control
   family on ONE row, sharing footprint, icon scale, colour + hover. The
   Full-Contact nudge (down + slightly left, to sit on the contact-name row
   near the Task Manager card) is applied to the whole cluster so nothing
   drifts out of line. */
.lead-header-cluster{ display:flex; align-items:center; gap:3px; align-self:center; flex:0 0 auto; }
/* MANUAL QA item-11 — on the Full Contact page the cluster used to sit
   IN-FLOW in the topbar and get transformed 42px down, so ~42px of empty
   topbar was reserved above "Back to Contacts". Position it absolutely
   instead (over the record-bar row, as designed) so the topbar collapses
   and the whole three-lane page rises with normal page padding. */
body.is-lead-record .topbar{ position:relative; }
body.is-lead-record .lead-header-cluster{ position:absolute; top:100%; right:6px; transform:translateY(2px); z-index:3; }
/* QC P6 — Full Contact Record ONLY: slightly larger, nudged down + left so
   it reads on the same row as the contact name/crumb and lands near the
   Task Manager card's top-right corner, instead of sitting up in the
   (visually compressed, on this view) topbar row above everything. Scoped
   to body.is-lead-record — every other view's bell (Command Center, Orbit
   List/Pipeline, Digital Card, Smart Accessories, Settings) is completely
   untouched; global bell size/position/behavior stays locked. */
body.is-lead-record .notif-bell{ width:42px; height:42px; }

/* ===== QC — Notification bell + Notification Center ===================== */
/* QC P10 — the bell is a STANDALONE icon (no button box): larger glyph, larger
   invisible hit area, a subtle violet hover glow, an obvious unread badge.
   Sits between the timeframe control and Live Data on the Command Center. */
.notif-bell{
  position:relative; flex:0 0 auto; width:38px; height:38px; border-radius:50%; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center;
  background:none; border:none; padding:0; color:var(--text-secondary);
  transition:color .14s ease, transform .1s ease, filter .16s ease;
}
/* Full Contact header quick-action cluster — LITERALLY the same control
   language as .notif-bell: same box, same glyph scale, same colour + hover
   glow, same active press, same dark/light. */
.lead-quick-actions{ display:inline-flex; align-items:center; gap:3px; }
.lead-qa-btn, .notif-bell{
  flex:0 0 auto; width:38px; height:38px; border-radius:50%; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center;
  background:none; border:none; padding:0; color:var(--text-secondary);
  transition:color .14s ease, transform .1s ease, filter .16s ease;
}
body.is-lead-record .lead-qa-btn, body.is-lead-record .notif-bell{ width:42px; height:42px; }
.lead-qa-btn svg, .notif-bell svg{ width:22px; height:22px; stroke:currentColor; fill:none; stroke-width:1.9; }
body.is-lead-record .lead-qa-btn svg, body.is-lead-record .notif-bell svg{ width:24px; height:24px; }
.lead-qa-btn:hover, .notif-bell:hover{ color:var(--text-primary); filter:drop-shadow(0 0 7px color-mix(in srgb, var(--violet) 55%, transparent)); }
.lead-qa-btn:focus-visible, .notif-bell:focus-visible{ outline:2px solid var(--violet); outline-offset:2px; }
.lead-qa-btn:active, .notif-bell:active{ transform:scale(0.92); }
.lead-qa-btn.is-off{ color:var(--text-tertiary); opacity:0.4; cursor:not-allowed; }
.lead-qa-btn.is-off:hover{ filter:none; }
@media (max-width:640px){
  .lead-quick-actions{ gap:1px; }
  .lead-qa-btn, .notif-bell, body.is-lead-record .lead-qa-btn, body.is-lead-record .notif-bell{ width:34px; height:34px; }
  .lead-qa-btn svg, .notif-bell svg, body.is-lead-record .lead-qa-btn svg, body.is-lead-record .notif-bell svg{ width:20px; height:20px; }
}
@media (max-width:460px){ .lead-quick-actions [data-lead-qa="appt"]{ display:none; } }
.notif-bell[aria-expanded="true"]{ color:var(--text-primary); }
.notif-bell.has-unread{ color:var(--text-primary); }
.notif-bell.has-unread svg{ filter:drop-shadow(0 0 6px color-mix(in srgb, var(--violet) 42%, transparent)); }
.notif-bell-badge{
  position:absolute; top:0; right:0; min-width:16px; height:16px; padding:0 4px; border-radius:99px;
  display:inline-flex; align-items:center; justify-content:center;
  font-size:10px; font-weight:800; line-height:1; color:#fff;
  background:var(--bad); border:2px solid var(--bg, var(--ink-950)); box-shadow:0 0 0 1px color-mix(in srgb, var(--bad) 40%, transparent);
}
@keyframes notifBellRing{
  0%, 82%, 100%{ transform:rotate(0); }
  86%{ transform:rotate(11deg); } 90%{ transform:rotate(-9deg); }
  94%{ transform:rotate(6deg); } 98%{ transform:rotate(-3deg); }
}
@media (prefers-reduced-motion:no-preference){
  .notif-bell.is-urgent svg{ animation:notifBellRing 3.4s ease-in-out infinite; transform-origin:50% 20%; }
}
.notif-bell.is-urgent .notif-bell-badge{ background:var(--bad); }

.notif-scrim{ position:fixed; inset:0; z-index:239; background:transparent; }
.notif-scrim[hidden]{ display:none; }
.notif-panel{
  position:fixed; z-index:240; width:min(380px, calc(100vw - 20px));
  display:flex; flex-direction:column; overflow:hidden; border-radius:18px;
  /* Apple-style translucent glass — layered highlight, deep blur, cool tint,
     hairline border, premium shadow. Dark-first; light override below. */
  background:
    linear-gradient(180deg, rgba(255,255,255,0.10), rgba(255,255,255,0) 38%),
    linear-gradient(200deg, color-mix(in srgb, var(--violet) 10%, transparent), transparent 55%),
    color-mix(in srgb, var(--ink-900) 74%, transparent);
  -webkit-backdrop-filter:blur(34px) saturate(1.8) brightness(1.06);
  backdrop-filter:blur(34px) saturate(1.8) brightness(1.06);
  border:1px solid color-mix(in srgb, #fff 13%, var(--line-strong));
  box-shadow:0 36px 90px -22px rgba(0,0,0,0.6), 0 0 0 1px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.12);
  opacity:0; transform:translateY(-8px) scale(0.98);
  transition:opacity .16s ease, transform .2s cubic-bezier(.32,.72,0,1);
}
.notif-panel.is-open{ opacity:1; transform:translateY(0) scale(1); }
.notif-panel[hidden]{ display:none; }
[data-theme="light"] .notif-panel{
  background:
    linear-gradient(180deg, rgba(255,255,255,0.66), rgba(255,255,255,0) 42%),
    linear-gradient(200deg, color-mix(in srgb, var(--violet) 9%, transparent), color-mix(in srgb, var(--cyan) 6%, transparent) 60%),
    color-mix(in srgb, #F1F0F8 82%, transparent);
  -webkit-backdrop-filter:blur(40px) saturate(1.5); backdrop-filter:blur(40px) saturate(1.5);
  border-color:color-mix(in srgb, var(--violet) 20%, rgba(28,27,64,0.12));
  box-shadow:0 40px 100px -28px rgba(28,27,64,0.28), 0 0 0 1px rgba(255,255,255,0.7), inset 0 1px 0 rgba(255,255,255,0.9);
}
@media (prefers-reduced-motion:reduce){
  .notif-panel{ transition:opacity .12s ease; transform:none; }
  .notif-panel.is-open{ transform:none; }
}
.notif-panel-hd{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:13px 15px 11px; border-bottom:1px solid color-mix(in srgb, #fff 8%, var(--line));
  flex:0 0 auto;
}
[data-theme="light"] .notif-panel-hd{ border-bottom-color:var(--line); }
.notif-panel-title{ font-size:13.5px; font-weight:800; letter-spacing:-0.01em; color:var(--text-primary); }
.notif-panel-actions{ display:flex; align-items:center; gap:2px; }
.notif-panel-actions .notif-markall[hidden]{ display:none; }
#notifClearAll{ color:var(--text-tertiary); }
#notifClearAll:hover{ color:var(--bad); }
.notif-markall{
  display:inline-flex; align-items:center; gap:5px; background:none; border:none; cursor:pointer; font:inherit;
  font-size:11.5px; font-weight:700; color:var(--text-tertiary); padding:3px 4px; border-radius:6px;
  transition:color .12s ease;
}
.notif-markall:hover{ color:var(--violet); }
.notif-markall svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.2; }
/* CORRECTION PASS 3 #1 — ROOT CAUSE of "50 notifications compress into
   unreadable slivers": .notif-item never opted out of the flex default
   (flex-shrink:1), so once total row content exceeded the panel's available
   height, the flex algorithm shrank every row to fit rather than leaving
   them full-height and letting THIS list scroll. max-height caps the list at
   roughly 8 full rows (row ~58px + 5px gap) regardless of how much extra
   room a tall viewport's placeNotifPanel() math would otherwise allow, so a
   long list always shows ~8 and scrolls for the rest; a short list (<=8)
   never reaches this cap and sizes to its own content as before — no empty
   space added, no change to that case. */
.notif-list{ --notif-gap:5px; overflow-y:auto; overscroll-behavior:contain; scroll-behavior:smooth; padding:6px; flex:1 1 auto; min-height:0; max-height:512px; display:flex; flex-direction:column; gap:var(--notif-gap); }
/* Priority-6M — one shared iOS-notification-card system. EVERY row (read or
   unread) is the same soft inset surface; the category tint (--notif-c, set by
   the .is-<tone> class) is always present but faint; unread adds a left accent
   bar + a touch more tint. Cards never touch/overlap (the .notif-list gap +
   each card's own border). Works in both themes. */
.notif-item{
  position:relative; display:flex; align-items:stretch; gap:0; width:100%;
  border-radius:13px; overflow:hidden; flex-shrink:0;
  --notif-c:#2FD0FF;
  background:
    linear-gradient(90deg, color-mix(in srgb, var(--notif-c) 8%, transparent), color-mix(in srgb, var(--notif-c) 3%, transparent) 60%),
    var(--surface-1);
  border:1px solid color-mix(in srgb, var(--notif-c) 16%, var(--line));
  transition:background .12s ease, border-color .12s ease;
}
/* MANUAL QA item-3 — iOS-lock-screen swipe-off: slide + fade fast, then
   collapse height so the rows below rise. Inline styles set by notifClearRow. */
.notif-item.is-clearing{
  pointer-events:none; overflow:hidden;
  transition:opacity .16s ease, transform .2s cubic-bezier(.4,0,.15,1),
             max-height .2s ease, margin-top .2s ease;
}
@media (prefers-reduced-motion:reduce){ .notif-item.is-clearing{ transition:none; } }
.notif-item.is-cyan{ --notif-c:#2FD0FF; } .notif-item.is-green{ --notif-c:#22C55E; }
.notif-item.is-violet{ --notif-c:#8B6CF7; } .notif-item.is-amber{ --notif-c:#FF8A3D; }
.notif-item.is-red{ --notif-c:#F1495F; }
[data-theme="light"] .notif-item{
  background:linear-gradient(90deg, color-mix(in srgb, var(--notif-c) 10%, transparent), color-mix(in srgb, var(--notif-c) 4%, transparent) 60%), #fff;
  border-color:color-mix(in srgb, var(--notif-c) 22%, var(--line));
}
.notif-item.is-unread::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:3px;
  background:var(--notif-c); border-radius:3px 0 0 3px;
}
.notif-item.is-unread{ border-color:color-mix(in srgb, var(--notif-c) 34%, var(--line)); }
.notif-item-main{
  flex:1 1 auto; min-width:0; display:flex; align-items:flex-start; gap:11px; text-align:left; cursor:pointer;
  background:none; border:none; font:inherit; padding:10px 6px 10px 12px;
  transition:background .12s ease;
}
.notif-item-main:hover{ background:color-mix(in srgb, var(--notif-c) 8%, transparent); }
.notif-item-more{
  flex:0 0 auto; align-self:stretch; width:34px; display:flex; align-items:center; justify-content:center;
  background:none; border:none; border-left:1px solid color-mix(in srgb, var(--notif-c) 12%, var(--line)); cursor:pointer;
  color:var(--text-tertiary); transition:color .12s ease, background .12s ease;
}
.notif-item-more:hover{ color:var(--text-primary); background:color-mix(in srgb, var(--notif-c) 10%, transparent); }
.notif-item-more svg{ width:16px; height:16px; fill:currentColor; }
.notif-row-menu{
  position:fixed; z-index:260; min-width:210px; padding:5px; border-radius:12px;
  background:color-mix(in srgb, var(--ink-900) 82%, transparent);
  -webkit-backdrop-filter:blur(24px) saturate(1.6); backdrop-filter:blur(24px) saturate(1.6);
  border:1px solid color-mix(in srgb, #fff 12%, var(--line-strong));
  box-shadow:0 24px 60px -18px rgba(0,0,0,0.6);
}
[data-theme="light"] .notif-row-menu{ background:rgba(255,255,255,0.98); border-color:var(--line); box-shadow:0 24px 60px -20px rgba(46,32,96,0.24); }
.notif-row-menu-item{
  display:block; width:100%; text-align:left; background:none; border:none; cursor:pointer; font:inherit;
  font-size:12px; font-weight:600; color:var(--text-primary); padding:8px 10px; border-radius:8px; transition:background .1s ease;
}
.notif-row-menu-item:hover{ background:var(--surface-hover); }
.notif-row-menu-item.is-danger{ color:var(--bad); }
.notif-row-menu-item.is-danger:hover{ background:var(--bad-dim); }
.notif-item .notif-av,
.notif-item .lead-owner-ini.notif-av{ width:30px; height:30px; font-size:11px; flex:0 0 auto; border-radius:9px; }
.notif-ic{
  flex:0 0 auto; width:30px; height:30px; border-radius:9px; display:flex; align-items:center; justify-content:center;
  background:color-mix(in srgb, var(--notif-c, var(--cyan)) 16%, transparent);
  border:1px solid color-mix(in srgb, var(--notif-c, var(--cyan)) 30%, transparent);
}
.notif-ic svg{ width:15px; height:15px; stroke:var(--notif-c, var(--cyan)); fill:none; stroke-width:2; }
.notif-ic.is-cyan{ --notif-c:#2FD0FF; } .notif-ic.is-green{ --notif-c:#22C55E; }
.notif-ic.is-violet{ --notif-c:#8B6CF7; } .notif-ic.is-amber{ --notif-c:#FF8A3D; }
.notif-ic.is-red{ --notif-c:#F1495F; }
.notif-body{ flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:2px; }
.notif-item-title{ font-size:12.5px; font-weight:700; color:var(--text-primary); line-height:1.3; }
.notif-item-line{ font-size:11.5px; color:var(--text-secondary); line-height:1.35; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.notif-item-meta{ flex:0 0 auto; display:flex; flex-direction:column; align-items:flex-end; gap:5px; padding-top:1px; }
.notif-dot{ width:7px; height:7px; border-radius:50%; background:var(--violet); }
.notif-time{ font-size:10px; color:var(--text-tertiary); font-family:'JetBrains Mono', ui-monospace, monospace; white-space:nowrap; }
.notif-empty{ padding:34px 20px 38px; text-align:center; }
.notif-empty-ic{
  display:inline-flex; align-items:center; justify-content:center; width:44px; height:44px; border-radius:13px; margin-bottom:12px;
  background:var(--surface-2); border:1px solid var(--line-strong);
}
.notif-empty-ic svg{ width:20px; height:20px; stroke:var(--text-tertiary); fill:none; stroke-width:1.8; }
.notif-empty-t{ font-size:13px; font-weight:700; color:var(--text-primary); }
.notif-empty-d{ font-size:11.5px; color:var(--text-tertiary); margin-top:4px; line-height:1.5; }
@media (max-width:520px){
  .notif-panel{ width:calc(100vw - 16px); }
}
/* Command Center's own subtitle only (not the shared .page-desc use of this
   same class on every other page) — a clean, clearly-white read rather than
   the muted secondary gray every other subtitle/description uses. Not pure
   #FFF (still --text-primary, the same "softened white" the rest of the
   dashboard's primary text uses) so it doesn't blow out next to the
   gradient heading above it. */
.topbar-title .topbar-subtitle{ color:var(--text-primary); font-weight:600; }
/* margin-left:auto is the real fix here: whenever the title's own width
   forces .topbar to wrap onto two lines (long title, or a narrower window),
   justify-content:space-between no longer has any effect on a lone
   second-line item — it would otherwise fall back to flex-start and sit at
   the LEFT, under the title, which is exactly the bug this corrects. With
   the auto margin, controls stay pinned to the right edge of their own line
   whether they share the first line with the title or wrap to their own. */
.topbar-controls{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; margin-left:auto; }
.date-range{ font-size:13.5px; color:var(--text-secondary); white-space:nowrap; }
.date-presets{ position:relative; display:flex; gap:2px; padding:4px; border-radius:12px; background:var(--surface-1); border:1px solid var(--line); }
.date-presets button{
  position:relative; z-index:1;
  border:none; background:none; color:var(--text-secondary); font-size:13px; font-weight:700;
  padding:8px 14px; border-radius:8px; cursor:pointer;
  /* color transition ~tracks the thumb's travel so the label doesn't turn
     dark before the pill arrives under it */
  transition:color .42s ease, background .18s ease, transform .12s ease;
}
.date-presets button:hover{ color:var(--text-primary); background:var(--surface-hover); }
.date-presets button:active{ transform:scale(0.96); }
/* Violet-dominant (item 6) — same hybrid violet/cyan family as
   --brand-gradient, color-stop boundary pushed to 60% so violet reads as
   the anchor color with cyan as a far-corner glint. */
.date-presets button.is-active{
  background:linear-gradient(135deg, var(--violet) 0%, var(--violet) 60%, var(--cyan) 100%);
  color:#0A0A16; box-shadow:0 2px 14px rgba(139,108,247,0.45), inset 0 0 0 1px rgba(139,108,247,0.3);
}
/* One physical sliding selection indicator. Two layers:
   - .date-preset-thumb (outer): position + width, eased over ~870ms with a
     smooth viscous curve (accelerate, long glide, soft settle — no bounce).
   - .date-preset-thumb-jelly (inner): a one-shot stretch -> compress ->
     tiny-overshoot -> settle keyframe on each move, its transform-origin
     set toward the destination (by positionDatePresetThumb) so the pill
     appears to reach for and then absorb into the target button.
   Text lives in the buttons (z-index:1), never in the thumb, so it never
   distorts. .has-thumb on the parent hands the active background to this
   element; button.is-active above is the no-JS fallback.
   prefers-reduced-motion is handled globally (durations forced to ~0). */
.date-preset-thumb{
  position:absolute; top:4px; bottom:4px; left:0; width:0;
  pointer-events:none; opacity:0; z-index:0;
  transition:transform .87s cubic-bezier(.34,0,.12,1), width .82s cubic-bezier(.4,0,.16,1);
}
.date-preset-thumb.is-ready{ opacity:1; }
.date-preset-thumb-jelly{
  display:block; width:100%; height:100%; border-radius:8px;
  background:linear-gradient(135deg, var(--violet) 0%, var(--violet) 60%, var(--cyan) 100%);
  box-shadow:0 2px 14px rgba(139,108,247,0.45), inset 0 0 0 1px rgba(139,108,247,0.3);
  will-change:transform;
}
.date-preset-thumb-jelly.is-jelly{ animation:thumbJelly .87s cubic-bezier(.4,0,.2,1) both; }
@keyframes thumbJelly{
  0%   { transform:scaleX(1)     scaleY(1);     }
  26%  { transform:scaleX(1.13)  scaleY(0.93);  }  /* reach toward destination */
  56%  { transform:scaleX(0.94)  scaleY(1.045); }  /* compress / absorb on arrival */
  78%  { transform:scaleX(1.026) scaleY(0.99);  }  /* one tiny overshoot */
  100% { transform:scaleX(1)     scaleY(1);     }
}
.date-presets.has-thumb button.is-active{ background:none; box-shadow:none; }
.date-presets.has-thumb button.is-active:hover{ background:none; color:#0A0A16; }

/* Live Data status — a real timestamp derived from the most recent event,
   not a decorative placeholder, paired with a small looping ECG sweep. */
.live-indicator{ display:flex; align-items:center; gap:10px; }
.live-indicator-text{ text-align:right; }
.live-indicator-label{
  display:flex; align-items:center; gap:6px; justify-content:flex-end; font-size:12.5px; font-weight:700; color:var(--text-primary);
}
/* Red now, matching the ECG — the whole "Live Data" status language reads
   red. livePulse (opacity 1 -> 0.4 -> 1 over 2.2s ease-in-out) is a gentle
   status breath, never a strobe, and stays clearly visible at its dimmest. */
.live-indicator-label .dot{ width:6px; height:6px; border-radius:50%; background:var(--bad); box-shadow:0 0 6px var(--bad); animation:livePulse 2.2s ease-in-out infinite; }
/* Relative-time sub-line ("2h ago" etc.) removed from view per request —
   "Live Data" + the dot + the ECG sweep already communicate liveness on
   their own. The element and its real update wiring stay in the DOM/JS
   (harmless, keeps the underlying real-timestamp logic intact) — just not
   shown. */
.live-indicator-sub{ display:none; }
.live-heartbeat{ width:56px; height:22px; flex:0 0 auto; }
.live-heartbeat path{ fill:none; stroke-linecap:round; stroke-linejoin:round; }
/* The full waveform shape stays visible at ALL times (the "monitor" itself
   never disappears) at a steady low brightness — thin and crisp, like a
   real ECG trace, not a decorative squiggle. */
/* The inactive trace stays visible at all times as a dim red line — the
   "monitor" itself — so the bright travelling sweep is always the obvious
   thing on it. */
.live-heartbeat .hb-base{ stroke:var(--bad); stroke-width:1.1; opacity:0.26; }
.live-heartbeat .hb-sweep{ stroke:var(--bad); stroke-width:1.6; filter:drop-shadow(0 0 4px var(--bad)); }
/* ONE bright red window travels the whole trace left -> right at a single
   constant HORIZONTAL velocity (it's a clip-rect translated in viewBox-x
   space, so it never slows or hesitates over the steep QRS spikes the way a
   stroke-dashoffset / arc-length sweep would). The trace shape is now two
   QRS complexes near the left, then a long calm flat run to the right edge:
   the sweep lights beat 1, a short flat, beat 2, then the long flat, exits
   completely to the right and is held there — fully off-screen — for a beat
   before the loop restarts it from fully off-screen left. Exactly one region
   is ever lit; there is no second window and no moment with two highlights.
   Single GPU-composited transform animation, no JS / rAF. */
.hb-clip-rect{ animation:heartbeatSweep 2.6s linear infinite; }
@keyframes heartbeatSweep{
  0%   { transform:translateX(0); }
  82%  { transform:translateX(122px); }
  100% { transform:translateX(122px); }
}
@keyframes livePulse{ 0%,100%{ opacity:1; } 50%{ opacity:0.4; } }

/* ==========================================================================
   KPI row — the number is the point
   ========================================================================== */
.kpi-grid{ display:grid; grid-template-columns:repeat(6, 1fr); gap:12px; margin-bottom:16px; }
.kpi-card{ padding:20px 20px 18px; display:flex; flex-direction:column; min-width:0; position:relative; overflow:hidden; }
/* --kpi-glow (set inline per card, see kpiGlowColor() in app.js) is each
   accent hue pre-adjusted to a constant perceived brightness — a raw hex
   here would make gold/cyan cards read visibly brighter than violet/blue
   ones at the same opacity. Full opacity now; the normalization already
   lives in the color's own alpha channel. */
.kpi-card::after{
  content:""; position:absolute; left:0; right:0; top:0; height:2px;
  background:var(--kpi-glow, var(--kpi-accent, var(--brand-gradient))); opacity:1;
}
.kpi-card{ transition:box-shadow .14s ease, border-color .14s ease, transform .14s cubic-bezier(.22,1,.36,1), background-color .3s ease, color .3s ease; }
.kpi-head{ display:flex; align-items:center; gap:8px; margin-bottom:14px; }
/* Icon + label bumped slightly (item 14) — dimensions/padding/margins around
   them are untouched, so the growth is contained and the KPI number below
   never visibly shifts. */
.kpi-icon{
  width:28px; height:28px; border-radius:7px; display:flex; align-items:center; justify-content:center; flex:0 0 auto;
  background:var(--surface-2);
  /* Dark: keep the neutral well but give it a crisp accent edge + a
     restrained accent glow BEHIND, so the well reads as the metric's colour
     while the icon (below) still out-reads it. */
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--kpi-accent-solid, var(--violet)) 24%, transparent),
             0 0 14px -5px color-mix(in srgb, var(--kpi-accent-solid, var(--violet)) 42%, transparent);
}
.kpi-icon svg{
  width:15px; height:15px; fill:none; stroke-width:2.15; stroke-linecap:round; stroke-linejoin:round;
  stroke:var(--kpi-accent-solid, var(--violet));
  /* the icon carries its own tight glow so it always sits ON TOP of the
     well's ambient one, never gets lost in it */
  filter:drop-shadow(0 0 4px color-mix(in srgb, var(--kpi-accent-solid, var(--violet)) 55%, transparent));
}
.kpi-label{ font-size:14.5px; font-weight:700; color:var(--text-primary); }
.kpi-value-row{ display:flex; align-items:baseline; gap:9px; margin-bottom:7px; }
.kpi-value{ font-size:var(--fs-kpi-number); font-weight:800; letter-spacing:-0.02em; line-height:1; transition:transform .22s cubic-bezier(.22,1,.36,1); transform-origin:left center; }
/* "N/total" style value (Smart Accessories' Active Accessories card) — the
   denominator reads as a lighter, smaller fraction, not a second number. */
.kpi-of{ font-size:0.55em; font-weight:700; color:var(--text-tertiary); margin-left:1px; }
.kpi-desc{ font-size:12.5px; color:var(--text-secondary); line-height:1.45; margin-bottom:10px; }
.kpi-change{ font-size:var(--fs-change); font-weight:700; display:flex; align-items:center; gap:3px; white-space:nowrap; }
.kpi-change.is-up{ color:var(--good); }
.kpi-change.is-down{ color:var(--bad); }
.kpi-change.is-flat{ color:var(--text-tertiary); }
.kpi-spark{ width:100%; height:36px; margin-top:12px; transition:filter .22s ease; }

/* ==========================================================================
   Panels — IQ hero + Journey
   ========================================================================== */
/* isolation:isolate == ROOT-CAUSE FIX for the "canvas flashes through a panel
   during scroll" bug. The IQ neural <canvas> is position:absolute z-index:2,
   but none of its ancestors (.iq-network / .iq-hero-body / .iq-hero) formed a
   stacking context — so its z-index:2 escaped into the ROOT context and
   z-ordered the (continuously repainting, GPU-layer-promoted) canvas ABOVE
   later static panels. During async/compositor scrolling that canvas layer
   desynced from the page for a frame and painted over the panels below it.
   isolation:isolate makes every .panel its own stacking context, so a
   positioned child's z-index can never leave the panel — zero rendering cost,
   zero visual change, no new compositor layer. */
.panel{ padding:24px; min-width:0; isolation:isolate; transition:box-shadow .14s ease, border-color .14s ease, transform .14s cubic-bezier(.22,1,.36,1), background-color .3s ease, color .3s ease; }
/* Trimmed vertical padding for the secondary/ops-row cards specifically —
   Top Actions, Smart Accessories, Traffic Sources, Live Activity,
   Engagement Overview — which had noticeably more empty space above/below
   their content than the content needed. KPI cards and Performance Journey
   are untouched (not this rule's selector list); height stays
   content-driven either way, nothing here fixes/clips a height. */
/* item 1, density audit — #saTopActions joins the list: it's the same
   Top-Actions-shaped panel as #topActionsPanel and had been left on the
   generic 24px .panel padding / 18px .panel-head margin ever since it was
   built, instead of the tightened treatment its Overview twin already
   has. Same fix for #saAccessories below, against its twin #accessoriesPanel. */
#topActionsPanel, #accessoriesPanel, #trafficPanel, #livePanel, #saTopActions{
  padding-top:19px; padding-bottom:19px;
}
/* Engagement Overview — the section heading ("Engagement Overview" / "Key
   engagement metrics") was removed in the refinement pass; the panel is now
   the instrument row alone. Trim the panel chrome so the four cards sit right
   under the panel edge with no reclaimed dead band where the heading was. */
#engagementPanel{ padding-top:15px; padding-bottom:15px; }
#topActionsPanel .panel-head, #accessoriesPanel .panel-head,
#trafficPanel .panel-head, #saTopActions .panel-head{
  margin-bottom:14px;
}
/* Ops row (Smart Accessories / Traffic Sources / Live Activity): the row
   heights are unchanged (still governed by align-items:stretch against the
   tallest of the three) — what moves is where that vertical space goes.
   Panel padding and header height are trimmed further (header collapses to
   ONE inline line, title + subtitle baseline-aligned, mirroring the
   Engagement Overview panel-head below — no subtitle text is removed, it
   just no longer reserves a whole second line) and the freed space is
   handed straight to the individual rows via more generous row padding, so
   the content breathes without the card itself growing. Later ID rule, so
   it wins over the shared padding above. */
/* #saShare/#saRecent (Smart Accessories) join this list — they're scoped
   copies of #trafficPanel/#livePanel and share the same density treatment
   rather than a duplicated ruleset. */
/* item 1, density audit — #saAccessories (item 14's literal duplicate of
   #accessoriesPanel) joins its twin's own tight-density selector list; it
   had been left on the generic .panel padding since it didn't exist yet
   when this list was written. Same rationale for #saShare/#saRecent
   already in this list against #trafficPanel/#livePanel. */
#accessoriesPanel, #trafficPanel, #livePanel, #saShare, #saRecent, #saAccessories{
  padding-top:11px; padding-bottom:11px;
  display:flex; flex-direction:column;
}
#accessoriesPanel .panel-head, #trafficPanel .panel-head, #saShare .panel-head, #saAccessories .panel-head{ margin-bottom:8px; }
#accessoriesPanel .panel-head > div, #trafficPanel .panel-head > div, #saShare .panel-head > div, #saAccessories .panel-head > div{
  display:flex; align-items:baseline; flex-wrap:wrap; gap:4px 10px;
}
/* white-space:nowrap keeps "- subtitle" as one atomic unit that either
   sits inline after the title (wide columns) or wraps ENTIRELY to its own
   line (narrow columns) — never splitting mid-phrase, which flex-wrap's
   default per-item wrapping would otherwise do (fit "-" alone at the end
   of the title's line, orphaning it from its own subtitle). */
#accessoriesPanel .panel-head p, #trafficPanel .panel-head p, #saShare .panel-head p, #saAccessories .panel-head p{ margin-top:0; font-size:var(--fs-meta); white-space:nowrap; }
.panel-head-hyphen{ color:var(--text-tertiary); font-size:13px; font-weight:600; }
/* flex:1 lets each list claim whatever height the stretch-equalized panel
   actually has beyond its own natural content, and justify-content:
   space-between spends that reclaimed space AS row gaps instead of it
   pooling as one dead strip below the last row — this is what lets Traffic
   Sources (6 rows) and Live Activity (5, fixed) each breathe using their
   OWN panel's real available room, not a single shared guess. */
#accessoriesList, #trafficList, #saShareList, #saAccessoriesList{ flex:1 1 auto; display:flex; flex-direction:column; justify-content:space-between; }
.ops-grid .rank-row, #saShareList .rank-row{ padding:9px 0; }
/* §1, Revision 3 — rankRow()'s shared .rank-label is a fixed 68px column
   (fine for Overview's short single-word sources; too narrow for an
   accessory nickname like "Austin Smart Bumper", which wrapped to 2-3
   lines). Scoped ONLY to Traffic Share: let the label grow into most of
   the row and shrink the bar's own growth share, so a full name fits on
   one line at normal widths — ellipsis only kicks in past that. Overview's
   own Traffic Sources rows are untouched (no selector outside #saShareList
   here). */
#saShareList .rank-label{
  width:auto; flex:1 1 130px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
#saShareList .rank-track{ flex:0.6 1 36px; }
.panel-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:10px; margin-bottom:18px; }
.panel-head h2{ font-size:var(--fs-section-title); font-weight:700; }
.panel-head p{ font-size:14px; color:var(--text-secondary); margin-top:3px; }
.panel-head .view-all{ font-size:13.5px; color:var(--text-secondary); font-weight:600; white-space:nowrap; }
.panel-head-controls{ display:flex; align-items:center; gap:10px; flex:0 0 auto; }

/* Top Actions (items 16-18) — no pagination anywhere; the list itself just
   scrolls, natively, on every breakpoint. #topActionsPanel is a flex column
   so #topActionsList can flex:1 within it; a max-height cap (set per
   breakpoint below) is what actually makes it scroll instead of just
   growing to fit every row. A hard cutoff at the panel edge would read as a
   bug, so a quiet fade-to-background hints there's more below — app.js's
   renderTopActionsList() only turns it on when the list truly overflows. */
#topActionsPanel{ display:flex; flex-direction:column; position:relative; }
#topActionsPanel.is-overflowing::after{
  content:""; position:absolute; left:24px; right:24px; bottom:14px; height:26px;
  background:linear-gradient(to bottom, transparent, var(--surface-1));
  pointer-events:none; border-radius:0 0 12px 12px;
}
#topActionsList{
  flex:1 1 auto; min-height:0; overflow-y:auto; overflow-x:hidden;
  -webkit-overflow-scrolling:touch;
}
/* Comfortable touch-scroll height — enough rows visible (~6) to make it
   obvious the list continues, without the card growing awkwardly tall. */
@media (max-width:1024px){
  #topActionsList{ max-height:380px; }
}
@media (min-width:1025px){
  #topActionsList{
    scrollbar-gutter:stable; scrollbar-width:thin; scrollbar-color:transparent transparent;
    /* Without a cap, align-items:stretch works backwards: a full action
       list (13 rows, ~798px unclamped) is naturally much taller than
       Performance Journey's own content (~420px) — so stretch grows
       JOURNEY up to match TOP ACTIONS instead of the intended other way
       around, leaving a large dead gap under the funnel and never
       triggering this list's own scroll. 332px is Journey's measured
       natural height (420px) minus this panel's head+padding, so both
       cards settle back to Journey's compact height and the list actually
       scrolls past that point instead of ballooning the row.
       Bumped +66px alongside the taller desktop .funnel box (280px, was
       214px — see the Performance Journey block below) so the two
       stretch-equalized cards still settle to the SAME height and no dead
       gap opens under the Top Actions list.
       Trimmed down again as the Journey footer was tightened further
       (phantom label line removed), so the two cards' bottoms still meet. */
    max-height:356px;
  }
  #topActionsList:hover, #topActionsList:focus-within{ scrollbar-color:rgba(255,255,255,0.18) transparent; }
  #topActionsList::-webkit-scrollbar{ width:6px; }
  #topActionsList::-webkit-scrollbar-track{ background:transparent; }
  #topActionsList::-webkit-scrollbar-thumb{ background:transparent; border-radius:99px; }
  #topActionsList:hover::-webkit-scrollbar-thumb, #topActionsList:focus-within::-webkit-scrollbar-thumb{ background:rgba(255,255,255,0.18); }
}

/* Ordinary panel hover — pointer/desktop devices ONLY (the guard is what
   keeps this from ever triggering, and then getting stuck showing, on a
   touchscreen tap). No movement anymore (see item 13) — a restrained white
   border/ambient glow only, so dashboard panels don't all physically
   travel toward the pointer on every pass. The six primary KPI cards keep
   their own stronger lift below (a deliberate exception, not this rule).
   prefers-reduced-motion is already handled globally (see the universal
   transition-duration override near the top of this file). */
@media (hover:hover) and (pointer:fine){
  .panel:hover{
    border-color:var(--line-strong);
    box-shadow:0 0 0 1px rgba(255,255,255,0.11), 0 0 26px -10px rgba(255,255,255,0.28);
  }
  .kpi-card:hover{
    transform:translateY(-6px) scale(1.015);
    border-color:var(--line-strong);
    box-shadow:0 0 0 1px rgba(255,255,255,0.05), 0 26px 46px -16px var(--kpi-glow, var(--brand-glow));
  }
  .kpi-card:hover .kpi-value{ transform:scale(1.03); }
  .kpi-card:hover .kpi-spark{ opacity:1; filter:saturate(1.15); }

  /* Item 19 — same hover philosophy as the KPI cards (lift + colored glow),
     adapted to each IQ card's own quadrant accent. animation-play-state
     pauses iqCardBreathe on hover so its continuous border-color/box-shadow
     keyframe stops fighting these hover values — a transition can't win
     against a running animation on the same property, so without the
     pause the hover state would flicker against the breathe cycle instead
     of holding steady. */
  .iq-card:hover{
    animation-play-state:paused;
    transform:translateY(-11px) scale(1.05);
    border-color:rgba(var(--card-accent-rgb, 139,108,247), 1);
    box-shadow:
      0 36px 64px -18px rgba(0,0,0,0.72),
      0 0 0 1px rgba(0,0,0,0.3),
      0 0 44px -2px rgba(var(--card-accent-rgb, 139,108,247), 0.85),
      0 0 90px -6px rgba(var(--card-accent-rgb, 139,108,247), 0.5);
    z-index:5;
  }
  /* .iq-slot has pointer-events:none, so :hover never fires on it directly —
     :has() is what lets the hovered card's slot rise above its siblings so
     the 3D lift reads cleanly with no sibling clipping the raised corner. */
  .iq-slot:has(.iq-card:hover){ z-index:6; }
}

/* Height grown a little (was 196px) specifically to give the mist layer
   (see startFunnelLoop in app.js) real vertical room to fully fade to
   transparent above/below the badge line before it would otherwise hit
   the canvas's own edge — see the item-14 mist-clipping fix. Paired with
   the desktop padding trim above, the panel's total height is essentially
   unchanged; the freed space just moved from unused padding to where the
   visualization actually needed it. */
.funnel{ position:relative; height:214px; }
.funnel-canvas{ position:absolute; inset:0; width:100%; height:100%; }
.funnel-nodes{ position:absolute; inset:0; display:flex; align-items:flex-start; justify-content:space-between; }
.funnel-node{ display:flex; flex-direction:column; align-items:center; gap:9px; width:19%; cursor:default; position:relative; }
/* Stage labels: clean white for Users / Page Views / Contacts Saved /
   Leads; Booking Clicks (the destination) is bold and gold — its own
   --ring-color, the same gold the badge / value / % already use — to
   reinforce it as the final goal without changing its size. */
.funnel-node-label{ font-size:12.5px; color:var(--text-primary); font-weight:600; }
.funnel-node.is-destination .funnel-node-label{ color:var(--ring-color); font-weight:800; }
/* Item 2 — the stage numbers carry an extremely subtle "alive" breath:
   a small brightness shift + a sub-1% scale on a slow cycle. Meant to be
   felt, not watched — no visible pulse or jump. Booking's number gets a
   marginally warmer gold breath (own keyframe) since it's the destination.
   prefers-reduced-motion is handled globally (animation-duration ~0). */
.funnel-node-value{
  font-size:20px; font-weight:800; transform-origin:center;
  animation:journeyValueBreathe 7s ease-in-out infinite;
}
.funnel-node:nth-child(2) .funnel-node-value{ animation-delay:-1.4s; }
.funnel-node:nth-child(3) .funnel-node-value{ animation-delay:-2.8s; }
.funnel-node:nth-child(4) .funnel-node-value{ animation-delay:-4.2s; }
.funnel-node:nth-child(5) .funnel-node-value{ animation-delay:-5.6s; }
.funnel-node.is-destination .funnel-node-value{ animation-name:journeyValueBreatheGold; }
@keyframes journeyValueBreathe{
  0%,100%{ filter:brightness(0.93); transform:scale(0.996); }
  50%{ filter:brightness(1.06); transform:scale(1.005); }
}
@keyframes journeyValueBreatheGold{
  0%,100%{ filter:brightness(0.94); transform:scale(0.996); text-shadow:0 0 6px rgba(255,194,51,0.22); }
  50%{ filter:brightness(1.11); transform:scale(1.006); text-shadow:0 0 13px rgba(255,194,51,0.46); }
}
@media (prefers-reduced-motion: reduce){
  .funnel-node-value{ animation:none; filter:none; transform:none; }
  .funnel-node.is-destination .funnel-node-value{ text-shadow:0 0 10px rgba(255,194,51,0.35); }
}

/* ---------------------------------------------------------------------------
   Journey badge — a luminous energy node, not a plain bordered circle.
   Layers (inside -> out): opaque dark body (so the particle stream behind it
   genuinely cannot show through) -> crisp coloured primary ring (the border)
   -> thin concentric inner ring (::after) -> faint outer energy ring
   (::before) -> a tight restrained aura + inner rim-light (box-shadow) ->
   colour-matched perimeter sparks (drawn on the canvas, orbiting just
   outside the ring). Strong at the badge, gone within ~14px. No big blur
   kernels; the icon stays razor sharp.
   --------------------------------------------------------------------------- */
.funnel-node-ring{
  width:68px; height:68px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  border:2px solid var(--ring-color, var(--violet)); position:relative; isolation:isolate;
  /* Item 4 — a premium luminous object again: a cool top glass highlight
     over a dimensional dark body (lighter than the near-flat #141a2e it had
     drifted to), so the interior reads as lit glass/metal, not a dark hole.
     Two stacked radial gradients — highlight on top, body underneath — both
     fully opaque where it matters, so the particle stream still can't show
     through. */
  background:
    radial-gradient(circle at 50% 22%, rgba(216,228,255,0.20) 0%, rgba(216,228,255,0.06) 32%, rgba(216,228,255,0) 58%),
    radial-gradient(circle at 50% 34%, #242d49 0%, #151b31 48%, #090c17 100%);
  /* Part 2 — two clearly separated local energy levels so each node reads
     as its OWN colored source without becoming an isolated circle:
       1. INNER HALO  — a crisp colored collar + a tight, near-full-strength
          glow right at the rim: this is what nails the stage's identity.
       2. OUTER AURA  — a wide, low-opacity wash of the same hue that
          dissolves outward into the broader Journey atmosphere.
     Interior glass highlight + rim-lights are unchanged (icons stay crisp). */
  box-shadow:
    0 0 0 3px color-mix(in srgb, var(--ring-color) 24%, transparent),        /* inner: crisp collar */
    0 0 11px -1px var(--ring-color, var(--brand-glow)),                       /* inner: tight bright halo */
    0 0 24px -4px color-mix(in srgb, var(--ring-color) 80%, transparent),     /* inner-mid */
    0 0 56px -10px color-mix(in srgb, var(--ring-color) 40%, transparent),    /* outer aura */
    0 0 100px -28px color-mix(in srgb, var(--ring-color) 24%, transparent),   /* outer: dissolve */
    inset 0 1.5px 1.5px rgba(255,255,255,0.14),
    inset 0 0 10px -6px color-mix(in srgb, var(--ring-color) 38%, transparent);
  transition:transform .25s ease;
  animation:nodeBreathe 4.4s ease-in-out infinite;
}
/* outer energy ring — part of the inner-halo tier: a defined colored edge
   just outside the badge */
.funnel-node-ring::before{
  content:""; position:absolute; inset:-9px; border-radius:50%; pointer-events:none;
  border:1px solid color-mix(in srgb, var(--ring-color) 50%, transparent);
  box-shadow:0 0 0 4px color-mix(in srgb, var(--ring-color) 9%, transparent), 0 0 10px -1px color-mix(in srgb, var(--ring-color) 30%, transparent);
}
/* thin concentric inner ring */
.funnel-node-ring::after{
  content:""; position:absolute; inset:5px; border-radius:50%; pointer-events:none;
  border:1px solid color-mix(in srgb, var(--ring-color) 48%, transparent);
}
.funnel-node:nth-child(1) .funnel-node-ring{ animation-delay:0s; }
.funnel-node:nth-child(2) .funnel-node-ring{ animation-delay:.4s; }
.funnel-node:nth-child(3) .funnel-node-ring{ animation-delay:.8s; }
.funnel-node:nth-child(4) .funnel-node-ring{ animation-delay:1.2s; }
.funnel-node:nth-child(5) .funnel-node-ring{ animation-delay:1.6s; }
@keyframes nodeBreathe{
  0%,100%{
    box-shadow:
      0 0 0 3px color-mix(in srgb, var(--ring-color) 22%, transparent),
      0 0 11px -1px var(--ring-color, var(--brand-glow)),
      0 0 24px -4px color-mix(in srgb, var(--ring-color) 78%, transparent),
      0 0 54px -10px color-mix(in srgb, var(--ring-color) 38%, transparent),
      0 0 100px -28px color-mix(in srgb, var(--ring-color) 22%, transparent),
      inset 0 1.5px 1.5px rgba(255,255,255,0.13),
      inset 0 0 10px -6px color-mix(in srgb, var(--ring-color) 36%, transparent);
    transform:scale(1);
  }
  50%{
    box-shadow:
      0 0 0 4px color-mix(in srgb, var(--ring-color) 30%, transparent),
      0 0 17px 0 var(--ring-color, var(--brand-glow)),
      0 0 32px -2px color-mix(in srgb, var(--ring-color) 88%, transparent),
      0 0 72px -6px color-mix(in srgb, var(--ring-color) 48%, transparent),
      0 0 118px -22px color-mix(in srgb, var(--ring-color) 30%, transparent),
      inset 0 1.5px 1.5px rgba(255,255,255,0.16),
      inset 0 0 12px -5px color-mix(in srgb, var(--ring-color) 44%, transparent);
    transform:scale(1.028);
  }
}
.funnel-node:hover .funnel-node-ring{ transform:scale(1.1); }
.funnel-node-ring svg{
  width:24px; height:24px; fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round;
  /* Item 4 — brighter, cleaner icon: a near-white stroke with just a hint
     of the ring hue, a stronger colored glow, and a tiny dark offset so the
     edges stay crisp against the lit interior. */
  stroke:color-mix(in srgb, var(--ring-color, #fff) 20%, #ffffff);
  filter:drop-shadow(0 0 5px color-mix(in srgb, var(--ring-color) 55%, transparent)) drop-shadow(0 1px 1px rgba(0,0,0,0.45));
}

/* Destination (Booking Clicks) — the successful endpoint. A fuller, brighter
   GOLD aura and rings (its own breathe keyframe so it can carry more shadow
   layers than the shared one), plus gold value/secondary text — the
   culmination, without a strobing pulse ring. */
.funnel-node.is-destination .funnel-node-ring{
  border-width:2.5px;
  /* Warmer glass highlight + faintly warm dark body for the gold destination. */
  background:
    radial-gradient(circle at 50% 22%, rgba(255,238,205,0.22) 0%, rgba(255,238,205,0.07) 32%, rgba(255,238,205,0) 58%),
    radial-gradient(circle at 50% 34%, #2c2740 0%, #1a1526 48%, #0c0910 100%);
  animation:nodeBreatheGold 4.4s ease-in-out infinite;
}
.funnel-node.is-destination .funnel-node-ring::before{ inset:-14px; border-color:color-mix(in srgb, var(--ring-color) 55%, transparent); box-shadow:0 0 0 5px color-mix(in srgb, var(--ring-color) 10%, transparent); }
.funnel-node.is-destination .funnel-node-ring::after{ border-color:color-mix(in srgb, var(--ring-color) 70%, transparent); }
.funnel-node.is-destination .funnel-node-value{ color:var(--ring-color); }
.funnel-node.is-destination .funnel-node-pct{ color:var(--ring-color) !important; opacity:0.95; }
/* Item 18 — strengthened outer aura/ring luminosity for the destination
   endpoint: a wider spread on the existing layers plus one additional soft
   outer-aura layer (the "0 0 90px" term below) that the other four badges
   don't have, so Booking Clicks reads as a visibly bigger energy event
   without changing its ring size, icon, or text. */
/* Booking Clicks — the destination: the same two-level halo as the others
   but richer at every level — strongest inner energy, a fuller gold collar,
   a visibly larger outer aura, slightly higher luminance — while staying
   elegant (soft, no strobe). */
@keyframes nodeBreatheGold{
  0%,100%{
    box-shadow:
      0 0 0 4px color-mix(in srgb, var(--ring-color) 32%, transparent),
      0 0 15px 0 var(--ring-color),
      0 0 32px -3px var(--ring-color),
      0 0 74px -8px color-mix(in srgb, var(--ring-color) 60%, transparent),
      0 0 128px -22px color-mix(in srgb, var(--ring-color) 34%, transparent),
      inset 0 1.5px 2px rgba(255,241,214,0.2),
      inset 0 0 14px -6px color-mix(in srgb, var(--ring-color) 42%, transparent);
    transform:scale(1);
  }
  50%{
    box-shadow:
      0 0 0 6px color-mix(in srgb, var(--ring-color) 40%, transparent),
      0 0 24px 2px var(--ring-color),
      0 0 46px 0 var(--ring-color),
      0 0 96px -4px color-mix(in srgb, var(--ring-color) 70%, transparent),
      0 0 156px -14px color-mix(in srgb, var(--ring-color) 42%, transparent),
      inset 0 1.5px 2px rgba(255,241,214,0.24),
      inset 0 0 16px -5px color-mix(in srgb, var(--ring-color) 52%, transparent);
    transform:scale(1.036);
  }
}
.funnel-node-pct{ font-size:12px; color:var(--text-secondary); font-weight:600; }
/* Item 22 — the tooltip now explains what the stage MEANS (a title +
   one-sentence description) instead of repeating the badge's own visible
   number/%. A fixed width (was min-width:180px) fits that sentence
   without the box's size varying stage-to-stage. */
.funnel-tooltip{
  position:absolute; bottom:calc(100% + 10px); left:50%; transform:translateX(-50%) translateY(4px);
  background:var(--ink-850); border:1px solid var(--line-strong); border-radius:12px; padding:12px 14px;
  width:200px; text-align:left; opacity:0; pointer-events:none; transition:opacity .16s ease, transform .16s ease; z-index:5;
  box-shadow:0 14px 40px rgba(0,0,0,0.5);
}
.funnel-node:hover .funnel-tooltip{ opacity:1; transform:translateX(-50%) translateY(0); }
.funnel-tooltip .tt-title{ font-size:13px; font-weight:800; letter-spacing:-0.005em; }
.funnel-tooltip .tt-desc{ font-size:12.5px; color:var(--text-secondary); line-height:1.45; margin-top:4px; }
/* The first and last badges sit close enough to the panel's own left/right
   edge that CENTERING their tooltip (like every middle stage) can push it
   past the viewport on narrower panels — real overflow even though the
   tooltip is invisible by default (opacity:0 still affects layout/
   scrollWidth; a previous version of this bug cost 31px of mobile
   overflow). Anchoring each end tooltip to its own inner edge instead —
   left opens rightward, right opens leftward — keeps both fully on-screen
   at every panel width without touching any middle stage's tooltip. */
.funnel-node:first-child .funnel-tooltip{ left:0; transform:translateY(4px); }
.funnel-node:first-child:hover .funnel-tooltip{ transform:translateY(0); }
.funnel-node:last-child .funnel-tooltip{ left:auto; right:0; transform:translateY(4px); }
.funnel-node:last-child:hover .funnel-tooltip{ transform:translateY(0); }

/* The old "Overall Conversion Rate" hero block has moved to Engagement
   Overview (as a gauge) — the footer now holds ONLY the three centered
   supporting stats below, using the space that freed up. */
/* Footer tightened — the gap between the funnel and these metrics, and the
   card's own bottom padding, were carrying dead space. Metrics pushed up
   toward the visualization; the approved badges above are untouched. */
.conversion-strip{
  margin-top:6px; padding-top:9px; border-top:1px solid var(--line);
  display:flex; align-items:center; justify-content:center;
}
/* Three metrics, evenly spaced and centered across the full footer width —
   Page Views Per User, Lead Conversion, Booking Conversion. Larger than the
   old dimmed "secondary" treatment since this is now the sole footer
   content, not a supporting sidenote to a bigger hero number. */
.conversion-secondary{ display:flex; align-items:flex-start; justify-content:center; gap:56px; width:100%; max-width:520px; }
/* min-width:0 (overriding flex's default min-width:auto) is what lets these
   actually shrink instead of a nowrap label overflowing its own column and
   visually running into the next one at narrow widths — the label wraps to
   a second line instead. */
.conv-metric{ text-align:center; min-width:0; flex:1 1 0; }
/* All three labels are now short enough ("Page Views / User", "Lead
   Conversion", "Appt. Conversion") to sit on ONE line at every desktop
   column width, so the old 2-line min-height reservation was pure phantom
   space that pushed the whole group low in the footer. A tight single-line
   min-height keeps the three values on the same baseline without the dead
   space — which is what lets the group read as centred. */
.conv-metric-label{
  font-size:11px; font-weight:700; letter-spacing:0.05em; text-transform:uppercase; color:var(--text-tertiary);
  line-height:1.22; min-height:1.5em; white-space:nowrap; display:flex; align-items:flex-end; justify-content:center;
}
.conv-metric-value{ font-size:27px; font-weight:800; letter-spacing:-0.015em; margin-top:3px; }
@media (max-width:600px){
  .conversion-secondary{ gap:12px; max-width:none; }
  .conv-metric-value{ font-size:22px; }
}

/* ==========================================================================
   1EIGHTY IQ — the neural artwork IS the section, not a picture inside it.
   A full-bleed image layer (object-fit:cover, radial mask) fills the entire
   hero body with no hard rectangular edge anywhere — the mask fades the
   image itself to fully transparent well before it reaches the container
   boundary, so the panel's own background shows through at the edges and
   there is nothing left to read as "an image sitting in a box". Insight
   cards float directly over the four corners where the artwork's own major
   hub nodes already sit, so a card reads as having grown out of that node
   rather than being placed near a random line.
   ========================================================================== */
.iq-hero{ margin-bottom:12px; padding-top:8px; padding-bottom:14px; }
/* Header sits just above the top-row cards (not the panel's raw top edge)
   with a small deliberate gap — header -> small gap -> top-left card,
   rather than floating independently with a void beneath it. Scoped to
   THIS panel only; every other panel keeps the generic spacing. */
.iq-hero .panel-head{ padding-top:0; margin-bottom:13px; }
/* Shorter box (was 320px/2.1:1) so the section's top edge sits close to
   the topmost pulse/network glow instead of framing a band of empty
   canvas above it — the network/brain/hub/card layout is all computed as
   fractions of this box (see IQ_HUBS in app.js), so nothing crops, it just
   fills a more compact frame. */
.iq-hero-body{ position:relative; aspect-ratio:2.35/1; min-height:270px; }
/* The network itself is drawn live on canvas — there is no raster "network"
   image anymore, so there is nothing left with a rectangular edge to read as
   a photo sitting in a box. Only the brain is a raster asset, and it is
   masked into a soft circle with its own glow, floating in the same space
   as the procedural nodes rather than framing them. .iq-network is a
   dedicated wrapper (not the same element as iq-hero-body) specifically so
   the responsive breakpoint can retarget IT alone — filling the whole hero
   on desktop, becoming a shorter self-contained banner on mobile — without
   touching how the insight slots lay out around it. */
/* Deliberately no background/border/overflow-clip of its own — the network
   sits directly on the panel's own surface, exactly like the KPI sparkline
   or any other in-panel content, rather than inside a second nested "box". */
.iq-network{ position:absolute; inset:0; }
/* Collapsing the sidebar hands the whole dashboard extra width, which was
   making the brain/network cluster read as slightly too dominant — a small,
   uniform shrink of the network's OWN box (not the hero panel, not the
   cards, which stay exactly where they are) restores that negative space.
   A real width/height resize (not a CSS transform) so the canvas's own
   resize()/ResizeObserver — and therefore every hub/particle/connector
   position computed from it — stays perfectly self-consistent; see
   app.js's setupIQNeuralCore for why a transform would have desynced the
   card-connector targeting instead. #app's class is toggled alongside the
   sidebar's own collapsed class (see applySidebarCollapsed in app.js). */
@media (min-width:1025px){
  .app.sidebar-collapsed .iq-network{ width:89%; height:89%; margin:auto; }
}
.iq-neural-canvas{ position:absolute; inset:0; width:100%; height:100%; display:block; pointer-events:none; z-index:2; }
.iq-brain-core{
  position:absolute; left:50%; top:50%; width:30%; aspect-ratio:1; transform:translate(-50%,-50%);
  z-index:1; pointer-events:none; border-radius:50%;
}
.iq-brain-core::before{
  content:""; position:absolute; inset:-35%; border-radius:50%; z-index:0;
  background:radial-gradient(circle, rgba(139,178,255,0.20), rgba(139,178,255,0.05) 55%, transparent 75%);
}
.iq-brain-core img{
  position:relative; width:100%; height:100%; display:block; object-fit:cover; border-radius:50%;
  -webkit-mask-image:radial-gradient(circle, #000 62%, transparent 92%);
  mask-image:radial-gradient(circle, #000 62%, transparent 92%);
  /* Continuous sine-wave breathing — out, in, out, in, with NO plateau at
     either extreme (a previous version held near each extreme for a beat,
     which read as a heartbeat/double-pulse rather than lungs). Exactly two
     distinct keyframe values (trough at 0%/100%, peak at 50%), so
     ease-in-out's own curve is the entire motion — nothing to pause on.
     Scale stays extremely restrained (0.985-1.015) so this is felt more
     than seen. Free to run: a plain CSS transform/filter animation on a
     single raster <img>, composited on the GPU, no canvas repaint or rAF
     cost at all — and already covered by the site-wide
     prefers-reduced-motion rule at the top of this file. */
  animation:iqBrainBreathe 6s ease-in-out infinite;
  transform-origin:center;
}
@keyframes iqBrainBreathe{
  0%, 100%{ transform:scale(0.985); filter:brightness(0.975) saturate(0.97); }
  50%{ transform:scale(1.015); filter:brightness(1.04) saturate(1.04); }
}

.iq-slot{ position:absolute; z-index:3; width:27%; max-width:290px; min-width:0; pointer-events:none; }
.iq-slot > *{ pointer-events:auto; }
/* Top-row cards (TL "Building Baseline" / TR) sit further down than the
   bottom row — the TL/TR hubs (IQ_HUBS y:0.24 in app.js) and their
   ring->hub plasma stream live in the upper-middle of the box, and a card
   starting at the very top edge sat on top of that stream/terminal glow.
   Pushed down enough to clear it and give the stream room to breathe. */
.iq-slot-tl{ left:3%; top:16%; }
.iq-slot-tr{ right:3%; top:16%; }
.iq-slot-bl{ left:3%; bottom:2%; }
.iq-slot-br{ right:3%; bottom:2%; }
.iq-slot-empty{
  position:absolute; z-index:3; left:50%; bottom:5%; transform:translateX(-50%);
  width:min(340px, 84%); pointer-events:auto;
}

/* ---------------------------------------------------------------------------
   1EIGHTY IQ — desktop vertical composition.

   The network canvas carries a tall band of near-empty space above the
   aura/ring (only the ~5%-alpha haze reaches the very top). Rather than let
   the header float high above that void with the panel framing dead canvas,
   the header is taken OUT of flow (position:absolute + z-index so it stays
   above the canvas/slots) and dropped DOWN into that band as one tight line
   — title + a quiet inline subtitle instead of a stacked two-line heading,
   which is what buys the room to sit it low without the second line reaching
   the aura ring on the shorter panels. Panel padding-top is trimmed and the
   header no longer reserves flow space, so the SECTION gets shorter, not
   taller. Nothing in the visualization is moved, shrunk, or cropped — the
   body box is unchanged, only the panel chrome around it tightens. The
   ≥1400px query further drops the header and lowers the upper cards clear of
   the TL/TR hub + plasma-terminal zone (IQ_HUBS y:0.24), where the panel is
   tall enough and the slots wide enough (one-line titles) to absorb it.
   ≤768px keeps the existing stacked in-flow heading + recomposition.
   --------------------------------------------------------------------------- */
@media (min-width:769px){
  .iq-hero{ position:relative; padding-top:4px; padding-bottom:10px; }
  /* Heading lifted OUT of flow and CENTERED horizontally across the top of
     the panel, sitting in the network canvas's near-empty top band (only the
     ~5%-alpha haze reaches up here). Kept as two centered lines — title, then
     the subtitle directly beneath it — and near its previous vertical
     position. The visualization is not moved, shrunk, or cropped; the header
     just no longer reserves flow space, so the section stays tight.
     ≤768px keeps the original stacked, left-aligned in-flow heading. */
  .iq-hero .panel-head{
    display:block; position:absolute; left:24px; right:24px; top:14px;
    z-index:5; margin:0; padding:0; text-align:center;
  }
  .iq-hero .panel-head > div{ display:block; min-width:0; }
  .iq-hero .panel-head h2{ line-height:1.15; }
  /* Held to 11.5px so the centred subtitle keeps clear horizontal air from
     the upper cards' inner edges even on the narrower 1024/1280 panels. */
  .iq-hero .panel-head p{ margin-top:2px; font-size:11.5px; letter-spacing:-0.002em; }

  /* Upper cards pulled UP so the pink / cyan plasma paths from the brain
     (their hubs sit at IQ_HUBS y:0.24) visually terminate into roughly the
     LOWER HALF of each card, rather than arriving above a card that floats
     too low. Bottom cards (iq-slot-bl / iq-slot-br) are deliberately NOT
     touched. Moving the top row UP only widens the gap to the bottom row,
     so there is no collision risk with it; the centered heading clears the
     cards horizontally (heading is centre-panel, cards hug the 3% edges). */
  .iq-slot-tl, .iq-slot-tr{ top:4%; }
}
/* Wide desktop: the panel is taller and the slots wide enough that the card
   titles stay on one line (shorter, so a smaller fraction of the body) —
   the upper cards can sit a little lower here and their hub still lands in
   the card's lower half. */
@media (min-width:1400px){
  .iq-hero .panel-head{ top:20px; }
  .iq-slot-tl, .iq-slot-tr{ top:6%; }
}

.iq-card{
  /* Fully opaque + NO backdrop-filter. The blur was sampling an already-dark
     animating canvas behind a 93%-opaque overlay — visually near-invisible,
     but a backdrop-filter over a continuously-repainting backdrop is exactly
     the WebKit/Chromium compositor pattern that flashes (shows the raw
     backdrop) mid-scroll. Solid #06070d reads identically and can never
     flash. (Part of the item-4 transparency-flash fix, not a style change.) */
  padding:13px 15px; border-radius:13px; background:var(--viz-surface); position:relative;
  /* Item 20 — every card (real insight or starter tip) now carries the
     same quadrant-colored ambient glow via iqCardBreathe, not just starter
     tips; iqCardHtml() sets --card-accent-rgb inline for real cards too
     (previously only iqStarterCardHtml did). Glow strengthened + the cycle
     moderately quickened this pass (was 0.4/0.22 borders on a 5.2s loop):
     brighter border, a second wide diffuse back-glow layer behind the
     card, ~3.9s inhale/exhale — still a smooth breath, never a strobe. */
  border:1px solid rgba(var(--card-accent-rgb, 139,108,247), 0.5);
  box-shadow:0 14px 34px -14px rgba(0,0,0,0.7), 0 0 0 1px rgba(0,0,0,0.3), 0 0 13px rgba(var(--card-accent-rgb, 139,108,247), 0.32), 0 0 34px -6px rgba(var(--card-accent-rgb, 139,108,247), 0.22);
  /* SETTLED state is the element's own base (opacity:1, no transform), and
     iqCardGrow now uses `backwards` (not `forwards`) fill. This is the fix
     for real-insight cards (e.g. BUILDING BASELINE) not lifting/scaling on
     hover: with `forwards`, iqCardGrow's final keyframe kept `transform`
     pinned at translateY(0) scale(1) FOREVER after the 0.5s mount — and a
     CSS animation's fill value wins over a plain :hover/:active `transform`
     declaration in the cascade, so the hover lift was silently overridden.
     Starter cards escaped it only because .iq-card--starter redeclares the
     `animation` shorthand without iqCardGrow at all. `backwards` fill shows
     the `from` state for the mount-in but releases `transform` back to the
     base the instant the animation ends — identical values, no flash — so
     :hover / :active can own it. Real and starter cards now share one
     interaction system; every future real insight inherits it. */
  opacity:1;
  animation:iqCardGrow .5s cubic-bezier(.22,1,.36,1) backwards, iqCardBreathe 3.9s ease-in-out infinite;
  transition:transform .2s cubic-bezier(.22,1,.36,1), border-color .2s cubic-bezier(.22,1,.36,1), box-shadow .2s cubic-bezier(.22,1,.36,1);
}
@keyframes iqCardGrow{
  from{ opacity:0; transform:translateY(6px) scale(0.97); }
  to{ opacity:1; transform:translateY(0) scale(1); }
}
.iq-card-head{ display:flex; align-items:center; gap:10px; margin-bottom:7px; }
.iq-card-icon{
  width:28px; height:28px; border-radius:50%; flex:0 0 auto; display:flex; align-items:center; justify-content:center;
  background:var(--card-accent, var(--violet)); box-shadow:0 0 12px -2px var(--card-accent, var(--violet));
}
.iq-card-icon svg{ width:14px; height:14px; stroke:#0A0A16; fill:none; stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; }
.iq-card-title{ font-size:var(--fs-iq-headline); font-weight:700; letter-spacing:-0.005em; }
.iq-card p{ font-size:var(--fs-iq-body); color:var(--text-secondary); line-height:1.5; }
.iq-card .iq-rec{ color:var(--card-accent, var(--violet)); font-weight:600; margin-top:5px; }

/* Starter tips — same card system (dimensions, grid position, mount
   animation) as a real insight, and now the SAME visual authority too:
   solid quadrant-colored icon, full-brightness title, full-color action
   line — baseline mode should read as intentionally populated, not "1 real
   card + 3 placeholders". The only remaining tell is the small "Tip" pill;
   everything else matches a real card's font weight/color/glow class. A
   real insight, when one exists, still gets the stronger network
   activity/priority (see app.js's connector + card-glow logic) — that
   hierarchy lives in the network/motion layer now, not in flat, static,
   dimmed card chrome. --card-accent-rgb is set inline alongside
   --card-accent (see iqStarterCardHtml) purely so this border can carry a
   real per-quadrant tint instead of a flat neutral line. */
/* Continuous, per-quadrant-colored breathing glow — replaces a previous
   JS-driven per-frame flash-and-decay (bright ramp on signal arrival, then
   exponential fade back to a dim resting border) that read as strobing
   rather than ambient light. This is pure CSS: a slow ease-in-out loop
   between two fixed states, so the glow is always present (never fully
   off) and never snaps. Cheap — box-shadow interpolation on up to 4 small,
   fixed-size DOM elements, no canvas/shadowBlur cost, one shared keyframe.
   Covered by the site-wide prefers-reduced-motion rule at the top of this
   file. Slightly out of phase per quadrant (odd/even offset) so all 4
   starter cards don't visibly pulse in lockstep. */
.iq-card--starter{
  background:rgba(6,7,13,0.9);
  /* .iq-card's base animation includes the one-time iqCardGrow mount-in —
     starter tips skip that and are simply visible/settled immediately
     (opacity:1; transform:none), keeping only the second, continuous
     iqCardBreathe animation running. */
  opacity:1; transform:none;
  animation:iqCardBreathe 3.9s ease-in-out infinite;
}
/* Anti-lockstep breathing offset, both card types. Real cards run TWO
   animations (iqCardGrow, iqCardBreathe — see .iq-card) so their
   animation-delay needs a matching 2-value list (0s for the one-time grow,
   -1.95s — half the 3.9s cycle — for the offset breathe); starter cards run
   breathe alone, so a single value. Same selector split is required — a
   2-value delay on a single-animation element just drops the second value,
   silently undoing the offset. */
.iq-slot-tr .iq-card--starter, .iq-slot-bl .iq-card--starter{ animation-delay:-1.95s; }
.iq-slot-tr .iq-card:not(.iq-card--starter), .iq-slot-bl .iq-card:not(.iq-card--starter){ animation-delay:0s, -1.95s; }
@keyframes iqCardBreathe{
  0%, 100%{
    border-color:rgba(var(--card-accent-rgb, 139,108,247), 0.5);
    box-shadow:0 14px 34px -14px rgba(0,0,0,0.7), 0 0 0 1px rgba(0,0,0,0.3), 0 0 13px rgba(var(--card-accent-rgb, 139,108,247), 0.32), 0 0 34px -6px rgba(var(--card-accent-rgb, 139,108,247), 0.22);
  }
  50%{
    border-color:rgba(var(--card-accent-rgb, 139,108,247), 0.9);
    box-shadow:0 14px 34px -14px rgba(0,0,0,0.7), 0 0 0 1px rgba(0,0,0,0.3), 0 0 24px rgba(var(--card-accent-rgb, 139,108,247), 0.6), 0 0 60px -4px rgba(var(--card-accent-rgb, 139,108,247), 0.42);
  }
}
/* Task 2 — press/touch equivalent of the desktop 3D hover (which is gated
   to real pointers below). A momentary lift + intensified colored glow
   while the card is held, released smoothly by .iq-card's own transition.
   Deliberately :active only — never a persisted/toggled selected state.
   :has() raises the whole slot so the pressed card renders above its
   neighbours during the lift. */
.iq-card:active{
  animation-play-state:paused;
  transform:translateY(-6px) scale(1.035);
  border-color:rgba(var(--card-accent-rgb, 139,108,247), 0.95);
  box-shadow:
    0 26px 48px -16px rgba(0,0,0,0.7),
    0 0 0 1px rgba(0,0,0,0.3),
    0 0 34px -2px rgba(var(--card-accent-rgb, 139,108,247), 0.7),
    0 0 66px -6px rgba(var(--card-accent-rgb, 139,108,247), 0.42);
  z-index:5;
}
.iq-slot:has(.iq-card:active){ z-index:6; }
@media (prefers-reduced-motion: reduce){
  .iq-card:hover, .iq-card:active{ transform:none; }
}
.iq-card-tag{
  display:inline-block; font-size:9.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase;
  color:var(--text-tertiary); background:var(--surface-2); border:1px solid var(--line);
  border-radius:99px; padding:2px 7px; margin-left:8px; vertical-align:middle;
}

.iq-empty{
  position:relative; z-index:1; font-size:13.5px; color:var(--text-secondary); line-height:1.6;
  padding:14px 18px; border-radius:13px; background:var(--viz-surface);
  border:1px solid var(--line-strong); text-align:center;
}

/* ==========================================================================
   Performance Journey + Top Actions row — ~65% / ~35%
   ========================================================================== */
.journey-row{ display:flex; gap:12px; margin-bottom:12px; align-items:stretch; }
.journey-panel{ flex:0 1 65%; min-width:0; }
.journey-row > #topActionsPanel{ flex:1 1 0; min-width:0; }
/* Item 20 — desktop-only vertical trim (top+bottom only; width/horizontal
   geometry untouched). journey-panel was still on the base .panel 24px
   padding; #topActionsPanel already had a lighter 19px from an earlier
   pass, trimmed a little further here. The funnel's own canvas height
   grows by roughly the same amount this frees up (see .funnel below) —
   both cards' TOTAL height stays essentially where it was, the space
   just moves from "unused padding" to "room the mist layer actually
   needs" and "a touch less dead air above/below the row." */
@media (min-width:1025px){
  /* footer/height tighten: less bottom padding on Journey, matching pull-up
     on Top Actions so the two cards' bottom edges still align */
  .journey-panel{ padding-top:15px; padding-bottom:9px; }
  .journey-panel > .panel-head{ margin-bottom:13px; }
  #topActionsPanel{ padding-top:14px; padding-bottom:11px; }
  #topActionsPanel > .panel-head{ margin-bottom:12px; }
  /* Tasks 4/5/8 — a taller funnel box on desktop, with the badge row
     vertically CENTRED in it (was flush to the top). This is the enabling
     change for the rest of the Performance Journey pass: it gives the
     particle wave real vertical depth above AND below the path, lets the
     ethereal mist spread into a much wider band, and — critically — opens
     enough headroom above each badge for its colored atmospheric glow to
     be anchored directly behind the badge (not down on the number/text)
     while still growing large enough that neighboring stage colors fuse.
     The canvas + particle/mist math all read live badge positions via
     getBoundingClientRect(), so they follow this automatically. */
  .funnel{ height:280px; }
  .funnel-nodes{ align-items:center; }
}

/* ==========================================================================
   Row below Performance Journey — Smart Accessories / Traffic / Live (widest)
   ========================================================================== */
.ops-grid{ display:flex; gap:12px; margin-bottom:12px; align-items:stretch; }
.ops-grid > #accessoriesPanel{ flex:1 1 0; min-width:0; }
.ops-grid > #trafficPanel{ flex:1 1 0; min-width:0; }
.ops-grid > #livePanel{ flex:2 1 0; min-width:0; }

.rank-row{ display:flex; align-items:center; gap:7px; padding:9px 0; }
.rank-row + .rank-row{ border-top:1px solid var(--line); }
.rank-icon{
  width:24px; height:24px; border-radius:7px; flex:0 0 auto; display:flex; align-items:center; justify-content:center;
  background:color-mix(in srgb, var(--row-accent, var(--violet)) 22%, transparent);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--row-accent, var(--violet)) 26%, transparent);
}
/* brighter than the flat accent so the glyph out-reads its same-hue well */
.rank-icon svg{ width:12px; height:12px; stroke:color-mix(in srgb, var(--row-accent, var(--violet)) 78%, #fff); fill:none; stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; }
.rank-label{ font-size:13.5px; font-weight:600; width:68px; flex:0 1 auto; line-height:1.25; }
.rank-count{ font-size:14.5px; font-weight:800; width:22px; text-align:right; flex:0 0 auto; }
/* The track's full width IS 100% — a `pct`-width fill is already exactly
   honest (verified: 24% -> 24.0% of rendered track width), so what actually
   needed fixing was legibility: thicker track, a lit gradient fill with real
   glow, and a touch more width reclaimed from the label/count columns so a
   30%ish share still reads as a confident, readable bar rather than a sliver. */
.rank-track{ flex:1; height:10px; border-radius:99px; background:rgba(255,255,255,0.055); overflow:hidden; position:relative; }
.rank-fill{
  height:100%; border-radius:99px; min-width:3px;
  background:linear-gradient(90deg, color-mix(in srgb, var(--row-accent, var(--violet)) 75%, black), var(--row-accent, var(--brand-gradient)));
  box-shadow:0 0 10px -1px var(--row-accent, var(--violet)), inset 0 1px 0 rgba(255,255,255,0.25);
}
.rank-pct{ font-size:13px; color:var(--text-secondary); font-weight:600; width:32px; text-align:right; flex:0 0 auto; }

/* ==========================================================================
   Engagement Overview — full-width "instrument cluster" cockpit
   ========================================================================== */
.engagement-cockpit{ margin-bottom:12px; }
/* align-items:start so the taller Card #1 (Active Time / User stopwatch)
   never stretches slots 2-4 — they keep their natural height, top-aligned.
   With the current data all four were equal height, so this is a no-op for
   the untouched instruments. */
.gauge-grid{ display:grid; grid-template-columns:repeat(4, 1fr); gap:16px; align-items:start; }
.gauge{
  display:flex; flex-direction:column; align-items:center; text-align:center; padding:22px 10px 20px;
  border-radius:16px; border:1px solid var(--line); min-width:0; position:relative; overflow:hidden;
  background:radial-gradient(ellipse 130% 80% at 50% 0%, color-mix(in srgb, var(--gauge-accent, var(--violet)) 10%, transparent), transparent 62%), var(--surface-1);
  /* Recessed cockpit-bezel depth — a dark inner shadow at the top edge (as
     if the instrument sits slightly below the panel's own surface) plus a
     faint bottom rim-light, instead of a flat card. */
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.05), inset 0 14px 24px -18px rgba(0,0,0,0.7), inset 0 -1px 0 rgba(255,255,255,0.03);
}
/* Each instrument owns a thin identity hairline at its own accent color —
   ties the cockpit's 4 distinct dial styles back into one coherent system,
   the same visual grammar the KPI row already uses. */
.gauge::before{ content:""; position:absolute; left:14px; right:14px; top:0; height:2px; border-radius:0 0 3px 3px; background:var(--gauge-accent, var(--violet)); opacity:0.75; }
.gauge-instrument{ position:relative; width:100%; max-width:184px; aspect-ratio:184/128; }
.gauge-instrument svg{ position:absolute; inset:0; width:100%; height:100%; }
/* Instrument "glass" — a soft diagonal highlight sitting above everything
   else in the dial, like light catching a curved cover lens. Pointer-events
   none so it never intercepts anything; kept extremely subtle. */
.gauge-instrument::after{
  content:""; position:absolute; inset:6%; border-radius:50%; pointer-events:none; z-index:2;
  background:linear-gradient(128deg, rgba(255,255,255,0.07) 0%, rgba(255,255,255,0.02) 22%, transparent 45%);
}
.gauge-ring-outer{ fill:none; stroke:rgba(255,255,255,0.05); stroke-width:1; }
.gauge-ring-inner{ fill:none; stroke:rgba(255,255,255,0.07); stroke-width:1; stroke-dasharray:2 4; }
.gauge-track{ fill:none; stroke:rgba(255,255,255,0.06); stroke-width:8; stroke-linecap:round; filter:drop-shadow(0 1px 1px rgba(0,0,0,0.5)); }
.gauge-fill{ fill:none; stroke-width:8; stroke-linecap:round; transition:stroke-dasharray .6s cubic-bezier(.22,1,.36,1); filter:drop-shadow(0 0 6px var(--gauge-glow, transparent)); }
.gauge-tick{ stroke:rgba(255,255,255,0.22); stroke-width:1.4; stroke-linecap:round; }
.gauge-tick.major{ stroke:rgba(255,255,255,0.42); stroke-width:2.1; }
/* Tachometer variant's high-performance zone marker — a single bold radial
   tick (like a real redline notch), always visible regardless of the fill's
   own progress, so it never reads as a second disconnected fill segment. */
.gauge-redline-mark{ stroke-width:2.5; stroke-linecap:round; opacity:0.85; }
/* Segmented variant — discrete VU-meter style arcs instead of one sweep. */
.gauge-seg{ fill:none; stroke:rgba(255,255,255,0.07); stroke-width:8; stroke-linecap:round; }
.gauge-center{
  position:absolute; left:0; right:0; top:54%; transform:translateY(-50%); text-align:center;
}
.gauge-center .v{ font-size:36px; font-weight:800; letter-spacing:-0.025em; text-shadow:0 2px 18px rgba(0,0,0,0.4); }
.gauge-label{ font-size:13.5px; color:var(--text-primary); font-weight:700; margin-top:16px; }
.gauge-change{ font-size:12px; font-weight:700; min-height:15px; margin-top:4px; }

/* Video Performance — a real panel now, not a bare row of numbers under a
   divider. Own cool cyan identity (distinct from the four hero cards'
   violet/red/green/gold), same premium dark/glass language as the rest of
   the dashboard, scaled down since this is a supporting strip, not a fifth
   hero instrument. */
/* Video Performance — graphite/black instrument module, same permanent-dark
   "cockpit island" language as the four Engagement hero cards above it (not
   var(--surface-1), which is solid white in light theme). Deliberately NOT
   another hero-gauge card: depth/separation comes from layered glass
   surfaces + restrained per-metric accent lighting, not a flat color wash —
   the old all-cyan treatment read as a generic SaaS panel next to them. */
.video-strip{
  margin-top:14px; padding:20px 22px 18px; border-radius:16px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.04), transparent 42%),
    radial-gradient(120% 90% at 50% -18%, rgba(255,255,255,0.05), transparent 60%),
    linear-gradient(160deg, #14171d 0%, #0a0c10 55%, #060708 100%);
  border:1px solid rgba(255,255,255,0.08);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.06),
    inset 0 -1px 0 rgba(0,0,0,0.5),
    0 18px 40px -26px rgba(0,0,0,0.75);
}
.video-strip-head{ display:flex; flex-direction:column; align-items:center; gap:9px; margin-bottom:18px; }
.video-strip-title{
  font-family:'JetBrains Mono','SFMono-Regular',monospace; font-size:12px; font-weight:700;
  letter-spacing:0.18em; text-transform:uppercase; color:#e7ecf3; text-align:center;
}
.video-strip-title-rule{
  width:34px; height:2px; border-radius:2px;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
}
.video-strip-row{ display:grid; grid-template-columns:repeat(3, 1fr); gap:12px; }
.video-stat{
  display:flex; align-items:center; gap:12px; padding:14px 15px; border-radius:12px;
  background:linear-gradient(180deg, rgba(255,255,255,0.035), rgba(255,255,255,0.008) 45%, transparent), #0d0f13;
  border:1px solid rgba(255,255,255,0.07);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.05), inset 0 -10px 16px -14px rgba(0,0,0,0.6);
}
.video-stat-icon{
  display:flex; align-items:center; justify-content:center; width:36px; height:36px; flex:0 0 auto;
  border-radius:10px; background:rgba(255,255,255,0.04); border:1px solid rgba(255,255,255,0.1);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.07);
  color:#cfd6e0;
}
.video-stat-icon svg{ width:18px; height:18px; }
/* very restrained, metric-specific icon-well tinting — identity comes
   mostly from the icon FORM itself (frame+play / stopwatch / ring), color
   is a light accent, never a full-card wash. */
.video-stat-plays .video-stat-icon{ color:#b7a8ff; background:rgba(142,124,255,0.1); border-color:rgba(142,124,255,0.26); }
.video-stat-watch .video-stat-icon{ color:#f0cf9a; background:rgba(224,168,58,0.1); border-color:rgba(224,168,58,0.26); }
.video-stat-body{ min-width:0; }
.video-stat-v{ font-size:21px; font-weight:800; letter-spacing:-0.01em; color:#f4f7fb; line-height:1.15; }
.video-stat-l{ font-size:10.5px; color:#8b93a3; font-weight:700; letter-spacing:0.05em; text-transform:uppercase; margin-top:3px; white-space:nowrap; }
/* Completion Rate keeps its own ring — the one stat here that's inherently
   a proportion deserves to look like one, with a bit more dimensionality
   than a flat single-color stroke. */
.video-stat-ring{ gap:14px; }
.video-stat-ringwrap{ position:relative; width:46px; height:46px; flex:0 0 auto; }
.video-stat-ringwrap svg{ width:46px; height:46px; display:block; filter:drop-shadow(0 2px 6px rgba(0,0,0,0.55)); }
.video-ring-track{ fill:none; stroke:rgba(255,255,255,0.09); stroke-width:4; }
.video-ring-fill{
  fill:none; stroke:url(#videoRingGrad); stroke-width:4; stroke-linecap:round;
  filter:drop-shadow(0 0 4px rgba(111,201,255,0.5));
  transition:stroke-dashoffset 0.6s ease;
}
.video-ring-label{
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  font-size:11px; font-weight:800; color:#f2f7f5;
}
@media (max-width:640px){
  .video-strip-row{ grid-template-columns:1fr; }
}

/* ==========================================================================
   Engagement Overview — shared card-title treatment (refinement pass)
   --------------------------------------------------------------------------
   The four hero cards now share ONE title treatment: the icon + label are
   CENTERED above the instrument, a step larger than before, with each card's
   own colour identity preserved by the per-card rules further down. There is
   NO divider strip under the title — the atmosphere canvas is a direct child
   of the card and fills the whole rectangle (behind the title too), so shooting
   stars / lightning / rain / gold travel through the entire card as one
   continuous environment. The title stays legible via a dark text halo and a
   very soft radial scrim localised behind the header only.
   ========================================================================== */
.eng-sw-header,.eng-gg-header,.eng-pl-header,.eng-cv-header{
  justify-content:center; gap:9px; padding:1px 4px 3px;
}
.eng-sw-header::before,.eng-gg-header::before,.eng-pl-header::before,.eng-cv-header::before{
  content:""; position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  width:118%; height:230%; z-index:-1; pointer-events:none;
  background:radial-gradient(60% 60% at 50% 45%, rgba(0,0,0,0.42), rgba(0,0,0,0.16) 55%, transparent 78%);
}
.eng-sw-title,.eng-gg-title,.eng-pl-title,.eng-cv-title{
  text-shadow:0 1px 3px rgba(0,0,0,0.85), 0 0 10px rgba(0,0,0,0.55);
}

/* ==========================================================================
   Engagement Overview — CARD #1 · ACTIVE TIME / USER
   Physical precision stopwatch (layered SVG) suspended in an ethereal violet
   mist (two canvases: one behind the instrument, one in front for foreground
   bokeh). Occupies gauge slot 1 only — slots 2-4 are untouched. Committed
   dark instrument in both themes (a deliberate single look).
   ========================================================================== */
.eng-stopwatch-card{
  position:relative; display:flex; flex-direction:column; align-self:stretch;
  min-height:436px; padding:15px 13px 13px; border-radius:18px; overflow:hidden;
  color:#c9bdf0;
  background:
    /* continuous top sheen — bridges the header into the stage so the two
       don't read as separate compartments (matches Cards #2 & #3, which
       already carry this layer). Replaces the perceived dark divider that
       used to sit in the un-lit gap below the header. */
    linear-gradient(180deg, rgba(200,190,235,0.045), transparent 15%),
    radial-gradient(70% 48% at 50% 46%, rgba(118,82,216,0.07), transparent 74%),
    radial-gradient(110% 50% at 50% -5%, rgba(139,108,247,0.05), transparent 60%),
    #06050b;
  border:1px solid rgba(140,120,210,0.16);
  box-shadow:
    inset 0 1px 0 rgba(180,150,255,0.06),
    inset 0 0 40px rgba(90,60,170,0.10),
    0 18px 40px -22px rgba(0,0,0,0.8);
  /* chamfered top-right corner — technical instrument framing from the ref */
  clip-path:polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%);
}
/* layered inset border */
.eng-stopwatch-card::after{
  content:""; position:absolute; inset:5px; border-radius:14px; pointer-events:none; z-index:5;
  border:1px solid rgba(150,125,220,0.10);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,0.4);
  clip-path:polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
}
.eng-sw-header{ position:relative; z-index:4; display:flex; align-items:center; gap:8px; }
.eng-sw-clock{
  display:flex; align-items:center; justify-content:center; width:25px; height:25px; flex:0 0 auto;
  border-radius:7px; color:#9d7bf0;
  border:1px solid rgba(157,123,240,0.45); background:rgba(139,108,247,0.10);
}
.eng-sw-clock svg{ width:15px; height:15px; }
.eng-sw-title{
  font-family:'JetBrains Mono','SFMono-Regular',monospace; font-size:13.5px; font-weight:700;
  letter-spacing:0.15em; text-transform:uppercase; color:#a99fd0;
}
.eng-sw-stage{
  position:relative; z-index:1; flex:1 1 auto; display:flex; align-items:center; justify-content:center;
  min-height:250px; margin:0;
}
.eng-sw-atmos,.eng-sw-atmos-front{ position:absolute; inset:0; width:100%; height:100%; pointer-events:none; }
.eng-sw-atmos{ z-index:1; }
.eng-sw-atmos-front{ z-index:3; }
.eng-sw-instrument{
  position:relative; z-index:2; width:100%; max-width:340px;
  /* nudge the enlarged instrument UP so its case + drop-shadow clear the
     Session Quality panel with intentional breathing room below */
  margin:-6px 0 14px;
  filter:drop-shadow(0 14px 32px rgba(0,0,0,0.62));
  /* barely-perceptible "alive" breathing — the whole instrument scales as
     ONE unit from its true centre (no piece animates independently) with a
     coordinated violet-glow swell. ~1% over an 8.5s cycle. */
  transform-origin:50% 58%;
  animation:engSwBreathe 8.5s ease-in-out infinite;
  will-change:transform, filter;
}
@keyframes engSwBreathe{
  0%,100%{
    transform:scale(1);
    filter:drop-shadow(0 14px 32px rgba(0,0,0,0.62)) drop-shadow(0 0 11px rgba(150,110,255,0.07));
  }
  50%{
    transform:scale(1.011);
    filter:drop-shadow(0 15px 34px rgba(0,0,0,0.62)) drop-shadow(0 0 20px rgba(150,110,255,0.19));
  }
}
.eng-sw-instrument svg{ display:block; width:100%; height:auto; overflow:visible; }
.eng-sw-footer{
  position:relative; z-index:4; display:flex; align-items:center; justify-content:space-between; gap:12px;
  margin-top:auto; padding:11px 13px; border-radius:11px;
  /* readability system — a real smoked-glass backing (was rgba(255,255,255,0.02),
     essentially none) so the label/scale text has contrast against the
     shooting-star field behind it, not just the panel's border/glow. */
  background:linear-gradient(180deg, rgba(20,14,34,0.62), rgba(10,7,18,0.7));
  backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px);
  border:1px solid rgba(150,125,220,0.16);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.04), inset 0 0 20px rgba(80,50,150,0.14);
}
.eng-sw-q-label{
  font-family:'JetBrains Mono',monospace; font-size:9px; font-weight:700;
  letter-spacing:0.16em; color:#b3a8dd;
}
.eng-sw-q-scale{ margin-top:6px; display:flex; align-items:baseline; gap:5px; }
.eng-sw-q{ font-size:11px; font-weight:700; letter-spacing:0.05em; color:rgba(205,198,230,0.55); }
.eng-sw-q-sep{ font-size:10px; color:rgba(205,198,230,0.32); }
.eng-sw-q.is-on{ font-size:16px; color:#b291ff; text-shadow:0 0 14px rgba(139,108,247,0.6); }
.eng-sw-spark{ width:96px; height:34px; flex:0 0 auto; overflow:visible; }

/* ==========================================================================
   Engagement Overview — CARD #4 · RETURNING VISITOR RATE
   Dark mechanical circular gauge inside a swirling ETHEREAL GOLD ENERGY
   field (dual canvas). Gauge slot 4 only. Committed dark instrument, gold
   identity — deliberately none of Card #1's purple.
   ========================================================================== */
.eng-loyalty-card{
  position:relative; display:flex; flex-direction:column; align-self:stretch;
  min-height:452px; padding:15px 13px 13px; border-radius:18px; overflow:hidden;
  color:#d9c9a4;
  background:
    /* continuous top sheen — bridges the header into the stage so the two
       don't read as separate compartments (matches Cards #2 & #3). Replaces
       the perceived dark divider that used to sit in the un-lit gap below
       the header. */
    linear-gradient(180deg, rgba(232,212,170,0.045), transparent 15%),
    radial-gradient(70% 48% at 50% 45%, rgba(214,168,74,0.08), transparent 74%),
    radial-gradient(110% 50% at 50% -5%, rgba(230,190,110,0.05), transparent 60%),
    #080703;
  border:1px solid rgba(210,175,95,0.16);
  box-shadow:
    inset 0 1px 0 rgba(255,222,150,0.06),
    inset 0 0 40px rgba(150,110,40,0.10),
    0 18px 40px -22px rgba(0,0,0,0.8);
  clip-path:polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%);
}
.eng-loyalty-card::after{
  content:""; position:absolute; inset:5px; border-radius:14px; pointer-events:none; z-index:5;
  border:1px solid rgba(210,175,95,0.10);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,0.4);
  clip-path:polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
}
.eng-gg-header{ position:relative; z-index:4; display:flex; align-items:center; gap:8px; }
.eng-gg-icon{
  display:flex; align-items:center; justify-content:center; width:25px; height:25px; flex:0 0 auto;
  border-radius:7px; color:#e6b855;
  border:1px solid rgba(230,184,85,0.45); background:rgba(214,168,74,0.12);
}
.eng-gg-icon svg{ width:16px; height:16px; }
.eng-gg-title{
  font-family:'JetBrains Mono','SFMono-Regular',monospace; font-size:13.5px; font-weight:700;
  letter-spacing:0.13em; text-transform:uppercase; color:#c9b78c;
}
.eng-gg-stage{
  position:relative; z-index:1; flex:1 1 auto; display:flex; align-items:center; justify-content:center;
  min-height:262px; margin:0;
}
.eng-gg-atmos,.eng-gg-atmos-front{ position:absolute; inset:0; width:100%; height:100%; pointer-events:none; }
.eng-gg-atmos{ z-index:1; }
.eng-gg-atmos-front{ z-index:3; }
.eng-gg-instrument{
  /* 330 -> 340: matches Card #1's cap now that the viewBox crop (app.js
     engGaugeCardHtml) gives all four hero gauges the same true diameter
     fraction — this only matters on very wide viewports where max-width,
     not the grid column, is the binding constraint. */
  position:relative; z-index:2; width:100%; max-width:340px; margin:-4px 0 12px;
  filter:drop-shadow(0 14px 30px rgba(0,0,0,0.6));
  transform-origin:50% 52%;
  animation:engGgBreathe 9s ease-in-out infinite;
  will-change:transform, filter;
}
@keyframes engGgBreathe{
  0%,100%{ transform:scale(1); filter:drop-shadow(0 14px 30px rgba(0,0,0,0.6)) drop-shadow(0 0 10px rgba(230,185,95,0.06)); }
  50%{ transform:scale(1.009); filter:drop-shadow(0 15px 32px rgba(0,0,0,0.6)) drop-shadow(0 0 20px rgba(236,196,110,0.2)); }
}
.eng-gg-instrument svg{ display:block; width:100%; height:auto; overflow:visible; }
/* Constant, stable radiant-gold aura on the live fill arc (app.js
   engGaugeSvg — .eng-gg-fill-live). Deliberately NOT animated: a fixed,
   richer glow that's always on at full intensity, no breathing/pulsing.
   (Whole-instrument .eng-gg-instrument "alive" breathing above is a
   separate, pre-existing, approved effect — untouched.) */
.eng-gg-fill-live{ filter:drop-shadow(0 0 9px rgba(255,222,160,0.75)) drop-shadow(0 0 18px rgba(230,185,95,0.4)); }
.eng-gg-footer{
  position:relative; z-index:4; margin-top:auto; padding:11px 13px; border-radius:11px;
  /* readability system — see .eng-sw-footer; same dark backing, gold tint. */
  background:linear-gradient(180deg, rgba(30,22,8,0.6), rgba(14,10,4,0.7));
  backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px);
  border:1px solid rgba(210,175,95,0.16);
  box-shadow:inset 0 1px 0 rgba(255,235,180,0.05), inset 0 0 20px rgba(140,100,35,0.14);
}
.eng-gg-loyalty-l{
  font-family:'JetBrains Mono',monospace; font-size:9px; font-weight:700;
  letter-spacing:0.16em; color:#d4bc8c;
}
.eng-gg-loyalty-row{ margin-top:6px; display:flex; align-items:center; justify-content:space-between; gap:12px; }
.eng-gg-tier{
  font-size:16px; font-weight:800; letter-spacing:0.04em; color:#eebf5f;
  text-shadow:0 0 14px rgba(230,185,95,0.55);
}
.eng-gg-nodes{ display:flex; align-items:center; gap:8px; flex:0 0 auto; }
.eng-gg-node{
  width:7px; height:7px; border-radius:50%; background:rgba(180,155,100,0.28);
}
.eng-gg-node.is-on{
  background:#efc061; box-shadow:0 0 8px rgba(239,192,97,0.85), 0 0 16px rgba(239,192,97,0.4);
}

/* ==========================================================================
   Engagement Overview — CARD #3 · ACTIONS / SESSION
   Dark precision gauge whose hero is a translucent chamber of turbulent
   radioactive-green plasma / vapour (dual canvas). Gauge slot 3 only. The
   mechanical instrument stays physically stable — all "breathing" lives in
   the canvas (illumination + density), never a transform.
   ========================================================================== */
.eng-plasma-card{
  position:relative; display:flex; flex-direction:column; align-self:stretch;
  min-height:452px; padding:15px 13px 13px; border-radius:18px; overflow:hidden;
  color:#c3d9ad;
  /* reactor instrument chassis — gunmetal ground + top metallic sheen + four
     tiny corner fasteners (scoped to Card #3 only) */
  background:
    radial-gradient(circle at 14px 14px, rgba(180,190,175,0.30) 0 1.3px, transparent 2px),
    radial-gradient(circle at calc(100% - 14px) 14px, rgba(180,190,175,0.30) 0 1.3px, transparent 2px),
    radial-gradient(circle at 14px calc(100% - 14px), rgba(180,190,175,0.30) 0 1.3px, transparent 2px),
    radial-gradient(circle at calc(100% - 14px) calc(100% - 14px), rgba(180,190,175,0.30) 0 1.3px, transparent 2px),
    linear-gradient(180deg, rgba(200,210,195,0.05), transparent 16%),
    radial-gradient(72% 42% at 50% 44%, rgba(120,200,60,0.07), transparent 72%),
    radial-gradient(110% 50% at 50% -5%, rgba(150,220,90,0.045), transparent 60%),
    #060804;
  border:1px solid rgba(120,132,116,0.28);
  box-shadow:
    inset 0 1px 0 rgba(210,220,200,0.10),
    inset 0 0 0 1px rgba(0,0,0,0.35),
    inset 0 0 42px rgba(60,110,25,0.10),
    0 18px 40px -22px rgba(0,0,0,0.82);
  clip-path:polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%);
}
.eng-plasma-card::after{
  content:""; position:absolute; inset:5px; border-radius:14px; pointer-events:none; z-index:5;
  border:1px solid rgba(140,150,135,0.14);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,0.5), inset 0 1px 0 rgba(210,220,200,0.05);
  clip-path:polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
}
.eng-pl-header{ position:relative; z-index:4; display:flex; align-items:center; gap:8px; }
.eng-pl-icon{
  display:flex; align-items:center; justify-content:center; width:25px; height:25px; flex:0 0 auto;
  border-radius:7px; color:#b6f24e;
  border:1px solid rgba(182,242,78,0.42); background:rgba(120,200,60,0.12);
}
.eng-pl-icon svg{ width:16px; height:16px; }
.eng-pl-title{
  font-family:'JetBrains Mono','SFMono-Regular',monospace; font-size:13.5px; font-weight:700;
  letter-spacing:0.13em; text-transform:uppercase; color:#a9c98f;
}
.eng-pl-stage{
  position:relative; z-index:1; flex:1 1 auto; display:flex; align-items:center; justify-content:center;
  min-height:262px; margin:0;
}
.eng-pl-atmos,.eng-pl-atmos-front{ position:absolute; inset:0; width:100%; height:100%; pointer-events:none; }
.eng-pl-atmos{ z-index:1; }
.eng-pl-atmos-front{ z-index:3; }
.eng-pl-instrument{
  /* 330 -> 340: matches Card #1, same reasoning as .eng-gg-instrument above. */
  position:relative; z-index:2; width:100%; max-width:340px; margin:-4px 0 12px;
  filter:drop-shadow(0 14px 30px rgba(0,0,0,0.6));
}
.eng-pl-instrument svg{ display:block; width:100%; height:auto; overflow:visible; }
.eng-pl-footer{
  position:relative; z-index:4; margin-top:auto; padding:11px 13px; border-radius:11px;
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  /* readability system — see .eng-sw-footer; same dark backing, green tint. */
  background:linear-gradient(180deg, rgba(14,26,8,0.6), rgba(6,12,4,0.7));
  backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px);
  border:1px solid rgba(150,210,110,0.16);
  box-shadow:inset 0 1px 0 rgba(210,255,170,0.05), inset 0 0 20px rgba(60,120,25,0.14);
}
.eng-pl-foot-label{
  font-family:'JetBrains Mono',monospace; font-size:9px; font-weight:700;
  letter-spacing:0.16em; color:#b6d19c;
}
.eng-pl-foot-lvl{
  margin-top:5px; font-size:16px; font-weight:800; letter-spacing:0.04em; color:#b6f24e;
  text-shadow:0 0 14px rgba(150,220,70,0.55);
}
.eng-pl-bars-wrap{ display:block; width:118px; flex:0 0 auto; }
.eng-pl-bars{ display:block; width:118px; height:36px; overflow:visible; }

/* ==========================================================================
   Engagement Overview — CARD #2 · CONVERSION RATE
   Obsidian / gunmetal / ruby / magma. The darkest, most severe card of the
   set. Dual canvas for the volcanic surface + magma cracks. Gauge slot 2.
   ========================================================================== */
.eng-conversion-card{
  position:relative; display:flex; flex-direction:column; align-self:stretch;
  min-height:474px; padding:15px 13px 13px; border-radius:16px; overflow:hidden;
  color:#b9a3a3;
  background:
    radial-gradient(circle at 13px 13px, rgba(150,120,120,0.22) 0 1.2px, transparent 2px),
    radial-gradient(circle at calc(100% - 13px) 13px, rgba(150,120,120,0.22) 0 1.2px, transparent 2px),
    radial-gradient(circle at 13px calc(100% - 13px), rgba(150,120,120,0.22) 0 1.2px, transparent 2px),
    radial-gradient(circle at calc(100% - 13px) calc(100% - 13px), rgba(150,120,120,0.22) 0 1.2px, transparent 2px),
    linear-gradient(180deg, rgba(210,190,190,0.04), transparent 14%),
    radial-gradient(75% 44% at 50% 44%, rgba(150,26,24,0.07), transparent 72%),
    #050303;
  border:1px solid rgba(120,90,90,0.26);
  box-shadow:
    inset 0 1px 0 rgba(220,200,200,0.07),
    inset 0 0 0 1px rgba(0,0,0,0.45),
    inset 0 0 46px rgba(120,16,16,0.09),
    0 20px 44px -22px rgba(0,0,0,0.9);
  clip-path:polygon(0 0, calc(100% - 15px) 0, 100% 15px, 100% 100%, 0 100%);
}
.eng-conversion-card::after{
  content:""; position:absolute; inset:5px; border-radius:12px; pointer-events:none; z-index:5;
  border:1px solid rgba(120,90,90,0.14);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,0.55), inset 0 1px 0 rgba(220,200,200,0.04);
  clip-path:polygon(0 0, calc(100% - 11px) 0, 100% 11px, 100% 100%, 0 100%);
}
.eng-cv-header{ position:relative; z-index:4; display:flex; align-items:center; gap:8px; }
.eng-cv-icon{
  display:flex; align-items:center; justify-content:center; width:25px; height:25px; flex:0 0 auto;
  border-radius:6px; color:#ff4433;
  border:1px solid rgba(255,68,51,0.42); background:rgba(150,26,24,0.14);
}
.eng-cv-icon svg{ width:16px; height:16px; }
.eng-cv-title{
  font-family:'JetBrains Mono','SFMono-Regular',monospace; font-size:13.5px; font-weight:700;
  letter-spacing:0.13em; text-transform:uppercase; color:#c99a9a;
}
.eng-cv-stage{
  position:relative; z-index:1; flex:1 1 auto; display:flex; align-items:center; justify-content:center;
  min-height:258px; margin:0;
}
.eng-cv-atmos,.eng-cv-atmos-front{ position:absolute; inset:0; width:100%; height:100%; pointer-events:none; }
.eng-cv-atmos{ z-index:1; }
.eng-cv-atmos-front{ z-index:3; }
.eng-cv-instrument{
  position:relative; z-index:2; width:100%; max-width:342px; margin:-6px 0 6px;
  filter:drop-shadow(0 14px 30px rgba(0,0,0,0.66));
}
.eng-cv-stage{ min-height:250px; }
.eng-cv-instrument svg{ display:block; width:100%; height:auto; overflow:visible; }
.eng-cv-panel{
  position:relative; z-index:4; display:flex; align-items:center; justify-content:space-between; gap:12px;
  margin-top:8px; padding:9px 12px; border-radius:9px;
  /* readability system — see .eng-sw-footer; same dark backing, ruby tint.
     Was rgba(255,235,235,0.02)/rgba(0,0,0,0.2) — too thin against the
     ember field to give the small label real contrast. */
  background:linear-gradient(180deg, rgba(30,10,10,0.6), rgba(8,4,4,0.72));
  backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px);
  border:1px solid rgba(120,90,90,0.18);
  box-shadow:inset 0 1px 0 rgba(220,200,200,0.05), inset 0 0 18px rgba(120,16,16,0.12);
  clip-path:polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 8px 100%, 0 calc(100% - 8px));
}
.eng-cv-panel:first-of-type{ margin-top:auto; }
.eng-cv-panel-l{ display:flex; flex-direction:column; gap:4px; min-width:0; }
.eng-cv-panel-label{
  font-family:'JetBrains Mono',monospace; font-size:8.5px; font-weight:700;
  letter-spacing:0.15em; color:#d3a09d; white-space:nowrap;
}
.eng-cv-panel-val{ font-size:14px; font-weight:800; letter-spacing:0.02em; color:#c99a9a; }
.eng-cv-panel-val.is-up{ color:#ff5a44; text-shadow:0 0 12px rgba(232,44,42,0.5); }
.eng-cv-panel-val.is-down{ color:#b06a62; }
.eng-cv-source{
  font-size:15px; font-weight:800; letter-spacing:0.03em; color:#ff4433;
  text-shadow:0 0 12px rgba(232,44,42,0.45); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.eng-cv-spark{ width:118px; height:26px; flex:0 0 auto; overflow:visible; }
.eng-cv-hist-wrap{ display:block; width:96px; flex:0 0 auto; }
.eng-cv-hist{ display:block; width:96px; height:32px; overflow:visible; }

/* ==========================================================================
   DESKTOP HERO-GAUGE ALIGNMENT — shared model, computed at runtime.
   The four cards keep their FULL hero stages untouched (each gauge still
   fills its card exactly as before — this is NOT a size change). After every
   render + on resize, engAlignHeroes() in app.js measures each gauge's true
   centre (from that SVG's own viewBox geometry) and writes ONE value per
   card, --eng-hero-shift, so the four gauge centres land on one horizontal
   line. The shift is a transform on the <svg> only (the breathing animation
   lives on the wrapping .eng-*-instrument div, so there is no conflict).
   ========================================================================== */
@media (min-width:769px){
  #engagementPanel .eng-sw-instrument > svg,
  #engagementPanel .eng-gg-instrument > svg,
  #engagementPanel .eng-pl-instrument > svg,
  #engagementPanel .eng-cv-instrument > svg{
    transform:translateY(var(--eng-hero-shift, 0px));
  }
}

@media (max-width:768px){
  .eng-stopwatch-card{ min-height:390px; }
  .eng-loyalty-card{ min-height:400px; }
  .eng-plasma-card{ min-height:400px; }
  .eng-conversion-card{ min-height:430px; }
  /* narrow 2-col mobile: pull the gauges in a touch so the side landmarks
     never reach the card edge */
  .eng-gg-instrument,.eng-pl-instrument,.eng-cv-instrument{ width:86%; }
  /* the two conversion panels get tight on a mobile column — shrink the
     trend/histogram so the label + value stay readable */
  .eng-cv-spark{ width:84px; }
  .eng-cv-hist-wrap,.eng-cv-hist{ width:62px; }
  .eng-cv-source{ font-size:13px; }
}

/* ==========================================================================
   Live Activity — compact but now the widest of the three-card row
   ========================================================================== */
.live-panel-compact{ display:flex; flex-direction:column; }
.live-panel-compact .panel-head{ margin-bottom:8px; align-items:center; }
/* SIX items per page (LIVE_FEED_VISIBLE in app.js). The list now GROWS to
   fill the card body (flex:1 1 auto) and each of the six rows shares that
   space equally (.feed-item flex:1 1 0), so the feed reads as six evenly
   spaced rows running from the header down to the pager — not five tall
   rows with space-between gaps, and not six compressed rows stranded at the
   top. min-height on the row is the mobile floor (see the responsive block)
   for when the stacked card has no extra height to distribute. */
#liveFeedList, #saLiveFeedList{ flex:1 1 auto; justify-content:flex-start; gap:5px; }
/* Live Activity's own "Live" chip reads a vivid neon GREEN here — distinct
   from the RED "Live Data" status at the top of the page (that one is
   untouched, see .live-indicator above). Colour only — the blink
   (livePulse, opacity-only) and the chip glow (liveBadgeGlowGreen) keep the
   exact same restrained timing as every other pulse on the page. */
.live-badge{
  display:flex; align-items:center; gap:6px; font-family:'JetBrains Mono', monospace; font-size:10.5px; font-weight:700;
  letter-spacing:0.08em; text-transform:uppercase; color:var(--live-green); padding:5px 10px 5px 8px; border-radius:99px;
  /* Item 7 — sped up from 2.2s to read as more actively "live"; still the
     same smooth ease-in-out, not a strobe. Live Activity's own badge only —
     the header's separate .live-indicator-label dot keeps its original
     2.2s timing. */
  background:var(--live-green-dim); flex:0 0 auto; animation:liveBadgeGlowGreen 1.4s ease-in-out infinite;
}
.live-badge .dot{ width:6px; height:6px; border-radius:50%; background:var(--live-green); box-shadow:0 0 7px var(--live-green), 0 0 14px rgba(57,255,136,0.5); animation:livePulse 1.4s ease-in-out infinite; }
@keyframes liveBadgeGlowGreen{ 0%,100%{ background:var(--live-green-dim); } 50%{ background:rgba(57,255,136,0.3); } }
/* Pagination footer — Live Activity's own always-on arrow+dot pager
   (#feedPager). Top Actions has no pagination at all anymore (plain
   native scroll on every breakpoint, see #topActionsList above).
   margin-top:auto anchors it to the bottom of the (stretched) panel. */
.mobile-pager{
  display:none; align-items:center; justify-content:center; gap:14px;
  margin-top:auto; padding-top:12px;
}
@media (max-width:1024px){ .mobile-pager{ display:flex; } }
#feedPager, #saFeedPager{ display:flex; }
/* The desktop-only expand-to-scroll-all button has no equivalent on touch
   devices (item 11 — mobile relies on pagination only), so it's simply not
   offered there rather than triggering a state mobile can't usefully use. */
@media (hover:none), (pointer:coarse){
  .panel-expand-btn{ display:none; }
}
.pager-btn{
  display:flex; align-items:center; justify-content:center; width:28px; height:28px;
  background:var(--surface-2); border:1px solid var(--line); border-radius:9px; cursor:pointer;
  color:var(--text-primary); transition:background .16s ease, border-color .16s ease, color .16s ease, opacity .16s ease;
}
.pager-btn svg{ width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:2.3; stroke-linecap:round; stroke-linejoin:round; }
.pager-btn:hover{ background:var(--surface-hover); border-color:var(--line-strong); }
.pager-btn:disabled{ opacity:0.32; cursor:default; background:var(--surface-2); border-color:var(--line); }
/* Dot pagination (item 16) — the current page reads as a bright white dot,
   every other available page as a muted gray one; renderPagerDots() in
   app.js generates exactly one dot per real page, never hardcoded to two. */
.pager-dots{ display:flex; align-items:center; gap:7px; }
.pager-dot{
  width:6px; height:6px; padding:0; border-radius:50%; background:var(--text-tertiary); flex:0 0 auto;
  border:none; cursor:pointer; position:relative;
  transition:background .18s ease, transform .18s ease, box-shadow .18s ease;
}
/* Real hit target bigger than the visible 6px dot, without changing its
   footprint in the flex row. */
.pager-dot::before{ content:""; position:absolute; inset:-6px; }
.pager-dot:hover{ background:var(--text-secondary); }
.pager-dot.is-current{ background:#fff; box-shadow:0 0 6px rgba(255,255,255,0.55); transform:scale(1.2); cursor:default; }
.pager-dot.is-current:hover{ background:#fff; }

.feed-list{ display:flex; flex-direction:column; }
/* Compact activity row — a single line of text next to a small icon, the
   standard density for an activity feed (GitHub / Linear style). Each row
   flex-grows to an equal share of the list body (see #liveFeedList) so six
   rows fill the card comfortably; min-height is the floor on a short
   stacked mobile card where there's no spare height to share. */
.feed-list-compact .feed-item{ padding:6px 0; min-height:36px; flex:1 1 0; }
.feed-list-compact .feed-icon{ width:22px; height:22px; }
/* One line (item 9) — text and source read as one sentence
   ("Instagram link clicked  via Instagram") instead of stacking. Icon at
   24px; single-line row + tight padding is what lets six rows per page fit
   without the panel growing (see LIVE_FEED_VISIBLE in app.js). */
.feed-item{ display:flex; align-items:center; gap:10px; padding:9px 0; }
.feed-item:first-child{ animation:feedIn .4s ease; }
@keyframes feedIn{ from{ opacity:0; transform:translateY(-4px); } to{ opacity:1; transform:translateY(0); } }
.feed-item + .feed-item{ border-top:1px solid var(--line); }
.feed-icon{
  width:24px; height:24px; border-radius:7px; display:flex; align-items:center; justify-content:center; flex:0 0 auto;
  background:color-mix(in srgb, var(--feed-accent, var(--cyan)) 22%, transparent);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--feed-accent, var(--cyan)) 26%, transparent);
}
.feed-icon svg{ width:12px; height:12px; stroke:color-mix(in srgb, var(--feed-accent, var(--cyan)) 78%, #fff); fill:none; stroke-width:2.2; }
/* Two-level color hierarchy preserved on one line: .feed-text (primary,
   --text-primary via inherited color) stays the dominant read; .feed-via
   keeps the exact secondary color/weight the old two-line .feed-meta used,
   just repositioned inline. Only .feed-text ellipsizes — "via Source" is
   always short and stays fully visible as the anchor for the sentence. */
.feed-body{ flex:1 1 auto; min-width:0; display:flex; align-items:baseline; gap:5px; overflow:hidden; }
.feed-text{ font-size:13.5px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.feed-via{ font-size:12px; color:var(--text-secondary); font-weight:500; white-space:nowrap; flex:0 0 auto; }
.feed-time{ font-size:12px; color:var(--text-secondary); white-space:nowrap; flex:0 0 auto; margin-left:12px; font-family:'JetBrains Mono', monospace; }
.empty-note{ font-size:13px; color:var(--text-secondary); padding:10px 0; }

/* ==========================================================================
   LEADS — real CRM (Phase 3).

   Control-center toolbar + operational table + full-viewport list pane,
   a right-side Quick View drawer, an in-dashboard full lead record, and a
   centered Add/Import sheet. HubSpot's information hierarchy, built in the
   1EIGHTY design system (tokens only — no new colour language). Light-mode
   overrides live in the LIGHT THEME section; responsive rules at the very
   end of this block.
   ========================================================================== */

/* ==========================================================================
   QC — ORBIT DARK-MODE READABILITY (scoped). A CRM must scan fast. In dark
   mode the shared --text-secondary / --text-tertiary tokens read too low-
   contrast on Orbit's frosted surfaces (table rows, column headers, the
   view-tab strip, filter controls, pipeline cards + column headers + the
   metric strip). Lift ONLY those two tokens WITHIN #viewLeads, so every
   consumer gets a readable value while the primary → secondary → tertiary
   hierarchy is preserved. Light mode is untouched (guarded selector). A few
   named elements get an extra nudge on top. Layouts/spacing unchanged.
   ========================================================================== */
:root:not([data-theme="light"]) #viewLeads{
  --text-secondary:#B4BFD3;   /* was #94A3B8 — row text, headers, tab labels */
  --text-tertiary:#8A93A9;    /* was #565C74 — metadata, was disappearing    */
}
:root:not([data-theme="light"]) #viewLeads .leads-thead,
:root:not([data-theme="light"]) #viewLeads .leads-th-lbl{ color:#C4CDDF; }
:root:not([data-theme="light"]) #viewLeads .leads-viewtab:not(.is-active),
:root:not([data-theme="light"]) #viewLeads .leads-ms-btn:not(.is-active),
:root:not([data-theme="light"]) #viewLeads .leads-mode-opt:not(.is-active),
/* #14 (Dock freeze pass) — Dock's toggle lives in the global header (outside
   #viewLeads/#viewClients) so it needs its own reference here for the exact
   same dark-mode inactive-tab color Orbit's copy gets. */
:root:not([data-theme="light"]) #chModeToggle .leads-mode-opt:not(.is-active),
:root:not([data-theme="light"]) #viewLeads .leads-control{ color:#C2CBDD; }
:root:not([data-theme="light"]) #viewLeads .lead-cell{ color:#BEC8DB; }
:root:not([data-theme="light"]) #viewLeads .lead-cell-email,
:root:not([data-theme="light"]) #viewLeads .lead-cell-tel,
:root:not([data-theme="light"]) #viewLeads .lead-activity-what{ color:#D2DAEA; }
:root:not([data-theme="light"]) #viewLeads .pipe-summary-l{ color:#C4CDDF; }
:root:not([data-theme="light"]) #viewLeads .pipe-card-co{ color:#BEC8DB; }
:root:not([data-theme="light"]) #viewLeads .pipe-card-src,
:root:not([data-theme="light"]) #viewLeads .pipe-card-foot{ color:#A7B1C6; }
/* the Quick View / Opportunity drawers are body-parented (outside #viewLeads);
   they carry the SAME scoped lift on .lead-drawer (see the QC#9/#10 block). */

/* ---- Toolbar ------------------------------------------------------------- */
.leads-toolbar{ display:flex; flex-direction:column; gap:12px; margin-bottom:14px; }
.leads-toolbar-top{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.leads-headcount{ display:flex; align-items:baseline; gap:7px; flex:0 0 auto; }
.leads-headcount-n{ font-family:var(--font-command); font-size:23px; font-weight:700; letter-spacing:-0.02em; color:var(--text-primary); }
.leads-headcount-l{ font-size:13px; font-weight:600; color:var(--text-secondary); }
/* .leads-headcount-sub is fully defined in the "PASS 5 — CRM depth" block
   below (as a real <button>: violet, ::before "· ", :hover, .is-active). The
   original tertiary-gray span rule that used to live here was 100% superseded
   by that later same-specificity rule — removed to avoid a misleading dead
   declaration. */

.leads-search{ position:relative; display:flex; align-items:center; flex:1 1 240px; min-width:190px; max-width:400px; }
.leads-search-ic{ position:absolute; left:11px; width:15px; height:15px; stroke:var(--text-tertiary); fill:none; stroke-width:2; pointer-events:none; }
.leads-search input{
  width:100%; padding:9px 34px; border-radius:10px; font:inherit; font-size:13px; color:var(--text-primary);
  background:var(--input-bg); border:1px solid var(--line-strong); transition:border-color .14s ease, box-shadow .14s ease;
}
.leads-search input::placeholder{ color:var(--text-tertiary); }
.leads-search input:focus{ outline:none; border-color:var(--violet); box-shadow:0 0 0 3px rgba(139,108,247,0.16); }
.leads-search input::-webkit-search-cancel-button{ -webkit-appearance:none; appearance:none; }
.leads-search-clear{
  position:absolute; right:7px; width:20px; height:20px; border-radius:6px; border:none; background:none; cursor:pointer;
  display:flex; align-items:center; justify-content:center; color:var(--text-tertiary);
}
.leads-search-clear:hover{ color:var(--text-primary); background:var(--surface-hover); }
.leads-search-clear svg{ width:12px; height:12px; stroke:currentColor; fill:none; stroke-width:2.4; }

.leads-toolbar-actions{ display:flex; gap:8px; margin-left:12px; flex:0 0 auto; }

/* Construction / Live segmented control — top-right of the toolbar. */
.leads-modetoggle{
  display:inline-flex; align-items:stretch; gap:2px; margin-left:auto; flex:0 0 auto;
  padding:3px; border-radius:10px; background:var(--surface-1); border:1px solid var(--line-strong);
}
.leads-modetoggle[hidden]{ display:none; }
.leads-mode-opt{
  display:inline-flex; align-items:center; gap:6px; cursor:pointer; white-space:nowrap; font:inherit;
  padding:6px 11px; border:none; border-radius:7px; background:none;
  font-size:12px; font-weight:700; color:var(--text-tertiary);
  transition:background .14s ease, color .14s ease, box-shadow .14s ease;
}
.leads-mode-opt svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2; }
.leads-mode-opt:hover{ color:var(--text-secondary); }
.leads-mode-opt.is-active{ color:var(--text-primary); background:var(--surface-hover); box-shadow:inset 0 0 0 1px var(--line-strong); }
.leads-mode-opt[data-mode="construction"].is-active{ color:#F0A83E; }
.leads-mode-opt[data-mode="live"].is-active{ color:var(--live-green); }
.leads-mode-dot{
  width:7px; height:7px; border-radius:50%; background:currentColor; flex:0 0 auto;
}
.leads-mode-opt[data-mode="live"].is-active .leads-mode-dot{
  box-shadow:0 0 6px var(--live-green), 0 0 12px rgba(57,255,136,0.45);
  animation:livePulse 1.6s ease-in-out infinite;
}

/* "Demo data" chip next to the count when Construction Mode is on — a calm
   amber pill, deliberately not an error red. */
.leads-demo-badge{
  display:inline-flex; align-items:center; gap:5px; flex:0 0 auto;
  font-size:10px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase;
  padding:3px 8px 3px 6px; border-radius:99px;
  color:#F0A83E; background:color-mix(in srgb, #F0A83E 15%, transparent);
  border:1px solid color-mix(in srgb, #F0A83E 32%, transparent);
}
.leads-demo-badge[hidden]{ display:none; }
.leads-demo-badge svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2; }
.leads-btn{
  display:inline-flex; align-items:center; justify-content:center; gap:7px; white-space:nowrap; cursor:pointer;
  padding:9px 15px; border-radius:10px; border:1px solid transparent; font:inherit; font-size:13px; font-weight:700;
  transition:transform .16s cubic-bezier(.22,1,.36,1), box-shadow .16s ease, background .16s ease, border-color .16s ease, color .16s ease;
}
.leads-btn svg{ width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:2; }
.leads-btn-primary{ background:var(--brand-gradient); color:#0A0A16; box-shadow:0 5px 16px -6px var(--brand-glow); }
.leads-btn-primary:hover{ transform:translateY(-1px); box-shadow:0 8px 22px -6px var(--brand-glow); }
.leads-btn-ghost{ background:var(--surface-2); border-color:var(--line-strong); color:var(--text-primary); }
.leads-btn-ghost:hover{ background:var(--surface-hover); border-color:var(--violet-dim); }

.leads-toolbar-filters{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.leads-toolbar-controls{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; width:100%; }
#leadsColBtn{ margin-left:auto; }
.leads-control span{ display:inline; }
.leads-menu-wrap{ position:relative; }
.leads-control{
  display:inline-flex; align-items:center; gap:7px; cursor:pointer; white-space:nowrap; font:inherit;
  padding:8px 11px; border-radius:10px; font-size:12.5px; font-weight:600; color:var(--text-secondary);
  background:var(--surface-1); border:1px solid var(--line-strong); transition:color .14s ease, border-color .14s ease;
}
/* QC P4 — the three dropdown triggers hold a stable width so swapping a long
   label ("Attempting Contact") for a short one ("Sold") no longer makes the
   control jump and drag its menu with it. The caret is pinned to the trailing
   edge; the label truncates rather than resizing the button. */
#leadsStatusBtn, #leadsSourceBtn, #leadsSortBtn{ min-width:158px; }
#leadsStatusBtn > span, #leadsSourceBtn > span, #leadsSortBtn > span{
  flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
#leadsStatusBtn .leads-control-caret, #leadsSourceBtn .leads-control-caret,
#leadsSortBtn .leads-control-caret{ margin-left:auto; flex:0 0 auto; }
.leads-control:hover{ color:var(--text-primary); border-color:var(--violet-dim); }
/* QC P3 — an obviously-active filter state for the pipeline owner control */
.leads-control.is-active{
  color:var(--text-primary); border-color:color-mix(in srgb, var(--violet) 55%, var(--line-strong));
  background:color-mix(in srgb, var(--violet) 12%, var(--surface-1));
}
.leads-control.is-active .leads-control-caret{ stroke:var(--violet); }
.leads-control > svg:first-child{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2; flex:0 0 auto; }
.leads-control-caret{ width:13px; height:13px; stroke:var(--text-tertiary); fill:none; stroke-width:2.4; transition:transform .16s ease; }
.leads-control[aria-expanded="true"] .leads-control-caret{ transform:rotate(180deg); }
.leads-reset{
  padding:7px 12px; border-radius:9px; cursor:pointer; font:inherit; font-size:12px; font-weight:700;
  background:none; border:1px solid var(--line-strong); color:var(--text-secondary); transition:color .14s ease, border-color .14s ease;
}
.leads-reset:hover{ color:var(--bad); border-color:var(--bad); }

/* ---- Shared menu (source / sort / inline status / bulk) ----------------- */
/* QC P4 — anchor LEFT (the controls are left-aligned in the toolbar; a
   right:0 anchor on a narrow trigger threw the menu off the left edge). JS
   (toggleLeadMenu) nudges it back in on the rare right-edge case using the
   real rendered rect. */
/* #16/#17 — shared "clear-glass" popover language. Less milky than a heavy
   frost: more transparent, restrained blur + a little saturation for the
   glare-glass look, a crisp hairline edge, and a fine top highlight. Used
   by every true floating selection surface in Orbit (status / source / owner
   / time / date pick menus, toolbar dropdowns). See .glass-select for the
   matching closed-control treatment. */
.leads-menu{
  position:absolute; z-index:70; top:calc(100% + 6px); left:0; min-width:200px;
  max-width:calc(100vw - 24px); padding:5px;
  display:flex; flex-direction:column; gap:1px;
  /* #14 — GLASS FLOAT material */
  background:var(--glass-float-glare), var(--glass-float-bg);
  border:1px solid var(--glass-float-edge); border-radius:12px;
  box-shadow:var(--glass-float-shadow);
  -webkit-backdrop-filter:blur(var(--glass-float-blur)) saturate(var(--glass-float-sat));
  backdrop-filter:blur(var(--glass-float-blur)) saturate(var(--glass-float-sat));
  animation:profileMenuIn .13s ease;
}
.leads-menu-item{
  display:flex; align-items:center; gap:9px; width:100%; text-align:left; cursor:pointer; font:inherit;
  padding:8px 10px; border:none; border-radius:8px; background:none; font-size:12.5px; font-weight:600; color:var(--text-primary);
  transition:background .12s ease, color .12s ease;
}
.leads-menu-item:hover{ background:color-mix(in srgb, var(--violet) 16%, transparent); }
.leads-menu-item .leads-menu-dot{ width:8px; height:8px; border-radius:50%; background:var(--chip-color, var(--text-tertiary)); flex:0 0 auto; }
.leads-menu-item .leads-menu-check{ margin-left:auto; width:14px; height:14px; stroke:var(--violet); fill:none; stroke-width:2.6; opacity:0; }
.leads-menu-item.is-selected{ color:var(--violet); }
.leads-menu-item.is-selected .leads-menu-check{ opacity:1; }

/* ---- Panel + table ---------------------------------------------------------- */
.leads-panel{ padding:0; overflow:hidden; position:relative; display:flex; flex-direction:column; }
@media (min-width:1025px){
  /* The list pane fills the viewport; the table body scrolls under a sticky
     header and the footer pins to the bottom. margin-bottom cancels .main's
     trailing padding-bottom (60px) for this view only, so there's no dead
     scroll region past the panel. */
  /* height is set in JS (layoutLeadsPanes) so the table card bottom kisses
     the viewport regardless of viewport height; min-height is a fallback. */
  #leadsListPane{ display:flex; flex-direction:column; min-height:calc(100dvh - 120px); margin-bottom:-60px; }
  .leads-panel{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
  .leads-table{ flex:1 1 auto; min-height:0; overflow-y:auto; overflow-x:auto; }
  .leads-foot{ margin-top:auto; flex:0 0 auto; }
}
.leads-table{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
.leads-thead, .lead-row{
  display:grid;
  grid-template-columns:var(--lead-cols, 34px 220px 208px 168px 150px 168px 184px);
  gap:0; align-items:center; padding:0 4px 0 20px;
  min-width:100%; width:max-content;
}
/* §3 — frosted sticky header. Dark = convincing glass; light gets its own. */
.leads-thead{
  position:sticky; top:0; z-index:8; height:42px;
  font-size:10.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-secondary);
  background:color-mix(in srgb, var(--surface-1) 74%, transparent);
  -webkit-backdrop-filter:blur(18px) saturate(1.4); backdrop-filter:blur(18px) saturate(1.4);
  border-bottom:1px solid color-mix(in srgb, var(--cyan) 22%, var(--line-strong));
  box-shadow:0 1px 0 rgba(255,255,255,0.04), 0 8px 18px -14px rgba(0,0,0,0.5);
}
[data-theme="light"] .leads-thead{
  background:color-mix(in srgb, #fff 78%, transparent);
  -webkit-backdrop-filter:blur(16px) saturate(1.25); backdrop-filter:blur(16px) saturate(1.25);
  border-bottom-color:color-mix(in srgb, var(--violet) 24%, var(--line-strong));
  box-shadow:0 1px 0 rgba(255,255,255,0.6), 0 10px 20px -16px rgba(28,27,64,0.28);
}
.leads-th{
  position:relative; min-width:0; height:100%;
  display:flex; align-items:center; justify-content:center; text-align:center;   /* §2 — HEADER centered */
  padding:0 14px;
}
.leads-th.leads-th-check{ padding:0; justify-content:flex-start; }
.leads-th-lbl{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.leads-th-sort{ cursor:pointer; user-select:none; transition:color .12s ease; }
.leads-th-sort:hover{ color:var(--text-primary); }
.leads-th.is-sorted .leads-th-lbl{ color:var(--text-primary); }
.leads-th-caret{
  position:absolute; right:5px; top:50%; transform:translateY(-50%);
  width:11px; height:11px; stroke:var(--violet); fill:none; stroke-width:2.6;
}
.leads-th-caret.is-desc{ transform:translateY(-50%) rotate(180deg); }

/* §1 — the divider BETWEEN columns IS the resize affordance. A thin
   cyan→violet energy line on the true boundary, with a wide invisible
   hit target and clear hover / active-drag illumination.
   Refinement Pass Part 2 — HEADER separators are DASHED (they read as
   adjustable column handles); BODY separators are CONTINUOUS solid lines
   running the full cell height so consecutive rows connect into one
   unbroken vertical rule down the data. Same subtle cyan→violet colour. */
.leads-th:not(.is-last):not(.leads-th-check)::after{
  content:""; position:absolute; right:0; top:16%; bottom:16%; width:1.5px; border-radius:2px;
  background:repeating-linear-gradient(180deg,
    color-mix(in srgb, var(--cyan) 52%, transparent) 0 3px,
    transparent 3px 7px);
  transition:opacity .14s ease, box-shadow .14s ease, width .14s ease;
}
.lead-cell:not(.lead-cell-last):not(.lead-cell-check)::after{
  content:""; position:absolute; right:0; top:0; bottom:0; width:1px;
  background:linear-gradient(180deg, color-mix(in srgb, var(--cyan) 34%, transparent),
    color-mix(in srgb, var(--violet) 36%, transparent));
  transition:background .14s ease;
}
/* header hover — keep the DASH pattern, just intensify it */
.leads-thead:hover .leads-th::after{
  background:repeating-linear-gradient(180deg, var(--cyan) 0 3px, transparent 3px 7px);
}
.lead-row:hover .lead-cell::after{ background:linear-gradient(180deg, color-mix(in srgb,var(--cyan) 55%,transparent), color-mix(in srgb,var(--violet) 55%,transparent)); }
[data-theme="light"] .leads-th::after{
  background:repeating-linear-gradient(180deg,
    color-mix(in srgb, var(--violet) 46%, transparent) 0 3px, transparent 3px 7px);
}
[data-theme="light"] .lead-cell::after{
  background:linear-gradient(180deg, color-mix(in srgb, var(--violet) 30%, transparent),
    color-mix(in srgb, var(--cyan) 28%, transparent));
}
.leads-col-resize{
  position:absolute; top:0; right:-9px; width:18px; height:100%; cursor:col-resize;
  z-index:9; touch-action:none;
}
.leads-th.is-resize-hot::after{
  width:3px; background:linear-gradient(180deg, var(--cyan), var(--violet));
  box-shadow:0 0 12px color-mix(in srgb, var(--cyan) 80%, transparent);
}
[data-theme="light"] .leads-th.is-resize-hot::after{ box-shadow:0 0 12px color-mix(in srgb, var(--violet) 55%, transparent); }
body.is-col-resizing{ cursor:col-resize; user-select:none; }
body.is-col-resizing .lead-row{ transition:none; }

.leads-tbody{ display:flex; flex-direction:column; width:max-content; min-width:100%; }
.lead-row{
  min-height:52px; cursor:pointer; position:relative;
  border-bottom:1px solid var(--line); transition:background .12s ease;
  /* Refinement Pass Part 2 — cells stretch to full row height so the body
     column dividers (.lead-cell::after) run edge to edge and connect
     row-to-row into one continuous vertical rule (overrides align-items:
     center from the shared .leads-thead/.lead-row rule above; the header
     keeps center — its cells set their own height:100%). */
  align-items:stretch;
}
.lead-row:last-child{ border-bottom:none; }
.lead-row:hover{ background:var(--surface-hover); }
.lead-row.is-selected{ background:color-mix(in srgb, var(--violet) 9%, transparent); }
.lead-row.is-open{ background:color-mix(in srgb, var(--violet) 12%, transparent); box-shadow:inset 3px 0 0 var(--violet); }

.lead-cell{ position:relative; min-width:0; font-size:12.5px; color:var(--text-secondary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; padding:0 14px; text-align:left; display:flex; align-items:center; }
/* the one multi-line cell (activity: "what" over "when") stacks its rows */
.lead-cell:has(.lead-activity-what){ flex-direction:column; align-items:flex-start; justify-content:center; }
.lead-cell-check{ overflow:visible; display:flex; align-items:center; padding:0; }
.lead-cell-status{ overflow:visible; }
.lead-check{
  appearance:none; -webkit-appearance:none; margin:0; flex:0 0 auto; cursor:pointer;
  width:16px; height:16px; border-radius:5px; border:1.5px solid var(--line-strong); background:var(--input-bg);
  display:inline-flex; align-items:center; justify-content:center; transition:background .12s ease, border-color .12s ease;
}
.lead-check:hover{ border-color:var(--violet-dim); }
.lead-check:checked{ background:var(--violet); border-color:var(--violet); }
.lead-check:checked::after{
  content:""; width:4px; height:8px; margin-top:-1px;
  border:solid #0A0A16; border-width:0 2px 2px 0; transform:rotate(45deg);
}
.lead-name{ font-size:13px; font-weight:700; color:var(--text-primary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-name:hover{ text-decoration:underline; text-underline-offset:2px; }

.lead-source-chip{
  display:inline-flex; align-items:center; justify-content:center; gap:5px;
  min-width:60px; max-width:150px;
  font-size:11.5px; font-weight:600; color:var(--text-primary);
  padding:3px 10px 3px 8px; border-radius:99px;
  background:color-mix(in srgb, var(--chip-color, var(--violet)) 15%, transparent);
}
.lead-source-chip svg{ width:11px; height:11px; stroke:var(--chip-color, var(--violet)); fill:none; stroke-width:2; flex:0 0 auto; }
.lead-source-chip span{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-source-chip .lead-source-acc{ width:10px; height:10px; opacity:0.75; }
/* #15 — editable source chip in the Contacts list: same click-to-pick UX
   language as the status badge. */
.lead-source-chip.is-editable{ font:inherit; font-size:11.5px; font-weight:600; border:none; cursor:pointer; padding-right:5px; transition:background .12s ease; }
.lead-source-chip.is-editable:hover{ background:color-mix(in srgb, var(--chip-color, var(--violet)) 26%, transparent); }
.lead-source-chip.is-editable:focus-visible{ outline:2px solid var(--violet); outline-offset:2px; }
.lead-source-caret{ width:11px !important; height:11px !important; stroke:currentColor !important; opacity:0.5; flex:0 0 auto; margin-left:-1px; }

.lead-status{ position:relative; display:flex; align-items:center; min-width:0; }
.lead-status-badge{
  display:inline-flex; align-items:center; justify-content:center; gap:6px; cursor:pointer; font:inherit;
  min-width:64px; max-width:180px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  font-size:11px; font-weight:700; letter-spacing:0.01em; color:var(--status-color, var(--text-primary));
  padding:4px 10px; border-radius:99px;
  background:color-mix(in srgb, var(--status-color, var(--violet)) 14%, transparent);
  border:1px solid color-mix(in srgb, var(--status-color, var(--violet)) 30%, transparent);
  transition:filter .12s ease;
}
.lead-status-badge:hover{ filter:brightness(1.12); }
.lead-status-badge > span{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-status-badge .lead-status-caret{ width:9px; height:9px; stroke:currentColor; fill:none; stroke-width:3; opacity:0.7; }

.lead-activity-what{ font-size:12px; color:var(--text-secondary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-activity-when{ font-size:10.5px; color:var(--text-tertiary); font-family:'JetBrains Mono', monospace; margin-top:1px; }

.lead-row-actions{ display:flex; align-items:center; justify-content:flex-end; }
.lead-quickbtn{
  width:28px; height:28px; border-radius:8px; cursor:pointer; opacity:0;
  display:flex; align-items:center; justify-content:center;
  background:none; border:1px solid transparent; color:var(--text-tertiary);
  transition:opacity .12s ease, background .12s ease, color .12s ease, border-color .12s ease;
}
.lead-row:hover .lead-quickbtn{ opacity:1; }
.lead-quickbtn:focus-visible{ opacity:1; }
.lead-quickbtn:hover{ background:var(--surface-2); color:var(--violet); border-color:var(--line-strong); }
.lead-quickbtn svg{ width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:2; }
@media (hover:none){ .lead-quickbtn{ opacity:1; } }

/* Inline status menu — fixed-positioned in JS (from the badge's rect) and
   parented to <body> so a scrolling table / drawer never clips it. */
.lead-status-menu{
  position:fixed; z-index:240; min-width:154px; padding:4px;
  display:flex; flex-direction:column; gap:1px;
  /* #14 — GLASS FLOAT material (shared with .leads-menu) */
  background:var(--glass-float-glare), var(--glass-float-bg);
  border:1px solid var(--glass-float-edge); border-radius:10px;
  box-shadow:var(--glass-float-shadow);
  -webkit-backdrop-filter:blur(var(--glass-float-blur)) saturate(var(--glass-float-sat));
  backdrop-filter:blur(var(--glass-float-blur)) saturate(var(--glass-float-sat));
  animation:profileMenuIn .12s ease;
}
.lead-status-opt{
  display:flex; align-items:center; gap:8px; width:100%; text-align:left; cursor:pointer; font:inherit;
  padding:7px 9px; border:none; border-radius:7px; background:none; font-size:12px; font-weight:600; color:var(--text-primary);
}
.lead-status-opt:hover{ background:color-mix(in srgb, var(--violet) 16%, transparent); }
.lead-status-opt .leads-menu-dot{ width:8px; height:8px; border-radius:50%; }

/* ---- Foot / pagination ---------------------------------------------------- */
.leads-foot{
  display:flex; align-items:center; justify-content:space-between; gap:12px; flex:0 0 auto;
  padding:11px 20px; border-top:1px solid var(--line);
}
.leads-foot-range{ font-size:11.5px; color:var(--text-tertiary); font-family:'JetBrains Mono', monospace; }
.leads-foot-pager{ display:flex; align-items:center; gap:4px; }
.leads-pagebtn{
  min-width:30px; height:30px; padding:0 9px; border-radius:8px; cursor:pointer; font:inherit; font-size:12px; font-weight:700;
  background:none; border:1px solid var(--line-strong); color:var(--text-secondary);
  transition:color .12s ease, border-color .12s ease, background .12s ease;
}
.leads-pagebtn:hover:not(:disabled){ color:var(--text-primary); border-color:var(--violet-dim); }
.leads-pagebtn.is-current{ background:var(--surface-hover); color:var(--text-primary); }
.leads-pagebtn:disabled{ opacity:0.4; cursor:default; }
.leads-pagebtn svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.4; vertical-align:middle; }

/* ---- Selection bar ------------------------------------------------------- */
.leads-selectbar{
  position:relative; display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  padding:9px 20px; font-size:12.5px; font-weight:700; color:var(--text-primary);
  background:color-mix(in srgb, var(--violet) 13%, var(--surface-1)); border-bottom:1px solid var(--line-strong);
}
.leads-selectbar-actions{ display:flex; gap:8px; }
.leads-selectbar-btn{
  padding:5px 11px; border-radius:8px; cursor:pointer; font:inherit; font-size:12px; font-weight:700;
  background:var(--surface-1); border:1px solid var(--line-strong); color:var(--text-primary);
}
.leads-selectbar-btn:hover{ border-color:var(--violet-dim); }
.leads-menu-bulk{ left:20px; right:auto; top:calc(100% + 4px); }

/* ---- Empty / loading / error states ------------------------------------- */
.leads-state{
  display:flex; flex-direction:column; align-items:center; text-align:center; gap:9px;
  padding:56px 32px; margin:auto 0;
}
.leads-state-icon{
  width:52px; height:52px; border-radius:15px; display:flex; align-items:center; justify-content:center; margin-bottom:4px;
  background:var(--surface-2); border:1px solid var(--line);
}
.leads-state-icon svg{ width:22px; height:22px; stroke:var(--violet); fill:none; stroke-width:1.9; }
.leads-state-icon-bad svg{ stroke:var(--bad); }
.leads-state-title{ font-size:17px; font-weight:800; letter-spacing:-0.01em; color:var(--text-primary); }
.leads-state-desc{ font-size:13px; color:var(--text-secondary); line-height:1.6; max-width:430px; }
.leads-state-cta{ width:auto; margin-top:8px; }
.leads-state-spinner{
  width:26px; height:26px; border-radius:50%;
  border:2.5px solid var(--line-strong); border-top-color:var(--violet); animation:leadSpin .8s linear infinite;
}
@keyframes leadSpin{ to{ transform:rotate(360deg); } }

/* ---- Quick View drawer -------------------------------------------------- */
/* Modal-UX pass — Opportunity and Contact Quick View are CENTERED FROSTED-
   GLASS modals, not right-side drawers. Same #leadDrawer / #leadOppDrawer
   nodes and render functions; only the container presentation changed. The
   scrim blurs + darkens the background so table text underneath can't
   compete; the card itself is ~90% opaque + heavily blurred so foreground
   hierarchy stays crisp. */
/* #18 — the SCRIM does the foreground/background separation so the panel
   itself can stay properly transparent. Neutral (no navy), a touch stronger
   + more blur now the panel is closer to FLOAT. */
.lead-drawer-scrim{
  position:fixed; inset:0; z-index:200; background:rgba(8,8,10,0.70);
  -webkit-backdrop-filter:blur(11px) saturate(0.88); backdrop-filter:blur(11px) saturate(0.88);
  opacity:0; pointer-events:none; transition:opacity .22s ease;
}
.lead-drawer-scrim.is-open{ opacity:1; pointer-events:auto; }
[data-theme="light"] .lead-drawer-scrim{ background:rgba(22,22,26,0.42); }
/* QC#9/#10 — dark-mode readability for Contact + Opportunity Quick View and
   the Full Contact Record. The approved frosted-glass material stays; we only
   lift the TEXT tokens WITHIN these CRM surfaces so labels and values are
   comfortably legible (older-eyes friendly) without flattening the hierarchy:
   primary values stay near-white, important labels move up to a clear
   secondary, and genuinely tertiary metadata is subdued but no longer dim.
   Scoped to .lead-drawer / #leadRecordPane — the rest of the app is untouched. */
:root:not([data-theme="light"]) .lead-drawer,
:root:not([data-theme="light"]) #leadRecordPane{
  --text-secondary:#B4BFD3;
  --text-tertiary:#8A93A9;
}
:root:not([data-theme="light"]) .lead-drawer .lf-v,
:root:not([data-theme="light"]) #leadRecordPane .lf-v{ color:#F7F8FC; }
:root:not([data-theme="light"]) .lead-drawer .lf-k,
:root:not([data-theme="light"]) #leadRecordPane .lf-k{ color:#BAC5D8; }
:root:not([data-theme="light"]) .lead-drawer .lead-section-title,
:root:not([data-theme="light"]) #leadRecordPane .lead-section-title{ color:#C6D0E1; }
.lead-drawer{
  position:fixed; top:50%; left:50%; z-index:201;
  width:min(528px, calc(100vw - 40px));
  max-height:min(676px, calc(100vh - 56px));
  display:flex; flex-direction:column; overflow:hidden;
  border-radius:22px;
  /* #14–#18 — GLASS PANEL material: NEUTRAL smoked / pearl glass, no navy /
     blue / lavender cast, no coloured floor glow. Materially close to FLOAT
     (low surface alpha) — the scrim behind it does the separation, not
     opacity. Same glass family, just a larger pane. */
  background:var(--glass-panel-glare), var(--glass-panel-bg);
  -webkit-backdrop-filter:blur(var(--glass-panel-blur)) saturate(var(--glass-panel-sat));
  backdrop-filter:blur(var(--glass-panel-blur)) saturate(var(--glass-panel-sat));
  /* #17 — ONE clean perimeter: a single hairline border + a single inset
     top highlight (both from the token) + a single soft drop shadow. No
     outer 1px ring, no blend-mode glare streak, no doubled edge. */
  border:1px solid var(--glass-panel-edge);
  box-shadow:var(--glass-panel-shadow);
  opacity:0; visibility:hidden;
  transform:translate(-50%, -46%) scale(0.97);
  transition:opacity .2s ease, transform .24s cubic-bezier(.32,.72,0,1), visibility 0s linear .24s;
}
.lead-drawer.is-open{
  opacity:1; visibility:visible;
  transform:translate(-50%, -50%) scale(1);
  transition:opacity .2s ease, transform .28s cubic-bezier(.32,.72,0,1);
}
/* #17 — a single, faint corner-to-corner specular (no mix-blend-mode, which
   was producing the "cheap"/dirty look). Sits above the tint, below content. */
.lead-drawer::before{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none; border-radius:inherit;
  background:linear-gradient(122deg, rgba(255,255,255,0.10) 0%, rgba(255,255,255,0) 20%, rgba(255,255,255,0) 82%, rgba(255,255,255,0.06) 100%);
}
[data-theme="light"] .lead-drawer::before{
  background:linear-gradient(122deg, rgba(255,255,255,0.5) 0%, rgba(255,255,255,0) 22%, rgba(255,255,255,0) 80%, rgba(255,255,255,0.28) 100%);
}
.lead-drawer > *{ position:relative; z-index:1; }
@media (prefers-reduced-motion:reduce){
  .lead-drawer{ transition:opacity .12s ease; transform:translate(-50%,-50%); }
  .lead-drawer.is-open{ transition:opacity .12s ease; }
}
/* background scroll lock while a centered CRM modal is open (class is
   toggled from live state, so it can't stick) */
html.is-crm-modal-open, html.is-crm-modal-open body{ overflow:hidden; }
/* only the body scrolls inside the modal — every other band stays put */
.lead-drawer > *:not(.lead-drawer-body){ flex:0 0 auto; }
.lead-drawer .lead-drawer-body{ flex:1 1 auto; min-height:0; }
.lead-drawer-head{ display:flex; align-items:flex-start; gap:12px; padding:13px 14px 12px; border-bottom:1px solid var(--line); }
.lead-avatar{
  flex:0 0 auto; display:flex; align-items:center; justify-content:center;
  width:44px; height:44px; border-radius:13px; background:var(--brand-gradient); color:#0A0A16; font-weight:800; font-size:15px;
}
/* #21 — identity elements navigate to the Full Contact Record */
/* co-class .lead-avatar supplies the gradient/size/weight; just reset the
   <button> UA font-family and chrome and add the interactive affordance */
.lead-avatar-nav{ font-family:inherit; padding:0; border:1px solid transparent; cursor:pointer; transition:filter .12s ease, transform .1s ease, box-shadow .12s ease; }
.lead-avatar-nav:hover{ filter:brightness(1.06); transform:translateY(-1px); box-shadow:0 6px 16px -6px color-mix(in srgb, var(--violet) 60%, transparent); }
.lead-avatar-nav:focus-visible{ outline:2px solid var(--violet); outline-offset:2px; }
/* inherits font-size/color/ellipsis from its own .lead-drawer-sub class */
.lead-drawer-sub-nav{ display:block; max-width:100%; text-align:left; background:none; border:none; padding:0; margin-top:1px; font-family:inherit; cursor:pointer; }
.lead-drawer-sub-nav:hover{ color:var(--cyan); text-decoration:underline; text-underline-offset:2px; }
.lead-drawer-sub-nav:focus-visible{ outline:2px solid var(--violet); outline-offset:2px; border-radius:4px; }
.lead-drawer-name[data-open-record-newtab]{ cursor:pointer; }
.lead-drawer-name[data-open-record-newtab]:hover{ color:var(--cyan); text-decoration:underline; text-underline-offset:3px; }
.lead-drawer-id{ flex:1 1 auto; min-width:0; padding-top:1px; }
/* #2/#3 — Email / Call / Text as compact icon actions inside the identity header */
.lead-drawer-head.has-headacts{ flex-wrap:wrap; align-items:center; row-gap:10px; }
.lead-drawer-head-actions{ display:inline-flex; gap:5px; flex:0 0 auto; align-self:center; margin-left:auto; }
.lead-head-act{
  width:34px; height:34px; flex:0 0 auto; display:inline-flex; align-items:center; justify-content:center;
  border-radius:9px; text-decoration:none; cursor:pointer;
  background:color-mix(in srgb, var(--violet) 9%, var(--surface-2));
  border:1px solid color-mix(in srgb, var(--violet) 20%, var(--line-strong));
  color:var(--violet); transition:background .12s ease, border-color .12s ease, transform .1s ease;
}
.lead-head-act:hover{ background:color-mix(in srgb, var(--violet) 18%, var(--surface-2)); border-color:var(--violet-dim); transform:translateY(-1px); }
.lead-head-act:active{ transform:translateY(0) scale(0.95); }
.lead-head-act svg{ width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:2; }
.lead-head-act.is-off{ background:var(--surface-2); border-color:var(--line); color:var(--text-tertiary); opacity:0.5; cursor:default; pointer-events:none; }
/* the whole head-actions group wraps below identity on a narrow modal */
@media (max-width:480px){
  .lead-drawer-head.has-headacts .lead-drawer-head-actions{ order:5; flex-basis:100%; margin-left:0; }
  .lead-drawer-head.has-headacts .lead-head-act{ flex:1 1 0; }
}
.lead-drawer-name{ font-size:16px; font-weight:800; letter-spacing:-0.01em; color:var(--text-primary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-drawer-sub{ font-size:12.5px; color:var(--text-secondary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-drawer-close{
  flex:0 0 auto; width:30px; height:30px; border-radius:8px; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); border:1px solid var(--line); color:var(--text-secondary);
}
.lead-drawer-close:hover{ color:var(--text-primary); background:var(--surface-hover); }
.lead-drawer-close svg{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2.4; }
.lead-drawer-body{ flex:1 1 auto; overflow-y:auto; padding:12px 14px 16px; }
/* Quick View / Opportunity compactness — scoped to .lead-drawer only, so the
   Full Contact Record's shared .lf-row/.lead-section-* components (left lane)
   are untouched. ~12-15% tighter rhythm than the base field-grid rules. */
.lead-drawer .lf-row{ min-height:32px; padding:7px 0; }
.lead-drawer .lead-section-title{ margin:14px 0 8px; }
.lead-drawer .lead-section-title:first-child{ margin-top:2px; }
.lead-drawer .lead-section-head{ margin:16px 0 8px; }
.lead-drawer .lead-tl-item{ padding-bottom:11px; }
.lead-drawer .lead-notes-mod{ margin:14px 0 6px; }
/* §5 — phone / email quick-reference row */
.lead-drawer-contact{ display:flex; flex-direction:column; gap:2px; padding:10px 16px 4px; }
.lead-drawer-cinfo{
  display:flex; align-items:center; gap:9px; text-decoration:none; border-radius:8px;
  padding:6px 8px; margin:0 -8px; font-size:13px; font-weight:600; color:var(--text-primary);
  transition:background .12s ease, color .12s ease;
}
.lead-drawer-cinfo:hover{ background:var(--surface-hover); color:var(--cyan); }
.lead-drawer-cinfo svg{ flex:0 0 auto; width:14px; height:14px; stroke:var(--text-tertiary); fill:none; stroke-width:2; }

/* ---- Opportunity drawer (Pipeline card click) ---------------------------- */
/* #2 (Stage 3B) — sized to the same language as Contact Quick View's
   .lead-avatar (44px / radius 13) so the two drawers' headers read as one
   component family; the green tint stays as the deliberate "this is a deal,
   not a person" cue. */
.lead-opp-badge{
  flex:0 0 auto; width:44px; height:44px; border-radius:13px; display:flex; align-items:center; justify-content:center;
  background:color-mix(in srgb, var(--good) 16%, var(--surface-2)); border:1px solid color-mix(in srgb, var(--good) 30%, var(--line-strong));
}
.lead-opp-badge svg{ width:19px; height:19px; stroke:var(--good); fill:none; stroke-width:2; }
.lead-opp-stagebar{
  display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap;
  padding:9px 14px; border-bottom:1px solid var(--line);
  background:color-mix(in srgb, var(--surface-1) 42%, transparent);
}
.lead-opp-stagebar-l{ display:flex; align-items:center; gap:8px; min-width:0; }
.lead-opp-k{ font-size:10px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary); }
.lead-opp-statuspills{ display:inline-flex; gap:3px; padding:3px; border-radius:9px; background:var(--surface-2); border:1px solid var(--line-strong); }
.lead-opp-statuspill{
  font:inherit; font-size:11px; font-weight:700; cursor:pointer; padding:4px 10px; border-radius:6px;
  background:none; border:none; color:var(--text-tertiary); transition:color .12s ease, background .12s ease;
}
.lead-opp-statuspill:hover{ color:var(--text-secondary); }
.lead-opp-statuspill.is-active{ color:var(--text-primary); background:var(--surface-1); box-shadow:inset 0 0 0 1px var(--line-strong); }
.lead-opp-statuspill.is-active.is-won{ color:var(--good); }
.lead-opp-statuspill.is-active.is-lost{ color:var(--text-secondary); }
.lead-opp-statuspill.is-active.is-open{ color:var(--cyan); }
.lead-opp-nexttask{
  display:flex; align-items:flex-start; gap:8px; font-size:12.5px; color:var(--text-secondary); line-height:1.45;
  padding:9px 11px; margin-bottom:12px; border-radius:9px;
  background:var(--surface-2); border:1px solid var(--line);
}
.lead-opp-nexttask svg{ flex:0 0 auto; width:14px; height:14px; margin-top:1px; stroke:var(--text-tertiary); fill:none; stroke-width:2; }
.lead-opp-nexttask svg.is-overdue{ stroke:var(--bad); }
.lead-opp-nexttask b{ color:var(--text-primary); font-weight:700; }

/* #9 — the contact identity line in the Opportunity head is a nav point */
.lead-opp-contactlink{
  display:inline-flex; align-items:center; gap:6px; max-width:100%; cursor:pointer; font:inherit;
  margin-top:3px; padding:3px 8px 3px 3px; border-radius:99px; border:1px solid transparent; background:none;
  font-size:12.5px; color:var(--text-secondary); transition:background .12s ease, color .12s ease, border-color .12s ease;
}
.lead-opp-contactlink:hover{ color:var(--text-primary); background:var(--surface-hover); border-color:var(--line-strong); }
.lead-opp-contactlink > span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.lead-opp-contact-ini{ width:18px !important; height:18px !important; font-size:8px !important; }
.lead-opp-contactlink-chev{ width:12px; height:12px; flex:0 0 auto; stroke:var(--text-tertiary); fill:none; stroke-width:2.4; }
/* #12 (Stage 3B) — ROOT CAUSE of the "broken play/+ button" report, FOUND:
   this button's trailing chevron <svg viewBox="0 0 24 24"> has always had no
   width/height attribute AND no CSS sizing it at all (unlike every other
   icon svg in this file, which is sized via its own dedicated class — e.g.
   .lead-section-link svg two rules below). An svg with no intrinsic size
   and nothing constraining it falls back to the browser's ~300x150px
   replaced-element default box; with no fill/stroke set either, SVG's
   default fill:black paints that open chevron path as a solid dark
   triangle — a large, malformed-looking shape sitting right in the
   Opportunity body's "Contact" row, near the identity area above it. This
   is a real, confirmed, pre-existing CSS gap, not a hover/tooltip issue —
   sizing it here (matching .lead-opp-contactlink-chev's language) is the
   actual fix. */
.lead-opp-inlinelink{
  display:inline-flex; align-items:center; gap:4px;
  font:inherit; font-size:inherit; color:var(--violet); background:none; border:none; padding:0; cursor:pointer; text-align:left;
}
.lead-opp-inlinelink:hover{ text-decoration:underline; }
.lead-opp-inlinelink svg{ width:12px; height:12px; flex:0 0 auto; stroke:currentColor; fill:none; stroke-width:2.4; }

/* #8 — Deal note module: a proper contained note surface, distinct from Contact Notes */
.lead-dealnote{
  border:1px solid var(--line); border-radius:12px; overflow:hidden; margin-bottom:12px;
  background:color-mix(in srgb, var(--good) 4%, var(--surface-1));
}
.lead-dealnote-hd{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  padding:9px 12px; border-bottom:1px solid var(--line);
  background:color-mix(in srgb, var(--good) 7%, transparent);
}
.lead-dealnote-t{ font-size:10.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:color-mix(in srgb, var(--good) 70%, var(--text-secondary)); }
.lead-dealnote-edit{
  font:inherit; font-size:11px; font-weight:700; cursor:pointer; color:var(--good);
  background:color-mix(in srgb, var(--good) 12%, transparent); border:1px solid color-mix(in srgb, var(--good) 28%, transparent);
  padding:4px 10px; border-radius:7px;
}
.lead-dealnote-edit:hover{ background:color-mix(in srgb, var(--good) 20%, transparent); }
.lead-dealnote-body{ padding:11px 12px; font-size:12.5px; line-height:1.55; color:var(--text-primary); white-space:pre-wrap; word-break:break-word; }
.lead-dealnote-empty{ padding:11px 12px; font-size:12px; color:var(--text-tertiary); line-height:1.5; }
.lead-dealnote-compose{ padding:10px 12px 12px; display:flex; flex-direction:column; gap:8px; border-top:1px solid var(--line); }
.lead-dealnote-input{
  width:100%; resize:vertical; min-height:64px; padding:9px 11px; border-radius:9px; font:inherit; font-size:12.5px; line-height:1.5;
  color:var(--text-primary); background:var(--input-bg); border:1px solid var(--line-strong);
}
.lead-dealnote-input:focus{ outline:none; border-color:var(--good); box-shadow:0 0 0 3px color-mix(in srgb, var(--good) 18%, transparent); }
.lead-dealnote-compose-actions{ display:flex; justify-content:flex-end; gap:8px; }
.lead-dealnote-compose-actions .lead-note-save{ background:var(--good); }

/* deal-status tag on the Pipeline card (only shown when won/lost) */
.pipe-card-dealstatus{
  font-size:9px; font-weight:800; letter-spacing:0.05em; text-transform:uppercase;
  padding:2px 6px; border-radius:99px; border:1px solid transparent;
}
.pipe-card-dealstatus.is-won{ color:var(--good); background:var(--good-dim); border-color:color-mix(in srgb, var(--good) 34%, transparent); }
.pipe-card-dealstatus.is-lost{ color:var(--text-tertiary); background:var(--surface-2); border-color:var(--line-strong); }
.lead-drawer-cinfo:hover svg{ stroke:var(--cyan); }
.lead-drawer-cinfo span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-drawer-cinfo.is-empty{ color:var(--text-tertiary); font-weight:500; cursor:default; }
.lead-drawer-cinfo.is-empty:hover{ background:none; color:var(--text-tertiary); }
/* item 8 — avatar doubles as an "open full record" affordance */
.lead-drawer-avatar-btn{ border:none; padding:0; cursor:pointer; font:inherit; transition:filter .12s ease, transform .1s ease; }
.lead-drawer-avatar-btn:hover{ filter:brightness(1.08); transform:translateY(-1px); }
/* #1 — full-record entry point, demoted just below EMAIL/CALL/TEXT */
/* QC#18 — quick actions row under the Quick View header: Open full record +
   Copy tracked link, sharing one line. */
.lead-drawer-quickacts{ display:flex; gap:7px; margin:0 14px 8px; flex:0 0 auto; }
.lead-drawer-openrec,
.lead-drawer-trackbtn{
  flex:1 1 0; min-width:0;
  display:flex; align-items:center; justify-content:center; gap:6px; cursor:pointer;
  padding:8px 6px; border:1px solid var(--line-strong); border-radius:10px;
  background:var(--surface-2); font:inherit; font-size:11.5px; font-weight:700;
  color:var(--text-secondary); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.lead-drawer-openrec:hover,
.lead-drawer-trackbtn:hover{ background:var(--surface-hover); color:var(--violet); border-color:var(--violet-dim); }
.lead-drawer-openrec svg,
.lead-drawer-trackbtn svg{ width:14px; height:14px; flex:0 0 auto; stroke:currentColor; fill:none; stroke-width:2; }
.lead-drawer-trackbtn.is-copied{ color:var(--good); border-color:color-mix(in srgb, var(--good) 40%, transparent); }
.lead-drawer-trackbtn.is-copied::after{ content:"✓"; }
.lead-drawer-trackbtn[disabled]{ opacity:0.6; cursor:default; }
@media (max-width:420px){ .lead-drawer-quickacts{ flex-wrap:wrap; } }
.lead-drawer-actions{ display:flex; gap:7px; padding:11px 16px; }
.lead-action{
  flex:1 1 0; min-width:0; display:inline-flex; flex-direction:column; align-items:center; gap:4px; cursor:pointer;
  padding:9px 5px; border-radius:10px; text-decoration:none; font:inherit; font-size:11px; font-weight:700;
  background:var(--surface-2); border:1px solid var(--line); color:var(--text-primary); transition:border-color .14s ease, background .14s ease;
}
.lead-action:hover{ border-color:var(--violet-dim); background:var(--surface-hover); }
.lead-action[aria-disabled="true"]{ opacity:0.38; pointer-events:none; }
.lead-action svg{ width:16px; height:16px; stroke:var(--violet); fill:none; stroke-width:2; }

/* ---- Shared field list + section titles + timeline (drawer & record) --- */
.lead-section-title{
  font-size:11px; font-weight:700; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary);
  margin:18px 0 9px;
}
.lead-section-title:first-child{ margin-top:2px; }
.lead-fields{ display:flex; flex-direction:column; }
.lead-field{
  display:grid; grid-template-columns:92px 1fr; gap:10px; align-items:start;
  padding:8px 0; border-bottom:1px solid var(--line);
}
.lead-field:last-child{ border-bottom:none; }
.lead-field-k{ font-size:10.5px; font-weight:700; letter-spacing:0.03em; text-transform:uppercase; color:var(--text-tertiary); padding-top:2px; }
.lead-field-v{ font-size:12.5px; color:var(--text-primary); word-break:break-word; }
.lead-field-v a{ color:var(--cyan); text-decoration:none; }
.lead-field-v a:hover{ text-decoration:underline; }
.lead-field-v .lead-muted{ color:var(--text-tertiary); }

.lead-timeline{ display:flex; flex-direction:column; }
.lead-tl-day{ font-size:10.5px; font-weight:700; letter-spacing:0.05em; text-transform:uppercase; color:var(--text-tertiary); margin:4px 0 9px; }
.lead-tl-day:not(:first-child){ margin-top:12px; }
.lead-tl-item{ display:grid; grid-template-columns:26px 1fr; gap:10px; padding-bottom:13px; position:relative; }
.lead-tl-item::before{ content:""; position:absolute; left:12.25px; top:27px; bottom:-1px; width:1.5px; background:var(--line); }
.lead-tl-item:last-child::before{ display:none; }
.lead-tl-dot{
  width:26px; height:26px; border-radius:8px; display:flex; align-items:center; justify-content:center; flex:0 0 auto;
  background:color-mix(in srgb, var(--tl-color, var(--violet)) 16%, transparent);
}
.lead-tl-dot svg{ width:13px; height:13px; stroke:var(--tl-color, var(--violet)); fill:none; stroke-width:2; }
.lead-tl-body{ min-width:0; padding-top:1px; }
.lead-tl-what{ font-size:12.5px; font-weight:600; color:var(--text-primary); }
.lead-tl-context{ font-size:11.5px; color:var(--text-secondary); margin-top:1px; line-height:1.45; }
.lead-tl-when{ font-size:10.5px; color:var(--text-tertiary); font-family:'JetBrains Mono', monospace; margin-top:3px; }
.lead-tl-empty{ font-size:12px; color:var(--text-tertiary); padding:4px 0 8px; }

/* ---- Email Activity — inline Gmail-style reader ---------------------- */
/* Collapsed row: scannable single line — kicker · subject (primary) ·
   recipient + time · chevron. Stays inside the timeline's own rhythm. */
.lead-tl-emailrow{
  display:flex; flex-direction:column; gap:2px; align-items:stretch;
  width:100%; text-align:left; background:none; border:none; padding:3px 6px 4px 0; cursor:pointer; font:inherit;
  border-radius:7px; transition:background .12s ease;
}
.lead-tl-emailrow:hover{ background:var(--surface-1); }
.lead-tl-emailrow:hover .lead-tl-emailsubj{ color:var(--violet); }
.lead-tl-emailtop{ display:flex; align-items:center; gap:8px; min-width:0; }
.lead-tl-emailkick{
  font-size:10px; font-weight:800; letter-spacing:0.05em; text-transform:uppercase;
  color:var(--tl-color, var(--violet)); flex:0 0 auto;
}
.lead-tl-emailsubj{
  font-size:12.5px; font-weight:700; color:var(--text-primary); flex:1 1 auto; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; transition:color .12s ease;
}
.lead-tl-emailmeta{
  font-size:10.5px; color:var(--text-tertiary); font-family:'JetBrains Mono', monospace;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.lead-tl-emailchev{
  width:13px; height:13px; stroke:var(--text-tertiary); fill:none; stroke-width:2.4; flex:0 0 auto;
  transition:transform .18s ease;
}
.lead-tl-email.is-open .lead-tl-emailchev{ transform:rotate(180deg); }
.lead-tl-email.is-open .lead-tl-emailsubj{ white-space:normal; }

/* Expanded: the message reads like an email document set into the dark
   timeline — a framed light canvas, not a colour-flooded panel. */
.lead-emailview{
  margin:9px 0 4px; border:1px solid var(--line-strong); border-radius:12px; overflow:hidden;
  background:var(--surface-1); box-shadow:0 18px 40px -26px rgba(0,0,0,0.6);
  animation:leadEmailViewIn .16s ease;
}
@keyframes leadEmailViewIn{ from{ opacity:0; transform:translateY(-4px); } to{ opacity:1; transform:none; } }
.lead-emailview-subj{
  font-size:14px; font-weight:800; letter-spacing:-0.01em; color:var(--text-primary);
  padding:13px 16px 10px; line-height:1.35;
}
.lead-emailview-hs{ padding:10px 16px 12px; border-bottom:1px solid var(--line); display:flex; flex-direction:column; gap:4px; background:var(--surface-2); }
.lead-emailview-h{ display:grid; grid-template-columns:46px 1fr; gap:10px; font-size:11.5px; line-height:1.5; }
.lead-emailview-h > span:first-child{ color:var(--text-tertiary); font-weight:700; text-transform:uppercase; letter-spacing:0.03em; font-size:10px; padding-top:1px; }
.lead-emailview-h > span:last-child{ color:var(--text-secondary); word-break:break-word; }
.lead-emailview-addr{ color:var(--text-tertiary); font-weight:500; text-transform:none; letter-spacing:0; }
/* #5 — the reader is a premium DARK-MODE mail surface: the body canvas
   follows the app theme (dark in dark mode, light in light mode). The
   authored SIGNATURE is the one exception — it keeps its own white card,
   because signatures are authored assuming a white background. */
.lead-emailview-doc{ background:var(--surface-1); color:var(--text-primary); padding:16px; }
.lead-emailview-body{ font-family:Arial,Helvetica,sans-serif; font-size:13px; line-height:1.6; white-space:normal; color:var(--text-primary); }
.lead-emailview-body.is-empty{ color:var(--text-tertiary); font-style:italic; }
.lead-emailview-sig{
  margin-top:16px; padding:12px 14px; border-radius:9px;
  background:#fff; border:1px solid #e6e6ee; box-shadow:0 1px 3px rgba(0,0,0,0.28);
  font-family:Arial,Helvetica,sans-serif; font-size:12px; line-height:1.5; color:#1a1a1a;
  overflow-x:auto; overflow-y:hidden;
}
.lead-emailview-sig img{ max-width:100%; height:auto; }
.lead-emailview-sig a{ color:#1a73e8; }
.lead-emailview-sig table{ max-width:none; }
.lead-emailview-note{ font-size:10.5px; color:var(--text-tertiary); padding:8px 16px 10px; background:var(--surface-2); }
[data-theme="light"] .lead-emailview-doc{ background:#fff; }
[data-theme="light"] .lead-emailview-sig{ box-shadow:none; background:#fbfbfd; }

/* #2/#3 — conversation view. The .lead-emailview frame holds a vertical
   stack of messages; each is collapsible, the latest opens expanded. */
.lead-emailthread .lead-emailview-subj{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; padding-bottom:8px; border-bottom:1px solid var(--line); }
.lead-emailthread-count{ font-size:10px; font-weight:800; letter-spacing:0.03em; text-transform:uppercase; color:var(--text-tertiary); }
.lead-emailthread-list{ display:flex; flex-direction:column; }
.lead-emailmsg{ border-bottom:1px solid var(--line); }
.lead-emailmsg:last-child{ border-bottom:none; }
.lead-emailmsg-head{
  display:flex; align-items:center; gap:11px; width:100%; text-align:left; cursor:pointer;
  background:none; border:none; font:inherit; padding:11px 16px; color:var(--text-secondary);
  transition:background .12s ease;
}
.lead-emailmsg-head:hover{ background:var(--surface-hover); }
.lead-emailmsg-dir{
  flex:0 0 auto; align-self:flex-start; margin-top:1px;
  font-size:8.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase;
  border-radius:5px; padding:3px 6px; line-height:1;
}
.lead-emailmsg.is-out .lead-emailmsg-dir{ color:var(--violet); background:color-mix(in srgb, var(--violet) 16%, transparent); }
.lead-emailmsg.is-in .lead-emailmsg-dir{ color:var(--cyan); background:color-mix(in srgb, var(--cyan) 16%, transparent); }
.lead-emailmsg-id{ flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:1px; }
.lead-emailmsg-name{ font-size:12px; font-weight:700; color:var(--text-primary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-emailmsg-addr{ font-size:10.5px; color:var(--text-tertiary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-emailmsg-when{ flex:0 0 auto; align-self:flex-start; margin-top:2px; font-size:10px; color:var(--text-tertiary); font-family:'JetBrains Mono',monospace; }
.lead-emailmsg-body{ display:none; }
.lead-emailmsg.is-expanded .lead-emailmsg-body{ display:block; }
.lead-emailmsg .lead-emailview-hs{ border-bottom:none; padding-top:8px; }
.lead-emailmsg.is-in .lead-emailview-doc{ background:var(--surface-2); }
[data-theme="light"] .lead-emailmsg.is-in .lead-emailview-doc{ background:#f5f7fb; }

/* #1 — follow-up quick chips (create a normal Task) */
.lead-followup{ display:flex; align-items:center; gap:5px; flex-wrap:wrap; margin-top:10px; padding-top:9px; border-top:1px solid var(--line); }
.lead-followup-l{ font-size:9.5px; font-weight:800; letter-spacing:0.05em; text-transform:uppercase; color:var(--text-tertiary); margin-right:2px; }
.lead-followup-chip{
  font:inherit; font-size:10.5px; font-weight:700; color:var(--text-secondary); cursor:pointer;
  background:var(--surface-1); border:1px solid var(--line-strong); border-radius:99px; padding:3px 9px;
  transition:border-color .12s ease, color .12s ease, background .12s ease;
}
.lead-followup-chip:hover{ color:var(--violet); border-color:var(--violet-dim); background:var(--surface-hover); }

/* ---- Full lead record -------------------------------------------------- */
.lead-record-bar{ display:flex; align-items:center; gap:12px; margin-bottom:16px; flex-wrap:wrap; }
/* MANUAL QA item-11 — the header cluster (Call/Email/Note/Appt + bell) now
   floats over the right end of this row; reserve room so the crumb never
   slides under it. */
body.is-lead-record .lead-record-bar{ padding-right:210px; min-height:44px; }
@media (max-width:1180px){ body.is-lead-record .lead-record-bar{ padding-right:180px; } }
@media (max-width:640px){ body.is-lead-record .lead-record-bar{ padding-right:0; padding-top:44px; } }
.lead-record-back{
  display:inline-flex; align-items:center; gap:7px; cursor:pointer; font:inherit; font-size:12.5px; font-weight:700;
  padding:8px 13px; border-radius:9px; background:var(--surface-2); border:1px solid var(--line-strong); color:var(--text-primary);
  transition:border-color .14s ease, background .14s ease;
}
.lead-record-back:hover{ border-color:var(--violet-dim); background:var(--surface-hover); }
.lead-record-back svg{ width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:2; }
.lead-record-crumb{ font-size:12.5px; color:var(--text-tertiary); }
.lead-record-crumb b{ color:var(--text-secondary); font-weight:700; }

/* §9 — Google-Docs-style save status (contact record + quick view) */
.lead-save-status{
  display:inline-flex; align-items:center; gap:6px; flex:0 0 auto;
  font-size:11px; font-weight:600; letter-spacing:0.01em; color:var(--text-tertiary);
  padding:3px 9px 3px 8px; border-radius:99px; border:1px solid transparent;
  transition:color .16s ease, background .16s ease, border-color .16s ease, opacity .16s ease;
}
.lead-save-status[hidden]{ display:none; }
.lead-save-status::before{
  content:""; width:6px; height:6px; border-radius:50%; background:currentColor; flex:0 0 auto;
}
.lead-save-status[data-state="saving"]{ color:var(--text-secondary); }
.lead-save-status[data-state="saving"]::before{ animation:leadSavePulse 1s ease-in-out infinite; }
.lead-save-status[data-state="saved"]{ color:var(--good); background:color-mix(in srgb, var(--good) 10%, transparent); border-color:color-mix(in srgb, var(--good) 26%, transparent); }
.lead-save-status[data-state="session"]{ color:var(--cyan); background:color-mix(in srgb, var(--cyan) 10%, transparent); border-color:color-mix(in srgb, var(--cyan) 26%, transparent); }
/* S-09 — "Saved on this device": genuinely durable-local (Construction Mode
   _leadMut). Same restrained cyan family as the session pill (both are
   "local, not your account") — a distinct wording, not a distinct color. */
.lead-save-status[data-state="local"]{ color:var(--cyan); background:color-mix(in srgb, var(--cyan) 10%, transparent); border-color:color-mix(in srgb, var(--cyan) 26%, transparent); }
.lead-save-status[data-state="error"]{ color:var(--bad); background:color-mix(in srgb, var(--bad) 10%, transparent); border-color:color-mix(in srgb, var(--bad) 30%, transparent); }
@keyframes leadSavePulse{ 0%,100%{ opacity:1; } 50%{ opacity:0.3; } }
@media (prefers-reduced-motion:reduce){ .lead-save-status[data-state="saving"]::before{ animation:none; } }

.lead-record-grid{ display:grid; grid-template-columns:300px minmax(0,1fr) 320px; gap:14px; align-items:start; }
.lead-record-lane{ display:flex; flex-direction:column; gap:14px; min-width:0; }
.lead-record-divider{ display:none; }
.lead-record-card{ background:var(--surface-1); border:1px solid var(--line); border-radius:var(--radius-md); padding:17px; }
.lead-record-card.is-timeline{ padding:17px 17px 8px; }

.lead-idcard-head{
  display:flex; flex-direction:column; align-items:center; text-align:center; gap:7px;
  padding-bottom:14px; margin-bottom:6px; border-bottom:1px solid var(--line);
}
.lead-idcard-avatar{ width:60px; height:60px; border-radius:18px; font-size:21px; }
/* QC P1/P2 — contact avatar photo. .has-photo mirrors the exact technique
   .avatar-badge.has-photo already uses for the logged-in user's own photo
   (background-image fill + hidden initials), just applied to .lead-avatar
   so both real render sites (this idcard avatar + the Quick View drawer's
   .lead-avatar-nav) share one visual treatment. */
.lead-avatar.has-photo{ background-size:cover; background-position:center; color:transparent; }
/* QC P1 (this pass) — the permanent visible upload badge was removed
   (product cut: clutter). "Change photo" lives in the More menu now; this
   wrap only still needs position:relative for its hidden file input. */
.lead-idcard-avatar-wrap{ position:relative; flex:0 0 auto; }
.lead-idcard-name{ font-size:17px; font-weight:800; letter-spacing:-0.01em; color:var(--text-primary); }
.lead-idcard-co{ font-size:12.5px; color:var(--text-secondary); }
.lead-idcard-colink{
  font:inherit; color:var(--violet); font-weight:600; background:none; border:none; padding:0; cursor:pointer;
  border-bottom:1px solid color-mix(in srgb, var(--violet) 35%, transparent); transition:border-color .12s ease, color .12s ease;
}
.lead-idcard-colink:hover{ color:var(--violet); border-bottom-color:var(--violet); }
.lead-idcard-colink:focus-visible{ outline:2px solid var(--violet); outline-offset:2px; border-radius:2px; }
/* #B — the Company field-row value as a Mission Control link (internal staff).
   Sits inside .lf-v, so it inherits that row's type; the affordance is a subtle
   violet underline that firms on hover, matching .lead-idcard-colink. */
.lead-company-colink{
  font:inherit; color:var(--violet); font-weight:600; background:none; border:none; padding:0; cursor:pointer;
  text-align:left; border-bottom:1px solid color-mix(in srgb, var(--violet) 35%, transparent);
  transition:border-color .12s ease, color .12s ease;
}
.lead-company-colink:hover{ color:var(--violet); border-bottom-color:var(--violet); }
.lead-company-colink:focus-visible{ outline:2px solid var(--violet); outline-offset:2px; border-radius:2px; }
.lead-idcard-status{ margin-top:3px; }
/* QC P2 — Full Contact identity centering root cause: .lf-edit (the
   hover-reveal pencil) is opacity:0 at rest but still an in-flow flex child
   with a 20px+5px-gap footprint, so the centered name/status row inside
   .lead-idcard-head was optically ~12px left of true center. Take it out of
   flow here (name + status are the only .lf fields in this head) so only
   the visible text is what gets centered; every other .lf-edit elsewhere is
   unaffected. */
.lead-idcard-head .lf{ position:relative; }
.lead-idcard-head .lf-edit{ position:absolute; top:50%; left:100%; transform:translateY(-50%); margin-left:5px; }
.lead-record-actions{ display:grid; grid-template-columns:repeat(4,1fr); gap:7px; margin:14px 0 2px; }

/* ---- Add / Import sheet ---------------------------------------------------- */
.lead-sheet-scrim{
  position:fixed; inset:0; z-index:210; background:rgba(4,5,10,0.55);
  -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
  opacity:0; pointer-events:none; transition:opacity .18s ease;
}
.lead-sheet-scrim.is-open{ opacity:1; pointer-events:auto; }
.lead-sheet{
  position:fixed; z-index:211; top:50%; left:50%; width:min(452px, 94vw); max-height:88vh; overflow-y:auto;
  background:var(--ink-900); border:1px solid var(--line-strong); border-radius:18px;
  box-shadow:0 44px 96px -32px rgba(0,0,0,0.72);
  transform:translate(-50%, -46%) scale(0.98); opacity:0; pointer-events:none;
  transition:opacity .18s ease, transform .2s cubic-bezier(.22,1,.36,1);
}
.lead-sheet.is-open{ transform:translate(-50%, -50%) scale(1); opacity:1; pointer-events:auto; }
.lead-sheet-head{ display:flex; align-items:center; justify-content:space-between; gap:10px; padding:17px 20px 13px; border-bottom:1px solid var(--line); }
.lead-sheet-title{ font-size:15px; font-weight:800; letter-spacing:-0.01em; color:var(--text-primary); margin-right:auto; }
/* PRE-LIVE BUILD — Duplicates + Templates sheets. Reuses the existing
   .lead-sheet/.lead-sheet-head/.lead-sheet-body chrome; only the new content
   below needs its own rules. */
.lead-sheet-count{ display:inline-flex; align-items:center; justify-content:center; min-width:18px; height:18px; padding:0 5px; border-radius:99px; background:var(--warn-dim, color-mix(in srgb, var(--warn) 18%, transparent)); color:var(--warn); font-size:11px; font-weight:800; }
.dup-pair{ padding:14px 0; border-bottom:1px solid var(--line); }
.dup-pair:last-child{ border-bottom:none; }
.dup-reason{ font-size:11px; font-weight:700; letter-spacing:0.03em; text-transform:uppercase; color:var(--text-tertiary); margin-bottom:8px; }
.dup-cards{ display:flex; align-items:stretch; gap:10px; }
.dup-card{ flex:1 1 0; min-width:0; padding:12px; border:1px solid var(--line); border-radius:12px; background:var(--surface-2); display:flex; flex-direction:column; gap:3px; }
.dup-card.is-keep-target{ border-color:color-mix(in srgb, var(--good) 45%, var(--line)); background:color-mix(in srgb, var(--good) 6%, var(--surface-2)); }
.dup-card-name{ font-size:13px; font-weight:800; color:var(--text-primary); }
.dup-card-line{ font-size:12px; color:var(--text-secondary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dup-card-sub{ font-size:11px; color:var(--text-tertiary); margin-top:2px; }
.dup-card .leads-btn{ margin-top:9px; width:100%; justify-content:center; }
.dup-vs{ flex:0 0 auto; align-self:center; font-size:11px; font-weight:700; color:var(--text-tertiary); }
.dup-confirm-row{ display:flex; gap:6px; margin-top:9px; }
.dup-confirm-row .leads-btn{ margin-top:0; }
.dup-will-merge{ margin-top:9px; padding:8px; text-align:center; font-size:11.5px; font-weight:600; color:var(--bad); background:color-mix(in srgb, var(--bad) 10%, transparent); border-radius:8px; }
/* PRE-LIVE BUILD 2C — saved message templates: the list/editor sheet + the
   Insert-template popover inside the composer. */
.tpl-newbtn{ width:100%; justify-content:center; margin-bottom:12px; }
.tpl-row{ display:flex; align-items:center; gap:8px; padding:9px 4px; border-bottom:1px solid var(--line); }
.tpl-row:last-child{ border-bottom:none; }
.tpl-row-chan{ flex:0 0 auto; font-size:10px; font-weight:800; letter-spacing:0.03em; text-transform:uppercase; padding:3px 7px; border-radius:99px; background:var(--surface-2); color:var(--text-tertiary); }
.tpl-row-chan.is-sms{ color:var(--violet); background:color-mix(in srgb, var(--violet) 12%, var(--surface-2)); }
.tpl-row-name{ flex:1 1 auto; min-width:0; font-size:13px; font-weight:700; color:var(--text-primary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tpl-row-btn{ flex:0 0 auto; width:28px; height:28px; border-radius:8px; background:none; border:1px solid transparent; cursor:pointer; display:flex; align-items:center; justify-content:center; color:var(--text-tertiary); }
.tpl-row-btn svg{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2; }
.tpl-row-btn:hover{ background:var(--surface-hover); color:var(--text-primary); }
.tpl-row-btn.is-danger:hover{ color:var(--bad); }
.lead-tpl-wrap{ position:relative; }
.lead-email-tplbtn{
  display:inline-flex; align-items:center; gap:5px; font:inherit; font-size:11.5px; font-weight:700;
  padding:5px 10px; border-radius:8px; border:1px solid var(--line); background:var(--surface-2); color:var(--text-secondary); cursor:pointer;
}
.lead-email-tplbtn svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2; }
.lead-email-tplbtn:hover{ color:var(--text-primary); border-color:var(--violet-dim); }
.lead-tpl-menu{
  z-index:120; min-width:190px; max-width:260px; max-height:220px; overflow-y:auto; padding:5px;
  border-radius:10px; background:var(--surface-1); border:1px solid var(--line); box-shadow:var(--shadow-card, 0 12px 30px -10px rgba(0,0,0,0.4));
}
.lead-tpl-menu-opt{ display:block; width:100%; text-align:left; font:inherit; font-size:12.5px; font-weight:600; padding:7px 9px; border-radius:7px; background:none; border:none; color:var(--text-primary); cursor:pointer; }
.lead-tpl-menu-opt:hover{ background:var(--surface-hover); }
.lead-tpl-menu-empty{ padding:8px 9px; font-size:12px; color:var(--text-tertiary); }
/* item 10 — Back is a distinct action from Close (X): returns to the parent
   settings sheet without exiting. */
.lead-sheet-back{
  display:inline-flex; align-items:center; gap:5px; cursor:pointer; font:inherit; font-size:12px; font-weight:700;
  color:var(--text-secondary); background:none; border:1px solid var(--line-strong); border-radius:8px; padding:5px 10px 5px 8px;
  transition:color .12s ease, border-color .12s ease, background .12s ease;
}
.lead-sheet-back:hover{ color:var(--text-primary); border-color:var(--violet-dim); background:var(--surface-hover); }
.lead-sheet-back svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.4; }
.lead-sheet-close{
  width:28px; height:28px; border-radius:8px; cursor:pointer; display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); border:1px solid var(--line); color:var(--text-secondary);
}
.lead-sheet-close:hover{ color:var(--text-primary); background:var(--surface-hover); }
.lead-sheet-close svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.4; }
.lead-sheet-body{ padding:16px 20px; display:flex; flex-direction:column; gap:12px; }
.lead-form-row{ display:flex; flex-direction:column; gap:5px; }
.lead-form-row label{ font-size:10.5px; font-weight:700; letter-spacing:0.03em; text-transform:uppercase; color:var(--text-tertiary); }
.lead-form-2col{ display:grid; grid-template-columns:1fr 1fr; gap:10px; }
.lead-input, .lead-select{
  width:100%; padding:9px 11px; border-radius:9px; font:inherit; font-size:13px; color:var(--text-primary);
  background:var(--input-bg); border:1px solid var(--line-strong); transition:border-color .14s ease, box-shadow .14s ease;
}
.lead-select{ cursor:pointer; appearance:none; -webkit-appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--text-tertiary) 50%),linear-gradient(135deg,var(--text-tertiary) 50%,transparent 50%);
  background-position:calc(100% - 16px) center, calc(100% - 11px) center; background-size:5px 5px, 5px 5px; background-repeat:no-repeat; padding-right:30px;
}
.lead-input:focus, .lead-select:focus{ outline:none; border-color:var(--violet); box-shadow:0 0 0 3px rgba(139,108,247,0.16); }
.lead-input::placeholder{ color:var(--text-tertiary); }

/* QC P5/P6/P7 — modern time field: a styled text input + a trailing clock
   button that opens a frosted 15-minute-slot list (96 rows/day, reuses
   .lead-status-menu for the shared Orbit frosted/dark-light chrome — same
   design family as the date calendar). Native smooth + scroll-snap so
   trackpad/wheel/touch scrolling settles a row into the center naturally;
   the current/default slot is scrolled into view on open (openTimePicker in
   app.js). Selecting a slot closes only this popover — the Task/Appointment
   sheet stays open (see the delegated `[data-time-set]` click handler). */
.lead-timepick{ position:relative; display:flex; }
.lead-timepick-in{ padding-right:34px; }
.lead-timepick-toggle{
  position:absolute; right:3px; top:3px; bottom:3px; width:30px; border:none; border-radius:7px;
  background:none; cursor:pointer; color:var(--text-tertiary);
  display:flex; align-items:center; justify-content:center; transition:color .12s ease, background .12s ease;
}
.lead-timepick-toggle:hover{ color:var(--violet); background:var(--surface-hover); }
.lead-timepick-in:focus + .lead-timepick-toggle{ color:var(--violet); }
.lead-timepick-toggle svg{ width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:2; }
.lead-timepick-menu{
  max-height:248px; overflow-y:auto; min-width:150px;
  scrollbar-width:thin; scroll-behavior:smooth; scroll-snap-type:y proximity; scroll-padding:4px 0;
}
.lead-timepick-menu::-webkit-scrollbar{ width:8px; }
.lead-timepick-menu::-webkit-scrollbar-thumb{ background:var(--line-strong); border-radius:99px; }
.lead-timepick-opt{ justify-content:flex-start; font-variant-numeric:tabular-nums; scroll-snap-align:center; }
.lead-timepick-opt.is-cur{
  color:var(--violet); font-weight:800;
  background:color-mix(in srgb, var(--violet) 14%, transparent);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--violet) 32%, transparent);
}
@media (max-width:520px){ .lead-timepick-menu{ max-height:200px; } }

/* QC P1 — modern Orbit date field + calendar. The field reuses the time
   field's shell (.lead-timepick / .lead-timepick-toggle) so date + time read
   as one matched component family. The calendar icon is currentColor (never a
   near-black native indicator) and brightens on hover/focus. */
.lead-datepick-in{ padding-right:34px; cursor:pointer; }
.lead-datepick-in:focus + .lead-timepick-toggle{ color:var(--violet); }
.lead-datepick-menu{
  width:264px; max-width:calc(100vw - 20px); padding:10px; gap:0;
}
.dp-head{ display:flex; align-items:center; justify-content:space-between; gap:6px; margin-bottom:8px; }
.dp-title{ font-size:12.5px; font-weight:800; color:var(--text-primary); letter-spacing:-0.01em; }
.dp-nav{
  width:26px; height:26px; flex:0 0 auto; border:none; border-radius:8px; cursor:pointer;
  background:var(--surface-2); color:var(--text-secondary);
  display:flex; align-items:center; justify-content:center; transition:background .12s ease, color .12s ease;
}
.dp-nav:hover{ background:var(--surface-hover); color:var(--text-primary); }
.dp-nav svg{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2.4; transform:rotate(90deg); }
.dp-nav-next svg{ transform:rotate(-90deg); }
.dp-dow{ display:grid; grid-template-columns:repeat(7,1fr); gap:2px; margin-bottom:2px; }
.dp-dow span{ text-align:center; font-size:10px; font-weight:700; color:var(--text-tertiary); padding:3px 0; }
.dp-grid{ display:grid; grid-template-columns:repeat(7,1fr); gap:2px; min-height:192px; align-content:start; }
.dp-cell{ height:30px; }
.dp-day{
  position:relative; height:30px; width:100%; border:none; border-radius:8px; cursor:pointer; font:inherit;
  font-size:12px; font-weight:600; color:var(--text-secondary);
  background:none; display:flex; align-items:center; justify-content:center;
  transition:background .1s ease, color .1s ease;
}
.dp-day:hover{ background:var(--surface-hover); color:var(--text-primary); }
.dp-day.is-today{ color:var(--violet); font-weight:800; }
.dp-day.is-today::after{
  content:""; position:absolute; left:50%; bottom:3px; transform:translateX(-50%);
  width:4px; height:4px; border-radius:50%; background:var(--violet);
}
.dp-day.is-sel{
  background:var(--violet); color:#fff; font-weight:800;
  box-shadow:0 4px 12px -3px color-mix(in srgb, var(--violet) 70%, transparent);
}
.dp-day.is-sel.is-today{ color:#fff; }
.dp-day.is-sel.is-today::after{ background:#fff; }
.dp-foot{ margin-top:8px; padding-top:8px; border-top:1px solid var(--line); display:flex; justify-content:center; }
.dp-today-btn{
  border:none; background:none; cursor:pointer; font:inherit; font-size:11.5px; font-weight:700;
  color:var(--violet); padding:4px 10px; border-radius:7px; transition:background .12s ease;
}
.dp-today-btn:hover{ background:color-mix(in srgb, var(--violet) 12%, transparent); }
@media (max-width:520px){ .lead-datepick-menu{ width:min(300px, calc(100vw - 20px)); } }

.lead-sheet-foot{ display:flex; justify-content:flex-end; gap:8px; padding:13px 20px 17px; border-top:1px solid var(--line); }
.lead-backend-note{
  display:flex; gap:9px; padding:10px 12px; border-radius:10px; line-height:1.5; font-size:11.5px; color:var(--text-secondary);
  background:var(--warn-dim); border:1px solid color-mix(in srgb, var(--warn) 30%, transparent);
}
.lead-backend-note svg{ flex:0 0 auto; width:15px; height:15px; stroke:var(--warn); fill:none; stroke-width:2; margin-top:1px; }
.lead-dropzone{
  display:flex; flex-direction:column; align-items:center; gap:8px; text-align:center;
  padding:26px 18px; border:1.5px dashed var(--line-strong); border-radius:12px; color:var(--text-secondary);
}
.lead-dropzone svg{ width:22px; height:22px; stroke:var(--text-tertiary); fill:none; stroke-width:1.8; }
.lead-dropzone-hint{ font-size:11.5px; color:var(--text-tertiary); }
.lead-dropzone-file{ font-size:12.5px; font-weight:700; color:var(--text-primary); }
.lead-dropzone.is-drag{ border-color:var(--violet); background:color-mix(in srgb, var(--violet) 8%, transparent); }
.lead-backend-note.is-warn{ background:var(--bad-dim); border-color:color-mix(in srgb, var(--bad) 30%, transparent); }
.lead-backend-note.is-warn svg{ stroke:var(--bad); }

/* ---- Lead import stepper ------------------------------------------------ */
.imp-steps{ display:flex; align-items:center; gap:6px; margin-bottom:14px; flex-wrap:wrap; }
.imp-step{ display:inline-flex; align-items:center; gap:6px; font-size:11px; font-weight:700; color:var(--text-tertiary); }
.imp-step i{
  width:18px; height:18px; border-radius:50%; display:inline-flex; align-items:center; justify-content:center;
  font-size:10px; font-style:normal; background:var(--surface-2); border:1px solid var(--line-strong); color:var(--text-tertiary);
}
.imp-step.is-on{ color:var(--text-primary); }
.imp-step.is-on i{ background:var(--violet); border-color:var(--violet); color:#fff; }
.imp-step.is-done i{ background:color-mix(in srgb, var(--good) 24%, transparent); border-color:transparent; color:var(--good); }
.imp-step-sep{ flex:1 1 8px; height:1px; background:var(--line); min-width:8px; }
.imp-tabs{ display:flex; gap:6px; margin-bottom:12px; }
.imp-tab{
  flex:1 1 0; padding:8px 6px; border-radius:9px; font:inherit; font-size:12px; font-weight:700; cursor:pointer;
  background:var(--surface-2); border:1px solid var(--line-strong); color:var(--text-secondary);
}
.imp-tab.is-on{ background:color-mix(in srgb, var(--violet) 12%, transparent); border-color:color-mix(in srgb, var(--violet) 45%, transparent); color:var(--text-primary); }
.imp-lead{ font-size:12.5px; color:var(--text-secondary); margin-bottom:10px; line-height:1.5; }
.imp-hint{ font-size:11px; color:var(--text-tertiary); }
.imp-row{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-top:8px; }
.imp-paste{
  width:100%; resize:vertical; min-height:120px; padding:10px 12px; border-radius:10px; font:inherit; font-size:12px;
  font-family:ui-monospace,Menlo,monospace; color:var(--text-primary); background:var(--input-bg); border:1px solid var(--line-strong);
}
.imp-map-wrap{ max-height:340px; overflow-y:auto; border:1px solid var(--line); border-radius:10px; }
.imp-map{ width:100%; border-collapse:collapse; font-size:12px; }
.imp-map th{
  position:sticky; top:0; text-align:left; padding:8px 12px; font-size:10.5px; font-weight:700; text-transform:uppercase;
  letter-spacing:0.04em; color:var(--text-tertiary); background:var(--surface-1); border-bottom:1px solid var(--line-strong);
}
.imp-map td{ padding:8px 12px; border-bottom:1px solid var(--line); vertical-align:middle; }
.imp-map tr:last-child td{ border-bottom:none; }
.imp-map-h{ font-weight:700; color:var(--text-primary); }
.imp-map-ex{ display:block; font-weight:500; font-size:11px; color:var(--text-tertiary); margin-top:2px; }
.imp-map-sel{ width:100%; min-width:150px; }
.imp-tiles{ display:grid; grid-template-columns:repeat(4,1fr); gap:8px; margin:4px 0 14px; }
.imp-tile{ padding:12px 10px; border-radius:10px; text-align:center; background:var(--surface-2); border:1px solid var(--line); }
.imp-tile b{ display:block; font-size:19px; font-weight:800; letter-spacing:-0.02em; line-height:1; }
.imp-tile span{ display:block; font-size:10px; font-weight:600; color:var(--text-tertiary); margin-top:5px; text-transform:uppercase; letter-spacing:0.03em; }
.imp-tile.is-good b{ color:var(--good); }
.imp-tile.is-cyan b{ color:var(--cyan); }
.imp-tile.is-bad b{ color:var(--bad); }
.imp-strat{ margin-bottom:12px; }
.imp-strat-h{ font-size:11px; font-weight:800; text-transform:uppercase; letter-spacing:0.04em; color:var(--text-tertiary); margin-bottom:7px; }
.imp-radio{ display:flex; align-items:flex-start; gap:8px; font-size:12.5px; color:var(--text-secondary); padding:6px 0; cursor:pointer; }
.imp-radio input{ margin-top:2px; flex:0 0 auto; }
.imp-bad{ margin-bottom:12px; border:1px solid color-mix(in srgb, var(--bad) 28%, transparent); border-radius:10px; overflow:hidden; }
.imp-bad-h{ font-size:11px; font-weight:800; text-transform:uppercase; letter-spacing:0.03em; color:var(--bad); padding:7px 11px; background:var(--bad-dim); }
.imp-bad-r{ font-size:11.5px; color:var(--text-secondary); padding:6px 11px; border-top:1px solid var(--line); }
.imp-progress{ height:6px; border-radius:99px; background:var(--surface-2); overflow:hidden; margin-bottom:12px; }
.imp-progress-bar{ height:100%; background:var(--violet); transition:width .2s ease; }
.imp-done{ text-align:center; padding:8px 0 4px; }
.imp-done-ic{ width:44px; height:44px; border-radius:50%; margin:0 auto 10px; display:flex; align-items:center; justify-content:center; background:color-mix(in srgb, var(--good) 18%, transparent); }
.imp-done-ic svg{ width:22px; height:22px; stroke:var(--good); fill:none; stroke-width:2; }
.imp-done-t{ font-size:15px; font-weight:800; margin-bottom:12px; }

/* ---- Lead integrations extras ---------------------------------------- */
.crm-integ-more{
  font:inherit; font-size:11px; font-weight:700; color:var(--violet); background:none; border:none; cursor:pointer; padding:0 0 0 4px;
}
.crm-integ-detail{
  grid-column:1 / -1; margin-top:7px; font-size:11.5px; line-height:1.55; color:var(--text-secondary);
  background:var(--surface-2); border:1px solid var(--line); border-radius:9px; padding:10px 11px;
}
.crm-integ-detail-sub{ margin-top:6px; color:var(--text-tertiary); }
.crm-integ-detail code, .crm-integ-key code{
  font-family:ui-monospace,Menlo,monospace; font-size:11px; background:var(--surface-1);
  border:1px solid var(--line-strong); border-radius:5px; padding:1px 5px; word-break:break-all;
}
.crm-integ-ref{ display:flex; flex-direction:column; gap:4px; margin-top:8px; font-size:11px; font-weight:600; color:var(--text-tertiary); }
.crm-integ-key{
  grid-column:1 / -1; margin-top:8px; display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  background:color-mix(in srgb, var(--good) 10%, transparent); border:1px solid color-mix(in srgb, var(--good) 30%, transparent);
  border-radius:9px; padding:9px 11px;
}
.crm-integ-key-h{ flex:1 1 100%; font-size:11px; font-weight:800; color:var(--good); text-transform:uppercase; letter-spacing:0.03em; }
.crm-integ-row{ flex-wrap:wrap; }
.crm-integ-main{ flex:1 1 200px; }

@media (max-width:520px){
  .imp-tiles{ grid-template-columns:1fr 1fr; }
}

/* ---- Toast ------------------------------------------------------------- */
.lead-toast{
  position:fixed; left:50%; bottom:26px; z-index:230; white-space:nowrap;
  padding:11px 18px; border-radius:11px; font-size:12.5px; font-weight:600; color:var(--text-primary);
  background:var(--ink-800); border:1px solid var(--line-strong);
  box-shadow:0 18px 42px -14px rgba(0,0,0,0.6);
  transform:translateX(-50%) translateY(14px); opacity:0; pointer-events:none;
  transition:opacity .2s ease, transform .2s ease;
}
.lead-toast.is-open{ transform:translateX(-50%) translateY(0); opacity:1; }

/* ---- Saved-view pills + CRM jelly slider (#5) ------------------------- */
.leads-viewtabs{
  display:flex; align-items:center; gap:0; border-bottom:1px solid var(--line-strong); margin:2px 0 0; padding-bottom:4px;
}
.leads-vt-list{
  position:relative;
  display:flex; align-items:center; gap:3px; overflow-x:auto; scrollbar-width:none; min-width:0; padding:2px 0;
}
.leads-vt-list::-webkit-scrollbar{ display:none; }
.leads-viewtab{
  position:relative; z-index:1; white-space:nowrap; cursor:pointer; font:inherit; border:1px solid transparent; background:none;
  padding:7px 12px; border-radius:9px; font-size:13px; font-weight:600; color:var(--text-secondary);
  display:inline-flex; align-items:center; gap:7px;
  transition:color .34s ease, background .14s ease, border-color .14s ease;
}
.leads-viewtab:active{ transform:scale(0.97); }
/* inactive hover — a soft semantic tint fills the rounded pill */
.leads-viewtab:hover{ color:var(--text-primary); background:var(--surface-hover); }
.leads-viewtab.has-accent:hover{
  color:color-mix(in srgb, var(--vt-accent) 82%, var(--text-primary));
  background:color-mix(in srgb, var(--vt-accent) 13%, transparent);
}
.leads-viewtab.is-active{
  color:var(--vt-accent, var(--text-primary));
  background:color-mix(in srgb, var(--vt-accent, var(--violet)) 14%, transparent);
  border-color:color-mix(in srgb, var(--vt-accent, var(--violet)) 32%, transparent);
}
/* one physical sliding indicator (own implementation — Overview's timeframe
   control is untouched). Outer = position/width eased; inner = one-shot
   jelly keyframe per move (positionLeadsViewThumb sets transform-origin). */
.leads-vt-thumb{
  position:absolute; top:2px; bottom:2px; left:0; width:0;
  pointer-events:none; opacity:0; z-index:0;
  transition:transform .62s cubic-bezier(.34,0,.12,1), width .58s cubic-bezier(.4,0,.16,1);
}
.leads-vt-thumb.is-ready{ opacity:1; }
.leads-vt-thumb-jelly{
  display:block; width:100%; height:100%; border-radius:9px; will-change:transform;
  background:color-mix(in srgb, var(--vt-thumb-accent, var(--violet)) 15%, var(--surface-1));
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--vt-thumb-accent, var(--violet)) 34%, transparent),
             0 1px 4px -1px rgba(0,0,0,0.14);
}
.leads-vt-thumb-jelly.is-jelly{ animation:vtThumbJelly .62s cubic-bezier(.4,0,.2,1) both; }
@keyframes vtThumbJelly{
  0%   { transform:scaleX(1)    scaleY(1);    }
  28%  { transform:scaleX(1.11) scaleY(0.94); }
  58%  { transform:scaleX(0.95) scaleY(1.04); }
  80%  { transform:scaleX(1.02) scaleY(0.99); }
  100% { transform:scaleX(1)    scaleY(1);    }
}
/* .has-thumb hands the fill to the slider; the active pill keeps only text */
.leads-vt-list.has-thumb .leads-viewtab.is-active{ background:none; border-color:transparent; }
.leads-vt-list.has-thumb .leads-viewtab.is-active:hover{ background:none; }
[data-theme="light"] .leads-vt-thumb-jelly{
  background:color-mix(in srgb, var(--vt-thumb-accent, var(--violet)) 14%, #fff);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--vt-thumb-accent, var(--violet)) 30%, transparent),
             0 1px 4px -1px rgba(28,27,64,0.14);
}
@media (prefers-reduced-motion:reduce){
  .leads-vt-thumb{ transition:none; }
  .leads-vt-thumb-jelly.is-jelly{ animation:none; }
}
.leads-viewtab-ic{ width:12px; height:12px; stroke:currentColor; fill:none; stroke-width:2; }
.leads-viewtab-n{
  font-family:'JetBrains Mono', monospace; font-size:11px; font-weight:700; color:var(--text-tertiary);
  background:var(--surface-2); padding:1px 6px; border-radius:99px;
}
.leads-viewtab.is-active .leads-viewtab-n{ color:var(--vt-accent, var(--violet)); background:color-mix(in srgb, var(--vt-accent, var(--violet)) 15%, transparent); }
.leads-viewtab-x{ margin-left:2px; font-size:14px; line-height:1; color:var(--text-tertiary); opacity:0; transition:opacity .12s ease; }
.leads-viewtab:hover .leads-viewtab-x{ opacity:0.8; }
.leads-viewtab-x:hover{ color:var(--bad); opacity:1; }
.leads-viewtab.is-adhoc{ font-style:italic; }

/* §14 — system-view identity colour is ALWAYS visible via a small dot +
   a tinted count pill, even when the tab is inactive. Active state deepens
   the tint and adds the underline. Not a rainbow pill — text stays neutral
   until active. */
.leads-viewtab-dot{
  flex:0 0 auto; width:6px; height:6px; border-radius:50%;
  background:var(--vt-accent, var(--text-tertiary));
  box-shadow:0 0 5px color-mix(in srgb, var(--vt-accent) 50%, transparent);
}
.leads-viewtab.has-accent .leads-viewtab-n{
  color:color-mix(in srgb, var(--vt-accent) 80%, var(--text-secondary));
  background:color-mix(in srgb, var(--vt-accent) 12%, var(--surface-2));
}
.leads-viewtab[draggable="true"]{ cursor:grab; }
.leads-viewtab.is-vt-dragging{ opacity:0.4; }
.leads-viewtab.vt-drop-before{ box-shadow:inset 2px 0 0 var(--violet); }

.leads-vt-add, .leads-vt-admin, .leads-vt-settings{
  flex:0 0 auto; display:inline-flex; align-items:center; justify-content:center; gap:6px; cursor:pointer;
  font:inherit; font-size:12px; font-weight:700; border:none; background:none; color:var(--text-tertiary);
  padding:8px 11px; transition:color .14s ease, background .14s ease;
}
.leads-vt-add{ border-left:1px solid var(--line); }
.leads-vt-add svg{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2.4; }
.leads-vt-add:hover{ color:var(--violet); background:var(--surface-1); }
.leads-vt-admin svg{ width:19px; height:19px; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linejoin:round; }
.leads-vt-admin:hover{ color:var(--violet); }
.leads-vt-admin:hover svg{ filter:drop-shadow(0 0 5px color-mix(in srgb, var(--violet) 60%, transparent)); }
.leads-vt-settings{ margin-left:auto; }
.leads-vt-settings svg{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2; }
.leads-vt-settings:hover{ color:var(--text-primary); background:var(--surface-1); }

.leads-menu-count{ margin-left:auto; font-family:'JetBrains Mono', monospace; font-size:11px; color:var(--text-tertiary); }
.leads-menu-item.is-selected .leads-menu-count{ color:var(--violet); }
.leads-menu-sep{ height:1px; background:var(--line); margin:4px 2px; }

/* §16 — status filter rows: label hard-left, checkbox hard-right, count
   between. Uses the full row width so the box is never crammed next to text. */
.leads-menu-cbx .leads-menu-lbl{ flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; }
.leads-menu-cbx .leads-menu-count{ margin-left:0; margin-right:10px; flex:0 0 auto; }
.leads-menu-cbx .lead-cbx{ margin-left:0; }
.leads-menu-item.leads-menu-cbx{ gap:9px; }

/* custom CRM checkbox (source multi-select filter) */
.lead-cbx{
  flex:0 0 auto; width:16px; height:16px; border-radius:4px; border:1.5px solid var(--line-strong);
  display:inline-flex; align-items:center; justify-content:center; background:var(--input-bg);
}
.lead-cbx.is-on{ background:var(--violet); border-color:var(--violet); }
.lead-cbx svg{ width:11px; height:11px; stroke:#0A0A16; fill:none; stroke-width:3; }
.leads-menu-cbx{ gap:8px; }

/* owner chip + lead score */
.lead-owner-chip{ display:inline-flex; align-items:center; gap:6px; font-size:inherit; color:var(--text-primary); min-width:0; }
.lead-owner-ini{
  flex:0 0 auto; width:18px; height:18px; border-radius:50%; font-size:9px; font-weight:800; letter-spacing:-0.02em;
  display:inline-flex; align-items:center; justify-content:center; text-transform:uppercase;
  color:#fff; text-shadow:0 1px 2px rgba(0,0,0,0.28);
  background:var(--owner-color, #5B4FCF);
  background-size:cover; background-position:center;
}
.lead-owner-ini.has-photo{ color:transparent; text-shadow:none; box-shadow:inset 0 0 0 1px rgba(255,255,255,0.14); }
.lead-owner-ini.is-me{ background-image:var(--me-owner-photo, none); }
.lead-owner-ini.is-unassigned{
  background:var(--surface-2); color:var(--text-tertiary); font-weight:700; text-shadow:none;
  box-shadow:inset 0 0 0 1px var(--line-strong);
}
[data-theme="light"] .lead-owner-ini{ text-shadow:0 1px 1px rgba(0,0,0,0.22); }
[data-theme="light"] .lead-owner-ini.has-photo{ box-shadow:inset 0 0 0 1px rgba(28,27,64,0.08); }
/* item 9 — banded score color (low=red / medium=amber / good=cyan / hot=green),
   set per-instance via --sc-color from leadScoreBand(); presentation only. */
.lead-score{
  display:inline-flex; align-items:center; gap:8px; font-weight:800; font-size:13px;
  color:var(--sc-color, var(--text-secondary));
}
.lead-score i{ display:block; width:56px; height:5px; border-radius:99px; background:var(--surface-hover); position:relative; overflow:hidden; }
.lead-score i::after{ content:""; position:absolute; inset:0 auto 0 0; width:calc(var(--sc,0) * 1%); background:currentColor; border-radius:99px; }

/* ---- Name cell + inline eye ------------------------------------------------ */
.lead-cell-name{ display:flex; align-items:center; gap:7px; min-width:0; overflow:visible; }
.lead-eye{
  flex:0 0 auto; width:22px; height:22px; border-radius:6px; cursor:pointer; opacity:0;
  display:flex; align-items:center; justify-content:center;
  background:none; border:1px solid transparent; color:var(--text-tertiary);
  transition:opacity .12s ease, background .12s ease, color .12s ease, border-color .12s ease;
}
.lead-row:hover .lead-eye, .lead-eye:focus-visible{ opacity:1; }
.lead-eye:hover{ background:var(--surface-2); color:var(--violet); border-color:var(--line-strong); }
.lead-eye svg{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2; }
@media (hover:none){ .lead-eye{ opacity:1; } }

/* ---- Inline-editable field (drawer + record) ----------------------------- */
.lf{ display:inline-flex; align-items:center; gap:5px; min-width:0; max-width:100%; }
.lf-plain{ display:flex; }
.lf-cur{ min-width:0; overflow:hidden; text-overflow:ellipsis; }
.lf-cur a{ color:var(--cyan); text-decoration:none; }
.lf-cur a:hover{ text-decoration:underline; }
.lf-edit{
  flex:0 0 auto; width:20px; height:20px; border-radius:5px; cursor:pointer; opacity:0;
  display:inline-flex; align-items:center; justify-content:center;
  background:none; border:1px solid transparent; color:var(--text-tertiary);
  transition:opacity .12s ease, background .12s ease, color .12s ease;
}
.lf:hover .lf-edit, .lf-edit:focus-visible{ opacity:1; }
.lf-edit:hover{ background:var(--surface-2); color:var(--violet); }
.lf-edit svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2; }
/* #12 (Stage 3B) — ROOT CAUSE of the "mysterious +/play button" report: on
   any touch/no-hover device this icon is ALWAYS visible (no hover state
   exists to reveal it), but it kept the hover-only styling — no background,
   no border, a bare 2px-outline glyph at partial opacity floating with
   nothing to signal "this is a button." A `title` tooltip (added in the
   prior pass) is INERT on touch devices too, since tooltips also require
   hover — that fix was invisible in exactly this context. A thin-stroke
   pencil silhouette with no chip around it, at low opacity, reads as an
   ambiguous wedge/triangle rather than a recognizable pencil — hence "play
   button." Fix: on touch, show it fully opaque with the SAME chip
   background/border the hover state already uses on desktop, so it reads
   as a deliberate small icon button instead of an unexplained mark. */
@media (hover:none){
  .lf-edit{ opacity:1; background:var(--surface-2); border-color:var(--line-strong); }
}
.lf-input{
  width:100%; min-width:120px; padding:4px 7px; border-radius:6px; font:inherit; font-size:12.5px; color:var(--text-primary);
  background:var(--input-bg); border:1px solid var(--violet); box-shadow:0 0 0 3px rgba(139,108,247,0.16);
}
.lf-plain .lf-input{ font-size:16px; font-weight:800; }
/* QC#4 — inline validation state for a field being edited (e.g. bad phone) */
.lf.is-editing{ flex-wrap:wrap; }
.lf-input.is-invalid{ border-color:var(--bad); box-shadow:0 0 0 3px color-mix(in srgb, var(--bad) 18%, transparent); }
.lf-err{ flex-basis:100%; margin-top:4px; font-size:11px; font-weight:600; color:var(--bad); line-height:1.35; }

/* ---- Dense field grid (drawer + record) -------------------------------- */
.lf-grid{ display:flex; flex-direction:column; }
.lf-row{
  display:grid; grid-template-columns:96px minmax(0,1fr); gap:10px; align-items:center;
  padding:6px 0; border-bottom:1px solid var(--line); min-height:32px;
}
.lf-row:last-child{ border-bottom:none; }
/* #6 — was var(--text-tertiary): ~3.0:1 (dark) / ~3.3:1 (light) contrast
   against the field row's surface, below WCAG AA's 4.5:1 for normal-weight
   text (11px bold-uppercase doesn't qualify for the 3:1 "large text"
   threshold). --text-secondary measures ~7:1 in both themes and keeps a
   clear secondary tier below --text-primary (the value) — real hierarchy
   instead of both label and a dozen unrelated muted UI bits sharing the
   same faint tone. Shared by Quick View / Full Record / Opportunity field
   rows alike — a pure contrast fix, doesn't touch size, weight, spacing,
   or the locked light-mode material. */
.lf-k{ font-size:10.5px; font-weight:700; letter-spacing:0.03em; text-transform:uppercase; color:var(--text-secondary); }
.lf-v{ font-size:12.5px; color:var(--text-primary); min-width:0; overflow:hidden; }
.lf-v .lead-muted{ color:var(--text-tertiary); }
.lead-source-chip-sm{ font-size:11px; padding:2px 8px 2px 6px; }
.lead-source-chip-sm svg{ width:10px; height:10px; }

.lead-section-head{ display:flex; align-items:center; justify-content:space-between; gap:8px; margin:18px 0 8px; }
.lead-section-head .lead-section-title{ margin:0; }
.lead-section-link{
  display:inline-flex; align-items:center; gap:5px; cursor:pointer; font:inherit; font-size:11px; font-weight:700;
  border:none; background:none; color:var(--violet); padding:2px 4px; border-radius:6px;
}
.lead-section-link:hover{ background:var(--surface-hover); }
.lead-section-link svg{ width:12px; height:12px; stroke:currentColor; fill:none; stroke-width:2; }

/* ---- Drawer action bar (moved to top) --------------------------------- */
.lead-drawer-actionbar{ display:flex; gap:6px; padding:11px 16px; border-bottom:1px solid var(--line); flex:0 0 auto; }
.lead-drawer-actionbar .lead-action{ flex:1 1 0; flex-direction:row; gap:6px; padding:8px 6px; font-size:11.5px; }
.lead-action span{ display:inline; }
/* #1 — prominent EMAIL / CALL / TEXT actions (Quick View header + Opp Contact section) */
.lead-drawer-actionbar.is-primary{ gap:8px; padding:12px 16px; }
/* #13 — translucent so the glass reads continuously through the panel
   instead of "opaque card inside glass". The violet stays as a control cue. */
.lead-drawer-actionbar.is-primary .lead-action{
  flex-direction:column; gap:5px; padding:11px 6px 10px; font-size:11.5px; font-weight:800; border-radius:12px;
  background:color-mix(in srgb, var(--violet) 14%, transparent);
  border-color:color-mix(in srgb, var(--violet) 26%, transparent);
}
.lead-drawer-actionbar.is-primary .lead-action:hover{ background:color-mix(in srgb, var(--violet) 22%, transparent); border-color:var(--violet-dim); }
.lead-drawer-actionbar.is-primary .lead-action svg{ width:18px; height:18px; }
.lead-drawer-body .lead-drawer-actionbar.is-primary{ padding:2px 0 6px; border:none; }

/* ---- Notes ------------------------------------------------------------ */
.lead-notes{ display:flex; flex-direction:column; gap:8px; }
.lead-note-compose{ display:flex; flex-direction:column; gap:6px; }
/* #3 — premium Notes module for Quick View: header + reveal-on-demand composer */
.lead-notes-mod{ margin:18px 0 6px; }
.lead-notes-mod-head{ display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:8px; }
.lead-notes-mod-head .lead-section-title{ margin:0; }
.lead-notes-mod-add{
  display:inline-flex; align-items:center; gap:5px; cursor:pointer; font:inherit; font-size:11px; font-weight:700;
  padding:5px 10px; border-radius:8px; color:var(--violet);
  background:color-mix(in srgb, var(--violet) 10%, transparent); border:1px solid color-mix(in srgb, var(--violet) 26%, transparent);
  transition:background .12s ease;
}
.lead-notes-mod-add:hover{ background:color-mix(in srgb, var(--violet) 18%, transparent); }
.lead-notes-mod-add svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2.4; }
.lead-notes-mod-compose{ display:flex; flex-direction:column; gap:8px; margin-bottom:10px; }
.lead-notes-mod-compose-actions{ display:flex; justify-content:flex-end; gap:8px; }
.lead-note-cancel{
  padding:6px 12px; border-radius:8px; cursor:pointer; font:inherit; font-size:11.5px; font-weight:700;
  background:var(--surface-2); border:1px solid var(--line-strong); color:var(--text-secondary);
}
.lead-note-cancel:hover{ color:var(--text-primary); }
.lead-notes-mod-list{ display:flex; flex-direction:column; gap:8px; }
.lead-notes-mod-empty{ font-size:12px; color:var(--text-tertiary); padding:4px 2px; }

/* ---- Notes ------------------------------------------------------------ */
.lead-notes{ display:flex; flex-direction:column; gap:8px; }
.lead-note-compose{ display:flex; flex-direction:column; gap:6px; }
.lead-note-input{
  width:100%; resize:vertical; min-height:40px; padding:8px 10px; border-radius:9px; font:inherit; font-size:12.5px;
  color:var(--text-primary); background:var(--input-bg); border:1px solid var(--line-strong);
}
.lead-note-input:focus{ outline:none; border-color:var(--violet); box-shadow:0 0 0 3px rgba(139,108,247,0.16); }
.lead-note-input:disabled{ opacity:0.6; cursor:not-allowed; }
.lead-note-save{
  align-self:flex-end; padding:6px 13px; border-radius:8px; cursor:pointer; font:inherit; font-size:11.5px; font-weight:700;
  background:var(--brand-gradient); color:#0A0A16; border:none;
}
.lead-note-save:disabled{ opacity:0.4; cursor:not-allowed; }
.lead-note-compose-lg{ margin-bottom:12px; }
.lead-note{ padding:9px 11px; border-radius:9px; background:var(--surface-1); border:1px solid var(--line); }
.lead-note-body{ font-size:12.5px; color:var(--text-primary); line-height:1.5; white-space:pre-wrap; word-break:break-word; }
.lead-note-meta{ font-size:10.5px; color:var(--text-tertiary); font-family:'JetBrains Mono', monospace; margin-top:4px; }

/* ---- Timeline filter tabs (record) ---------------------------------- */
.lead-tl-tabs{ display:flex; gap:2px; border-bottom:1px solid var(--line); margin:0 0 12px; overflow-x:auto; scrollbar-width:none; }
.lead-tl-tabs::-webkit-scrollbar{ display:none; }
.lead-tl-tab{
  white-space:nowrap; cursor:pointer; font:inherit; border:none; background:none; position:relative;
  padding:6px 10px 9px; font-size:11.5px; font-weight:700; color:var(--text-tertiary); transition:color .14s ease;
}
.lead-tl-tab:hover{ color:var(--text-secondary); }
.lead-tl-tab.is-active{ color:var(--text-primary); }
.lead-tl-tab.is-active::after{ content:""; position:absolute; left:8px; right:8px; bottom:-1px; height:2px; background:var(--violet); border-radius:2px; }

/* ---- Communication placeholder card -------------------------------- */
.lead-comms-row{
  display:flex; align-items:center; gap:9px; padding:7px 0; border-bottom:1px solid var(--line);
  font-size:12px; color:var(--text-secondary);
}
.lead-comms-row:last-child{ border-bottom:none; }
.lead-comms-row svg{ width:14px; height:14px; stroke:var(--text-tertiary); fill:none; stroke-width:2; flex:0 0 auto; }
.lead-comms-row span{ flex:1 1 auto; }
.lead-comms-row em{ font-style:normal; font-size:10px; font-weight:700; letter-spacing:0.04em; text-transform:uppercase; color:var(--text-tertiary); }

/* ---- Customization panel ------------------------------------------- */
.leads-cfg-scrim{
  position:fixed; inset:0; z-index:214; background:rgba(4,5,10,0.5);
  -webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
  opacity:0; pointer-events:none; transition:opacity .2s ease;
}
.leads-cfg-scrim.is-open{ opacity:1; pointer-events:auto; }
.leads-cfg{
  position:fixed; top:0; right:0; bottom:0; z-index:215; width:min(400px, 94vw);
  display:flex; flex-direction:column; overflow:hidden;
  background:var(--ink-900); border-left:1px solid var(--line-strong); box-shadow:-26px 0 64px -22px rgba(0,0,0,0.65);
  transform:translateX(100%); visibility:hidden;
  transition:transform .26s cubic-bezier(.4,0,.2,1), visibility 0s linear .26s;
}
.leads-cfg.is-open{ transform:translateX(0); visibility:visible; transition:transform .26s cubic-bezier(.4,0,.2,1); }
.leads-cfg-head{ display:flex; align-items:center; justify-content:space-between; padding:16px 16px 12px; border-bottom:1px solid var(--line); }
.leads-cfg-title{ font-size:15px; font-weight:800; letter-spacing:-0.01em; color:var(--text-primary); }
.leads-cfg-close{
  width:28px; height:28px; border-radius:8px; cursor:pointer; display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); border:1px solid var(--line); color:var(--text-secondary);
}
.leads-cfg-close:hover{ color:var(--text-primary); background:var(--surface-hover); }
.leads-cfg-close svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.4; }
.leads-cfg-tabs{ display:flex; gap:2px; padding:8px 12px; border-bottom:1px solid var(--line); }
.leads-cfg-tab{
  flex:1 1 0; cursor:pointer; font:inherit; border:none; background:none; padding:7px 6px; border-radius:8px;
  font-size:11.5px; font-weight:700; color:var(--text-tertiary); transition:background .12s ease, color .12s ease;
}
.leads-cfg-tab:hover{ color:var(--text-secondary); }
.leads-cfg-tab.is-active{ color:var(--text-primary); background:var(--surface-hover); }
.leads-cfg-body{ flex:1 1 auto; overflow-y:auto; padding:12px 16px 18px; }
.leads-cfg-foot{ flex:0 0 auto; display:flex; justify-content:space-between; gap:8px; padding:12px 16px; border-top:1px solid var(--line); }
.leads-cfg-foot .leads-btn{ flex:1 1 0; }

.cfg-section-label{ font-size:10px; font-weight:800; letter-spacing:0.07em; text-transform:uppercase; color:var(--text-tertiary); margin:14px 0 7px; }
.cfg-section-label:first-child{ margin-top:2px; }
.cfg-list{ display:flex; flex-direction:column; gap:4px; }
.cfg-row{
  display:flex; align-items:center; gap:9px; padding:8px 10px; border-radius:9px;
  background:var(--surface-1); border:1px solid var(--line);
}
.cfg-row[draggable="true"]{ cursor:grab; }
.cfg-row.is-dragging{ opacity:0.4; }
.cfg-row.cfg-drop-above{ box-shadow:inset 0 2px 0 var(--violet); }
.cfg-row.is-locked{ opacity:0.85; }
.cfg-row.is-off{ opacity:0.5; }
.cfg-row-avail{ background:none; border-style:dashed; }
.cfg-grip{ flex:0 0 auto; color:var(--text-tertiary); display:flex; }
.cfg-grip svg{ width:16px; height:16px; fill:currentColor; }
.cfg-label{ flex:1 1 auto; font-size:12.5px; font-weight:600; color:var(--text-primary); min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cfg-toggle{
  flex:0 0 auto; width:24px; height:24px; border-radius:7px; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); border:1px solid var(--line-strong); color:var(--text-tertiary);
}
.cfg-toggle svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.4; }
.cfg-toggle.is-on{ background:var(--violet); border-color:var(--violet); color:#0A0A16; }
.cfg-lock{ flex:0 0 auto; color:var(--text-tertiary); }
.cfg-lock svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2; }
.cfg-def .cfg-color{
  flex:0 0 auto; width:22px; height:22px; padding:0; border:1px solid var(--line-strong); border-radius:6px; cursor:pointer; background:none;
}
.cfg-def .cfg-dot{ flex:0 0 auto; width:9px; height:9px; border-radius:50%; }
.cfg-name{
  flex:1 1 auto; min-width:0; padding:5px 8px; border-radius:7px; font:inherit; font-size:12.5px; color:var(--text-primary);
  background:var(--input-bg); border:1px solid var(--line-strong);
}
.cfg-name:focus{ outline:none; border-color:var(--violet); }
.cfg-sys{ flex:0 0 auto; font-size:8.5px; font-weight:800; letter-spacing:0.06em; color:var(--text-tertiary); background:var(--surface-2); padding:2px 5px; border-radius:4px; }
.cfg-del{
  flex:0 0 auto; width:22px; height:22px; border-radius:6px; cursor:pointer; display:flex; align-items:center; justify-content:center;
  background:none; border:1px solid transparent; color:var(--text-tertiary);
}
.cfg-del:hover{ color:var(--bad); background:var(--bad-dim); }
.cfg-del svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2.4; }
.cfg-add{
  margin-top:10px; width:100%; padding:9px; border-radius:9px; cursor:pointer; font:inherit; font-size:12px; font-weight:700;
  background:none; border:1px dashed var(--line-strong); color:var(--text-secondary);
}
.cfg-add:hover{ color:var(--violet); border-color:var(--violet-dim); }

/* =====================================================================
   PASS 5 — CRM depth: search position, table structure, full record
   accordion + activity + property stack, view builder, CRM panels,
   readability bump.
   ===================================================================== */

/* §12 — Contact Command: compress the top band. Controls sit right under
   the page header; the count moves to a small line by Add Contact; saved
   views + filters + table all move up. */
.leads-toolbar{ gap:7px; margin-top:-2px; margin-bottom:8px; }
.leads-toolbar-top{ align-items:center; gap:10px; row-gap:6px; }
.leads-search{ order:1; margin-left:0; flex:1 1 260px; max-width:none; }
.leads-modetoggle{ order:2; margin-left:0; flex:0 0 auto; }
.leads-toolbar-actions{ order:3; margin-left:0; flex:0 0 auto; }
.leads-headcount{ order:4; flex:1 1 100%; justify-content:flex-end; gap:7px; align-items:baseline; margin-top:-2px; }
.leads-headcount-n{ font-family:var(--font-command); font-size:13px; font-weight:800; letter-spacing:0; color:var(--text-secondary); }
.leads-headcount-l{ font-size:12px; color:var(--text-tertiary); }
/* #8 — now a real <button>, not a plain span: reset UA chrome so it keeps
   sitting inline with the count/label exactly as before, plus a hover/
   active-filter state so it reads as genuinely interactive rather than a
   label that happens to be clickable. */
.leads-headcount-sub{
  font:inherit; font-size:11px; color:var(--violet); font-weight:600;
  background:none; border:none; padding:0; margin:0; cursor:pointer; border-radius:5px;
  transition:color .12s ease, background .12s ease;
}
.leads-headcount-sub:not(:empty)::before{ content:"· "; color:var(--text-tertiary); }
.leads-headcount-sub:hover{ color:var(--cyan); }
.leads-headcount-sub.is-active{ color:var(--cyan); text-decoration:underline; text-underline-offset:2px; }
.leads-toolbar-filters{ margin-top:0; }
@media (max-width:600px){ .leads-headcount{ justify-content:flex-start; } }

/* PASS 9 §4/§25 — kill the vertical dead air above the table/board. The
   List|Pipeline switch shares a row with the saved-view tabs; every band
   is tightened so the workspace begins noticeably higher. */
.leads-toolbar{ gap:4px; margin-top:-4px; margin-bottom:5px; }
.leads-toolbar-top{ row-gap:4px; }
/* #9 — was -4px, pulling the count/"new to review" row tight against the
   Import/Add contact row above it (0px effective gap once row-gap:4px on
   .leads-toolbar-top is accounted for). A small breathing correction only —
   not a header redesign. */
.leads-headcount{ margin-top:4px; }
.leads-viewrow{ display:flex; align-items:stretch; gap:12px; border-bottom:1px solid var(--line-strong); }
.leads-viewrow .leads-modeswitch{ align-self:center; flex:0 0 auto; margin:0; }
.leads-viewrow .leads-viewtabs{ flex:1 1 auto; border-bottom:none; margin:0; min-width:0; align-items:center; }
.leads-viewtab{ padding:7px 12px; font-size:12.5px; }
.leads-toolbar-filters{ padding-top:2px; }
.leads-toolbar-controls{ gap:7px; }
@media (min-width:1024px){
  #leadsListPane{ min-height:calc(100dvh - 104px); margin-bottom:-60px; }
}
/* pipeline board fills the reclaimed height */
.leads-pipeline{ flex:1 1 auto; min-height:0; }
@media (max-width:760px){
  .leads-viewrow{ flex-wrap:wrap; }
  .leads-viewrow .leads-viewtabs{ flex-basis:100%; }
}

/* ---- table body sizing (dividers handled by the ::after rules above) ---- */
.leads-th-sort{ font-weight:800; }
.lead-row{ min-height:52px; }
.lead-cell{ font-size:13px; }
.lead-name{ font-size:13.5px; }
.lead-activity-what{ font-size:12.5px; }
.lead-activity-when{ font-size:11px; }

/* ---- full record: THREE INDEPENDENT VERTICAL LANES (§1) ------------
   Desktop: the grid is height-locked to the viewport (measured in JS so it
   survives any viewport change). LEFT and RIGHT are scrolling LANES whose
   card/stack is natural height — hovering a lane and wheeling scrolls that
   whole lane; the other two lanes never move. CENTER is a fixed-height
   workspace: only its activity feed scrolls internally. */
@media (min-width:1181px){
  #leadRecordPane{ margin-bottom:-60px; }
  .lead-record-bar{ margin-bottom:10px; }
  .lead-record-grid{
    display:grid; gap:0; align-items:stretch; overflow:hidden;
    /* QC P3 — the two divider tracks were a generous 14px each (Refinement
       Pass Part 2, item 3), which read as dead space between lanes on
       review. Tightened to 6px — lanes now nearly kiss while the divider
       still fills its whole track, keeps the col-resize cursor, and keeps
       the wide invisible ::after hit zone (bleeds -6px past the track either
       way) so the drag target stays just as forgiving despite the visual
       track shrinking. Lane widths themselves (--lane-l/--lane-r) untouched. */
    grid-template-columns:var(--lane-l,304px) 6px minmax(380px,1fr) 6px var(--lane-r,320px);
  }
  .lead-record-lane{ min-width:0; min-height:0; max-height:100%; }
  .lead-lane-left, .lead-lane-right{
    overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain;
    display:flex; flex-direction:column; gap:11px;
  }
  /* symmetric hairline of inner clearance; overlay scrollbars (macOS)
     reserve nothing, classic scrollbars overlay the last ~9px */
  .lead-lane-left{ padding:0 1px 0 0; }
  .lead-lane-right{ padding:0 0 0 1px; }
  .lead-lane-left > .lead-record-card,
  .lead-lane-right > .lead-acc-card{ flex:0 0 auto; }         /* natural height */
  .lead-lane-center{ overflow:hidden; display:flex; }
  .lead-lane-center > .lead-record-card.is-timeline{
    flex:1 1 auto; display:flex; flex-direction:column; min-height:0; height:100%;
  }
  .lead-tl-scroll{ flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; }

  .lead-record-lane::-webkit-scrollbar, .lead-tl-scroll::-webkit-scrollbar{ width:9px; }
  .lead-record-lane::-webkit-scrollbar-thumb, .lead-tl-scroll::-webkit-scrollbar-thumb{
    background:var(--line-strong); border-radius:99px; border:3px solid transparent; background-clip:content-box;
  }

  /* Refinement Pass Part 2 — item 5: push the whole record grid — and so the
     RIGHT lane's independent scrollbar — to the true right edge of the
     workspace. .main carries 10px of right padding; the pane cancels exactly
     that with a negative right margin (the pane itself isn't overflow-
     clipped, unlike the grid), so the reclaimed 10px flows into the center
     workspace + right lane and the scrollbar rides the real edge instead of
     floating inside a dead strip. .main's own padding is untouched — every
     other view keeps it. Independent scroll / accordion / scroll-position
     preservation are all unchanged. */
  #leadRecordPane{ margin-right:-10px; }
  .lead-lane-right{ padding-right:9px; }

  /* Refinement Pass Part 2 — item 4: the persistent visual divider is now
     INVISIBLE. The line (::before) and the grip are fully transparent at
     rest — the even card gutter (item 3) is what separates the lanes. The
     resizer is 100% intact: the divider fills its whole 14px track, keeps
     the col-resize cursor, keeps a wide forgiving ::after hit zone that
     bleeds past the track, and persisted lane widths / double-click reset
     are untouched (JS unchanged). Hovering the gutter fades in an extremely
     subtle hairline cue so the affordance is still discoverable. */
  .lead-record-divider{
    display:block; align-self:stretch; cursor:col-resize; position:relative; touch-action:none; z-index:5;
  }
  .lead-record-divider::before{
    content:""; position:absolute; top:0; bottom:0; left:50%; width:1px; transform:translateX(-50%);
    background:color-mix(in srgb, var(--cyan) 30%, var(--violet));
    opacity:0; transition:opacity .14s ease, box-shadow .14s ease, width .14s ease;
  }
  /* wide invisible hit zone that spills past the 14px track */
  .lead-record-divider::after{
    content:""; position:absolute; top:0; bottom:0; left:-6px; right:-6px; z-index:6;
  }
  .lead-record-divider-grip{
    position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); z-index:7;
    width:3px; height:34px; border-radius:99px; pointer-events:none;
    background:color-mix(in srgb, var(--cyan) 40%, var(--violet));
    opacity:0; transition:opacity .14s ease, height .14s ease, box-shadow .14s ease;
  }
  .lead-record-divider:hover::before,
  .lead-record-divider.is-dragging::before{
    opacity:0.5; width:2px; background:linear-gradient(180deg, var(--cyan), var(--violet));
    box-shadow:0 0 16px color-mix(in srgb, var(--cyan) 55%, transparent);
  }
  .lead-record-divider.is-dragging::before{ opacity:0.9; }
  .lead-record-divider:hover .lead-record-divider-grip,
  .lead-record-divider.is-dragging .lead-record-divider-grip{
    opacity:0.9; box-shadow:0 0 14px color-mix(in srgb, var(--cyan) 50%, transparent), inset 0 0 0 1px color-mix(in srgb, #fff 22%, transparent);
  }
  body.is-lane-resizing{ cursor:col-resize; user-select:none; }
}
@media (max-width:1180px){
  .lead-record-divider{ display:none; }
  /* QC P6 — below the 3-lane breakpoint the record grid stacks (§ tablet
     layout further down) and the Task Manager card is no longer in the
     top-right at all, so the "align with its corner" offset stops making
     sense — reset to the same size/position the bell uses on every other
     view rather than risk it landing somewhere awkward mid-reflow. */
  body.is-lead-record .lead-header-cluster{ position:absolute; top:100%; right:6px; transform:translateY(2px); }
  body.is-lead-record .lead-qa-btn, body.is-lead-record .notif-bell{ width:38px; height:38px; }
  body.is-lead-record .lead-qa-btn svg, body.is-lead-record .notif-bell svg{ width:22px; height:22px; }
}
/* item 2, visual refinement pass — ROOT CAUSE of the huge lane gutter: this
   stray unscoped rule used to sit here as `.lead-record-grid{ gap:16px; }`,
   with no media condition. Same selector/specificity as the desktop rule
   above (line ~2851, `gap:0` — the actual "tight seam" design), but later
   in source order, so on every desktop width it silently WON, undoing that
   rule and adding a real 16px gap on both sides of BOTH divider tracks —
   the "huge visual gutter" the lanes felt like they had. The sub-1181px
   tier already has its own correct gap (line ~2416, gap:14px) — this line
   was pure redundant leftover for that tier and an active bug for desktop.
   Deleted, not re-added under a media guard — desktop wants gap:0 and now
   correctly gets it. */
.lead-record-card{ border-radius:var(--radius-md); }
.lead-record-idcard{ padding:18px 16px; }
.lead-record-crumb{ display:flex; align-items:center; gap:6px; }
.lead-record-crumb span{ color:var(--text-tertiary); }
.lead-record-crumb::before{ content:none; }

/* ---- right-side accordion cards ---------------------------------- */
.lead-acc-card{ background:var(--surface-1); border:1px solid var(--line); border-radius:var(--radius-md); overflow:hidden; }
.lead-acc-head{
  width:100%; display:flex; align-items:center; justify-content:space-between; gap:8px; cursor:pointer;
  font:inherit; font-size:12px; font-weight:800; letter-spacing:0.05em; text-transform:uppercase; color:var(--text-secondary);
  background:none; border:none; padding:13px 15px; transition:background .12s ease, color .12s ease;
}
.lead-acc-head:hover{ background:var(--surface-hover); color:var(--text-primary); }
.lead-acc-chev{ width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:2.4; transition:transform .18s ease; flex:0 0 auto; }
.lead-acc-card.is-collapsed .lead-acc-chev{ transform:rotate(-90deg); }
.lead-acc-body{ padding:2px 15px 14px; border-top:1px solid var(--line); }
.lead-acc-card.is-collapsed .lead-acc-body{ display:none; }
.lead-comms-rows{ margin-top:8px; padding-top:8px; border-top:1px solid var(--line); }
.lead-comms-card{ display:none; }

/* ---- activity workspace ---------------------------------------- */
.lead-tl-tab{ font-size:12px; padding:7px 11px 10px; }
.lead-tl-tab.is-active::after{ background:var(--violet); height:2.5px; }
.lead-note-compose-lg{ margin-bottom:14px; }
.lead-tl-empty{ font-size:13px; padding:24px 0; text-align:center; }

/* ---- property stack readability ------------------------------ */
/* item 1 — internal breathing room in the left lane: more row rhythm and
   clearer separation BETWEEN property groups. Purely vertical — the lane
   is not made wider and no horizontal padding is added. */
.lf-row{ grid-template-columns:108px minmax(0,1fr); min-height:36px; padding:9px 0; }
.lf-k{ font-size:11px; align-self:center; }
.lf-v{ font-size:13px; line-height:1.45; }
.lead-section-head{ margin:22px 0 10px; }
.lead-section-title{ font-size:11.5px; letter-spacing:0.06em; }
.lead-idcard-name{ font-size:18px; }
.lead-idcard-co{ font-size:13px; }
.lead-record-idcard .lead-idcard-head{ padding-bottom:4px; }

/* ---- Quick View / menus readability -------------------------- */
.lead-drawer-name{ font-size:16.5px; }
.lead-drawer-sub{ font-size:13px; }
.leads-menu-item{ font-size:13px; padding:9px 11px; }
.lead-status-opt{ font-size:12.5px; padding:8px 10px; }
.leads-control{ font-size:13px; }
.leads-mode-opt{ font-size:12.5px; }
.lead-tl-what{ font-size:13px; }
.lead-tl-context{ font-size:12px; }
.lead-tl-when{ font-size:11px; }
.lead-note-input{ font-size:13px; }
.lead-note-body{ font-size:13px; }

/* ---- view builder (in the sheet) ---------------------------- */
/* QC (this pass) — P5: 560px was still causing unnecessary label/description
   wrapping across CRM Settings' shared shell (main panel, Notification
   Preferences, Integrations, Email Signature — all four use this same
   class, kept consistent per the product ask). 640px gives real breathing
   room, including enough width for the Email Signature editor's new
   side-by-side editor/preview layout (P3), while staying well short of a
   full-screen modal. viewbuilder/export/import share this class too and
   only benefit from the same extra room. */
.lead-sheet-wide{ width:min(640px, 96vw); }
/* #10 (Dock freeze pass) — the Order/Invoice builder + Order receipt: ~20%
   wider than the base 452px sheet (not the 640px .lead-sheet-wide — that's
   a bigger jump than asked for), just enough room for customer info, line
   items, totals and actions to stop feeling cramped. Not fullscreen. */
.lead-sheet-invoice{ width:min(540px, 95vw); }
/* #11 — Dock New Order wizard: substantially larger than any other sheet,
   still centered/responsive within the shared .lead-sheet scrim system. */
.lead-sheet-xl{ width:min(980px, 96vw); max-height:92vh; }
.vb-conds{ display:flex; flex-direction:column; gap:8px; }
.vb-cond{ display:grid; grid-template-columns:1.1fr 0.9fr 1.3fr auto; gap:7px; align-items:center; }
.vb-cond .lead-select, .vb-cond .lead-input{ font-size:12.5px; padding:7px 9px; }
.vb-del{
  width:26px; height:26px; border-radius:7px; cursor:pointer; font-size:16px; line-height:1;
  background:none; border:1px solid var(--line-strong); color:var(--text-tertiary);
}
.vb-del:hover{ color:var(--bad); border-color:var(--bad); }

/* ---- CRM admin / settings panel (in the sheet) ------------- */
.crm-quick{ display:flex; flex-wrap:wrap; gap:8px; }
.crm-quick .leads-btn{ flex:1 1 auto; }
.crm-group{ margin-bottom:16px; }
.crm-group:last-child{ margin-bottom:0; }
.crm-group-h{ font-size:10.5px; font-weight:800; letter-spacing:0.07em; text-transform:uppercase; color:var(--text-tertiary); margin:0 0 4px; }
.crm-rows{ display:flex; flex-direction:column; border:1px solid var(--line); border-radius:12px; overflow:hidden; }
.crm-row{ display:flex; align-items:center; justify-content:space-between; gap:12px; padding:11px 12px; border-bottom:1px solid var(--line); background:color-mix(in srgb, var(--surface-1) 40%, transparent); transition:background .12s ease; }
.crm-row.is-clickable{ cursor:pointer; }
.crm-row.is-clickable:hover{ background:var(--surface-hover); }
.crm-row:last-child{ border-bottom:none; }
.crm-row-ext{ display:inline-flex; align-items:center; gap:5px; flex:0 0 auto; font-size:10px; font-weight:800; letter-spacing:0.04em; text-transform:uppercase; color:var(--text-tertiary); }
.crm-row-ext svg{ width:12px; height:12px; stroke:currentColor; fill:none; stroke-width:2; }
.crm-row-t{ font-size:13px; font-weight:700; color:var(--text-primary); }
.crm-row-d{ font-size:11.5px; color:var(--text-tertiary); margin-top:1px; }
.crm-row-soon{ font-size:9.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary); background:var(--surface-2); padding:3px 7px; border-radius:99px; flex:0 0 auto; }

/* ---- QC P5/P7 — CRM Settings: Notification Preferences ------------------
   Per-category Email/SMS toggles. In-App is a locked/always-on badge (the
   Notification Center itself is unchanged — see .lead-backend-note below
   for the honest "not delivered yet" disclosure). A vertical list, not a
   literal table — the sheet is only 452px wide, so a 3-column table would
   be cramped; each category gets its own row with the two toggle pills
   wrapping naturally on narrow viewports. */
.notif-pref-list{ display:flex; flex-direction:column; border:1px solid var(--line); border-radius:12px; overflow:hidden; margin-bottom:14px; }
.notif-pref-row{
  display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap;
  padding:11px 12px; border-bottom:1px solid var(--line); background:color-mix(in srgb, var(--surface-1) 40%, transparent);
}
.notif-pref-row:last-child{ border-bottom:none; }
.notif-pref-row-txt{ min-width:0; flex:1 1 160px; }
.notif-pref-row-t{ font-size:13px; font-weight:700; color:var(--text-primary); }
.notif-pref-badge{ display:inline-block; font-size:9px; font-weight:800; letter-spacing:0.03em; text-transform:uppercase; color:var(--warn); background:color-mix(in srgb, var(--warn) 14%, transparent); border-radius:5px; padding:1px 5px; vertical-align:middle; margin-left:4px; }
.notif-pref-chan.is-pending{ color:var(--warn); border-color:color-mix(in srgb, var(--warn) 35%, var(--line)); background:color-mix(in srgb, var(--warn) 8%, var(--surface-2)); }
.notif-pref-row-d{ font-size:11.5px; color:var(--text-tertiary); margin-top:1px; line-height:1.4; }
.notif-pref-row-chans{ display:flex; align-items:center; gap:6px; flex:0 0 auto; }
.notif-pref-chan{
  display:inline-flex; align-items:center; gap:4px; font-size:10.5px; font-weight:700; color:var(--text-tertiary);
  background:var(--surface-2); border:1px solid var(--line); border-radius:99px; padding:5px 9px 5px 7px; cursor:default;
}
.notif-pref-chan svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2.2; }
.notif-pref-chan-btn{
  display:inline-flex; align-items:center; gap:4px; font:inherit; font-size:10.5px; font-weight:700; cursor:pointer;
  color:var(--text-secondary); background:var(--surface-2); border:1px solid var(--line-strong); border-radius:99px; padding:5px 9px 5px 7px;
  transition:background .14s ease, color .14s ease, border-color .14s ease;
}
.notif-pref-chan-btn svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2.2; }
.notif-pref-chan-btn:hover{ border-color:var(--violet-dim); color:var(--text-primary); }
.notif-pref-chan-btn.is-on{
  color:#0A0A16; background:var(--brand-gradient); border-color:transparent;
}
[data-theme="light"] .notif-pref-chan-btn.is-on{ color:#fff; }
.notif-pref-dest{ display:flex; flex-direction:column; gap:8px; margin-bottom:14px; }
.notif-pref-dest-row{
  display:flex; align-items:center; gap:10px; padding:10px 12px; border:1px solid var(--line); border-radius:10px;
  background:color-mix(in srgb, var(--surface-1) 40%, transparent);
}
.notif-pref-dest-row svg{ flex:0 0 auto; width:15px; height:15px; stroke:var(--text-tertiary); fill:none; stroke-width:2; }
.notif-pref-dest-k{ font-size:10.5px; font-weight:700; letter-spacing:0.03em; text-transform:uppercase; color:var(--text-tertiary); }
.notif-pref-dest-v{ font-size:13px; font-weight:600; color:var(--text-primary); margin-top:1px; }
.notif-pref-dest-add{
  font:inherit; font-size:12.5px; font-weight:700; color:var(--violet); background:none; border:none; cursor:pointer; padding:0;
}
.notif-pref-dest-add:hover{ text-decoration:underline; }

/* ---- light theme — pass 5 ---- */
/* frosted light header handled above */
[data-theme="light"] .lead-acc-card, [data-theme="light"] .lead-record-card{ box-shadow:var(--shadow-card); }
[data-theme="light"] .lead-cbx svg{ stroke:#fff; }
[data-theme="light"] .leads-viewtab.is-active{
  background:color-mix(in srgb, var(--vt-accent, var(--violet)) 12%, #fff);
  border-color:color-mix(in srgb, var(--vt-accent, var(--violet)) 30%, transparent);
}
[data-theme="light"] .leads-viewtab.has-accent:hover{ background:color-mix(in srgb, var(--vt-accent) 12%, #fff); }
[data-theme="light"] .leads-viewtab:hover{ background:var(--surface-hover); }

/* ---- Light theme — pass 4 additions ------------------------------------- */
[data-theme="light"] .leads-cfg{ background:var(--ink-800); }
[data-theme="light"] .leads-cfg-scrim{ background:rgba(28,27,64,0.34); }
[data-theme="light"] .lead-note-save{ color:#fff; }
[data-theme="light"] .cfg-toggle.is-on{ color:#fff; }
[data-theme="light"] .lead-note{ box-shadow:var(--shadow-card); }
[data-theme="light"] .leads-viewtab-n{ background:var(--surface-2); }

/* ---- Leads responsive ------------------------------------------------------ */
@media (max-width:1180px){
  /* below the 3-lane breakpoint: normal responsive stacking, no independent
     scroll, no dividers, page flows naturally */
  .lead-record-grid{ display:grid; grid-template-columns:minmax(0,1.3fr) minmax(0,1fr); gap:14px; height:auto !important; overflow:visible; }
  .lead-lane-right{ grid-column:1 / -1; display:grid; grid-template-columns:1fr 1fr; gap:12px; align-content:start; }
  #leadRecordPane{ min-height:auto !important; margin-bottom:0 !important; }
  .lead-record-lane, .lead-tl-scroll{ overflow:visible !important; max-height:none !important; }
  .lead-record-card.is-timeline, .lead-record-idcard{ height:auto !important; max-height:none !important; }
  .lead-record-card.is-timeline{ min-height:520px; }
}
@media (max-width:900px){
  .lead-record-grid{ grid-template-columns:1fr; }
  .lead-lane-right{ grid-template-columns:1fr; }
}
@media (max-width:860px){
  .leads-toolbar-top{ gap:10px; }
  .leads-search{ order:1; flex-basis:100%; margin-left:0; max-width:none; }
  .leads-modetoggle{ order:2; margin-left:0; }
  .leads-toolbar-actions{ order:3; margin-left:auto; }
  .leads-headcount{ order:4; }
  .leads-toolbar-controls{ margin-left:0; flex-wrap:wrap; }
  .leads-viewtabs{ flex-wrap:wrap; }
  .leads-vt-settings{ margin-left:auto; }
  /* Keep the CRM table itself intact — scroll it horizontally rather than
     collapsing it into cards. */
  .leads-table{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .leads-thead, .lead-row{ min-width:760px; }
  #leadsListPane{ margin-bottom:0; }
  .lead-eye{ opacity:1; }
}
@media (max-width:520px){
  .leads-btn span{ display:none; }
  .leads-btn{ padding:9px 12px; }
  .leads-control#leadsColBtn span{ display:none; }
  /* QC P4/P14 — don't force the wide stable min-width on phones */
  #leadsStatusBtn, #leadsSourceBtn, #leadsSortBtn{ min-width:0; }
  .leads-mode-opt span{ display:none; }
  .leads-mode-opt{ padding:6px 9px; }
  .lead-sheet{ width:100vw; max-height:92vh; border-radius:16px 16px 0 0; top:auto; bottom:0; transform:translate(-50%, 100%); }
  .lead-sheet.is-open{ transform:translate(-50%, 0); }
  .leads-cfg{ width:100vw; }
  .lead-drawer-actionbar{ flex-wrap:wrap; }
  .lead-drawer-actionbar .lead-action{ flex-basis:calc(50% - 3px); }
  /* the centered modal becomes a near-full-screen rounded card on phones */
  .lead-drawer{
    width:calc(100vw - 14px);
    max-height:calc(100vh - 20px);
    border-radius:18px;
  }
}

/* ==========================================================================
   Settings — one vertical column, four sections (item 8).
   ========================================================================== */
.settings-grid{ display:flex; flex-direction:column; gap:12px; max-width:680px; }
/* Mobile/narrow: Personalization lives as the LAST direct child of
   .settings-grid in the DOM (see index.html) — .settings-col is a plain
   block wrapper here, so mobile just stacks everything in that natural DOM
   order with zero extra CSS: Profile, Marketing, Preferences,
   Notifications, Account, Personalization. (An earlier `display:contents`
   + per-card `order` attempt to control this was dropped — Chrome doesn't
   reliably apply flex `order` to children hoisted by a `display:contents`
   ancestor, so it silently fell back to plain DOM order and never actually
   moved Personalization to the end.) positionPersonalizationCard() in
   app.js physically moves the same element into .settings-col-left, right
   after Marketing, only at desktop widths (see below) — real DOM
   placement, not a CSS-only illusion, so it can't be undermined by the
   same kind of engine-specific quirk. */
/* Full dashboard width (no max-width cap, same gutters every other view
   already uses), two INDEPENDENT flex columns (item 1) — deliberately not
   a single CSS grid with shared row-tracks, which sizes each row to the
   tallest cell across BOTH columns and would push the right column's
   later cards down to align with the left column's (unrelated) row
   heights. Each .settings-col packs to its own content height instead. */
@media (min-width:1150px){
  /* align-items:stretch (was flex-start) so both columns take the same
     height — now driven by the grid's own min-height (below), not just the
     taller column's content — and each column's last card grows into that
     height, so Account (right) and Dashboard Experience (left) always
     terminate on the same baseline. */
  /* Settings-specific viewport fill (NOT a global .main change). Root cause
     of the "large empty black scroll tail": .settings-grid was only ever as
     tall as its natural content (~the left column), so on a tall desktop
     viewport the cards ended well short of the bottom AND .main's generic
     60px padding-bottom (meant for ordinary scrolling pages) still reserved
     document height below them — the two together read as a big black
     region you could scroll into. Fix mirrors the Leads panel's: give the
     grid a min-height that reaches near the viewport bottom, then pull the
     trailing .main padding up to meet it with a negative margin scoped to
     this view only. 100dvh for a truthful mobile-safe viewport unit. The
     ~76px offset = .main padding-top (3) + the generic page header block +
     a small intentional bottom gutter; QA fixture mode adds 32px body
     padding for its banner, so in ?qa mode the gutter reads ~32px larger
     than production — calibrated for production, same as Leads. */
  .settings-grid{
    display:flex; flex-direction:row; align-items:stretch; gap:16px; max-width:none;
    min-height:calc(100dvh - 76px); margin-bottom:-60px;
  }
  .settings-col{ display:flex; flex-direction:column; gap:10px; min-width:0; }
  .settings-col-left{ flex:1.15 1 0; }
  .settings-col-right{ flex:1 1 0; }
  /* QC#6 — Account (right) and Dashboard Experience (left) grow to fill their
     column, so Log Out is pinned to the bottom-right INSIDE the Account card
     regardless of content height. */
  .settings-col-right .settings-card-account,
  .settings-col-left #settingsPersonalizationCard{ flex:1 1 auto; display:flex; flex-direction:column; }
  .settings-col-left #settingsPersonalizationCard > .settings-note{ margin-top:auto; }
  .settings-card-account .settings-account-foot{ margin-top:auto; }
  /* Slightly tighter card chrome, desktop only — packs the composition
     without touching mobile's already-comfortable spacing. */
  .settings-card{ padding:18px 20px; }
  .settings-card-title{ margin-bottom:10px; }
  .settings-row{ padding:9px 0; }
}
.settings-card{ padding:22px; }
.settings-card-title{ font-size:15px; font-weight:700; margin-bottom:14px; }
.settings-row{ display:flex; align-items:center; justify-content:space-between; gap:16px; padding:11px 0; }
.settings-row + .settings-row{ border-top:1px solid var(--line); }
.settings-row-label{ font-size:13.5px; font-weight:600; color:var(--text-primary); }
.settings-row-value{ font-size:13.5px; color:var(--text-secondary); font-weight:500; }
.settings-row-hint{ font-size:12px; color:var(--text-tertiary); margin-top:2px; max-width:300px; }
.settings-row-control{ align-items:flex-start; }
.settings-badge{
  font-size:11px; font-weight:700; letter-spacing:0.03em; color:var(--text-tertiary); background:var(--surface-2);
  border:1px solid var(--line); padding:4px 10px; border-radius:99px; white-space:nowrap; flex:0 0 auto;
}
/* Reuses the exact .theme-toggle component from the sidebar (same markup,
   same behavior via setTheme/syncThemeToggleUI in app.js) — just not
   full-width/left-aligned here, since it sits inline in a settings row. */
.settings-theme-toggle{ width:auto; justify-content:flex-end; padding:0; }
.settings-switch{ position:relative; display:inline-flex; flex:0 0 auto; }
.settings-switch input{ position:absolute; opacity:0; width:1px; height:1px; }
.settings-switch-track{
  display:block; width:38px; height:22px; border-radius:99px; background:var(--surface-2); border:1px solid var(--line-strong); position:relative;
}
.settings-switch-track::after{
  content:""; position:absolute; top:2px; left:2px; width:16px; height:16px; border-radius:50%; background:var(--text-tertiary);
}
.settings-switch.is-disabled{ cursor:not-allowed; opacity:0.6; }
.settings-note{ font-size:12px; color:var(--text-tertiary); line-height:1.6; margin-top:14px; }
.settings-note.is-error{ color:var(--bad); }
.settings-copy{ font-size:13.5px; color:var(--text-secondary); line-height:1.65; }
.settings-logout-btn{ width:auto; padding:10px 22px; color:var(--bad); border-color:color-mix(in srgb, var(--bad) 30%, transparent); }
.settings-logout-btn:hover{ background:var(--bad-dim); }
.settings-action-btn{ width:auto; padding:9px 16px; flex:0 0 auto; }
/* QC#6 — support/help module + Log Out, BOTH inside the Account card. Support
   is a hairline-separated block above; Log Out is bottom-right of the card. */
.settings-card-account .settings-support{
  display:flex; align-items:center; gap:13px; margin-top:16px; padding-top:16px;
  border-top:1px solid var(--line);
}
.settings-support-ic{
  flex:0 0 auto; width:36px; height:36px; border-radius:10px; display:flex; align-items:center; justify-content:center;
  background:color-mix(in srgb, var(--violet) 12%, var(--surface-2));
  border:1px solid color-mix(in srgb, var(--violet) 24%, var(--line-strong));
}
.settings-support-ic svg{ width:17px; height:17px; stroke:var(--violet); fill:none; stroke-width:2; }
.settings-support-body{ flex:1 1 auto; min-width:0; }
.settings-support-title{ font-size:13px; font-weight:700; color:var(--text-primary); }
.settings-support-copy{ font-size:11.5px; color:var(--text-secondary); margin:2px 0 0; line-height:1.5; }
.settings-support-btn{ width:auto; padding:8px 14px; flex:0 0 auto; font-size:12.5px; }
.settings-support-btn svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2; margin-right:6px; }
.settings-account-foot{ display:flex; justify-content:flex-end; margin-top:16px; }
.settings-logout-btn svg{ width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:2; margin-right:7px; vertical-align:-2px; }
@media (max-width:620px){
  .settings-card-account .settings-support{ flex-wrap:wrap; }
  .settings-support-btn{ width:100%; justify-content:center; }
  .settings-account-foot .settings-logout-btn{ width:100%; justify-content:center; }
}

/* ==========================================================================
   MANAGE USERS — admin-only account seat / role / capability screen.
   Reuses .panel/.glass/.btn; adds only layout + table styling here. Scoped
   to #viewManageUsers so nothing else is affected.
   ========================================================================== */
#viewManageUsers .mu-wrap{ display:flex; flex-direction:column; gap:14px; max-width:1080px; }
#viewManageUsers .mu-panel{ padding:0; overflow:hidden; }
#viewManageUsers .mu-sub{ font-size:12.5px; color:var(--text-secondary); margin:3px 0 0; padding:14px 20px 0; }
#viewManageUsers .mu-table-wrap{ overflow-x:auto; }
#viewManageUsers .mu-table{ width:100%; border-collapse:collapse; font-size:13px; }
#viewManageUsers .mu-table th{
  text-align:left; font-size:10.5px; font-weight:700; letter-spacing:0.08em; text-transform:uppercase;
  color:var(--text-tertiary); padding:14px 14px 10px; border-bottom:1px solid var(--line); white-space:nowrap;
}
#viewManageUsers .mu-table td{ padding:12px 14px; border-bottom:1px solid var(--line); vertical-align:middle; }
#viewManageUsers .mu-table tr:last-child td{ border-bottom:0; }
#viewManageUsers .mu-row{ cursor:pointer; transition:background 0.12s ease; }
#viewManageUsers .mu-row:hover,
#viewManageUsers .mu-row:focus-visible{ background:var(--surface-1); outline:none; }
#viewManageUsers .mu-row-name{ display:flex; align-items:center; gap:6px; }
#viewManageUsers .mu-cell-email{ font-weight:500; word-break:break-all; color:var(--text-secondary); }
#viewManageUsers .mu-cell-actions{ text-align:right; white-space:nowrap; }
#viewManageUsers .mu-you{
  display:inline-block; font-size:10px; font-weight:700; letter-spacing:0.04em; text-transform:uppercase;
  padding:2px 7px; border-radius:999px; background:var(--surface-2); color:var(--text-secondary);
}
#viewManageUsers .mu-empty{ font-size:13px; color:var(--text-secondary); line-height:1.6; padding:28px 20px; text-align:center; }
#viewManageUsers .mu-empty strong{ color:var(--text-primary); display:block; margin-bottom:4px; }
/* "activates with the next backend release" — intentional, premium, not an error */
#viewManageUsers .mu-notready{ text-align:center; padding:40px 32px; max-width:520px; margin:24px auto 0; }
#viewManageUsers .mu-notready-badge{
  width:52px; height:52px; margin:0 auto 18px; border-radius:14px;
  display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); border:1px solid var(--line-strong, var(--line));
}
#viewManageUsers .mu-notready-badge svg{ width:22px; height:22px; stroke:var(--text-secondary); fill:none; stroke-width:1.6; }
#viewManageUsers .mu-notready h2{ font-size:16px; font-weight:700; margin:0 0 10px; line-height:1.35; }
#viewManageUsers .mu-notready p{ font-size:13px; color:var(--text-secondary); line-height:1.65; margin:0; }
#viewManageUsers .mu-demo-banner{
  font-size:12px; font-weight:600; color:var(--text-secondary);
  background:var(--surface-2); border:1px solid var(--line); border-radius:10px; padding:9px 13px;
}
#viewManageUsers .mu-danger{ color:var(--bad); border-color:color-mix(in srgb, var(--bad) 30%, transparent); }
#viewManageUsers .btn-sm{ padding:6px 12px; font-size:12px; }

/* Topbar: [Users][Invitations] tabs + primary Add User action */
#viewManageUsers .mu-topbar{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
#viewManageUsers .mu-tabs{ display:flex; gap:4px; padding:4px; background:var(--surface-1); border:1px solid var(--line); border-radius:11px; }
#viewManageUsers .mu-tab{
  font:inherit; font-size:13px; font-weight:600; color:var(--text-secondary);
  background:none; border:0; border-radius:8px; padding:8px 16px; cursor:pointer; display:flex; align-items:center; gap:7px;
  transition:background 0.12s ease, color 0.12s ease;
}
#viewManageUsers .mu-tab:hover{ color:var(--text-primary); }
#viewManageUsers .mu-tab.is-active{ background:var(--surface-3, var(--surface-2)); color:var(--text-primary); box-shadow:0 1px 2px rgba(0,0,0,0.15); }
#viewManageUsers .mu-tab-count{
  display:inline-flex; align-items:center; justify-content:center; min-width:18px; height:18px; padding:0 5px;
  font-size:10.5px; font-weight:700; border-radius:999px; background:var(--warn-dim, rgba(216,162,74,0.18)); color:var(--warn, #d8a24a);
}

/* Toolbar: search + filters, wraps naturally on tablet/mobile */
#viewManageUsers .mu-toolbar{ display:flex; flex-wrap:wrap; gap:8px; }
#viewManageUsers .mu-search{
  flex:1 1 220px; min-width:180px; display:flex; align-items:center; gap:8px;
  padding:8px 12px; border-radius:9px; border:1px solid var(--line-strong, var(--line)); background:var(--input-bg, var(--surface-1));
}
#viewManageUsers .mu-search svg{ width:15px; height:15px; stroke:var(--text-tertiary); fill:none; stroke-width:2; flex:0 0 auto; }
#viewManageUsers .mu-search input{ font:inherit; font-size:13px; border:0; background:none; outline:none; color:var(--text-primary); width:100%; }
#viewManageUsers .mu-filter{
  font:inherit; font-size:13px; padding:8px 10px; border-radius:9px;
  border:1px solid var(--line-strong, var(--line)); background:var(--input-bg, var(--surface-1)); color:var(--text-primary);
  flex:0 1 auto; min-width:0;
}

/* Add User sheet — mode tabs, security-sensitive grant-A opt-in, send toggle */
#viewManageUsers .mu-add-modetabs,
.mu-add-modetabs{ display:flex; gap:6px; margin-bottom:16px; padding:4px; background:var(--surface-1); border:1px solid var(--line); border-radius:10px; }
.mu-add-modetab{
  flex:1 1 0; font:inherit; font-size:12.5px; font-weight:600; color:var(--text-secondary);
  background:none; border:0; border-radius:7px; padding:8px 10px; cursor:pointer;
}
.mu-add-modetab.is-active{ background:var(--surface-3, var(--surface-2)); color:var(--text-primary); }
.mu-grant-a{
  display:flex; align-items:flex-start; gap:8px; font-size:12.5px; color:var(--warn, #d8a24a); line-height:1.5;
  margin:10px 0 0; padding:10px 12px; border-radius:9px; background:var(--warn-dim, rgba(216,162,74,0.1)); border:1px solid color-mix(in srgb, var(--warn, #d8a24a) 34%, transparent);
}
.mu-grant-a input{ margin-top:2px; flex:0 0 auto; }
.mu-send-toggle{ display:flex; flex-wrap:wrap; gap:16px; font-size:13px; color:var(--text-primary); margin:8px 0 4px; }
.mu-send-toggle label{ display:flex; align-items:center; gap:6px; cursor:pointer; }
.mu-sheet-actions{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:18px; padding-top:14px; border-top:1px solid var(--line); }
/* Activation-result / invite-state copy (muActivationResultHtml, invite
   detail statusNote) — was rendered with no rule at all until now. */
.mu-hint{ font-size:12.5px; line-height:1.5; color:var(--text-secondary); margin:10px 0 0; }
.mu-hint-error{ color:var(--bad); }

/* Per-user capability overrides (Manage Users profile, Super User A only) */
.mu-cap-groups{ display:flex; flex-direction:column; gap:14px; margin-top:10px; }
.mu-cap-group-title{ font-size:10.5px; font-weight:800; letter-spacing:0.07em; text-transform:uppercase; color:var(--text-tertiary); margin-bottom:6px; }
.mu-cap-row{
  display:flex; align-items:center; gap:10px; padding:7px 0;
  border-bottom:1px solid var(--line);
}
.mu-cap-group .mu-cap-row:last-child{ border-bottom:0; }
.mu-cap-check{ display:flex; align-items:center; gap:9px; cursor:pointer; flex:1 1 auto; min-width:0; }
.mu-cap-check input{ flex:0 0 auto; width:16px; height:16px; accent-color:var(--violet, #8e7cff); cursor:pointer; }
.mu-cap-label{ display:flex; flex-direction:column; gap:1px; font-size:12.5px; font-weight:600; color:var(--text-primary); min-width:0; }
.mu-cap-hint{ font-size:11px; font-weight:500; color:var(--text-tertiary); }
.mu-cap-tag{
  flex:0 0 auto; font-size:10px; font-weight:700; letter-spacing:0.03em; color:var(--text-tertiary);
  background:var(--surface-2); border-radius:6px; padding:3px 7px; white-space:nowrap;
}
.mu-cap-tag-override{ color:var(--warn, #d8a24a); background:var(--warn-dim, rgba(216,162,74,0.14)); }
.mu-cap-reset{
  flex:0 0 auto; font:inherit; font-size:11px; font-weight:700; color:var(--violet, #8e7cff);
  background:none; border:0; cursor:pointer; padding:3px 2px;
}
.mu-cap-reset:hover{ text-decoration:underline; }

@media (max-width:480px){
  /* Capability row stays understandable on a narrow sheet — label on its
     own line, the checkbox + tag/reset controls on the line below it,
     instead of squeezing all four onto one row. */
  .mu-cap-row{ flex-wrap:wrap; row-gap:4px; }
  .mu-cap-label{ flex-basis:100%; }
}

@media (max-width:640px){
  #viewManageUsers .mu-table thead{ display:none; }
  #viewManageUsers .mu-table,
  #viewManageUsers .mu-table tbody,
  #viewManageUsers .mu-table tr,
  #viewManageUsers .mu-table td{ display:block; width:100%; }
  #viewManageUsers .mu-table tr{ padding:12px 14px; border-bottom:1px solid var(--line); }
  #viewManageUsers .mu-table td{ padding:2px 0; border-bottom:0; }
  #viewManageUsers .mu-table td:empty{ display:none; }
  #viewManageUsers .mu-toolbar{ flex-direction:column; }
  #viewManageUsers .mu-filter{ width:100%; }
}

/* Item 7 — restrained marketing opt-in inside its own card. */
.settings-cta-title{ font-size:14.5px; font-weight:700; margin-bottom:4px; }
.settings-cta-desc{ font-size:12.5px; color:var(--text-secondary); margin-bottom:12px; }
/* Compact promotional callout — the site's own real guarantee language
   (see card/index.html), not invented terms. */
.settings-guarantee{
  display:flex; align-items:flex-start; gap:9px; margin-top:14px; padding-top:14px; border-top:1px solid var(--line);
  font-size:12px; color:var(--text-secondary); line-height:1.5;
}
.settings-guarantee svg{
  width:15px; height:15px; flex:0 0 auto; margin-top:1px; fill:none; stroke:var(--cyan); stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round;
}

/* Item 10 — pencil-triggered inline edit. At rest, .settings-view-mode
   (value + pencil) is visible and .settings-edit-mode is hidden; clicking
   the pencil swaps which one is hidden (see wireProfileEditRows in
   app.js). Never both visible, never a permanently-open input. */
.settings-edit-row .settings-view-mode{ display:flex; align-items:center; gap:8px; }
.settings-edit-row .settings-edit-mode{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; justify-content:flex-end; }
.settings-edit-note{ font-size:12.5px; color:var(--text-secondary); line-height:1.5; max-width:280px; margin:0; text-align:right; }
.settings-pencil-btn{
  display:flex; align-items:center; justify-content:center; width:26px; height:26px; padding:0; border-radius:8px;
  background:none; border:1px solid transparent; color:var(--text-tertiary); cursor:pointer; transition:background .16s ease, color .16s ease;
}
.settings-pencil-btn:hover{ background:var(--surface-hover); color:var(--text-primary); }
.settings-pencil-btn svg{ width:14px; height:14px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }

/* Profile — inline phone edit + password change (item 9). */
.settings-inline-edit{ display:flex; align-items:center; gap:8px; flex:0 0 auto; }
.settings-input{
  width:180px; padding:8px 11px; border-radius:9px; font-size:13px; color:var(--text-primary);
  background:var(--input-bg); border:1px solid var(--line);
}
.settings-input:focus{ outline:none; border-color:var(--violet); box-shadow:0 0 0 3px rgba(139,108,247,0.18); }
.settings-input::placeholder{ color:var(--text-tertiary); }
.settings-save-btn{
  padding:8px 14px; border-radius:9px; font-size:12.5px; font-weight:700; color:var(--text-primary);
  background:var(--surface-2); border:1px solid var(--line-strong); cursor:pointer; white-space:nowrap; transition:background .16s ease;
}
.settings-save-btn:hover{ background:var(--surface-hover); }
.settings-password-panel{
  margin-top:12px; padding:16px; border-radius:12px; background:var(--surface-1); border:1px solid var(--line);
  display:flex; flex-direction:column; gap:10px;
}
.settings-password-panel .settings-input{ width:100%; }
/* Item 4 — eye toggle for what's being TYPED right now, never a claim
   about revealing an existing stored password (Supabase Auth doesn't
   expose one to reveal). */
.settings-password-field{ position:relative; }
.settings-password-field .settings-input{ padding-right:38px; }
.settings-eye-btn{
  position:absolute; right:3px; top:50%; transform:translateY(-50%);
  width:26px; height:26px; padding:0; display:flex; align-items:center; justify-content:center;
  background:none; border:none; border-radius:7px; color:var(--text-tertiary); cursor:pointer; transition:background .16s ease, color .16s ease;
}
.settings-eye-btn:hover{ background:var(--surface-hover); color:var(--text-primary); }
.settings-eye-btn svg{ width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.settings-password-actions{ display:flex; align-items:center; gap:10px; margin-top:2px; }
.settings-cancel-btn{ background:none; border:none; color:var(--text-secondary); font-size:13px; font-weight:600; cursor:pointer; padding:6px 4px; }
.settings-cancel-btn:hover{ color:var(--text-primary); }
.settings-password-msg{ font-size:12.5px; color:var(--text-secondary); }
.settings-password-msg.is-error{ color:var(--bad); }
.settings-password-msg.is-success{ color:var(--good); }

/* Dashboard Preferences selects (Default Timeframe / 1EIGHTY Logo Action). */
.settings-select{
  appearance:none; padding:9px 30px 9px 12px; border-radius:10px; font-size:13px; font-weight:600; color:var(--text-primary);
  background:var(--surface-2) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239599AE' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 8px center;
  background-size:15px; border:1px solid var(--line); cursor:pointer; flex:0 0 auto;
}
.settings-select:focus{ outline:none; border-color:var(--violet); }

/* ==========================================================================
   Responsive — 1440 / 1280 desktop, 1024 compact/tablet, 768 tablet, 430/390 phone
   ========================================================================== */
@media (max-width:1280px){
  .kpi-grid{ grid-template-columns:repeat(3, 1fr); }
}
@media (max-width:1024px){
  /* The desktop collapsed-rail feature doesn't apply here — the sidebar is
     already an off-canvas drawer at this width (existing behavior,
     untouched), so a persisted "collapsed" preference from a wider session
     stays visually inert and the collapse control itself is hidden rather
     than sitting in the open drawer as a confusing no-op. */
  /* Sidebar slimming (item 3) is desktop-only — the mobile off-canvas
     drawer keeps its original, more spacious width regardless of
     --sidebar-w, since it's a full-width overlay panel, not a permanent
     column competing with the dashboard for space. */
  .sidebar{ position:fixed; z-index:40; transform:translateX(-100%); transition:transform .25s ease; box-shadow:20px 0 60px rgba(0,0,0,0.5); width:260px !important; overflow-y:auto; }
  .sidebar.is-open{ transform:translateX(0); }
  .sidebar-collapse-btn, .sidebar-divider{ display:none; }
  .main{ padding:10px 10px 50px; }
  body.is-overview .main{ padding-bottom:24px; }
  .journey-row{ flex-direction:column; }
  .journey-panel{ flex-basis:auto; }
  .ops-grid{ flex-direction:column; }
  .ops-grid > div{ flex:none; }
  /* Stacked Live Activity card is content-height (no stretch to distribute),
     so keep the six rows to a compact fixed rhythm rather than an equal
     share of nothing. */
  #liveFeedList{ flex:0 1 auto; }
  .feed-list-compact .feed-item{ flex:0 0 auto; min-height:0; padding:6px 0; }
  .topbar{ align-items:stretch; margin-bottom:26px; }
  .menu-toggle{ display:inline-flex !important; }
  /* item 5/10 — the desktop command-header panel's tighter 10px margin is a
     desktop-density choice; preserve the existing stacked-mobile breathing
     room here rather than forcing it. */
  body.is-command-header:not(.is-lead-record) .topbar{ margin-bottom:26px; }
}
@media (max-width:768px){
  .kpi-grid{ grid-template-columns:repeat(2, 1fr); gap:10px; }
  .gauge-grid{ grid-template-columns:1fr 1fr; }
  /* MOBILE IQ = the SAME four-quadrant composition as desktop, scaled down
     to fit — brain centred, one card in each corner, the network connecting
     them. NOT a stacked list. The body just takes a near-square aspect and
     the brain + cards shrink. app.js rebuilds the procedural field for the
     smaller brain + this aspect (iqRegime / buildIQField) so the plasma
     still originates at the ring and connectors still target the cards. */
  .iq-hero-body{ position:relative; aspect-ratio:1.45/1; height:auto; min-height:0; }
  .iq-network{ position:absolute; inset:0; aspect-ratio:auto; width:auto; }
  /* Brain width MUST equal 2 x iqRegime().rBase in app.js (25% <-> 0.125) —
     these had drifted apart (CSS said 27%, JS said 0.125/25%), which is
     exactly the "canvas geometry and DOM geometry disagree" bug: the
     particle/plasma field was built assuming a brain 2 points SMALLER than
     what actually rendered, so ambient dust and filament origins sat
     slightly inside the visible brain image instead of right at its edge. */
  .iq-brain-core{ width:25%; }
  .iq-slot{ position:absolute; z-index:3; width:37%; max-width:none; margin:0; }
  .iq-slot-tl{ left:2%; top:3%; right:auto; bottom:auto; }
  .iq-slot-tr{ right:2%; top:3%; left:auto; bottom:auto; }
  .iq-slot-bl{ left:2%; bottom:3%; right:auto; top:auto; }
  .iq-slot-br{ right:2%; bottom:3%; left:auto; top:auto; }
  .iq-slot-empty{ display:none; }
  .iq-slot:empty{ display:none; }
  /* compact card — visually subordinate to the brain, text still readable */
  .iq-card{ animation:none; opacity:1; transform:none; padding:8px 9px; border-radius:10px; }
  .iq-card-head{ gap:6px; margin-bottom:4px; }
  .iq-card-icon{ width:19px; height:19px; }
  .iq-card-icon svg{ width:10px; height:10px; }
  .iq-card-title{ font-size:10px; line-height:1.15; letter-spacing:0; }
  .iq-card p{ font-size:9.5px; line-height:1.32; }
  .iq-card .iq-rec{ margin-top:3px; }
  .iq-card-tag{ font-size:7px; padding:1px 4px; margin-left:5px; }
}
@media (max-width:430px){
  .main{ padding:10px 10px 44px; }
  body.is-overview .main{ padding-bottom:22px; }
  /* Two columns x three rows, no horizontal scroll/carousel — every metric
     visible on load. Cards use the full width the grid gives them (minus
     the shared gutter), same real estate math as every other mobile panel
     below, not a separate narrower lane. */
  .kpi-grid{ display:grid; grid-template-columns:repeat(2, 1fr); gap:10px; margin-bottom:14px; }
  .kpi-card{ padding:16px 16px 14px; }
  .panel{ padding:16px; }
  .topbar-title h1, .page-title h1{ font-size:20px; letter-spacing:0.1em; }
  /* Date range + timeframe selector read as one centered control group on
     mobile instead of the desktop's right-aligned inheritance. */
  .topbar-controls{ flex-direction:column; align-items:center; width:100%; margin-left:0; gap:8px; }
  .date-range{ text-align:center; }
  .funnel-node-ring{ width:46px; height:46px; }
  .funnel-node-ring svg{ width:17px; height:17px; }
  .funnel-node{ gap:6px; }
  .funnel-node-value{ font-size:14px; }
  .funnel-node-label{ font-size:10px; line-height:1.2; }
  .funnel-node-pct{ font-size:9.5px; }
  /* Item 21 — Performance Journey nearly kisses the mobile gutters instead
     of sitting at the same inset every other card uses: a negative margin
     eats most (not all — "a tiny intentional margin" survives) of .main's
     own 10px side padding, while the card's own padding is reduced by a
     matching amount so the funnel/content isn't pushed flush against the
     card's border. The badges themselves are untouched (still 19% width,
     see .funnel-node) — they simply end up with more container width to
     spread across, which is what maximizes the gap BETWEEN them without
     shrinking or redesigning any single badge. */
  .journey-panel{ margin-left:-6px; margin-right:-6px; padding-left:10px; padding-right:10px; }
  .gauge-instrument{ width:110px; height:76px; }
  .date-presets button{ padding:6px 9px; font-size:11px; }
  .rank-label{ width:150px; }
  /* phone: squarer IQ scene, smaller brain, cards to the very edges */
  .iq-hero-body{ aspect-ratio:0.98/1; }
  .iq-brain-core{ width:21%; }  /* MUST equal 2 x iqRegime().rBase (0.105) — see the ≤768px note above for why this must stay in sync */
  .iq-slot{ width:40%; }
  .iq-slot-tl{ left:1%; top:2%; } .iq-slot-tr{ right:1%; top:2%; }
  .iq-slot-bl{ left:1%; bottom:2%; } .iq-slot-br{ right:1%; bottom:2%; }
  .iq-card{ padding:6px 7px; border-radius:9px; }
  .iq-card-head{ gap:5px; margin-bottom:3px; }
  .iq-card-icon{ width:16px; height:16px; }
  .iq-card-icon svg{ width:9px; height:9px; }
  .iq-card-title{ font-size:9px; }
  .iq-card p{ font-size:8.5px; line-height:1.3; }
  .iq-card-tag{ font-size:6.5px; }
}
@media (max-width:390px){
  .kpi-card{ padding:14px 14px 12px; }
  .kpi-value{ font-size:32px; }
  .funnel-node-ring{ width:42px; height:42px; }
  .funnel-node-ring svg{ width:15px; height:15px; }
  .funnel-node-label{ font-size:9.5px; }
  .funnel-node-pct{ font-size:9px; }
}

.menu-toggle{
  display:none; align-items:center; justify-content:center; width:38px; height:38px; border-radius:10px;
  background:var(--surface-1); border:1px solid var(--line); color:var(--text-primary); cursor:pointer;
}
.sidebar-scrim{ display:none; }
@media (max-width:1024px){
  .sidebar-scrim.is-open{ display:block; position:fixed; inset:0; background:rgba(0,0,0,0.5); z-index:35; }
}

/* ==========================================================================
   LIGHT THEME
   Dark mode is the source of truth and is 100% untouched — everything below
   is additive, gated on :root[data-theme="light"] (or the [data-theme="light"]
   descendant form). Most of the work is done by the token overrides in the
   :root[data-theme="light"] block near the top of this file; the rules here
   handle components that hardcode dark-only values or need art-directed
   light treatment.

   Two heavy visualization modules — 1EIGHTY IQ and Performance Journey —
   deliberately stay DARK in light mode (see .iq-hero / .journey-panel
   below): their neon/plasma/brain/particle art is authored for a dark
   ground, so in a light dashboard they read as embedded dark consoles.
   That's a design choice, not a shortcut — forcing them light would mean
   redrawing every canvas.
   ========================================================================== */

/* ---- Theme transition — a restrained ~300ms ease on the big surfaces/text
   when the theme flips. Scoped to elements that DON'T already own a
   `transition` (adding one here would clobber theirs); .sidebar / .panel /
   .kpi-card get theme easing appended to their own transition lists in
   place instead, and .nav-item already eases background+color. Never `*`,
   never canvas. --- */
body,
.gauge,
.lead-row,
.leads-panel,
.leads-thead,
.lead-record-card,
.settings-input,
.settings-select,
.settings-card-title,
.date-presets,
.rank-track,
.topbar-title h1,
.topbar-subtitle,
.page-title h1,
.page-title .page-desc{
  transition:background-color .3s ease, border-color .3s ease, color .3s ease, box-shadow .3s ease;
}

[data-theme="light"] body{ -webkit-font-smoothing:auto; }

/* ---- Cards need real depth on a light ground (dark mode leaned on
   contrast alone). Soft, low, cool shadow — never a hard gray box. --- */
[data-theme="light"] .panel,
[data-theme="light"] .kpi-card,
[data-theme="light"] .login-card{ box-shadow:var(--shadow-card); }
/* QC#9 — the login mark now uses the transparent RGBA asset in BOTH themes
   (a bright violet !e, legible on the dark smoke and the light periwinkle),
   so no per-theme swap is needed. In light mode drop the violet glow. */
[data-theme="light"] .login-mark{ filter:none; }
[data-theme="light"] .panel:hover{
  border-color:var(--line-strong);
  box-shadow:0 2px 8px rgba(24,26,54,0.06), 0 18px 40px -18px rgba(24,26,54,0.14);
}

/* ---- KPI cards ---- */
/* Light: the pale 15%-tint well read as a washed-out pastel blob. Now a
   genuinely SATURATED accent well (near-full accent) + a soft accent bloom,
   with a crisp DARK glyph on top — high contrast, unmistakably the metric's
   colour, and it works for every accent including the pale ones (cyan/gold)
   where a coloured-on-pale glyph would have vanished. */
[data-theme="light"] .kpi-icon{
  background:color-mix(in srgb, var(--kpi-accent-solid, var(--violet)) 88%, #fff);
  box-shadow:0 4px 13px -3px color-mix(in srgb, var(--kpi-accent-solid, var(--violet)) 55%, transparent),
             inset 0 1px 0 rgba(255,255,255,0.28);
}
[data-theme="light"] .kpi-icon svg{ stroke:#0E1320; filter:none; }
[data-theme="light"] .kpi-card:hover{
  box-shadow:0 2px 6px rgba(24,26,54,0.06), 0 22px 40px -18px var(--kpi-glow, var(--brand-glow));
}

/* ---- Gauges (Engagement Overview) — white-on-dark strokes/insets flipped ---- */
[data-theme="light"] .gauge{
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.6), inset 0 12px 22px -18px rgba(24,26,54,0.18), 0 1px 2px rgba(24,26,54,0.04);
}
[data-theme="light"] .gauge-ring-outer{ stroke:rgba(28,27,64,0.08); }
[data-theme="light"] .gauge-ring-inner{ stroke:rgba(28,27,64,0.10); }
[data-theme="light"] .gauge-track,
[data-theme="light"] .gauge-seg{ stroke:rgba(28,27,64,0.10); filter:none; }
[data-theme="light"] .gauge-tick{ stroke:rgba(28,27,64,0.28); }
[data-theme="light"] .gauge-tick.major{ stroke:rgba(28,27,64,0.48); }
[data-theme="light"] .gauge-center .v{ text-shadow:0 1px 10px rgba(24,26,54,0.10); }

/* ---- Ranked lists (Traffic / Smart Accessories) ---- */
[data-theme="light"] .rank-track{ background:rgba(28,27,64,0.09); }
/* same saturated-well + dark-glyph treatment for the other metric icon
   wells that share this language (Traffic / Smart Accessories rows, Live
   Activity feed). Top Actions is excluded further down — it's a dark card. */
[data-theme="light"] .rank-icon{
  background:color-mix(in srgb, var(--row-accent, var(--violet)) 82%, #fff);
  box-shadow:0 3px 10px -3px color-mix(in srgb, var(--row-accent, var(--violet)) 50%, transparent);
}
[data-theme="light"] .rank-icon svg{ stroke:#0E1320; }
[data-theme="light"] .feed-icon{
  background:color-mix(in srgb, var(--feed-accent, var(--cyan)) 82%, #fff);
  box-shadow:0 3px 10px -3px color-mix(in srgb, var(--feed-accent, var(--cyan)) 50%, transparent);
}
[data-theme="light"] .feed-icon svg{ stroke:#0E1320; }

/* ---- Pagination dots ---- */
[data-theme="light"] .pager-dot.is-current,
[data-theme="light"] .pager-dot.is-current:hover{ background:var(--violet); box-shadow:0 0 6px color-mix(in srgb, var(--violet) 45%, transparent); }

/* ---- Light-mode navigation rail — an intentional pearl / soft
   lavender-white plane. Blends with the light dashboard but stays its own
   surface via a faint tint gradient, a hairline + inner light edge, and a
   soft depth shadow. Icon wells get an accent tint so every section colour
   still reads strongly; active items keep their per-section accent. Dark
   mode is untouched. --- */
[data-theme="light"] .sidebar{
  --sidebar-bg:#EDECF6;
  background:#EDECF6;
  border-right:1px solid rgba(28,27,64,0.10);
  box-shadow:inset -1px 0 0 rgba(255,255,255,0.65), 5px 0 26px -14px rgba(46,32,96,0.16);
}
/* 1E mark in light mode — swap in a genuinely transparent presentation of
   the SAME gradient mark (assets/logo-mark-light.png). It's the original
   logo-mark.png with its baked black background keyed out: a TIGHT
   luminance cut (smoothstep 150->235 on the max channel) removes the black
   ground AND the soft outer glow (which read as a dirty halo on the pearl),
   keeping only the crisp gradient mark + a ~1px clean edge. Exact same
   pixel positions / proportions as the dark asset — only alpha changes.
   NO background box, NO CSS recolour filter, NO drop-shadow — it sits flat
   and clean on the light rail. Dark mode keeps logo-mark.png untouched.
   Both sidebar states covered (sizing rules target .s-mark-lite too). */
[data-theme="light"] .sidebar-logo .s-mark{ display:none; }
[data-theme="light"] .sidebar-logo .s-mark-lite{ display:block; }
[data-theme="light"] .sidebar-profile{
  background:#FFFFFF; border-color:rgba(28,27,64,0.09);
  box-shadow:0 1px 2px rgba(46,32,96,0.05);
}
[data-theme="light"] .sidebar-upsell{ background:#FFFFFF; border-color:rgba(28,27,64,0.09); box-shadow:0 1px 3px rgba(46,32,96,0.05); }
[data-theme="light"] .sidebar-divider{ background:rgba(28,27,64,0.10); }
/* Light sidebar nav icons — the 14% pastel well let cyan/amber icons wash
   into the pearl. Now a stronger accent interior + a defined accent ring +
   a thicker full-accent glyph so every section colour has real weight. */
[data-theme="light"] .nav-item .nav-icon{
  background:color-mix(in srgb, var(--nav-accent, var(--violet)) 22%, #fff);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--nav-accent, var(--violet)) 46%, transparent);
}
[data-theme="light"] .nav-item .nav-icon svg{ stroke-width:2.35; }
[data-theme="light"] .nav-item.is-active .nav-icon{ background:color-mix(in srgb, var(--nav-accent, var(--violet)) 30%, #fff); box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--nav-accent, var(--violet)) 55%, transparent); }
[data-theme="light"] .nav-item:hover{ background:rgba(28,27,64,0.045); color:var(--text-primary); }
[data-theme="light"] .nav-item.is-active{
  color:var(--text-primary);
  background:color-mix(in srgb, var(--nav-accent, var(--violet)) 15%, #fff);
  box-shadow:0 0 0 1px color-mix(in srgb, var(--nav-accent, var(--violet)) 20%, transparent),
             inset 2px 0 0 var(--nav-accent, var(--violet)),
             0 6px 16px -9px color-mix(in srgb, var(--nav-accent, var(--violet)) 55%, transparent);
}
/* travelling indicator carries the active treatment in light mode too */
[data-theme="light"] .sidebar-nav.has-thumb .nav-item.is-active{ background:none; box-shadow:none; }
[data-theme="light"] .nav-thumb-jelly{
  background:color-mix(in srgb, var(--na) 15%, #fff);
  box-shadow:0 6px 16px -9px color-mix(in srgb, var(--na) 55%, transparent),
             inset 0 0 0 1px color-mix(in srgb, var(--na) 24%, transparent);
}
[data-theme="light"] .sidebar-foot-item:hover,
[data-theme="light"] .sidebar-collapse-btn:hover{ background:rgba(28,27,64,0.05); color:var(--text-primary); }
[data-theme="light"] .sidebar-foot-item.is-active{ background:color-mix(in srgb, var(--violet) 15%, #fff); }
@media (min-width:1025px){
  [data-theme="light"] .sidebar.is-collapsed .sidebar-foot-item:hover,
  [data-theme="light"] .sidebar.is-collapsed .sidebar-collapse-btn:hover,
  [data-theme="light"] .sidebar.is-collapsed .nav-item:not(.is-active):hover{
    background:rgba(28,27,64,0.05);
    box-shadow:0 0 0 1px rgba(122,85,240,0.16), 0 6px 14px -6px rgba(122,85,240,0.24);
  }
  [data-theme="light"] .sidebar.is-collapsed .nav-item:not(.is-active):hover .nav-icon{
    background:color-mix(in srgb, var(--nav-accent, var(--violet)) 20%, #fff);
  }
}

/* ---- Top bar / Command Center ---- */
[data-theme="light"] .topbar-title h1 .cmd-accent{ color:var(--text-primary); }
/* Light-mode "1EIGHTY ecosystem" shimmer. The dark-theme gradient runs to a
   near-WHITE middle stop — invisible as text on a light ground, which is
   why the phrase read blank. Uses `background-image` (not the `background`
   shorthand, which was silently resetting -webkit-background-clip and
   killing the text fill) + a deep blue->cyan->violet palette that keeps
   4:1+ contrast on the pearl page while still feeling more alive than the
   plain sentence before it. */
[data-theme="light"] .ecosystem-accent{
  background-image:linear-gradient(100deg, #2C5FD6 0%, #3F7BEE 20%, #0B8FC0 44%, #6A3AE0 60%, #0B8FC0 78%, #3F7BEE 100%);
  -webkit-background-clip:text; background-clip:text; color:transparent;
  text-shadow:0 0 9px rgba(58,110,230,0.28);
}

/* ---- Buttons ---- */
[data-theme="light"] .btn-primary{ box-shadow:0 4px 14px rgba(122,85,240,0.28); }
[data-theme="light"] .btn-primary:hover{ box-shadow:0 6px 20px rgba(122,85,240,0.38); }
[data-theme="light"] .glow-static::before{ opacity:0.42; }

/* ---- Timeframe selector ---- */
[data-theme="light"] .date-preset-thumb-jelly{
  box-shadow:0 2px 10px rgba(122,85,240,0.30), inset 0 0 0 1px rgba(122,85,240,0.22);
}

/* ---- Leads — premium light CRM ---- */
[data-theme="light"] .leads-search input,
[data-theme="light"] .lead-input,
[data-theme="light"] .lead-select{ background:#FFFFFF; }
/* frosted light header handled above */
[data-theme="light"] .lead-row:hover{ background:color-mix(in srgb, var(--violet) 5%, #fff); }
/* Solidify the status pill on white so the coloured text stays legible. */
[data-theme="light"] .lead-status-badge{
  background:color-mix(in srgb, var(--status-color, var(--violet)) 18%, #fff);
  border-color:color-mix(in srgb, var(--status-color, var(--violet)) 40%, #fff);
  color:color-mix(in srgb, var(--status-color, var(--violet)) 72%, #000);
}
[data-theme="light"] .leads-modetoggle{ background:#fff; }
[data-theme="light"] .leads-mode-opt[data-mode="construction"].is-active{ color:#B26E12; }
[data-theme="light"] .leads-mode-opt[data-mode="live"].is-active{ color:#12924E; }
[data-theme="light"] .leads-mode-opt[data-mode="live"].is-active .leads-mode-dot{
  box-shadow:0 0 5px rgba(18,146,78,0.6), 0 0 10px rgba(18,146,78,0.35);
}
[data-theme="light"] .leads-demo-badge{
  color:#9A5A0A; background:color-mix(in srgb, #F0A83E 20%, #fff); border-color:color-mix(in srgb, #F0A83E 45%, #fff);
}
[data-theme="light"] .lead-row.is-selected{ background:color-mix(in srgb, var(--violet) 8%, #fff); }
[data-theme="light"] .lead-check:checked::after{ border-color:#FFFFFF; }
/* #12/#13/#14 — light-mode Orbit dropdowns are driven by the shared GLASS
   FLOAT tokens (see :root[data-theme="light"] at the top of this file); no
   per-class light override needed. */
[data-theme="light"] .lead-drawer-scrim,
[data-theme="light"] .lead-sheet-scrim{ background:rgba(28,27,64,0.34); }
[data-theme="light"] .lead-sheet{ background:var(--ink-750); box-shadow:0 44px 96px -34px rgba(46,32,96,0.4); }
/* Quick View / Opportunity buttons need their own flair in light mode — a
   flat var(--surface-2) fill reads as bland next to the frosted card. */
[data-theme="light"] .lead-drawer-openrec,
[data-theme="light"] .lead-drawer-trackbtn{
  background:linear-gradient(180deg, rgba(255,255,255,0.85), color-mix(in srgb, var(--violet) 7%, #fff));
  border-color:color-mix(in srgb, var(--violet) 24%, var(--line-strong));
  box-shadow:0 1px 0 rgba(255,255,255,0.8) inset, 0 6px 16px -10px rgba(122,85,240,0.35);
}
[data-theme="light"] .lead-drawer-openrec:hover{
  background:linear-gradient(180deg, rgba(255,255,255,0.9), color-mix(in srgb, var(--violet) 12%, #fff));
  box-shadow:0 1px 0 rgba(255,255,255,0.9) inset, 0 8px 20px -10px rgba(122,85,240,0.45);
}
[data-theme="light"] .lead-action{
  background:linear-gradient(180deg, rgba(255,255,255,0.8), color-mix(in srgb, var(--violet) 5%, #fff));
  box-shadow:0 1px 0 rgba(255,255,255,0.8) inset;
}
[data-theme="light"] .lead-action:hover{ box-shadow:0 1px 0 rgba(255,255,255,0.9) inset, 0 4px 12px -8px rgba(122,85,240,0.4); }
[data-theme="light"] .lead-head-act{
  background:linear-gradient(180deg, rgba(255,255,255,0.8), color-mix(in srgb, var(--violet) 8%, #fff));
}
[data-theme="light"] .lead-toast{ background:var(--ink-750); box-shadow:0 18px 44px -14px rgba(46,32,96,0.32); }
[data-theme="light"] .lead-record-card{ box-shadow:var(--shadow-card); }

/* ---- DARK modules embedded in the light dashboard: 1EIGHTY IQ, the
   Performance Journey, AND Top Actions (which sits beside the Journey on
   desktop — keeping it dark makes that row read as one deliberate unit).
   Re-declaring the token subset scopes the dark palette to these subtrees
   only, so their headings/cards/rows stay readable and (for IQ/Journey)
   their canvases keep the ground they were painted for. --- */
[data-theme="light"] .iq-hero,
[data-theme="light"] .journey-panel,
[data-theme="light"] #topActionsPanel{
  background:var(--viz-surface);
  border:1px solid rgba(255,255,255,0.08);
  box-shadow:0 1px 2px rgba(24,26,54,0.10), 0 24px 50px -26px rgba(24,26,54,0.30);
  --text-primary:#F3F4F9;
  --text-secondary:#94A3B8;
  --text-tertiary:#565C74;
  /* explicit color so descendants that rely on INHERITED color (h2, card
     titles, the stage numbers, action rows) get the dark-panel value, not
     the page's light text which was already computed higher up the tree */
  color:#F3F4F9;
  --surface-1:rgba(255,255,255,0.028);
  --surface-2:rgba(255,255,255,0.05);
  --surface-hover:rgba(255,255,255,0.065);
  --line:rgba(255,255,255,0.07);
  --line-strong:rgba(255,255,255,0.14);
  --ink-850:#0E111C;
  --input-bg:rgba(255,255,255,0.04);
  --scrollbar-thumb:rgba(255,255,255,0.14);
  --scrollbar-thumb-active:rgba(255,255,255,0.3);
}
/* the IQ hero's own inner surface reference */
[data-theme="light"] .iq-hero{ background:radial-gradient(ellipse 120% 90% at 50% 0%, rgba(139,108,247,0.10), transparent 60%), var(--viz-surface); }
/* Top Actions overflow fade blends to its own dark surface, not the page. */
[data-theme="light"] #topActionsPanel.is-overflowing::after{ background:linear-gradient(to bottom, transparent, var(--viz-surface)); }
/* Top Actions is a DARK card in light mode — its internal treatment must
   stay dark-mode too. The generic light .rank-icon / .rank-track overrides
   would otherwise wash the action icons to a white well and flatten the
   bars; restore the dark-mode values inside this panel only. */
[data-theme="light"] #topActionsPanel .rank-icon{ background:color-mix(in srgb, var(--row-accent, var(--violet)) 20%, transparent); box-shadow:none; }
[data-theme="light"] #topActionsPanel .rank-icon svg{ stroke:color-mix(in srgb, var(--row-accent, var(--violet)) 82%, #fff); }
[data-theme="light"] #topActionsPanel .rank-track{ background:rgba(255,255,255,0.055); }
/* dark-appropriate hover glow for the dark modules (the generic light
   .panel:hover would put an invisible pale shadow on them) */
@media (hover:hover) and (pointer:fine){
  [data-theme="light"] .iq-hero:hover,
  [data-theme="light"] .journey-panel:hover,
  [data-theme="light"] #topActionsPanel:hover{
    border-color:rgba(255,255,255,0.14);
    box-shadow:0 0 0 1px rgba(255,255,255,0.10), 0 0 26px -10px rgba(255,255,255,0.24), 0 24px 50px -26px rgba(24,26,54,0.30);
  }
}

/* ---- Engagement Overview is another DARK module in light mode ---------------
   The OUTER cockpit panel (which frames the four bespoke gauge instruments)
   stays near-black in light mode so the four cards — each a committed dark
   instrument in BOTH themes — sit on a matching ground instead of a white
   card. Same token-subset scoping as IQ / the Journey above; the individual
   .eng-*-card treatments are untouched. Dark mode is unaffected (these rules
   are all [data-theme="light"]-scoped). --- */
[data-theme="light"] #engagementPanel{
  background:radial-gradient(ellipse 120% 90% at 50% 0%, rgba(139,108,247,0.08), transparent 58%), var(--viz-surface);
  border:1px solid rgba(255,255,255,0.08);
  box-shadow:0 1px 2px rgba(24,26,54,0.10), 0 24px 50px -26px rgba(24,26,54,0.30);
  --text-primary:#F3F4F9;
  --text-secondary:#94A3B8;
  --text-tertiary:#565C74;
  color:#F3F4F9;
  --surface-1:rgba(255,255,255,0.028);
  --surface-2:rgba(255,255,255,0.05);
  --surface-hover:rgba(255,255,255,0.065);
  --line:rgba(255,255,255,0.07);
  --line-strong:rgba(255,255,255,0.14);
}
/* h2 + subtitle: white title, muted subtitle — same values the Journey /
   IQ headings resolve to in light mode. */
[data-theme="light"] #engagementPanel .panel-head h2{ color:#F3F4F9; }
[data-theme="light"] #engagementPanel .panel-head p{ color:#94A3B8; }
/* Video Performance below the gauges is a permanent dark "cockpit island"
   regardless of site theme, same as the four hero cards above it — every
   one of its colors (styles.css .video-strip* rules) is now a hardcoded
   hex, not a theme var, so no light-theme override is needed here anymore. */
@media (hover:hover) and (pointer:fine){
  [data-theme="light"] #engagementPanel:hover{
    border-color:rgba(255,255,255,0.14);
    box-shadow:0 0 0 1px rgba(255,255,255,0.10), 0 0 26px -10px rgba(255,255,255,0.24), 0 24px 50px -26px rgba(24,26,54,0.30);
  }
}

/* ---- Settings ---- */
[data-theme="light"] .settings-password-panel{ background:var(--surface-2); }
[data-theme="light"] .settings-select{
  background-color:var(--input-bg);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23565C71' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}
[data-theme="light"] .settings-switch-track{ background:var(--surface-hover); }
[data-theme="light"] .settings-save-btn{ background:var(--surface-2); }

/* ==========================================================================
   PRODUCT PREVIEW MOCKS — Digital Card ("Card Studio") + Smart Accessories
   ("Accessory Manager"). Non-functional visual previews of modules being
   built, shown UNDER a Coming Soon overlay (same spirit as the Leads
   preview). Everything uses the standard tokens so both mocks theme
   automatically in light and dark. aria-hidden in the markup; nothing wired.
   ========================================================================== */
.mock-note{ font-size:12.5px; color:var(--text-tertiary); margin-bottom:10px; }
.mock-shell{ position:relative; overflow:hidden; padding:0; }
@media (min-width:1025px){
  .mock-shell{ min-height:calc(100dvh - 150px); margin-bottom:-50px; }
}
/* QC P1 — ROOT CAUSE of "My Accessories / Accessory Performance sit flush
   against the card's left edge": this rule keyed its 22px inset entirely off
   [aria-hidden="true"], which was accurate only for the original static-only
   "nothing wired" mock. renderSaAll() (app.js) now calls
   manager.removeAttribute('aria-hidden') on every real render — Construction
   mode included, so in practice this fires almost immediately — which
   silently dropped #saManager back to .mock-shell's own padding:0 the moment
   real content painted. #saManager is named explicitly here so the inset
   holds in both the pre-render and live states; Card Studio's own mock
   (still genuinely inert, aria-hidden never removed) is unaffected. */
.mock-shell > [aria-hidden="true"], #saManager{ padding:22px; }
/* density-audit finding — .mock-shell's min-height/negative-margin pair was
   built for the Coming-Soon-only era of these previews (still correct for
   Card Studio below, a genuine static placeholder that wants a full,
   immersive card height). Smart Accessories stopped being a placeholder
   several sessions ago, but kept inheriting this ~viewport-tall minimum —
   on a normal desktop that reserves far more height than the now-dense
   real content needs, showing as one large empty band at the bottom of the
   shell (not between modules, but exactly as wasted). Scoped to this page
   only; Card Studio's own .mock-shell is untouched. */
@media (min-width:1025px){
  #viewSmartAccessories .mock-shell{ min-height:0; margin-bottom:0; }
}
/* SA header — less dead air between the page subtitle and the first
   analytics row; a dashboard, not a landing-page hero. Top inset only —
   left/right/bottom stay at the shared 22px so the card's outer frame
   still reads consistently with Card Studio's. */
#viewSmartAccessories .mock-shell > [aria-hidden="true"],
#viewSmartAccessories #saManager{ padding-top:14px; }

/* ---- shared Coming Soon overlay (mirrors .leads-overlay) ---- */
.mock-overlay{
  position:absolute; inset:0; display:flex; align-items:flex-start; justify-content:center;
  padding:clamp(48px, 15vh, 150px) 24px 24px;
  background:radial-gradient(ellipse 78% 68% at 50% 30%, rgba(6,7,12,0.62) 0%, rgba(6,7,12,0.4) 52%, rgba(6,7,12,0.12) 88%);
  backdrop-filter:blur(1.5px); -webkit-backdrop-filter:blur(1.5px);
}
[data-theme="light"] .mock-overlay{
  background:radial-gradient(ellipse 78% 68% at 50% 30%, rgba(233,234,243,0.78) 0%, rgba(233,234,243,0.5) 52%, rgba(233,234,243,0.1) 88%);
}
.mock-overlay-card{
  text-align:center; max-width:380px; padding:30px 34px; border-radius:20px;
  background:rgba(10,12,20,0.8); border:1px solid var(--line-strong);
  box-shadow:0 26px 64px -18px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04), 0 0 44px -18px var(--brand-glow);
  backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px);
}
[data-theme="light"] .mock-overlay-card{
  background:rgba(255,255,255,0.92); color:var(--text-primary); border-color:var(--line-strong);
  box-shadow:0 26px 64px -22px rgba(24,26,54,0.3), 0 0 0 1px rgba(255,255,255,0.7), 0 0 44px -20px var(--brand-glow);
}
.mock-overlay-icon{
  width:52px; height:52px; margin:0 auto 16px; border-radius:15px; display:flex; align-items:center; justify-content:center;
  background:var(--brand-gradient); box-shadow:0 0 24px -4px var(--brand-glow);
}
.mock-overlay-icon svg{ width:25px; height:25px; stroke:#0A0A16; fill:none; stroke-width:2; }
.mock-overlay-eyebrow{ font-family:'JetBrains Mono', monospace; font-size:11px; font-weight:700; letter-spacing:0.12em; text-transform:uppercase; color:var(--cyan); margin-bottom:7px; }
.mock-overlay-title{ font-size:25px; font-weight:800; letter-spacing:-0.01em; margin-bottom:9px; }
.mock-overlay-desc{ font-size:14.5px; color:var(--text-secondary); line-height:1.55; }

/* ---- Digital Card — real identity/share hero + preview + performance ---- */
.dc-identity-card{ padding:16px 18px; }
/* #15-17 — one horizontal identity / command bar */
.dc-headbar{ display:flex; align-items:center; gap:20px; flex-wrap:wrap; }
.dc-headbar-id{ display:flex; align-items:center; gap:13px; flex:1 1 240px; min-width:220px; }
.dc-id-avatar{
  width:56px; height:56px; flex:0 0 auto; border-radius:50%; border:2px solid var(--line-strong);
  background-size:cover; background-position:center; display:flex; align-items:center; justify-content:center; overflow:hidden;
}
.dc-id-avatar #dcAvatarInitials{ width:100%; height:100%; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:18px; font-weight:800; color:#0A0A16; background:var(--brand-gradient); }
.dc-id-avatar.has-photo #dcAvatarInitials{ display:none; }
.dc-id-info{ min-width:0; flex:1 1 auto; }
.dc-id-name{ font-size:18px; font-weight:800; letter-spacing:-0.01em; line-height:1.25; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dc-id-role{ font-size:12.5px; color:var(--text-secondary); margin-top:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dc-id-status{
  display:flex; align-items:center; gap:6px; font-size:10px; font-weight:800;
  letter-spacing:0.05em; text-transform:uppercase; color:var(--good); background:var(--good-dim);
  border:1px solid color-mix(in srgb, var(--good) 32%, transparent); border-radius:99px; padding:5px 11px 4px; flex:0 0 auto;
}
.dc-status-dot{ width:6px; height:6px; border-radius:50%; background:var(--good); box-shadow:0 0 0 3px color-mix(in srgb, var(--good) 25%, transparent); }

/* card link column */
.dc-headbar-link{
  flex:1 1 300px; min-width:240px; display:flex; flex-direction:column; gap:7px;
  padding-left:20px; border-left:1px solid var(--line);
}
.dc-link-label{
  font-family:'JetBrains Mono', ui-monospace, monospace; font-size:10px; font-weight:700;
  letter-spacing:0.12em; text-transform:uppercase; color:var(--text-tertiary);
}
.dc-id-url-row{ display:flex; align-items:center; gap:8px; min-width:0; }
.dc-id-url-ic{ width:13px; height:13px; flex:0 0 auto; stroke:var(--text-tertiary); fill:none; stroke-width:2; }
.dc-id-url{
  font-family:'JetBrains Mono', ui-monospace, monospace; font-size:12.5px; color:var(--text-secondary);
  flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.dc-id-actions{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.dc-act-btn{ width:auto; padding:8px 13px; font-size:12px; gap:6px; }
.dc-act-btn svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; flex:0 0 auto; }
.dc-act-btn.is-copied{ color:var(--good); border-color:color-mix(in srgb, var(--good) 45%, transparent); background:color-mix(in srgb, var(--good) 14%, transparent); }

/* compact QR column */
.dc-headbar-qr{ flex:0 0 auto; display:flex; flex-direction:column; align-items:center; gap:7px; }
.dc-qr-img{
  width:104px; height:104px; border-radius:9px; overflow:hidden; background:#fff;
  display:flex; align-items:center; justify-content:center; padding:6px;
  box-shadow:0 0 0 1px var(--line-strong), 0 6px 18px -12px rgba(0,0,0,0.45);
}
.dc-qr-img img{ width:100%; height:100%; display:block; image-rendering:pixelated; }
.dc-qr-img .empty-note{ font-size:9px; color:#555; text-align:center; padding:4px; line-height:1.3; }
.dc-qr-copy-mini{
  display:inline-flex; align-items:center; gap:5px; cursor:pointer; font:inherit; font-size:10.5px; font-weight:700;
  padding:4px 10px; border-radius:7px; color:var(--text-secondary);
  background:var(--surface-2); border:1px solid var(--line-strong); transition:color .12s ease, border-color .12s ease;
}
.dc-qr-copy-mini:hover{ color:var(--text-primary); border-color:var(--violet-dim); }
.dc-qr-copy-mini.is-copied{ color:var(--good); border-color:color-mix(in srgb, var(--good) 45%, transparent); }
.dc-qr-copy-mini svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2; flex:0 0 auto; }

/* #11 — desktop identity presence. Previously this block had no min-width
   rule at all: 48px avatar / 18px name at every width from a phone up to an
   ultrawide monitor, so it read as an afterthought under the "Digital Card"
   command bar rather than the confident identity display the desktop's
   available width can support. Mobile (≤1080px, where the max-width rules
   below already reflow the layout) is untouched — this only fires above
   that same breakpoint the existing responsive rules already use. */
@media (min-width:1081px){
  .dc-identity-card{ padding:22px 26px; }
  .dc-headbar-id{ gap:18px; }
  /* QC#6 — ~50% larger desktop identity avatar to balance the 27px name */
  .dc-id-avatar{ width:112px; height:112px; border-width:3px; }
  .dc-id-avatar #dcAvatarInitials{ font-size:34px; }
  .dc-id-name{ font-size:27px; letter-spacing:-0.015em; }
  .dc-id-role{ font-size:14.5px; margin-top:4px; }
}
/* responsive reflow */
@media (max-width:1080px){
  .dc-headbar-link{ flex-basis:100%; padding-left:0; border-left:none; border-top:1px solid var(--line); padding-top:12px; order:3; }
  .dc-headbar-qr{ order:2; }
}
@media (max-width:560px){
  .dc-headbar{ gap:14px; }
  .dc-headbar-id{ min-width:0; flex-basis:100%; }
  .dc-headbar-qr{ flex-basis:100%; flex-direction:row; justify-content:flex-start; }
  .dc-id-actions{ width:100%; }
  .dc-act-btn{ flex:1 1 auto; justify-content:center; }
}

.dc-main-row{ display:flex; gap:16px; align-items:stretch; margin:16px 0; }
/* No align-items:center here on purpose — flex's default cross-axis
   stretch keeps .panel-head/.dc-preview-cap at full container width (so
   their own text-align/justify-content behave normally); only the phone
   itself is centered, via margin:0 auto on .dc-phone. */
.dc-preview-card{ flex:0 0 300px; display:flex; flex-direction:column; }
.dc-performance-card{ flex:1 1 0; min-width:0; }
.dc-preview-cap{ font-size:12px; color:var(--text-tertiary); text-align:center; margin-top:14px; }

.dc-perf-stats{ display:grid; grid-template-columns:repeat(3,1fr); gap:10px; margin-bottom:18px; }
/* Small reusable stat pill (identity bar + big number + label) — used here
   and nowhere else today, but kept as a standalone, page-agnostic
   component (not named after either page) since it's exactly the kind of
   thing a future card-metric surface would want to reuse. */
.stat-tile{
  position:relative; overflow:hidden; min-width:0;
  padding:15px 16px 14px; border-radius:var(--radius-md);
  background:linear-gradient(180deg, color-mix(in srgb, var(--violet) 6%, var(--surface-1)), var(--surface-1));
  border:1px solid var(--line-strong);
}
.stat-tile::before{ content:""; position:absolute; left:0; top:0; bottom:0; width:2px; background:var(--brand-gradient); opacity:0.6; }
.stat-tile-v{ font-size:22px; font-weight:800; letter-spacing:-0.02em; line-height:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.stat-tile-l{ font-size:10.5px; font-weight:700; color:var(--text-tertiary); text-transform:uppercase; letter-spacing:0.04em; margin-top:6px; }
[data-theme="light"] .stat-tile{ background:linear-gradient(180deg, color-mix(in srgb, var(--violet) 4%, #fff), #fff); box-shadow:var(--shadow-card); }
.dc-stat .stat-tile-v{ color:var(--dc-stat-accent, var(--text-primary)); }
.dc-stat-chg{ font-size:11px; font-weight:700; margin-top:5px; display:flex; align-items:center; gap:3px; }
.dc-stat-chg.is-up{ color:var(--good); }
.dc-stat-chg.is-down{ color:var(--bad); }
.dc-stat-chg.is-flat{ color:var(--text-tertiary); }
.dc-perf-sub{ display:flex; flex-direction:column; gap:16px; }
.dc-perf-col + .dc-perf-col{ padding-top:16px; border-top:1px solid var(--line); }
.dc-perf-col-h{ font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:0.04em; color:var(--text-tertiary); margin-bottom:8px; }
.dc-perf-col .rank-row{ padding:7px 0; }
.dc-perf-col .feed-item{ padding:6px 0; }

@media (max-width:1024px){
  .dc-main-row{ flex-direction:column; }
  .dc-preview-card{ flex:1 1 auto; }
}
@media (max-width:640px){
  .dc-perf-stats{ grid-template-columns:1fr 1fr; }
}

/* ---- Card Studio editor (Coming Soon preview — see .mock-shell) ---- */
.dc-editor{ display:flex; flex-direction:column; gap:14px; min-width:0; }
/* §23 — Contact + Links & Socials share a row so Appearance rises into the
   space they used to occupy stacked; the tall empty gutter below the
   editor collapses. Presentation only — nothing here is a live builder. */
.dc-editor-pair{ display:grid; grid-template-columns:1fr 1fr; gap:14px; align-items:start; min-width:0; }
.dc-editor-pair > .dc-block{ min-width:0; }
@media (max-width:1180px){ .dc-editor-pair{ grid-template-columns:1fr; } }
.dc-block{ background:var(--surface-1); border:1px solid var(--line); border-radius:var(--radius-md); padding:16px; }
.dc-block-head{ font-size:13px; font-weight:800; margin-bottom:12px; display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; }
.dc-block-hint{ font-size:11px; font-weight:500; color:var(--text-tertiary); letter-spacing:0; }
.dc-identity{ display:flex; gap:14px; align-items:center; }
.dc-avatar{ position:relative; width:62px; height:62px; flex:0 0 auto; border-radius:50%; border:2px solid var(--line-strong); }
.dc-avatar-initials{ width:100%; height:100%; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:19px; font-weight:800; color:#0A0A16; background:var(--brand-gradient); }
.dc-avatar-badge{ position:absolute; right:-2px; bottom:-2px; width:22px; height:22px; border-radius:50%; background:var(--brand-gradient); display:flex; align-items:center; justify-content:center; border:2px solid var(--surface-1); }
.dc-avatar-badge svg{ width:11px; height:11px; stroke:#0A0A16; fill:none; stroke-width:2.4; }
.dc-fields{ flex:1 1 auto; display:flex; flex-direction:column; gap:8px; min-width:0; }
.dc-field{ display:flex; flex-direction:column; gap:3px; }
.dc-field label{ font-size:10px; font-weight:700; letter-spacing:0.05em; text-transform:uppercase; color:var(--text-tertiary); }
.dc-input{ font-size:13px; font-weight:600; color:var(--text-primary); background:var(--input-bg); border:1px solid var(--line); border-radius:8px; padding:7px 10px; }
.dc-input-sm{ font-size:12.5px; font-weight:500; padding:6px 9px; flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dc-row, .dc-link{ display:flex; align-items:center; gap:10px; padding:8px 0; }
.dc-row + .dc-row, .dc-link + .dc-link{ border-top:1px solid var(--line); }
.dc-row-ic{ width:26px; height:26px; flex:0 0 auto; border-radius:8px; display:flex; align-items:center; justify-content:center; background:color-mix(in srgb, var(--dc, var(--violet)) 16%, transparent); }
.dc-row-ic svg{ width:13px; height:13px; stroke:var(--dc, var(--violet)); fill:none; stroke-width:2; }
.dc-row-l{ font-size:12.5px; font-weight:600; color:var(--text-secondary); width:74px; flex:0 0 auto; }
.dc-grip{ color:var(--text-tertiary); font-size:11px; letter-spacing:-2px; cursor:grab; flex:0 0 auto; }
.dc-link .dc-row-l{ flex:1 1 auto; width:auto; color:var(--text-primary); }
.dc-mini-toggle{ width:34px; height:19px; border-radius:99px; background:var(--surface-2); border:1px solid var(--line-strong); position:relative; flex:0 0 auto; }
.dc-mini-toggle span{ position:absolute; top:1px; left:1px; width:15px; height:15px; border-radius:50%; background:var(--text-tertiary); transition:transform .18s ease; }
.dc-mini-toggle.is-on{ background:color-mix(in srgb, var(--good) 30%, transparent); border-color:color-mix(in srgb, var(--good) 45%, transparent); }
.dc-mini-toggle.is-on span{ transform:translateX(15px); background:var(--good); }
.dc-templates{ display:flex; gap:8px; margin-bottom:12px; }
.dc-template{ flex:1 1 0; font-size:11px; font-weight:700; text-align:center; padding:8px 4px; border-radius:10px; border:1px solid var(--line); color:var(--text-secondary); }
.dc-template.is-selected{ border-color:color-mix(in srgb, var(--violet) 55%, transparent); background:color-mix(in srgb, var(--violet) 12%, transparent); color:var(--text-primary); }
.dc-tpl-swatch{ display:block; height:26px; border-radius:6px; margin-bottom:6px; }
.dc-tpl-a{ background:linear-gradient(135deg,#8B6CF7,#2FD0FF); }
.dc-tpl-b{ background:linear-gradient(135deg,#141828,#3E7BFA); }
.dc-tpl-c{ background:linear-gradient(135deg,#EDECF6,#C9C6E8); }
.dc-swatches{ display:flex; gap:8px; align-items:center; }
.dc-sw{ width:24px; height:24px; border-radius:50%; flex:0 0 auto; border:2px solid transparent; box-shadow:0 0 0 1px var(--line-strong); }
.dc-sw.is-selected{ border-color:var(--surface-1); box-shadow:0 0 0 2px var(--violet); }
.dc-sw-custom{ display:flex; align-items:center; justify-content:center; background:var(--surface-2); color:var(--text-secondary); font-weight:700; box-shadow:0 0 0 1px var(--line-strong); }
/* Realistic modern-iPhone hardware: tall 19.5:9 screen, thin uniform bezel,
   continuous-corner radius, floating Dynamic Island, titanium-edge sheen,
   side buttons. Compact on purpose so it complements the dashboard instead of
   dominating it. The screen holds a faithful miniature of the real public
   card (card/index.html) — dark shell, rainbow gradient cover + avatar ring,
   white name / gradient company / mono title, 5-action grid, secondary bar. */
.dc-phone{
  width:230px; border-radius:44px; padding:6px; position:relative; margin:0 auto;
  background:
    linear-gradient(150deg,#42444f 0%,#17181e 26%,#0b0c11 50%,#17181e 74%,#42444f 100%);
  box-shadow:0 44px 84px -26px rgba(0,0,0,0.62), 0 8px 24px -12px rgba(0,0,0,0.5),
    inset 0 0 0 1px rgba(255,255,255,0.08), inset 0 0 0 3px rgba(0,0,0,0.55);
}
.dc-phone-btn{ position:absolute; border-radius:2px; background:linear-gradient(90deg,#4a4c57,#1b1c23); }
.dc-phone-btn-vol{ left:-2px; top:118px; width:3px; height:74px; box-shadow:0 44px 0 -22px #1b1c23, 0 96px 0 -22px #1b1c23; border-radius:2px 0 0 2px; }
.dc-phone-btn-pwr{ right:-2px; top:150px; width:3px; height:64px; border-radius:0 2px 2px 0; background:linear-gradient(270deg,#4a4c57,#1b1c23); }
.dc-phone-screen{
  position:relative; border-radius:38px; overflow:hidden; background:#07080E;
  aspect-ratio:9 / 19.3; display:flex; flex-direction:column;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,0.7), inset 0 0 22px rgba(0,0,0,0.55);
}
.dc-phone-island{
  position:absolute; top:9px; left:50%; transform:translateX(-50%);
  width:74px; height:22px; border-radius:99px; background:#000; z-index:5;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,0.05), 0 1px 3px rgba(0,0,0,0.6);
}
.dc-phone-island::after{
  content:""; position:absolute; right:9px; top:50%; transform:translateY(-50%);
  width:6px; height:6px; border-radius:50%;
  background:radial-gradient(circle at 35% 35%, #26304a, #05060a 70%);
  box-shadow:inset 0 0 0 1px rgba(120,150,200,0.25);
}
.dc-phone-screen::after{
  content:""; position:absolute; left:50%; bottom:6px; transform:translateX(-50%);
  width:88px; height:3.5px; border-radius:99px; background:rgba(255,255,255,0.4); z-index:6;
}
/* #24 — the mini preview scrolls now, same as the real published card is a
   long scrolling page: the hero (cover/avatar/name/actions/CTA/learn-more/
   divider) no longer has to be squeezed to fit one fixed phone-screen
   height, and it reads as more honestly "the same page, zoomed out". */
.dc-phone-scroll{
  flex:1 1 auto; min-height:0; overflow-y:auto; overflow-x:hidden; -webkit-overflow-scrolling:touch;
  display:flex; flex-direction:column; padding-bottom:16px; scrollbar-width:none;
}
.dc-phone-scroll::-webkit-scrollbar{ display:none; }

/* ---- mini card ---- */
.dc-card{ flex:1 1 auto; display:flex; flex-direction:column; background:#07080E; color:#F4F5FA; }
.dc-card-cover{
  position:relative; height:84px; flex:0 0 auto; overflow:hidden;
  background:linear-gradient(115deg,#FF4F8B 0%,#8B5CF6 48%,#22C6FF 100%);
}
.dc-card-cover::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(180deg, transparent 40%, rgba(7,8,14,0.5) 78%, #07080E 100%);
}
.dc-card-body{ position:relative; flex:1 1 auto; padding:0 16px 16px; text-align:center; display:flex; flex-direction:column; align-items:center; }
/* #24 — mirrors the real card's photo row: two small circular side actions
   (Reviews / Form on the real card) flanking a larger, hero-scale avatar,
   instead of a lone small avatar with nothing beside it. */
.dc-card-photorow{ display:flex; align-items:center; justify-content:center; gap:10px; margin:-34px 0 8px; z-index:2; position:relative; }
.dc-card-sidebtn{
  flex:0 0 auto; width:26px; height:26px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  background:rgba(20,21,28,0.82); box-shadow:inset 0 0 0 1px rgba(255,255,255,0.1), 0 0 14px -6px rgba(139,92,246,0.55);
  margin-top:20px;
}
.dc-card-sidebtn svg{ width:11px; height:11px; stroke:#C7CAD8; fill:none; stroke-width:2; }
.dc-card-avatar{
  position:relative; width:68px; height:68px; border-radius:50%; z-index:2; flex:0 0 auto;
  background:conic-gradient(from 210deg,#FF4F8B,#8B5CF6,#22C6FF,#FF4F8B);
  padding:2px; box-sizing:border-box;
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 0 20px -6px rgba(139,92,246,0.6);
}
.dc-card-avatar::before{
  content:""; position:absolute; inset:2px; border-radius:50%;
  background:#0B0D16 var(--dc-preview-photo, none) center / cover no-repeat;
}
.dc-card-avatar span{
  position:relative; z-index:1; font-size:19px; font-weight:800; color:#F4F5FA;
  letter-spacing:0.02em;
}
.dc-card-avatar.has-photo span{ display:none; }
.dc-card-name{ font-size:16px; font-weight:800; line-height:1.2; color:#fff; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; margin-top:2px; }
.dc-card-company{
  font-size:11.5px; font-weight:800; margin-top:3px; max-width:100%;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  background:linear-gradient(90deg,#FF4F8B,#8B5CF6,#22C6FF);
  -webkit-background-clip:text; background-clip:text; color:transparent;
}
.dc-card-title{
  font-size:9px; font-weight:700; letter-spacing:0.12em; text-transform:uppercase;
  color:#8C90A6; margin-top:5px; font-family:ui-monospace,"SFMono-Regular",Menlo,monospace;
  max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* #24 — 4 columns / 8 actions (2 rows), matching the real card's action-grid
   shape (Instagram, LinkedIn, Website, Book, Email, Call, Text, Connect)
   instead of a single row of 5 placeholders. */
.dc-card-actions{ display:grid; grid-template-columns:repeat(4,1fr); gap:8px 6px; width:100%; margin:14px 0 10px; }
.dc-card-act{ display:flex; flex-direction:column; align-items:center; gap:4px; min-width:0; }
.dc-card-act i{
  width:28px; height:28px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  background:rgba(255,255,255,0.07); box-shadow:inset 0 0 0 1px rgba(255,255,255,0.08);
}
.dc-card-act svg{ width:12px; height:12px; stroke:#C7CAD8; fill:none; stroke-width:2; }
.dc-card-act em{ font-size:7px; font-style:normal; font-weight:600; color:#8C90A6; letter-spacing:0.02em; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:100%; }
.dc-card-act.is-connect i{ background:linear-gradient(135deg,#FF4F8B,#8B5CF6,#22C6FF); box-shadow:0 4px 12px -4px rgba(139,92,246,0.6); }
.dc-card-act.is-connect svg{ stroke:#0B0D16; }
.dc-card-act.is-connect em{ color:#C7CAD8; }
.dc-card-secondary{ display:flex; gap:6px; width:100%; box-shadow:0 10px 20px -10px rgba(139,92,246,0.45); border-radius:12px; }
.dc-card-sec-btn{
  flex:1 1 auto; padding:9px 6px; border-radius:12px; font-size:9.5px; font-weight:800;
  letter-spacing:0.04em; text-transform:uppercase; text-align:center; color:#0B0D16;
  background:linear-gradient(135deg,#FF4F8B,#8B5CF6,#22C6FF);
}
.dc-card-sec-btn.is-share{
  flex:0 0 auto; width:32px; padding:9px 0; display:flex; align-items:center; justify-content:center;
  background:rgba(255,255,255,0.08); box-shadow:inset 0 0 0 1px rgba(255,255,255,0.1);
}
.dc-card-sec-btn.is-share svg{ width:12px; height:12px; stroke:#C7CAD8; fill:none; stroke-width:2; }
/* #24 — the real card's closing "Learn More" band + line/dot/line divider,
   so the mini preview's section order matches all the way to the fold. */
.dc-card-learnmore{
  display:block; margin-top:9px; padding:9px 8px; border-radius:11px; width:100%; box-sizing:border-box;
  font-size:9.5px; font-weight:700; color:#C7CAD8; text-align:center;
  background:rgba(255,255,255,0.04); border:1px solid rgba(255,255,255,0.08);
}
.dc-card-divider{ display:flex; align-items:center; gap:8px; width:100%; margin-top:14px; }
.dc-card-divider span{ flex:1 1 auto; height:1px; background:rgba(255,255,255,0.12); }
.dc-card-divider i{ width:5px; height:5px; border-radius:50%; background:#8B6CF7; flex:0 0 auto; }

/* CORRECTION PASS #2 — Icon Style, redesigned for premium execution. Four
   treatments, scoped to Card Studio's own preview via .cs-icons-{style} on
   .dc-card (the plain client-facing Digital Card carries no such class and
   is untouched). Container size/padding/gap are IDENTICAL across all four
   (only fill/border/glow/icon-rendering change) so switching styles never
   reflows the action grid. */

/* LINE — refined thin iconography on a barely-there glass chip: a hairline
   inset ring instead of a filled disc, thin high-contrast stroke. */
.cs-icons-line .dc-card-act i,
.cs-icons-line .cs-preview-social i,
.cs-icons-line .cs-preview-footer-social i{
  background:rgba(255,255,255,0.045);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,0.16);
}
.cs-icons-line .dc-card-act svg,
.cs-icons-line .cs-preview-social svg,
.cs-icons-line .cs-preview-footer-social svg{ stroke:#EDEEF7; fill:none; stroke-width:1.6; }

/* MATTE — CORRECTION PASS 2 #3. ROOT CAUSE of the "unfinished" look: these
   icons (see index.html's <symbol id="ic-envelope">/"ic-linkedin"/etc.) are
   authored as LINE ART — a fillable shape plus separate open-path stroke
   detail (the envelope's flap fold, the "in" letterform) — built to be
   STROKED, not filled. Switching them to `fill` silently broke every
   compound icon: an open stroke path has zero fill area, so those detail
   lines simply vanished. Matte now differentiates ONLY the container (a
   refined soft surface: a gentle top-lit gradient, a crisp inset edge that
   reads as an intentional button boundary — not a blur — plus a soft outer
   drop shadow for real depth) while the icon itself stays the same crisp
   STROKE technique Line/Glow already use correctly, just a hair bolder so
   it reads as more substantial. */
/* CORRECTION PASS 3 #4 — polish only (no geometry/stroke-width change): a
   graduated multi-stop surface (a true top-lit specular catch fading through
   the middle to a slightly darker base) plus a crisper hairline top edge,
   reads as an intentionally lit physical button rather than a flat tinted
   circle. */
.cs-icons-matte .dc-card-act i,
.cs-icons-matte .cs-preview-social i,
.cs-icons-matte .cs-preview-footer-social i{
  background:linear-gradient(180deg, rgba(255,255,255,0.24) 0%, rgba(255,255,255,0.09) 24%, rgba(255,255,255,0.035) 58%, rgba(255,255,255,0.015) 100%);
  box-shadow:
    0 0 0 1px rgba(255,255,255,0.13) inset,
    0 1px 0 0 rgba(255,255,255,0.28) inset,
    0 -2.5px 4px 0 rgba(0,0,0,0.36) inset,
    0 5px 12px -6px rgba(0,0,0,0.65);
}
.cs-icons-matte .dc-card-act svg,
.cs-icons-matte .cs-preview-social svg,
.cs-icons-matte .cs-preview-footer-social svg{ stroke:#F4F5FB; fill:none; stroke-width:1.9; }

/* GLOW — restrained accent illumination: a softly accent-tinted surface plus
   a tight, controlled ambient bloom (never a filled neon disc), icon stays a
   crisp bright stroke so it's always legible over any accent color. */
.cs-icons-glow .dc-card-act i,
.cs-icons-glow .cs-preview-social i,
.cs-icons-glow .cs-preview-footer-social i{
  background:color-mix(in srgb, var(--cs-accent,#8B5CF6) 20%, rgba(255,255,255,0.05));
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--cs-accent,#8B5CF6) 42%, transparent) inset,
    0 0 9px -1px color-mix(in srgb, var(--cs-accent,#8B5CF6) 50%, transparent);
}
.cs-icons-glow .dc-card-act svg,
.cs-icons-glow .cs-preview-social svg,
.cs-icons-glow .cs-preview-footer-social svg{ stroke:#FFFFFF; fill:none; stroke-width:1.8; }

/* AUTHENTIC — CORRECTION PASS 2 #3. Same fill-breaks-line-art fix as Matte
   (see its comment above): every icon keeps the stroke technique, generic
   AND branded alike, so the whole row still reads as ONE icon family.
   Generic actions (phone/email/text/share/website/booking — no data-brand)
   sit on the identical Matte surface for that family cohesion. A genuinely
   branded service (Instagram/Facebook/LinkedIn/Google/YouTube/etc. —
   data-brand set inline as --ic-brand by csIconEl()) gets a softly
   brand-TINTED surface with a crisp brand-colored ring + a brand-colored
   stroke icon — art-directed identity, never a solid saturated coin dropped
   behind every glyph, and never a broken/filled icon. */
.cs-icons-authentic .dc-card-act i,
.cs-icons-authentic .cs-preview-social i,
.cs-icons-authentic .cs-preview-footer-social i{
  background:linear-gradient(180deg, rgba(255,255,255,0.24) 0%, rgba(255,255,255,0.09) 24%, rgba(255,255,255,0.035) 58%, rgba(255,255,255,0.015) 100%);
  box-shadow:
    0 0 0 1px rgba(255,255,255,0.13) inset,
    0 1px 0 0 rgba(255,255,255,0.28) inset,
    0 -2.5px 4px 0 rgba(0,0,0,0.36) inset,
    0 5px 12px -6px rgba(0,0,0,0.65);
}
.cs-icons-authentic .dc-card-act svg,
.cs-icons-authentic .cs-preview-social svg,
.cs-icons-authentic .cs-preview-footer-social svg{ stroke:#F4F5FB; fill:none; stroke-width:1.9; }
/* CORRECTION PASS 3 #4 — polish only: the SAME graduated top-lit structure
   as the generic/Matte surface above, tinted by the brand color instead of
   staying neutral, plus a thin neutral inner highlight shared with every
   other chip — this is what ties a branded icon back into the same "one
   family" surface language instead of reading as a disconnected colored
   sticker. Icon geometry/stroke-width unchanged. */
.cs-icons-authentic i[data-brand]:not([data-brand=""]){
  background:linear-gradient(180deg,
    color-mix(in srgb, var(--ic-brand) 38%, rgba(255,255,255,0.22)) 0%,
    color-mix(in srgb, var(--ic-brand) 24%, rgba(255,255,255,0.07)) 26%,
    color-mix(in srgb, var(--ic-brand) 14%, rgba(255,255,255,0.02)) 60%,
    color-mix(in srgb, var(--ic-brand) 8%, rgba(255,255,255,0.01)) 100%);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--ic-brand) 48%, rgba(255,255,255,0.18)) inset,
    0 1px 0 0 rgba(255,255,255,0.3) inset,
    0 -2px 3px 0 rgba(0,0,0,0.28) inset,
    0 5px 12px -6px color-mix(in srgb, var(--ic-brand) 58%, transparent);
}
.cs-icons-authentic i[data-brand]:not([data-brand=""]) svg{ stroke:var(--ic-brand); fill:none; stroke-width:2; }

/* CORRECTION PASS 4 — GRADIENT, matched to the attached reference screenshot
   of the real published card: a quiet, flat dark disc (no embossing, no
   glow — the container stays deliberately out of the way) with the icon's
   STROKE (never fill — same line-art-breaks-on-fill reasoning as Matte/
   Authentic above) painted with the app's own signature pink->violet->cyan
   gradient (#csIconGradient, defined once in index.html's shared SVG defs
   and reused per-icon via objectBoundingBox). Uniform across every icon,
   generic and social alike — the reference shows Instagram/LinkedIn/Website/
   Book/Email/Call getting the SAME gradient treatment, not individual brand
   colors (that distinction is what Authentic, above, already exists for). */
.cs-icons-gradient .dc-card-act i,
.cs-icons-gradient .cs-preview-social i,
.cs-icons-gradient .cs-preview-footer-social i{
  background:rgba(255,255,255,0.05);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,0.1);
}
.cs-icons-gradient .dc-card-act svg,
.cs-icons-gradient .cs-preview-social svg,
.cs-icons-gradient .cs-preview-footer-social svg{ stroke:url(#csIconGradient); fill:none; stroke-width:1.8; }

@media (max-width:1024px){
  .dc-phone{ width:246px; }
}
@media (max-width:420px){
  .dc-phone{ width:212px; }
  .dc-card-act em{ font-size:7px; }
}


@media (max-width:768px){
  /* pin the Coming Soon card near the top of the viewport (dropping the
     blur so `fixed` isn't re-trapped by the backdrop-filter containing
     block — same fix the Leads overlay uses) */
  .mock-overlay{ backdrop-filter:none; -webkit-backdrop-filter:none; padding:0; }
  .mock-overlay-card{ position:fixed; top:148px; left:16px; right:16px; margin:0 auto; max-width:360px; }
}
@media (max-width:560px){
  .mock-shell > [aria-hidden="true"], #saManager{ padding:14px; }
  .mock-overlay-card{ padding:24px 24px; }
  .mock-overlay-title{ font-size:21px; }
}

/* =====================================================================
   PASS 6 — Contact record 3-column workspace, contextual composer,
   deep property stack, resizable/scrollable table, page size,
   Smart Accessories redesign.
   ===================================================================== */

/* ---- Left property stack: group subheads ---------------------------- */
/* item 1 — a clear vertical break between property groups (was 14/6) */
.lf-group{
  font-size:10px; font-weight:800; letter-spacing:0.09em; text-transform:uppercase;
  color:var(--text-tertiary); padding:20px 0 9px; margin:6px 0 2px;
  border-bottom:1px solid var(--line-strong);
}
.lf-grid > .lf-group:first-child{ padding-top:4px; margin-top:0; }
.lf-grid .lf-row:last-child{ border-bottom:none; }
.lf-allhidden{ font-size:12px; color:var(--text-tertiary); padding:16px 2px; }
/* Priority-10 — Do Not Contact reads as important without shouting: a thin
   left rule + tinted key, both themes. It sits at the end of the contact
   block, directly under Lifecycle Stage. */
.lf-row.is-emph-warn{ position:relative; padding-left:10px; }
.lf-row.is-emph-warn::before{ content:""; position:absolute; left:0; top:8px; bottom:8px; width:2px; border-radius:2px; background:var(--warn); }
.lf-row.is-emph-warn .lf-k{ color:var(--warn); }

/* Left lane: hide-empty toggle (click-delegated <button>, not a checkbox) */
.lead-hideempty{
  display:flex; align-items:center; gap:8px; cursor:pointer; user-select:none;
  font:inherit; font-size:11.5px; font-weight:600; color:var(--text-secondary);
  background:none; border:none; text-align:left; width:100%;
  padding:6px 0 14px; margin-bottom:2px;   /* item 1 — breathing before first field */
}
.lead-hideempty:hover{ color:var(--text-primary); }
.lead-hideempty:hover .lead-cbx2{ border-color:var(--violet-dim); }
.lead-hideempty:focus-visible{ outline:2px solid var(--violet); outline-offset:2px; border-radius:6px; }
.lead-cbx2{
  flex:0 0 auto; width:16px; height:16px; border-radius:5px; border:1.5px solid var(--line-strong);
  display:inline-flex; align-items:center; justify-content:center; background:var(--input-bg); transition:background .12s ease, border-color .12s ease;
}
.lead-cbx2.is-on{ background:var(--violet); border-color:var(--violet); }
.lead-cbx2 svg{ width:11px; height:11px; stroke:#0A0A16; fill:none; stroke-width:3; }
[data-theme="light"] .lead-cbx2 svg{ stroke:#fff; }

/* =====================================================================
   PASS 7 — Contact-record center workspace: tab strip + comm launcher,
   scrolling feed, universal comm bar, expanded email composer, aux tabs.
   ===================================================================== */

/* ---- Center card shell ---- */
.lead-record-card.is-timeline{ padding:0; overflow:hidden; }
.lead-tl-top{
  flex:0 0 auto; display:flex; align-items:stretch; gap:6px;
  border-bottom:1px solid var(--line-strong); padding:0 8px 0 4px;
  position:relative;
}
.lead-tl-tabs{
  flex:1 1 auto; display:flex; gap:1px; margin:0; border-bottom:none; overflow-x:auto; scrollbar-width:none;
  -webkit-mask:linear-gradient(90deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
  mask:linear-gradient(90deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
}
.lead-tl-tabs::-webkit-scrollbar{ display:none; }
.lead-tl-tab{
  flex:0 0 auto; white-space:nowrap; cursor:pointer; font:inherit; border:none; background:none; position:relative;
  padding:12px 12px 12px; font-size:12px; font-weight:700; color:var(--text-tertiary); transition:color .14s ease;
}
.lead-tl-tab:hover{ color:var(--text-secondary); }
.lead-tl-tab.is-active{ color:var(--text-primary); }
.lead-tl-tab.is-active::after{ content:""; position:absolute; left:8px; right:8px; bottom:0; height:2.5px; border-radius:2px 2px 0 0; background:var(--violet); }
.lead-tl-tabs{ padding-bottom:0; }

/* comm launcher (§5) */
.lead-comm-launcher-wrap{ flex:0 0 auto; display:flex; align-items:center; position:relative; }
.lead-comm-launcher{
  width:32px; height:32px; border-radius:9px; cursor:pointer; display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); border:1px solid var(--line-strong); color:var(--text-secondary);
  transition:color .14s ease, border-color .14s ease, box-shadow .14s ease;
}
.lead-comm-launcher svg{ width:16px; height:16px; stroke:currentColor; fill:none; stroke-width:2; }
.lead-comm-launcher:hover{ color:var(--violet); border-color:var(--violet-dim); box-shadow:0 0 0 3px color-mix(in srgb, var(--violet) 12%, transparent); }
.lead-comm-launch-menu{
  position:absolute; top:calc(100% + 6px); right:0; z-index:40; min-width:184px; padding:5px;
  display:flex; flex-direction:column; gap:1px;
  background:var(--ink-800); border:1px solid var(--line-strong); border-radius:11px;
  box-shadow:0 22px 48px -14px rgba(0,0,0,0.55);
}
.lead-comm-launch-opt{
  display:flex; align-items:center; gap:9px; width:100%; text-align:left; cursor:pointer; font:inherit;
  padding:8px 10px; border:none; border-radius:7px; background:none; font-size:12.5px; font-weight:600; color:var(--text-primary);
}
.lead-comm-launch-opt:hover{ background:var(--surface-hover); }
.lead-comm-launch-opt svg{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2; }
.lead-comm-launch-opt em{ margin-left:auto; font-style:normal; font-size:9px; font-weight:800; letter-spacing:0.05em; text-transform:uppercase; color:var(--text-tertiary); }

/* ---- Note composer (§9) — Add Note button TOP-RIGHT ---- */
.lead-note-composer{
  flex:0 0 auto; margin:12px 16px 4px; padding:12px; border-radius:12px;
  background:var(--surface-2); border:1px solid var(--line-strong);
}
.lead-note-composer-head{ display:flex; align-items:center; justify-content:space-between; margin-bottom:8px; }
.lead-note-composer-t{ font-size:11px; font-weight:800; letter-spacing:0.05em; text-transform:uppercase; color:var(--text-tertiary); }
.lead-note-composer .lead-note-save{ align-self:auto; }
.lead-note-input-lg{
  width:100%; resize:vertical; min-height:66px; max-height:220px; padding:10px 12px; border-radius:9px; font:inherit; font-size:13px;
  color:var(--text-primary); background:var(--input-bg); border:1px solid var(--line-strong); line-height:1.55;
  transition:border-color .14s ease, box-shadow .14s ease;
}
.lead-note-input-lg:focus{ outline:none; border-color:var(--violet); box-shadow:0 0 0 3px color-mix(in srgb, var(--violet) 18%, transparent); }
.lead-note-input-lg:disabled{ opacity:0.55; }

/* per-tab action strip (tasks / appts / docs / updates) */
.lead-tab-action{ flex:0 0 auto; display:flex; gap:8px; align-items:center; margin:12px 16px 2px; }
.lead-tab-action-in{ flex:1 1 auto; font-size:12.5px; padding:9px 11px; }
.lead-tab-action .lead-note-save{ align-self:auto; flex:0 0 auto; }
.lead-tab-action-doc{ font-size:12px; color:var(--text-tertiary); }
.lead-tab-action-wrap{ flex-wrap:wrap; }

/* ---- Center feed ---- */
.lead-tl-scroll{ padding:14px 16px 10px; }
.lead-tl-blank{ text-align:center; padding:40px 16px; color:var(--text-tertiary); }
.lead-tl-blank-ic{
  width:44px; height:44px; border-radius:13px; margin:0 auto 12px; display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); border:1px solid var(--line-strong);
}
.lead-tl-blank-ic svg{ width:20px; height:20px; stroke:var(--text-tertiary); fill:none; stroke-width:2; }
.lead-tl-blank-t{ font-size:13.5px; font-weight:700; color:var(--text-secondary); }
.lead-tl-blank-s{ font-size:12px; margin-top:4px; }
.lead-notes-feed{ display:flex; flex-direction:column; gap:8px; }

/* aux lists — tasks / appointments / documents */
.lead-aux-list{ display:flex; flex-direction:column; gap:8px; }
.lead-aux-row{
  display:flex; align-items:center; gap:11px; padding:10px 12px; border-radius:10px;
  background:var(--surface-1); border:1px solid var(--line);
}
.lead-aux-main{ flex:1 1 auto; min-width:0; }
.lead-aux-title{ font-size:12.5px; font-weight:600; color:var(--text-primary); }
.lead-aux-meta{ font-size:11px; color:var(--text-tertiary); margin-top:2px; }
.lead-aux-meta.is-overdue{ color:var(--bad); font-weight:700; }
/* manually-entered meeting link on an appointment row */
.lead-appt-link{ display:flex; align-items:center; gap:6px; margin-top:6px; min-width:0; }
.lead-appt-link a{
  display:inline-flex; align-items:center; gap:5px; font-size:11px; font-weight:700; color:var(--cyan);
  text-decoration:none; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.lead-appt-link a:hover{ text-decoration:underline; }
.lead-appt-link a svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2; flex:0 0 auto; }
.lead-appt-link-copy{
  flex:0 0 auto; width:22px; height:22px; border-radius:6px; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center;
  background:var(--surface-2); border:1px solid var(--line); color:var(--text-tertiary);
}
.lead-appt-link-copy:hover{ color:var(--text-primary); }
.lead-appt-link-copy.is-copied{ color:var(--good); border-color:color-mix(in srgb, var(--good) 40%, transparent); }
.lead-appt-link-copy svg{ width:12px; height:12px; stroke:currentColor; fill:none; stroke-width:2; }
.lead-appt-link.is-manual{ font-size:10.5px; }
.lead-aux-tag{ font-size:9.5px; font-weight:800; letter-spacing:0.05em; text-transform:uppercase; color:var(--text-tertiary); background:var(--surface-2); border:1px solid var(--line); padding:3px 7px; border-radius:99px; flex:0 0 auto; }
.lead-aux-tag.is-upcoming{ color:var(--cyan); border-color:color-mix(in srgb, var(--cyan) 35%, transparent); background:color-mix(in srgb, var(--cyan) 12%, transparent); }
.lead-task-check{
  flex:0 0 auto; width:20px; height:20px; border-radius:6px; cursor:pointer; display:flex; align-items:center; justify-content:center;
  background:var(--input-bg); border:1.5px solid var(--line-strong); color:#0A0A16; transition:background .12s ease, border-color .12s ease;
}
.lead-task-check.is-on{ background:var(--good); border-color:var(--good); }
.lead-task-check svg{ width:12px; height:12px; stroke:#0A0A16; fill:none; stroke-width:3; }
.lead-task-row.is-done .lead-aux-title{ text-decoration:line-through; color:var(--text-tertiary); }
.lead-appt-date{
  flex:0 0 auto; width:40px; text-align:center; border-radius:8px; padding:4px 0;
  background:var(--surface-2); border:1px solid var(--line);
}
.lead-appt-date b{ display:block; font-size:15px; font-weight:800; line-height:1; color:var(--text-primary); }
.lead-appt-date span{ font-size:9px; text-transform:uppercase; letter-spacing:0.04em; color:var(--text-tertiary); }
.lead-appt-row.is-past{ opacity:0.62; }
.lead-doc-ic{ flex:0 0 auto; width:32px; height:32px; border-radius:8px; display:flex; align-items:center; justify-content:center; background:color-mix(in srgb, var(--cyan) 12%, transparent); }
.lead-doc-ic svg{ width:15px; height:15px; stroke:var(--cyan); fill:none; stroke-width:2; }

/* ---- Universal bottom communication bar (§6) ---- */
.lead-commbar{
  flex:0 0 auto; display:grid; grid-template-columns:auto 1fr auto; align-items:center; gap:9px;
  padding:11px 12px; border-top:1px solid var(--line-strong); background:var(--surface-2);
}
.lead-commbar-schedule{ grid-column:1 / -1; display:flex; align-items:center; gap:8px; padding-top:9px; }
.lead-commbar-schedule label{ font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:0.04em; color:var(--text-tertiary); }
.lead-commbar-schedule input{ width:auto; font-size:12px; padding:6px 8px; }
.lead-commbar-channel-wrap, .lead-commbar-send-wrap{ position:relative; flex:0 0 auto; }
.lead-commbar-channel{
  display:inline-flex; align-items:center; gap:7px; cursor:pointer; font:inherit; font-size:12.5px; font-weight:700; color:var(--text-primary);
  padding:8px 10px; border-radius:9px; background:var(--surface-1); border:1px solid var(--line-strong);
}
.lead-commbar-channel:hover{ border-color:var(--violet-dim); }
.lead-commbar-channel > svg:first-child{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2; }
.lead-commbar-caret{ width:12px; height:12px; stroke:var(--text-tertiary); fill:none; stroke-width:2.6; }
.lead-commbar-menu, .lead-commbar-sendmenu{
  position:absolute; bottom:calc(100% + 6px); z-index:40; min-width:176px; padding:5px;
  display:flex; flex-direction:column; gap:1px;
  background:var(--ink-800); border:1px solid var(--line-strong); border-radius:11px; box-shadow:0 -18px 44px -14px rgba(0,0,0,0.5);
}
.lead-commbar-menu{ left:0; }
.lead-commbar-sendmenu{ right:0; min-width:150px; }
.lead-commbar-menu-opt, .lead-commbar-sendmenu button{
  display:flex; align-items:center; gap:9px; width:100%; text-align:left; cursor:pointer; font:inherit;
  padding:8px 10px; border:none; border-radius:7px; background:none; font-size:12.5px; font-weight:600; color:var(--text-primary);
}
.lead-commbar-menu-opt:hover, .lead-commbar-sendmenu button:hover{ background:var(--surface-hover); }
.lead-commbar-menu-opt.is-active, .lead-commbar-sendmenu button.is-active{ color:var(--violet); }
.lead-commbar-menu-opt svg{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2; }
.lead-commbar-menu-opt em{ margin-left:auto; font-style:normal; font-size:9px; font-weight:800; letter-spacing:0.05em; text-transform:uppercase; color:var(--text-tertiary); }
.lead-commbar-mid{ display:flex; align-items:center; gap:8px; min-width:0; }
.lead-commbar-field, .lead-commbar-input{
  width:100%; text-align:left; font:inherit; font-size:13px; color:var(--text-primary);
  padding:9px 12px; border-radius:9px; background:var(--input-bg); border:1px solid var(--line-strong);
  transition:border-color .14s ease, box-shadow .14s ease;
}
.lead-commbar-field{ cursor:text; color:var(--text-tertiary); }
.lead-commbar-field:hover{ border-color:var(--violet-dim); }
.lead-commbar-input:focus{ outline:none; border-color:var(--violet); box-shadow:0 0 0 3px color-mix(in srgb, var(--violet) 18%, transparent); }
.lead-commbar-callnow{
  flex:0 0 auto; display:inline-flex; align-items:center; gap:6px; font-size:12px; font-weight:700; text-decoration:none;
  color:var(--good); padding:8px 10px; border-radius:8px; border:1px solid color-mix(in srgb, var(--good) 35%, transparent);
}
.lead-commbar-send{
  display:inline-flex; align-items:center; gap:7px; cursor:pointer; font:inherit; font-size:12.5px; font-weight:800;
  color:#0A0A16; background:var(--brand-gradient); border:none; padding:9px 14px; border-radius:9px 0 0 9px;
}
.lead-commbar-send:disabled{ opacity:0.45; cursor:not-allowed; }
.lead-commbar-send svg{ width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:2.4; }
.lead-commbar-sendopts{
  cursor:pointer; padding:9px 8px; border:none; border-radius:0 9px 9px 0; color:#0A0A16;
  background:var(--brand-gradient); box-shadow:inset 1px 0 0 rgba(0,0,0,0.18);
}
.lead-commbar-sendopts svg{ width:12px; height:12px; stroke:currentColor; fill:none; stroke-width:3; }
.lead-commbar-send-wrap{ display:flex; }
[data-theme="light"] .lead-commbar-send, [data-theme="light"] .lead-commbar-sendopts{ color:#fff; }
[data-theme="light"] .lead-commbar{ background:var(--surface-1); }

/* ---- Expanded composer (§5/§6/§7/§8/§13) — EMAIL body gets the space;
   SMS / WhatsApp / Phone are compact and size to their own content ---- */
.lead-email-composer{
  flex:1 1 auto; display:flex; flex-direction:column; min-height:0; overflow:hidden;
  border-top:1px solid color-mix(in srgb, var(--cyan) 20%, var(--line-strong));
  background:var(--surface-1);
  box-shadow:0 -24px 46px -22px rgba(0,0,0,0.45);
  animation:leadEmailUp .22s cubic-bezier(.22,1,.36,1);
}
/* §6 — compact channels never inherit the full email height */
.lead-email-composer.is-compact{ flex:0 0 auto; }
/* #2 — the PHONE dialer is the exception: it must never push the "Log call"
   bar off-screen. Let it take the free space and cap its own height so on a
   normal viewport the whole pad shows with no scroll, and on a short one the
   pad scrolls INSIDE while the send bar stays pinned + visible. */
.lead-email-composer[data-channel="phone"]{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.lead-email-composer[data-channel="phone"] .lead-dial{ flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; justify-content:flex-start; }
/* #7 — while the dialer is open the call surface OWNS the workspace: hide
   the feed strip entirely so the composer starts directly under the tab
   row with no stray "Today" grouping above it. */
.lead-record-card.is-timeline:has(.lead-email-composer[data-channel="phone"]) > .lead-tl-scroll{ display:none; }
.lead-dial-field{ width:100%; max-width:280px; align-self:center; display:flex; flex-direction:column; gap:4px; margin-top:5px; }
.lead-dial-flabel{ font-size:9.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary); padding-left:2px; }
.lead-dial-field .lead-dial-outcomes{ margin:0; max-width:none; }
.lead-dial-field .lead-dial-notes{ margin:0; max-width:none; }
/* #3 (polish pass) — when the EMAIL composer is open it OWNS the workspace,
   same as the dialer: the feed is hidden entirely so "NEW EMAIL" starts
   directly beneath the All Activity / Notes / Tasks / Appointments tab row
   with no timeline peeking through. Compact composers (SMS/WhatsApp) still
   leave the feed visible above them. */
.lead-record-card.is-timeline:has(.lead-email-composer:not(.is-compact)) > .lead-tl-scroll{ display:none; }
.lead-record-card.is-timeline:has(.lead-email-composer:not(.is-compact)) > .lead-tl-top{ border-bottom:none; }
@keyframes leadEmailUp{ from{ transform:translateY(20px); opacity:0; } to{ transform:translateY(0); opacity:1; } }
.lead-email-head{ flex:0 0 auto; display:flex; align-items:center; justify-content:space-between; padding:11px 12px 11px 14px; border-bottom:1px solid var(--line); }
.lead-email-head-t{ display:flex; align-items:center; gap:8px; font-size:12px; font-weight:800; letter-spacing:0.07em; text-transform:uppercase; color:var(--text-secondary); }
.lead-email-head-t svg{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2; }
/* §7 — top-right control is now the single Discard Draft affordance */
.lead-email-x{ width:26px; height:26px; border-radius:7px; cursor:pointer; display:flex; align-items:center; justify-content:center; background:var(--surface-2); border:1px solid var(--line); color:var(--text-secondary); transition:color .12s ease, border-color .12s ease, background .12s ease; }
.lead-email-x:hover{ color:var(--bad); border-color:var(--bad); background:color-mix(in srgb, var(--bad) 8%, transparent); }
.lead-email-x svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.2; }
.lead-email-fields{ flex:0 0 auto; padding:4px 14px; }
.lead-email-row{ display:flex; align-items:center; gap:10px; padding:6px 0; border-bottom:1px solid var(--line); flex-wrap:wrap; }
.lead-email-row label{ flex:0 0 44px; font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:0.03em; color:var(--text-tertiary); }
.lead-email-from{ font-size:12.5px; color:var(--text-secondary); }
.lead-email-in{ flex:1 1 auto; min-width:0; border:none; background:none; font:inherit; font-size:12.5px; color:var(--text-primary); padding:2px 0; }
.lead-email-in:focus{ outline:none; }
/* item 5 — required-subject validation state, cleared on next keystroke */
.lead-email-row.is-invalid{ border-color:var(--bad); }
.lead-email-row.is-invalid label{ color:var(--bad); }
.lead-email-row.is-invalid .lead-email-in::placeholder{ color:var(--bad); opacity:0.7; }
.lead-email-ccbtn{ font:inherit; font-size:11px; font-weight:700; color:var(--violet); background:none; border:none; cursor:pointer; padding:5px 0; }

/* §5 — writing area: body on top, signature appended at the bottom, read as
   ONE continuous message. This element owns the single vertical scrollbar
   (overflow-y:auto); the body <textarea> auto-grows to its content
   (fitCommBody() in app.js) and the signature renders at natural height,
   so scrolling the surface reveals body → signature continuously rather
   than each region scrolling independently. */
.lead-email-writing{
  flex:1 1 auto; display:flex; flex-direction:column; min-height:0;
  margin:10px 14px 10px; border-radius:10px; overflow-y:auto; overflow-x:hidden;
  background:var(--input-bg); border:1px solid var(--line-strong);
  transition:border-color .14s ease, box-shadow .14s ease;
}
.lead-email-writing:focus-within{ border-color:var(--violet); box-shadow:0 0 0 3px color-mix(in srgb, var(--violet) 16%, transparent); }
.lead-email-writing .lead-email-body{
  flex:0 0 auto; min-height:132px; resize:none; margin:0; border:none; background:none; box-shadow:none;
  padding:13px 14px 6px; overflow:hidden;
}
.lead-email-writing .lead-email-body:focus{ box-shadow:none; }
.lead-email-sig{ flex:0 0 auto; padding:0 14px 12px; }
.lead-email-sig-rule{ height:1px; background:var(--line); margin:2px 0 9px; }
/* QC (this pass) — P4: renders the REAL sanitized rich HTML (fonts, links,
   colors, tables, images), not a flattened plain-text <pre>. A light,
   email-safe card — a signature is normally authored assuming a white
   background, so rendering it straight against the composer's dark theme
   would wash out dark text/logos. Same visual family as the signature
   editor's own sandboxed preview, just inline (no iframe needed here since
   the composer already only ever shows the SANITIZED value, same trust
   boundary as the editor's preview). */
.lead-email-sig-body{
  margin:0 0 6px; padding:9px 11px; border-radius:9px; background:#fff; color:#1a1a1a;
  font-family:Arial,Helvetica,sans-serif; font-size:12px; line-height:1.5;
  /* No vertical cap / no inner scrollbar — the signature flows at its
     natural height inside .lead-email-writing, which is the one surface
     that scrolls. Only run-away WIDTH (an extra-wide authored table)
     scrolls, horizontally, so its layout is never squashed or cropped. */
  overflow-x:auto; overflow-y:hidden;
}
/* Targeted image-rendering rule: respect the authored width, scale height
   proportionally, never distort. `max-width:100%` + `height:auto` alone —
   NO max-height. A prior max-height clamped the rendered height while the
   authored `width` attribute held, squishing headshots. Small authored
   icons keep their size; a large photo scales with the box; aspect ratio
   is never touched. Gmail/Outlook fixed-width tables are unaffected. */
.lead-email-sig-body img{ max-width:100%; height:auto; }
.lead-email-sig-body a{ color:#1a73e8; }
/* Real signatures (Outlook/Gmail exports especially) are frequently built
   from nested fixed-width tables. Keep their authored width intact — the
   horizontal overflow above scrolls anything wider than the box rather
   than force-shrinking the table, which crushed cell content and
   distorted the layout. Never a silent crop, never a forced squash. */
.lead-email-sig-body table{ max-width:none; }
.lead-email-sig-note{
  display:inline-flex; align-items:center; gap:6px; font:inherit; font-size:10px; color:var(--text-tertiary);
  background:none; border:none; padding:0; cursor:pointer; transition:color .12s ease;
}
.lead-email-sig-note:hover{ color:var(--violet); }
.lead-email-sig-note svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:1.8; flex:0 0 auto; }

/* generic body (compact SMS / WhatsApp / Phone-notes) */
.lead-email-body{
  resize:none; margin:10px 14px 8px; padding:11px 13px; border-radius:10px; font:inherit; font-size:13px;
  line-height:1.55; color:var(--text-primary); background:var(--input-bg); border:1px solid var(--line-strong);
  transition:border-color .14s ease, box-shadow .14s ease;
}
.lead-email-body:focus{ outline:none; border-color:var(--violet); box-shadow:0 0 0 3px color-mix(in srgb, var(--violet) 16%, transparent); }
.lead-email-composer.is-compact .lead-email-body{ min-height:88px; max-height:168px; }
.lead-email-composer[data-channel="phone"] .lead-dial-notes{ min-height:64px; max-height:120px; }

/* Part 2 — premium dial surface (phone channel). A single centred column:
   who you're calling → the number → a proper keypad (digit + letters) →
   a real green call action. Sits on a fixed-width column so the whole
   thing centres as one unit in the much wider composer. */
/* #2 — the entire dialer fits a normal desktop viewport with no scroll:
   spacing is tight, the keypad is capped so keys stay tap-sized without
   ballooning, and the notes field is short. Premium feel preserved. */
.lead-dial{ display:flex; flex-direction:column; align-items:center; gap:7px; padding:10px 14px 10px; }
.lead-dial-who{
  display:flex; align-items:center; gap:9px; width:100%; max-width:244px;
  padding:7px 10px; border-radius:11px; background:var(--surface-1); border:1px solid var(--line);
}
.lead-dial-avatar{
  flex:0 0 auto; width:28px; height:28px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-size:10.5px; font-weight:800; color:#fff; background:linear-gradient(135deg, var(--violet), var(--cyan));
}
.lead-dial-whotext{ display:flex; flex-direction:column; min-width:0; line-height:1.28; }
.lead-dial-whotext b{ font-size:12px; font-weight:700; color:var(--text-primary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-dial-whotext span{ font-size:10px; color:var(--text-tertiary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-dial-display{
  display:flex; align-items:center; gap:6px; width:100%; max-width:244px; margin:0;
  background:var(--input-bg); border:1px solid var(--line-strong); border-radius:11px; padding:3px 4px 3px 6px;
  transition:border-color .14s ease, box-shadow .14s ease;
}
.lead-dial-display:focus-within{ border-color:var(--violet); box-shadow:0 0 0 3px color-mix(in srgb, var(--violet) 15%, transparent); }
.lead-dial-num{
  flex:1 1 auto; min-width:0; font:inherit; font-size:17px; font-weight:700; letter-spacing:0.03em; text-align:center;
  color:var(--text-primary); background:transparent; border:none; border-radius:8px; padding:7px 4px;
}
.lead-dial-num:focus{ outline:none; }
.lead-dial-num::placeholder{ font-size:12.5px; font-weight:600; letter-spacing:0; color:var(--text-tertiary); }
.lead-dial-bksp{
  flex:0 0 auto; width:32px; height:32px; border-radius:9px; cursor:pointer; display:flex; align-items:center; justify-content:center;
  background:none; border:none; color:var(--text-tertiary); transition:color .12s ease, background .12s ease;
}
.lead-dial-bksp:hover{ color:var(--text-primary); background:var(--surface-hover); }
.lead-dial-bksp svg{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2.4; }
.lead-dial-pad{ display:grid; grid-template-columns:repeat(3, 1fr); gap:6px 10px; width:100%; max-width:206px; margin:0; }
.lead-dial-key{
  cursor:pointer; font:inherit; color:var(--text-primary);
  background:var(--surface-1); border:1px solid var(--line); border-radius:50%;
  aspect-ratio:1; width:100%; max-width:58px; padding:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:0;
  transition:background .1s ease, border-color .1s ease, transform .06s ease, box-shadow .12s ease;
}
.lead-dial-key-d{ font-size:17px; font-weight:600; line-height:1; }
.lead-dial-key-l{ font-size:7.5px; font-weight:800; letter-spacing:0.1em; color:var(--text-tertiary); margin-top:1px; }
.lead-dial-key:hover{
  background:color-mix(in srgb, var(--violet) 9%, var(--surface-1));
  border-color:var(--violet-dim);
  box-shadow:0 2px 10px -4px color-mix(in srgb, var(--violet) 40%, transparent);
}
.lead-dial-key:active{ transform:scale(0.93); background:color-mix(in srgb, var(--violet) 16%, var(--surface-1)); }
.lead-comp-callbtn.lead-dial-call{
  align-self:center; display:inline-flex; align-items:center; justify-content:center; gap:8px;
  width:100%; max-width:244px; margin:1px 0 0; padding:10px 16px; border-radius:12px;
  font-size:13px; font-weight:800; letter-spacing:0.02em;
  background:linear-gradient(135deg, #16a34a, #22c55e); border:1px solid transparent; color:#fff;
  box-shadow:0 8px 22px -10px rgba(34,197,94,0.6); transition:transform .08s ease, box-shadow .16s ease, filter .16s ease;
}
.lead-comp-callbtn.lead-dial-call:hover{ filter:brightness(1.06); box-shadow:0 10px 26px -10px rgba(34,197,94,0.7); }
.lead-comp-callbtn.lead-dial-call:active{ transform:scale(0.98); }
.lead-comp-callbtn.lead-dial-call svg{ width:15px; height:15px; fill:currentColor; stroke:none; }
.lead-email-composer[data-channel="phone"] .lead-dial-notes{ width:100%; max-width:244px; margin:1px 0 0; align-self:center; min-height:40px; max-height:88px; }
.lead-dial-outcomes{ display:flex; flex-wrap:wrap; gap:5px; justify-content:center; width:100%; max-width:280px; margin:2px 0 0; align-self:center; }
.lead-dial-outcome{
  font:inherit; font-size:10px; font-weight:700; color:var(--text-secondary); cursor:pointer;
  background:var(--surface-1); border:1px solid var(--line-strong); border-radius:99px; padding:3px 8px;
  transition:border-color .12s ease, color .12s ease, background .12s ease;
}
.lead-dial-outcome:hover{ color:var(--violet); border-color:var(--violet-dim); }
.lead-dial-outcome.is-picked{ color:#fff; background:var(--violet); border-color:transparent; }

.lead-comp-hint{ font-size:10.5px; color:var(--text-tertiary); line-height:1.45; padding:2px 14px 6px; }

[data-theme="light"] .lead-note-composer, [data-theme="light"] .lead-tl-top{ background:var(--surface-1); }
[data-theme="light"] .lead-comm-launch-menu, [data-theme="light"] .lead-commbar-menu, [data-theme="light"] .lead-commbar-sendmenu{ background:var(--ink-800); }

/* ---- Timeline: per-event communication tag ------------------------- */
.lead-tl-tag{
  display:inline-block; vertical-align:1px; margin-left:6px; font-size:9.5px; font-weight:800;
  letter-spacing:0.05em; text-transform:uppercase; padding:1px 6px; border-radius:99px;
  color:var(--tl-color, var(--violet));
  background:color-mix(in srgb, var(--tl-color, var(--violet)) 15%, transparent);
}

/* ---- Right accordion cards: control-surface header ---------------- */
.lead-acc-card{ border-color:var(--line-strong); }
.lead-acc-head{
  background:var(--surface-2);
  border-bottom:1px solid var(--line-strong);
  font-size:11.5px;
}
.lead-acc-card.is-collapsed .lead-acc-head{ border-bottom:none; }
.lead-acc-head:hover{ background:var(--surface-hover); }
.lead-acc-body{ border-top:none; padding:8px 15px 13px; }
.lead-comms-rows{ border-top-color:var(--line-strong); }
[data-theme="light"] .lead-acc-head{ background:var(--surface-2); }

/* ---- Table: interactive cells ------------------------------------ */
.lead-cell-tel{ color:var(--cyan); text-decoration:none; }
.lead-cell-tel:hover{ text-decoration:underline; text-underline-offset:2px; }
.lead-cell-email{ user-select:text; }
.lead-cell-owner{ overflow:visible; }
.lead-owner-btn{
  display:inline-flex; align-items:center; max-width:100%; cursor:pointer; font:inherit; font-size:inherit;
  border:1px solid transparent; background:none; color:inherit; padding:3px 6px; margin:-3px -6px; border-radius:7px;
  transition:background .12s ease, border-color .12s ease;
}
.lead-owner-btn:hover{ background:var(--surface-2); border-color:var(--line-strong); }
.lead-owner-btn .lead-owner-chip{ overflow:hidden; }
.lead-owner-btn .lead-muted{ color:var(--text-tertiary); }

/* ---- Foot: page-size selector ----------------------------------- */
.leads-foot-size{ display:flex; align-items:center; gap:4px; margin-right:auto; margin-left:6px; }
.leads-foot-size:empty{ display:none; }
.leads-foot-size-l{ font-size:11px; font-weight:600; color:var(--text-tertiary); text-transform:uppercase; letter-spacing:0.04em; margin-right:3px; }
.leads-foot-size-btn{
  cursor:pointer; font:inherit; font-size:11.5px; font-weight:700; color:var(--text-tertiary);
  background:none; border:1px solid var(--line-strong); border-radius:7px; padding:4px 9px; transition:color .12s ease, border-color .12s ease, background .12s ease;
}
.leads-foot-size-btn:hover{ color:var(--text-secondary); }
.leads-foot-size-btn.is-active{ color:var(--violet); border-color:var(--violet-dim); background:color-mix(in srgb, var(--violet) 10%, transparent); }

/* ---- Potential-value picker menu -------------------------------- */
.lead-dealvalue-menu{ min-width:200px; }
.lead-dv-clear{ color:var(--text-tertiary); border-top:1px solid var(--line); }
.lead-dv-add{ display:flex; gap:6px; padding:7px 6px 4px; border-top:1px solid var(--line); margin-top:3px; }
.lead-dv-input{ flex:1 1 auto; min-width:0; font-size:12px; padding:6px 8px; box-shadow:none; border-color:var(--line-strong); }
.lead-dv-input:focus{ border-color:var(--violet); box-shadow:0 0 0 3px rgba(139,108,247,0.16); }
.lead-dv-save{
  flex:0 0 auto; cursor:pointer; font:inherit; font-size:11.5px; font-weight:800; color:#0A0A16;
  background:var(--brand-gradient); border:none; border-radius:7px; padding:6px 12px;
}
[data-theme="light"] .lead-dv-save{ color:#fff; }


/* =====================================================================
   PASS 8 — Lead capture arch, tasks/appointments, pipeline, export,
   profile photo, contact-record polish, Smart Accessories compaction.
   ===================================================================== */

/* §24 — inside an individual contact record the big page header is hidden;
   pull the record up into the reclaimed space. */
body.is-lead-record .topbar{ margin-bottom:6px; min-height:0; }
body.is-lead-record .topbar-controls{ display:none; }
.lead-record-bar{ align-items:center; gap:10px; }
.lead-record-back{ font-size:12px; padding:7px 11px; }
.lead-record-crumb b{ color:var(--text-primary); font-weight:800; font-size:14px; }
.lead-record-crumb span{ color:var(--text-tertiary); font-weight:500; }

/* §13 — utility strip (icons only) */
.lead-util-strip{ display:flex; align-items:center; gap:5px; margin-left:auto; }
/* item 10 — now anchored under the identity/job-title block instead of the
   top bar: centered, with its own separation from "Contact properties". */
.lead-record-idcard .lead-util-strip{ justify-content:center; margin:0 0 16px; }
.lead-util-btn{
  width:32px; height:32px; border-radius:9px; cursor:pointer; display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); border:1px solid var(--line-strong); color:var(--text-secondary);
  transition:color .14s ease, border-color .14s ease, background .14s ease;
}
.lead-util-btn:hover{ color:var(--violet); border-color:var(--violet-dim); background:var(--surface-hover); box-shadow:0 0 0 3px color-mix(in srgb, var(--violet) 12%, transparent); }
.lead-util-btn:disabled{ opacity:0.4; cursor:not-allowed; }
.lead-util-btn svg{ width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:2; }

/* §8 — premium frosted-glass hover tooltips for icon actions */
[data-tip]{ position:relative; }
[data-tip]::after{
  content:attr(data-tip); position:absolute; top:calc(100% + 8px); left:50%; transform:translateX(-50%) translateY(4px);
  padding:5px 9px; border-radius:8px; white-space:nowrap; pointer-events:none; z-index:120;
  font-size:11px; font-weight:700; letter-spacing:0.01em; color:var(--text-primary);
  background:color-mix(in srgb, var(--ink-800) 78%, transparent);
  -webkit-backdrop-filter:blur(14px) saturate(1.4); backdrop-filter:blur(14px) saturate(1.4);
  border:1px solid color-mix(in srgb, var(--cyan) 24%, var(--line-strong));
  box-shadow:0 12px 30px -12px rgba(0,0,0,0.55);
  opacity:0; transition:opacity .12s ease, transform .12s ease;
}
[data-tip]::before{
  content:""; position:absolute; top:calc(100% + 3px); left:50%; transform:translateX(-50%) rotate(45deg);
  width:7px; height:7px; z-index:121; pointer-events:none;
  background:color-mix(in srgb, var(--ink-800) 78%, transparent);
  border-left:1px solid color-mix(in srgb, var(--cyan) 24%, var(--line-strong));
  border-top:1px solid color-mix(in srgb, var(--cyan) 24%, var(--line-strong));
  opacity:0; transition:opacity .12s ease;
}
[data-tip]:hover::after{ opacity:1; transform:translateX(-50%) translateY(0); transition-delay:.28s; }
[data-tip]:hover::before{ opacity:1; transition-delay:.28s; }
[data-theme="light"] [data-tip]::after, [data-theme="light"] [data-tip]::before{
  background:color-mix(in srgb, #fff 82%, transparent);
  border-color:color-mix(in srgb, var(--violet) 26%, var(--line-strong));
}
/* tooltips anchored to a strip near the top edge point down instead */
.lead-tl-tools [data-tip]::after{ top:auto; bottom:calc(100% + 8px); }
.lead-tl-tools [data-tip]::before{ top:auto; bottom:calc(100% + 3px); transform:translateX(-50%) rotate(225deg); }
.lead-util-more-wrap{ position:relative; }
.lead-util-more-menu{
  position:absolute; top:calc(100% + 6px); right:0; z-index:60; min-width:196px; padding:5px;
  background:var(--ink-800); border:1px solid var(--line-strong); border-radius:11px;
  box-shadow:0 22px 48px -14px rgba(0,0,0,0.55); display:flex; flex-direction:column; gap:1px;
}
.lead-util-more-opt{
  display:flex; align-items:center; gap:9px; width:100%; text-align:left; text-decoration:none; cursor:pointer; font:inherit;
  padding:8px 10px; border:none; border-radius:7px; background:none; font-size:12.5px; font-weight:600; color:var(--text-primary);
}
.lead-util-more-opt:hover{ background:var(--surface-hover); }
.lead-util-more-opt svg{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2; }

/* §22 — tab-strip tools: note shortcut + comm launcher */
.lead-tl-tools{ flex:0 0 auto; display:flex; align-items:center; gap:5px; padding-left:6px; }
.lead-tl-tool{
  width:30px; height:30px; border-radius:8px; cursor:pointer; display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); border:1px solid var(--line-strong); color:var(--text-secondary); transition:color .14s ease, border-color .14s ease;
}
.lead-tl-tool:hover{ color:var(--violet); border-color:var(--violet-dim); }
.lead-tl-tool svg{ width:14px; height:14px; stroke:currentColor; fill:none; stroke-width:2; }

/* §20/§21 (+ #3) — note author + full timestamp, avatar-led */
.lead-note-hd{ display:flex; align-items:center; gap:8px; margin-bottom:6px; }
.lead-note-hd-t{ display:flex; flex-direction:column; min-width:0; line-height:1.25; }
.lead-note-when{ font-size:10.5px; color:var(--text-tertiary); font-family:'JetBrains Mono', monospace; }
.lead-note-by{ font-size:12px; font-weight:800; color:var(--text-primary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-note-avatar{ width:22px !important; height:22px !important; font-size:9px !important; }

/* §9 — right accordion cards: grip + drag reorder */
.lead-acc-head{ display:flex; align-items:center; gap:4px; padding:0; }
.lead-acc-grip{
  flex:0 0 auto; width:22px; align-self:stretch; display:flex; align-items:center; justify-content:center;
  color:var(--text-tertiary); cursor:grab; opacity:0.55; transition:opacity .12s ease;
}
.lead-acc-card:hover .lead-acc-grip{ opacity:1; }
.lead-acc-grip svg{ width:13px; height:13px; fill:currentColor; }
.lead-acc-headbtn{
  flex:1 1 auto; display:flex; align-items:center; justify-content:space-between; gap:8px; cursor:pointer;
  font:inherit; font-size:11.5px; font-weight:800; letter-spacing:0.05em; text-transform:uppercase; color:var(--text-secondary);
  background:none; border:none; padding:13px 15px 13px 4px;
}
.lead-acc-headbtn:hover{ color:var(--text-primary); }
.lead-acc-card.is-acc-dragging{ opacity:0.4; }
.lead-acc-card.acc-drop-before{ box-shadow:0 -2px 0 var(--violet); }
.lead-acc-add{
  display:flex; align-items:center; justify-content:center; gap:6px; width:100%; margin-top:8px; padding:8px;
  cursor:pointer; font:inherit; font-size:11.5px; font-weight:700; color:var(--violet);
  background:none; border:1px dashed var(--line-strong); border-radius:8px;
}
.lead-acc-add:hover{ border-color:var(--violet-dim); background:color-mix(in srgb, var(--violet) 6%, transparent); }
.lead-acc-add:disabled{ opacity:0.4; cursor:not-allowed; }
.lead-acc-add svg{ width:12px; height:12px; stroke:currentColor; fill:none; stroke-width:2.6; }

/* §6-10 — aux list rows (tasks / appts) */
.lead-aux-edit{
  flex:0 0 auto; width:24px; height:24px; border-radius:6px; cursor:pointer; opacity:0;
  display:flex; align-items:center; justify-content:center; background:none; border:1px solid transparent; color:var(--text-tertiary);
  transition:opacity .12s ease, color .12s ease, border-color .12s ease;
}
.lead-aux-row:hover .lead-aux-edit{ opacity:1; }
.lead-aux-edit:hover{ color:var(--violet); border-color:var(--line-strong); }
.lead-aux-edit svg{ width:12px; height:12px; stroke:currentColor; fill:none; stroke-width:2; }
.lead-tag-open{ color:var(--cyan); border-color:color-mix(in srgb,var(--cyan) 32%,transparent); background:color-mix(in srgb,var(--cyan) 12%,transparent); }
.lead-tag-past_due{ color:var(--bad); border-color:color-mix(in srgb,var(--bad) 38%,transparent); background:color-mix(in srgb,var(--bad) 12%,transparent); }
.lead-tag-completed{ color:var(--good); border-color:color-mix(in srgb,var(--good) 32%,transparent); background:color-mix(in srgb,var(--good) 12%,transparent); }
.lead-tag-canceled, .lead-tag-appt-canceled{ opacity:0.7; }
.lead-tag-appt-scheduled{ color:var(--cyan); border-color:color-mix(in srgb,var(--cyan) 32%,transparent); background:color-mix(in srgb,var(--cyan) 12%,transparent); }
.lead-tag-appt-completed{ color:var(--good); border-color:color-mix(in srgb,var(--good) 32%,transparent); background:color-mix(in srgb,var(--good) 12%,transparent); }
.lead-tag-appt-no_show{ color:var(--warn); border-color:color-mix(in srgb,var(--warn) 34%,transparent); background:color-mix(in srgb,var(--warn) 12%,transparent); }

/* item 11 — Live Task Widget, pinned at the top of the right lane. Color
   language: red = overdue/needs attention, amber = next up, green =
   recently completed. The breathing glow lives on one small status dot,
   not the whole card, to stay restrained rather than distracting. */
/* item 3, visual refinement pass — Task Manager reads as a specialized
   LIVE utility module, not another generic accordion card: a finer,
   status-tinted border + a restrained inset/outer glow (both driven by the
   same --tw-color the meta text and dots already used), a slightly
   tighter frame (smaller radius, trimmed padding) than the plain
   .lead-record-card/.lead-acc-card siblings around it. Still the same
   surface/family — just a hair more distinguished. */
.lead-taskwidget{
  background:var(--surface-1); flex:0 0 auto;
  border:1px solid color-mix(in srgb, var(--tw-color, var(--line-strong)) 28%, var(--line));
  border-radius:calc(var(--radius-md) - 3px); padding:11px 12px;
  box-shadow:0 0 0 1px color-mix(in srgb, var(--tw-color, transparent) 7%, transparent) inset,
             0 8px 22px -16px color-mix(in srgb, var(--tw-color, transparent) 65%, transparent);
}
.lead-taskwidget[data-taskglow="red"]{ --tw-color:var(--bad); }
.lead-taskwidget[data-taskglow="amber"]{ --tw-color:var(--warn); }
.lead-taskwidget[data-taskglow="green"]{ --tw-color:var(--good); }
.lead-taskwidget-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:8px; }
.lead-taskwidget-headtext{ display:flex; flex-direction:column; gap:3px; min-width:0; }
/* persistent module identity — always "Task Manager", regardless of state */
.lead-taskwidget-label{ display:flex; align-items:center; gap:5px; font-size:9.5px; font-weight:800; letter-spacing:0.07em; text-transform:uppercase; color:var(--text-tertiary); }
.lead-taskwidget-label svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2; }
/* dynamic status line — colored by --tw-color so it visually ties to the
   glow dot / meta text / dots below, instead of sitting flat gray. */
.lead-taskwidget-title{ display:flex; align-items:center; gap:6px; font-size:12px; font-weight:800; color:var(--tw-color, var(--text-secondary)); }
.lead-taskwidget-dot-lg{
  width:7px; height:7px; border-radius:50%; flex:0 0 auto; background:var(--tw-color, var(--text-tertiary));
  animation:tw-breathe 2.6s ease-in-out infinite;
}
@keyframes tw-breathe{
  0%, 100%{ box-shadow:0 0 0 0 color-mix(in srgb, var(--tw-color, transparent) 45%, transparent); }
  50%{ box-shadow:0 0 0 4px color-mix(in srgb, var(--tw-color, transparent) 0%, transparent); }
}
.lead-taskwidget-add{
  flex:0 0 auto; width:24px; height:24px; border-radius:7px; cursor:pointer; display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); border:1px solid var(--line-strong); color:var(--text-secondary); transition:color .12s ease, border-color .12s ease;
}
.lead-taskwidget-add:hover{ color:var(--violet); border-color:var(--violet-dim); }
.lead-taskwidget-add:disabled{ opacity:0.4; cursor:not-allowed; }
.lead-taskwidget-add svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.2; }
.lead-taskwidget-empty{ font-size:12px; color:var(--text-tertiary); padding:8px 0 2px; }
.lead-taskwidget-body{
  display:flex; align-items:flex-start; gap:10px; cursor:pointer; border-radius:8px;
  margin:6px -6px 0; padding:6px; transition:background .12s ease;
  animation:tw-cardin .22s cubic-bezier(.2,.7,.3,1);
}
@keyframes tw-cardin{ from{ opacity:0; transform:translateY(3px); } to{ opacity:1; transform:none; } }
.lead-taskwidget-body:hover{ background:var(--surface-hover); }
.lead-taskwidget-main{ flex:1 1 auto; min-width:0; }
.lead-taskwidget-t{ font-size:13px; font-weight:700; color:var(--text-primary); }
.lead-taskwidget-meta{ font-size:11px; color:var(--tw-color, var(--text-tertiary)); font-weight:600; margin-top:2px; }
.lead-taskwidget-ctx{ font-size:11px; color:var(--text-tertiary); margin-top:3px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-taskwidget-dots{ display:flex; align-items:center; justify-content:center; gap:5px; padding-top:8px; }
.lead-taskwidget-dot{ width:5px; height:5px; border-radius:50%; background:var(--line-strong); transition:background .15s ease, transform .15s ease; }
.lead-taskwidget-dot.is-active{ background:var(--tw-color, var(--violet)); transform:scale(1.3); }

/* ---- QC (this pass) — P6-P9: Digital Card status widget --------------
   Same "distinguished mini-card" family as .lead-taskwidget just above
   (compact frame, tighter radius/padding than the plain accordion cards),
   but with the brand violet as its own fixed identity color rather than a
   dynamic urgency color — this is a 1EIGHTY PRODUCT attached to the
   contact, not a state that escalates. Hierarchy on purpose: status badge
   and company/name read first; the raw URL is smallest or absent — see the
   P9 "what should a rep instantly recognize" ordering. */
.lead-dc-widget{
  background:var(--surface-1); flex:0 0 auto;
  border:1px solid color-mix(in srgb, var(--violet) 22%, var(--line));
  border-radius:calc(var(--radius-md) - 3px); padding:11px 12px;
  box-shadow:0 0 0 1px color-mix(in srgb, var(--violet) 5%, transparent) inset;
}
.lead-dc-widget-head{ display:flex; align-items:center; justify-content:space-between; gap:8px; }
.lead-dc-widget-label{ display:flex; align-items:center; gap:5px; font-size:9.5px; font-weight:800; letter-spacing:0.07em; text-transform:uppercase; color:var(--text-tertiary); }
.lead-dc-widget-label svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2; }
.lead-dc-widget-empty{ display:flex; align-items:center; justify-content:space-between; gap:10px; font-size:12px; color:var(--text-tertiary); padding:8px 0 2px; }
.lead-dc-assign-btn{
  flex:0 0 auto; font:inherit; font-size:11px; font-weight:700; color:var(--text-tertiary); cursor:not-allowed;
  background:var(--surface-2); border:1px solid var(--line-strong); border-radius:7px; padding:5px 10px; opacity:0.65;
}
.lead-dc-widget-body{
  display:flex; align-items:center; gap:10px; cursor:pointer; text-decoration:none; border-radius:8px;
  margin:8px -6px -2px; padding:6px; transition:background .12s ease;
}
.lead-dc-widget-body:hover{ background:var(--surface-hover); }
.lead-dc-widget-ini{
  flex:0 0 auto; width:30px; height:30px; border-radius:10px; display:flex; align-items:center; justify-content:center;
  font-size:11.5px; font-weight:800; color:#0A0A16; background:var(--dc-accent, var(--violet));
}
[data-theme="light"] .lead-dc-widget-ini{ color:#fff; }
.lead-dc-widget-main{ flex:1 1 auto; min-width:0; }
.lead-dc-widget-name{ display:block; font-size:12.5px; font-weight:700; color:var(--text-primary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-dc-widget-url{ display:block; font-size:10.5px; color:var(--text-tertiary); margin-top:1px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-dc-widget-eye{
  flex:0 0 auto; width:15px; height:15px; stroke:var(--violet); fill:none; stroke-width:1.9;
  opacity:0; transform:translateX(-3px); transition:opacity .14s ease, transform .14s ease;
}
.lead-dc-widget-body:hover .lead-dc-widget-eye{ opacity:1; transform:none; }
.lead-dc-widget-co{ font-weight:600; color:var(--text-tertiary); }
.lead-dc-widget-foot{ display:flex; align-items:center; gap:7px; margin-top:9px; font-size:11px; }
/* #13 (Dock freeze pass) — Dock's Digital Cards card only (this same
   .lead-dc-widget-foot class is reused by Orbit's own Digital Cards widget
   elsewhere and must stay untouched there): Open in Card Studio reads as
   this card's clear right-aligned CTA instead of sitting flush left. */
.lead-acc-card[data-acc="digitalcards"] .lead-dc-widget-foot{ justify-content:flex-end; }
.lead-dc-widget-foot a, .lead-dc-widget-link{ color:var(--violet); font-weight:700; background:none; border:none; padding:0; cursor:pointer; font:inherit; font-size:11px; }
.lead-dc-widget-foot a:hover, .lead-dc-widget-link:hover{ text-decoration:underline; }
.lead-dc-widget-dot{ color:var(--text-tertiary); }

/* #16 — 1EIGHTY account relationship summary in Full Contact */
.lead-acct-widget-grid{ display:grid; grid-template-columns:1fr 1fr; gap:6px 12px; margin-top:9px; }
.lead-acct-kv{ display:flex; flex-direction:column; gap:1px; min-width:0; }
.lead-acct-kv span{ font-size:9.5px; font-weight:700; letter-spacing:0.04em; text-transform:uppercase; color:var(--text-tertiary); }
.lead-acct-kv b{ font-size:12px; font-weight:700; color:var(--text-primary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lead-acct-widget-note{ font-size:10px; color:var(--text-tertiary); margin-top:9px; line-height:1.4; }

/* #10 — clickable account-user name → Orbit contact */
.ch360-person-open{ font:inherit; font-weight:700; font-size:12px; color:var(--text-primary); background:none; border:none; padding:0; cursor:pointer; text-align:left; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ch360-person-open:hover{ color:var(--violet); text-decoration:underline; }
.ch360-person-orbitlink{ display:inline-flex; align-items:center; gap:5px; max-width:100%; font:inherit; font-size:11px; font-weight:700; color:var(--violet); background:none; border:none; padding:2px 0 0; cursor:pointer; text-align:left; overflow-wrap:anywhere; }
.ch360-person-orbitlink svg{ width:12px; height:12px; stroke:currentColor; fill:none; stroke-width:2; }
.ch360-person-orbitlink:hover{ text-decoration:underline; }
.lead-tab-action-l{ flex:1 1 auto; font-size:11px; font-weight:600; color:var(--text-tertiary); }
.lead-tab-action .lead-note-save{ display:inline-flex; align-items:center; gap:6px; }
.lead-tab-action .lead-note-save svg{ width:12px; height:12px; stroke:currentColor; fill:none; stroke-width:2.6; }
.lead-appt-invite{ flex-direction:row !important; align-items:center; justify-content:space-between; }
.lead-appt-invite span{ font-size:10.5px; font-weight:700; letter-spacing:0.03em; text-transform:uppercase; color:var(--text-tertiary); }

/* §7/§8 — composer external-action buttons */
.lead-comp-openext, .lead-comp-callbtn{
  display:inline-flex; align-items:center; gap:7px; align-self:flex-start; text-decoration:none; cursor:pointer;
  font:inherit; font-size:12px; font-weight:700; margin:4px 14px 0;
  padding:7px 12px; border-radius:8px; border:1px solid var(--line-strong); color:var(--text-secondary);
  background:none;
}
.lead-comp-callbtn{ color:var(--good); border-color:color-mix(in srgb, var(--good) 40%, transparent); }
.lead-comp-openext:hover{ color:var(--text-primary); border-color:var(--violet-dim); }
.lead-comp-openext svg, .lead-comp-callbtn svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2; }
.lead-commbar-field.is-open{ color:var(--violet); font-weight:600; }
.lead-tab-hint{ font-size:10px; color:var(--text-tertiary); margin-left:8px; }

/* §27-31 — List / Pipeline switch + Kanban */
.leads-modeswitch{ display:inline-flex; gap:2px; padding:3px; border-radius:10px; background:var(--surface-1); border:1px solid var(--line-strong); align-self:flex-start; }
.leads-ms-btn{
  display:inline-flex; align-items:center; gap:6px; cursor:pointer; font:inherit; font-size:12px; font-weight:700;
  color:var(--text-tertiary); background:none; border:none; padding:6px 12px; border-radius:7px; transition:color .12s ease, background .12s ease;
}
.leads-ms-btn svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2; }
.leads-ms-btn:hover{ color:var(--text-secondary); }
.leads-ms-btn.is-active{ color:var(--text-primary); background:var(--surface-hover); box-shadow:inset 0 0 0 1px var(--line-strong); }

.leads-pipeline{ display:flex; flex-direction:column; min-height:0; flex:1 1 auto; overflow:hidden; }
/* #4 — the summary strip and the board below it now share ONE geometry:
   same fixed per-item width (270px), same gap (12px), same 16px outer
   padding, same layout model (flex row, horizontal scroll rather than
   reflow) as .pipe-board/.pipe-col below. Previously this was an
   independent 5-column CSS Grid (repeat(5,1fr), 10px gap) sitting above an
   entirely different fixed-270px flex board with 6 columns — two unrelated
   layouts that could never actually line up, and the summary's own
   ≤1240px breakpoint collapsed it to 3 columns while the board never
   reflowed at all, guaranteeing misalignment at exactly the widths where a
   real laptop views this page. With matching geometry, cell 1 sits above
   column 1, cell 2 above column 2, etc. at rest (scrollLeft 0) at every
   width — cell count staying at 5 against 6+ columns is a real difference
   in what they represent (5 fixed KPIs vs. N pipeline stages), not solved
   by forcing them to the same count, so the trailing column(s) beyond the
   5th summary cell simply have no KPI above them, which reads as
   intentional rather than misaligned since the shared grid is now visibly
   one system. */
.pipe-summary{ flex:0 0 auto; display:flex; gap:12px; padding:14px 16px; border-bottom:1px solid var(--line); overflow-x:auto; }
.pipe-summary-cell{ flex:0 0 270px; }
/* item 1, final visual refinement pass — pushed well past the previous
   pass's restrained treatment: richer tint, brighter border, a real inner
   +outer glow, and a slow (7s, same cadence Performance Journey's own
   breathing values use — not its code, just the same tasteful pace) STATIC
   breathing pulse on border/glow intensity only. No moving gradients, no
   traveling light — the aura expands/contracts in place. Staggered
   per-cell delays (like Performance Journey's funnel nodes) so the five
   don't all breathe in lockstep. */
.pipe-summary-cell{
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--pc) 16%, transparent), transparent 65%),
    var(--surface-1);
  border:1px solid color-mix(in srgb, var(--pc) 48%, var(--line-strong));
  border-radius:var(--radius-md); padding:12px 10px; position:relative; overflow:hidden;
  display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; gap:2px;
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--pc) 14%, transparent) inset,
    0 0 34px -12px color-mix(in srgb, var(--pc) 80%, transparent);
  animation:pipeSummaryBreathe 7s ease-in-out infinite;
}
.pipe-summary-cell:nth-child(2){ animation-delay:-1.4s; }
.pipe-summary-cell:nth-child(3){ animation-delay:-2.8s; }
.pipe-summary-cell:nth-child(4){ animation-delay:-4.2s; }
.pipe-summary-cell:nth-child(5){ animation-delay:-5.6s; }
@keyframes pipeSummaryBreathe{
  0%,100%{
    box-shadow:0 0 0 1px color-mix(in srgb, var(--pc) 10%, transparent) inset, 0 0 26px -14px color-mix(in srgb, var(--pc) 65%, transparent);
    border-color:color-mix(in srgb, var(--pc) 38%, var(--line-strong));
  }
  50%{
    box-shadow:0 0 0 1px color-mix(in srgb, var(--pc) 22%, transparent) inset, 0 0 42px -9px color-mix(in srgb, var(--pc) 95%, transparent);
    border-color:color-mix(in srgb, var(--pc) 68%, var(--line-strong));
  }
}
.pipe-summary-v{ font-size:20px; font-weight:800; letter-spacing:-0.02em; color:var(--pc); text-shadow:0 0 12px color-mix(in srgb, var(--pc) 34%, transparent); }
/* Modal-UX pass — labels stronger + more legible against the card in dark */
.pipe-summary-l{ font-size:10.5px; font-weight:700; color:color-mix(in srgb, var(--text-secondary) 88%, var(--text-primary)); text-transform:uppercase; letter-spacing:0.05em; }
/* Sold — the same "this is the goal" prestige language as the Sold
   pipeline column, stronger again: richer wash, brighter border, and its
   own hotter breathing amplitude on top of the shared keyframe above. */
.pipe-summary-cell.is-gold{
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--pc) 24%, transparent), transparent 70%),
    var(--surface-1);
  border-color:color-mix(in srgb, var(--pc) 62%, var(--line-strong));
  box-shadow:0 0 0 1px color-mix(in srgb, var(--pc) 20%, transparent) inset, 0 0 44px -8px color-mix(in srgb, var(--pc) 95%, transparent);
  animation-name:pipeSummaryBreatheGold;
}
.pipe-summary-cell.is-gold .pipe-summary-v{ text-shadow:0 0 16px color-mix(in srgb, var(--pc) 60%, transparent); }
@keyframes pipeSummaryBreatheGold{
  0%,100%{
    box-shadow:0 0 0 1px color-mix(in srgb, var(--pc) 16%, transparent) inset, 0 0 34px -12px color-mix(in srgb, var(--pc) 78%, transparent);
    border-color:color-mix(in srgb, var(--pc) 50%, var(--line-strong));
  }
  50%{
    box-shadow:0 0 0 1px color-mix(in srgb, var(--pc) 30%, transparent) inset, 0 0 52px -6px color-mix(in srgb, var(--pc) 100%, transparent);
    border-color:color-mix(in srgb, var(--pc) 85%, var(--line-strong));
  }
}
.pipe-note{ flex:0 0 auto; display:flex; align-items:center; gap:8px; font-size:11.5px; color:var(--text-tertiary); padding:8px 16px; }
.pipe-note svg{ width:13px; height:13px; stroke:var(--warn); fill:none; stroke-width:2; }
.pipe-board{ flex:1 1 auto; min-height:0; display:flex; gap:12px; overflow-x:auto; overflow-y:hidden; padding:14px 16px 16px; align-items:flex-start; }
/* item 12 — buckets brought up to the rest of the page: stage-coloured
   identity hairline, a faint tinted header, clearer drop target and empty
   state. No new behaviour, no redesign. */
.pipe-col{
  flex:0 0 270px; display:flex; flex-direction:column; min-height:0; max-height:100%; position:relative; overflow:hidden;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--pc) 13%, transparent), transparent 52%),
    var(--surface-1);
  border:1px solid color-mix(in srgb, var(--pc) 30%, var(--line-strong)); border-radius:var(--radius-md);
  /* item 4 + Refinement Pass Part 2 — a restrained, STATIC atmospheric glow
     per column (no animation/motion — just a soft colored aura sitting
     behind the card), so each stage reads as distinguishable even before
     the label registers. Stronger now: a real colored border tint, a
     deeper wash, and a wider aura — still no traveling light, no pulse. */
  box-shadow:0 0 38px -14px color-mix(in srgb, var(--pc) 72%, transparent);
  transition:border-color .12s ease, box-shadow .12s ease;
}
.pipe-col::before{
  content:""; position:absolute; left:12px; right:12px; top:0; height:2px; border-radius:0 0 3px 3px;
  background:var(--pc); opacity:0.9;
  box-shadow:0 0 16px 1px color-mix(in srgb, var(--pc) 62%, transparent);
}
/* a faint stage-tinted header band on the working (non-closed) stages */
.pipe-col:not(.is-closed) .pipe-col-hd{
  background:linear-gradient(180deg, color-mix(in srgb, var(--pc) 12%, transparent), transparent);
  border-bottom-color:color-mix(in srgb, var(--pc) 26%, var(--line));
}
/* closed / terminal stages read as intentional, not disabled */
.pipe-col.is-closed{ background:var(--surface-1); }
.pipe-col.is-closed::before{ opacity:0.4; }
.pipe-col.is-closed .pipe-col-name{ color:var(--text-tertiary); }
/* Not Interested — the deliberate visually-receding dead-end (last column).
   No accent aura at all: neutral border, no colored glow, grayscale-ish
   hairline. Sold is ALSO .is-closed but gets its full gold treatment from
   the [data-pipe-col="sold"] rules just below (later + equal specificity). */
.pipe-col.is-closed:not([data-pipe-col="sold"]):not(.is-over){
  border-color:var(--line-strong);
  box-shadow:none;
}
/* Sold — the destination/victory stage. Same restrained language as every
   other column, just stronger, mirroring (not copying/modifying) the gold
   halo treatment Performance Journey's own destination stage already
   uses: warmer wash, brighter hairline + glow, and the column name itself
   picks up the gold accent. Performance Journey's own markup/CSS is
   untouched — this only reads its established color language. Sold is
   ALSO `closed:true` (like Not Interested), so these rules must come
   AFTER .is-closed's — same specificity (two class-equivalent selectors),
   and .is-closed would otherwise win on source order and mute the gold
   treatment right back down to the generic closed-stage look. */
.pipe-col[data-pipe-col="sold"]{
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--pc) 22%, transparent), transparent 58%),
    var(--surface-1);
  border-color:color-mix(in srgb, var(--pc) 52%, var(--line-strong));
  box-shadow:0 0 52px -12px color-mix(in srgb, var(--pc) 85%, transparent);
}
.pipe-col[data-pipe-col="sold"] .pipe-col-hd{
  background:linear-gradient(180deg, color-mix(in srgb, var(--pc) 18%, transparent), transparent);
  border-bottom-color:color-mix(in srgb, var(--pc) 34%, var(--line));
}
.pipe-col[data-pipe-col="sold"]::before{ opacity:1; box-shadow:0 0 24px 2px color-mix(in srgb, var(--pc) 72%, transparent); }
.pipe-col[data-pipe-col="sold"] .pipe-col-name{ color:var(--pc); text-shadow:0 0 12px color-mix(in srgb, var(--pc) 45%, transparent); }
.pipe-col[data-pipe-col="sold"] .pipe-col-dot{ box-shadow:0 0 12px -1px color-mix(in srgb, var(--pc) 85%, transparent); }
.pipe-col.is-over{ border-color:var(--pc); box-shadow:0 0 0 2px color-mix(in srgb, var(--pc) 40%, transparent); }
.pipe-col.is-over .pipe-col-body{ background:color-mix(in srgb, var(--pc) 7%, transparent); }
.pipe-col-hd{ flex:0 0 auto; display:flex; align-items:center; gap:8px; padding:12px 12px 11px; border-bottom:1px solid var(--line); }
.pipe-col-dot{ width:9px; height:9px; border-radius:3px; background:var(--pc); flex:0 0 auto; box-shadow:0 0 8px -1px color-mix(in srgb, var(--pc) 70%, transparent); }
.pipe-col-name{ flex:1 1 auto; font-size:12px; font-weight:800; letter-spacing:0.04em; text-transform:uppercase; color:var(--text-primary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pipe-col-n{ font-family:'JetBrains Mono', monospace; font-size:11px; font-weight:700; color:var(--text-secondary); background:color-mix(in srgb, var(--pc) 12%, var(--surface-2)); border:1px solid color-mix(in srgb, var(--pc) 22%, transparent); padding:1px 7px; border-radius:99px; }
.pipe-col-body{ flex:1 1 auto; min-height:0; overflow-y:auto; padding:11px 10px; display:flex; flex-direction:column; gap:9px; transition:background .12s ease; }
.pipe-col-empty{ font-size:11px; color:var(--text-tertiary); text-align:center; padding:16px 8px; border:1px dashed var(--line-strong); border-radius:9px; opacity:0.75; }
.pipe-card{
  background:var(--surface-2); border:1px solid var(--line-strong); border-radius:10px; padding:10px 11px; cursor:grab;
  display:flex; flex-direction:column; gap:6px; transition:border-color .12s ease, box-shadow .12s ease, transform .1s ease;
}
.pipe-card:hover{ border-color:var(--violet-dim); box-shadow:0 6px 16px -10px rgba(0,0,0,0.5); }
.pipe-card:active{ cursor:grabbing; }
.pipe-card.is-dragging{ opacity:0.4; }
.pipe-card-top{ display:flex; align-items:baseline; justify-content:space-between; gap:8px; }
.pipe-card-name{ font-size:13px; font-weight:800; color:var(--text-primary); cursor:pointer; min-width:0; word-break:break-word; }
.pipe-card-name:hover{ text-decoration:underline; }
.pipe-card-val{ font-size:11.5px; font-weight:800; color:var(--good); font-family:'JetBrains Mono', monospace; flex:0 0 auto; }
.pipe-card-co{ font-size:11px; color:var(--text-tertiary); }
.pipe-card-meta{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.pipe-card-status{ font-size:9.5px; padding:2px 7px; }
.pipe-card-src{ display:inline-flex; align-items:center; gap:4px; font-size:10.5px; color:var(--text-tertiary); }
.pipe-card-src svg{ width:10px; height:10px; stroke:var(--chip-color, var(--text-tertiary)); fill:none; stroke-width:2; }
.pipe-card-foot{ display:flex; align-items:center; justify-content:space-between; gap:8px; font-size:10.5px; color:var(--text-tertiary); }
.pipe-card-owner{ display:inline-flex; align-items:center; gap:5px; }
.pipe-card-owner .lead-owner-ini{ width:15px; height:15px; font-size:8px; }
.pipe-card-task{ display:inline-flex; align-items:center; gap:4px; }
.pipe-card-task svg{ width:10px; height:10px; stroke:currentColor; fill:none; stroke-width:2; }
.pipe-card-task.is-overdue{ color:var(--bad); font-weight:700; }

/* ===========================================================================
   PIPELINE — LIGHT MODE (Contact Command only; scoped entirely to .pipe-*,
   Overview is never touched). The dark board's atmospheric neon auras and
   bright-on-black accent hexes read as a washed-out radioactive haze on the
   pearl theme, so light gets its OWN tuning: the SAME semantic stage colours,
   but darkened for contrast on white, subtle tinted fills, real (non-glowing)
   colour borders, and controlled soft shadows instead of the atmospheric
   glow. Dark mode is deliberately left as-is. --pc is the fixed stage hex set
   inline by renderPipeline(). Gold is nudged to a browner tone that stays
   premium AND legible on white (raw #FFC233 is invisible as text/edge). */
[data-theme="light"] .pipe-summary-cell{
  background:color-mix(in srgb, var(--pc) 9%, var(--surface-1));
  border-color:color-mix(in srgb, var(--pc) 46%, var(--line-strong));
  box-shadow:0 1px 2px rgba(28,27,64,0.05), inset 0 0 0 1px color-mix(in srgb, var(--pc) 9%, transparent);
  animation:none;   /* no pulsing colour haze on white */
}
/* light — the NUMBER carries the colour, vivid and forward (not the washed
   dark-tinted value from the previous pass), while staying readable on white */
[data-theme="light"] .pipe-summary-v{ color:color-mix(in srgb, var(--pc) 66%, #0c0e14); text-shadow:none; }
[data-theme="light"] .pipe-summary-l{ color:var(--text-secondary); font-weight:700; }
[data-theme="light"] .pipe-summary-cell.is-gold{
  background:color-mix(in srgb, #E8A200 13%, var(--surface-1));
  border-color:color-mix(in srgb, #B87400 46%, var(--line-strong));
  box-shadow:0 1px 3px rgba(160,105,0,0.16), inset 0 0 0 1px color-mix(in srgb, #C88600 16%, transparent);
}
[data-theme="light"] .pipe-summary-cell.is-gold .pipe-summary-v{ color:#9C6600; text-shadow:none; }

[data-theme="light"] .pipe-col{
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--pc) 12%, transparent), transparent 62%),
    color-mix(in srgb, var(--pc) 7%, var(--surface-1));
  border-color:color-mix(in srgb, var(--pc) 42%, var(--line-strong));
  box-shadow:0 2px 8px -3px color-mix(in srgb, var(--pc) 20%, rgba(28,27,64,0.08));
}
[data-theme="light"] .pipe-col::before{
  opacity:1; box-shadow:none;
  background:color-mix(in srgb, var(--pc) 80%, #2a2c3d);
}
[data-theme="light"] .pipe-col-dot{ box-shadow:none; }
[data-theme="light"] .pipe-col:not(.is-closed) .pipe-col-hd{
  background:linear-gradient(180deg, color-mix(in srgb, var(--pc) 15%, transparent), transparent);
  border-bottom-color:color-mix(in srgb, var(--pc) 34%, var(--line));
}
[data-theme="light"] .pipe-col-n{
  color:var(--text-secondary);
  background:color-mix(in srgb, var(--pc) 10%, #fff);
  border-color:color-mix(in srgb, var(--pc) 30%, var(--line-strong));
}
/* Not Interested — a receded plain slate card, no colour identity */
[data-theme="light"] .pipe-col.is-closed:not([data-pipe-col="sold"]):not(.is-over){
  background:var(--surface-1);
  border-color:var(--line-strong);
  box-shadow:0 1px 2px rgba(28,27,64,0.04);
}
[data-theme="light"] .pipe-col.is-closed:not([data-pipe-col="sold"])::before{ background:var(--line-strong); }
/* Sold — the destination stage. Meant to be the one column that's allowed
   to be a little louder than the rest: this is where you want your deals. */
[data-theme="light"] .pipe-col[data-pipe-col="sold"]{
  background:
    linear-gradient(180deg, color-mix(in srgb, #E8A200 22%, transparent), transparent 58%),
    color-mix(in srgb, #E8A200 12%, var(--surface-1));
  border-color:color-mix(in srgb, #B87400 58%, var(--line-strong));
  box-shadow:0 3px 18px -5px rgba(184,116,0,0.32), 0 0 0 1px color-mix(in srgb, #E8A200 18%, transparent) inset;
  animation:pipeGoldAura 6s ease-in-out infinite;
}
[data-theme="light"] .pipe-col[data-pipe-col="sold"]::before{
  background:linear-gradient(90deg, #E0A100, #F2C558, #E0A100); box-shadow:0 0 10px 1px rgba(220,158,0,0.45);
}
[data-theme="light"] .pipe-col[data-pipe-col="sold"] .pipe-col-hd{
  background:linear-gradient(180deg, color-mix(in srgb, #E8A200 20%, transparent), transparent);
  border-bottom-color:color-mix(in srgb, #B87400 38%, var(--line));
}
[data-theme="light"] .pipe-col[data-pipe-col="sold"] .pipe-col-name{
  color:#8A5A00; text-shadow:0 0 1px rgba(138,90,0,0.15); font-weight:800;
}
[data-theme="light"] .pipe-col[data-pipe-col="sold"] .pipe-col-dot{ box-shadow:0 0 6px -1px rgba(220,158,0,0.7); }
@keyframes pipeGoldAura{
  0%, 100%{ box-shadow:0 3px 18px -5px rgba(184,116,0,0.32), 0 0 0 1px color-mix(in srgb, #E8A200 18%, transparent) inset; }
  50%{ box-shadow:0 3px 22px -4px rgba(184,116,0,0.42), 0 0 0 1px color-mix(in srgb, #E8A200 26%, transparent) inset; }
}
/* drop feedback — a clean colour ring, no glow, still obvious on Not Interested */
[data-theme="light"] .pipe-col.is-over{
  border-color:color-mix(in srgb, var(--pc) 62%, #3a3d52);
  box-shadow:0 0 0 2px color-mix(in srgb, var(--pc) 22%, transparent);
}
[data-theme="light"] .pipe-col.is-over .pipe-col-body{ background:color-mix(in srgb, var(--pc) 6%, transparent); }
/* cards — a clean white surface lifting off the tinted column */
[data-theme="light"] .pipe-card{
  background:var(--surface-1); border-color:var(--line-strong);
  box-shadow:0 1px 2px rgba(28,27,64,0.05);
}
[data-theme="light"] .pipe-card:hover{
  border-color:var(--violet-dim); box-shadow:0 4px 12px -4px rgba(28,27,64,0.14);
}

/* #4 — .pipe-summary is a fixed-width flex row now (matching .pipe-board),
   so it no longer reflows into fewer columns at narrow widths; like the
   board, it scrolls horizontally instead. The old 3-column grid-collapse
   rule this replaced is why the strip and board used to visibly diverge
   at exactly laptop/tablet widths. */

/* §32 — Export sheet */
.export-segs{ display:flex; gap:8px; flex-wrap:wrap; }
.export-seg{
  cursor:pointer; font:inherit; font-size:12px; font-weight:700; color:var(--text-secondary);
  background:var(--surface-2); border:1px solid var(--line-strong); border-radius:9px; padding:9px 12px;
  display:inline-flex; flex-direction:column; gap:2px; align-items:flex-start;
}
.export-seg span{ font-size:10px; font-weight:600; color:var(--text-tertiary); }
.export-seg.is-active{ color:var(--violet); border-color:var(--violet-dim); background:color-mix(in srgb, var(--violet) 10%, transparent); }
.export-fields{ display:grid; grid-template-columns:1fr 1fr; gap:5px; }
.export-field{
  display:flex; align-items:center; gap:8px; cursor:pointer; font:inherit; font-size:12px; color:var(--text-secondary);
  background:none; border:none; padding:5px 4px; text-align:left;
}
.export-field.is-on{ color:var(--text-primary); }
.export-preview{ margin-top:6px; padding:11px 13px; border-radius:9px; background:var(--surface-2); border:1px solid var(--line-strong); font-size:12px; color:var(--text-secondary); }
.export-preview b{ color:var(--text-primary); font-size:14px; margin-right:4px; }

/* CRM Settings rows / integrations */
.crm-row.is-clickable{ cursor:pointer; width:100%; text-align:left; background:none; border:none; border-bottom:1px solid var(--line); }
.crm-row.is-clickable:hover{ background:var(--surface-hover); }
.crm-row-chev{ width:14px; height:14px; stroke:var(--text-tertiary); fill:none; stroke-width:2.4; flex:0 0 auto; }
.crm-row-soon.is-new{ color:var(--good); background:color-mix(in srgb, var(--good) 14%, transparent); }
.crm-integ-group{ margin-bottom:14px; }
.crm-integ-h{ font-size:11px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary); margin-bottom:8px; }
.crm-integ-row{ display:flex; align-items:center; gap:11px; padding:11px 0; border-bottom:1px solid var(--line); }
.crm-integ-row:last-child{ border-bottom:none; }
.crm-integ-ic{ flex:0 0 auto; width:34px; height:34px; border-radius:9px; display:flex; align-items:center; justify-content:center; background:var(--surface-2); border:1px solid var(--line); }
.crm-integ-ic svg{ width:15px; height:15px; stroke:var(--violet); fill:none; stroke-width:2; }
.crm-integ-main{ flex:1 1 auto; min-width:0; }
.crm-integ-name{ font-size:13px; font-weight:700; color:var(--text-primary); display:flex; align-items:center; gap:7px; flex-wrap:wrap; }
.crm-integ-state{ font-size:11px; color:var(--text-tertiary); margin-top:1px; line-height:1.4; }
/* connection state badge — one restrained pill per tone, works both themes */
.crm-integ-badge{
  font-size:9.5px; font-weight:800; letter-spacing:0.05em; text-transform:uppercase;
  padding:2px 7px; border-radius:99px; border:1px solid var(--line-strong); color:var(--text-tertiary);
  background:var(--surface-2);
}
.crm-integ-badge.is-good{ color:var(--good); background:var(--good-dim); border-color:color-mix(in srgb, var(--good) 34%, transparent); }
.crm-integ-badge.is-bad{ color:var(--bad); background:var(--bad-dim); border-color:color-mix(in srgb, var(--bad) 34%, transparent); }
.crm-integ-badge.is-pending{ color:var(--warn); background:var(--warn-dim); border-color:color-mix(in srgb, var(--warn) 34%, transparent); }

/* email signature editor — QC (this pass), P3 visual upgrade: a two-column
   "studio" (editor primary/left, a realistic email-canvas preview
   secondary/right; stacks below on narrow viewports). Visual (contenteditable,
   paste-friendly) / HTML (raw sanitized source) share one visible surface,
   plus a sandboxed <iframe srcdoc> preview isolated from the dashboard's own
   CSS — the same way a real email client renders a signature, now shown in
   natural message context (see sigPreviewDoc() in app.js) instead of
   floating alone. Reuses .sa-tf-select (the existing pill-toggle language)
   and .lead-save-status (the existing autosave-pill language) rather than
   inventing new components. */
.lead-sheet-intro{ font-size:12.5px; color:var(--text-secondary); line-height:1.55; margin:0 0 14px; }
.lead-sig-input{ font-family:'JetBrains Mono', ui-monospace, monospace; font-size:12.5px; line-height:1.5; resize:vertical; min-height:180px; }
.sig-studio{ display:flex; flex-direction:column; gap:18px; }
.sig-studio-editor{ display:flex; flex-direction:column; min-width:0; }
.sig-toolbar{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:8px; }
.sig-editor-visual{
  min-height:180px; max-height:320px; overflow-y:auto; padding:11px 13px; border-radius:10px; font-size:13px; line-height:1.5;
  color:var(--text-primary); background:var(--input-bg); border:1px solid var(--line-strong);
  transition:border-color .14s ease, box-shadow .14s ease;
}
.sig-editor-visual:focus{ outline:none; border-color:var(--violet); box-shadow:0 0 0 3px rgba(139,108,247,0.16); }
.sig-editor-visual img{ max-width:100%; height:auto; }
.sig-editor-html{ margin:0; }
.sig-studio-preview{ display:flex; flex-direction:column; min-width:0; }
.sig-studio-preview-h{
  font-size:10px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary); margin-bottom:8px;
}
/* The white email surface itself, floated as a clean card inside the dark
   dashboard — a soft ambient drop shadow plus a hairline ring do the
   framing, nothing skeuomorphic. The message context (sender row, "to"
   line, the short note above the signature) is rendered INSIDE the iframe
   by sigPreviewDoc(), so this wrapper stays deliberately plain. */
.sig-studio-preview-frame-wrap{
  border:1px solid var(--line-strong); border-radius:14px; overflow:hidden; background:#fff;
  box-shadow:0 1px 2px rgba(0,0,0,0.05), 0 22px 48px -24px rgba(0,0,0,0.55);
}
.sig-preview-frame{ display:block; width:100%; height:344px; border:none; background:#fff; }
@media (max-width:640px){ .sig-preview-frame{ height:280px; } }

/* Gmail status chip in the composer From row */
.lead-email-conn{
  display:inline-flex; align-items:center; gap:5px; margin-left:8px; cursor:pointer;
  font:inherit; font-size:10px; font-weight:700; letter-spacing:0.02em;
  padding:2px 8px; border-radius:99px; border:1px solid var(--line-strong);
  background:var(--surface-2); color:var(--text-tertiary); transition:border-color .12s ease, color .12s ease;
}
.lead-email-conn svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2; flex:0 0 auto; }
.lead-email-conn:hover{ color:var(--text-secondary); border-color:var(--violet-dim); }
.lead-email-conn.is-good{ color:var(--good); border-color:color-mix(in srgb, var(--good) 34%, transparent); }
.lead-email-conn.is-bad{ color:var(--bad); border-color:color-mix(in srgb, var(--bad) 34%, transparent); }
.lead-email-conn.is-pending{ color:var(--warn); border-color:color-mix(in srgb, var(--warn) 34%, transparent); }

/* §34 / §24 — profile photo. Layout: avatar + a control cluster that
   clearly belongs to it. Upload / Use camera are matched-size secondary
   buttons; Remove is a quiet destructive text link beneath them. */
.avatar-badge.has-photo, .settings-photo.has-photo{ background-size:cover; background-position:center; color:transparent; }
.settings-photo-row{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; padding-bottom:18px; margin-bottom:16px; border-bottom:1px solid var(--line); }
.settings-photo{
  flex:0 0 auto; width:72px; height:72px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  background:linear-gradient(135deg, var(--violet), var(--cyan)); color:#0A0A16; font-weight:800; font-size:21px; overflow:hidden;
  box-shadow:0 0 0 1px var(--line-strong), 0 6px 16px -8px rgba(0,0,0,0.4);
}
.settings-photo-ctrls{ flex:1 1 auto; min-width:200px; display:flex; flex-direction:column; align-items:flex-start; gap:9px; }
.settings-photo-btns{ display:flex; gap:8px; flex-wrap:wrap; }
.settings-photo-btn{
  display:inline-flex; align-items:center; gap:7px; padding:8px 14px; border-radius:9px;
  font-size:12.5px; font-weight:700; color:var(--text-primary);
  background:var(--surface-2); border:1px solid var(--line-strong); cursor:pointer;
  transition:background .16s ease, border-color .16s ease;
}
.settings-photo-btn:hover{ background:var(--surface-hover); border-color:var(--violet-dim); }
.settings-photo-btn svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2; }
.settings-photo-remove{
  background:none; border:none; padding:0; font:inherit; font-size:12px; font-weight:600;
  color:var(--text-tertiary); cursor:pointer; transition:color .14s ease;
}
.settings-photo-remove:hover{ color:var(--bad); }
.settings-photo-note{ flex-basis:100%; font-size:11px; color:var(--text-tertiary); margin:0; }

/* #12-17 — profile picture border. .pb-ring-host is the ONLY thing that
   opts an element into the ring treatment: applied to the four "this is the
   logged-in user" avatars (#avatarBadge, #profileMenuAvatar, #settingsPhoto,
   #dcAvatar) and to the small preview swatches below — deliberately never
   to .lead-avatar / .lead-owner-ini (contact/lead avatars elsewhere in
   Orbit), so this is purely a personal identity customization, not
   something that leaks onto CRM data. The ring itself is a ::after behind
   the host's own opaque circle (same "glow sits behind, z-index:-1"
   technique .glow-static already uses elsewhere in this file) sized via
   inset so only a thin annulus peeks out beyond the avatar's real edge —
   no padding/wrapper change to the host's own box, no layout shift. */
.pb-ring-host{ position:relative; }
.pb-ring-host[data-pb]:not([data-pb="none"])::after{
  content:""; position:absolute; inset:-4px; border-radius:50%; z-index:-1; pointer-events:none;
}
/* QC P4 — light-theme contrast backstop. Every preset's ring is a bloom
   (box-shadow glow) around a colored conic gradient — both rely on a dark
   background for contrast. #profileMenuAvatar sits on .profile-menu's
   near-white, backdrop-blurred light-theme background (rgba(255,255,255,.98)
   + blur(20px)); pale/white-dominant presets (Diamond's white/icy facets
   especially, 24K's champagne highlight) had almost no color contrast left
   against it and read as "the border disappeared in light mode" even though
   data-pb/the ring were rendering correctly the whole time. `outline` is an
   additive property (doesn't replace the per-preset box-shadow/gradient), so
   this gives every preset — on all four hosts, not just the profile menu —
   a visible hairline silhouette in light mode without touching a single
   existing color or animation. */
[data-theme="light"] .pb-ring-host[data-pb]:not([data-pb="none"])::after{
  outline:1.5px solid rgba(28,27,64,0.18);
  outline-offset:-1px;
}
/* #23 (Stage 3B) — REGRESSION FIX: #settingsPhoto (the live preview avatar in
   Settings) carries `overflow:hidden` to clip an uploaded photo, which also
   clipped away the ring ::after (it lives entirely in the -4/-5px overhang) —
   so selecting a border changed nothing visible there. The background photo
   still clips to border-radius:50% without overflow:hidden, and the only child
   is a centered initials span, so it's safe to let the ring show. The hairline
   box-shadow is dropped while a border is active so the two don't fight. */
#settingsPhoto[data-pb]:not([data-pb="none"]){ overflow:visible; box-shadow:none; }
/* QC#7 — same clip fix for the Digital Card identity avatar: overflow:hidden
   (for photo cropping) + the 2/3px hairline border were both hiding the
   selected profile-border ring. #dcAvatarInitials clips the photo to the
   circle on its own, so overflow can be visible and the border dropped while
   a ring is active. */
#dcAvatar[data-pb]:not([data-pb="none"]){ overflow:visible; border-color:transparent; }
/* #4/#5/#24 (Stage 3B) — final preset set: none / pulse / orbit / glow / energy.
   Pulse keeps its established violet brand identity. Orbit (steel azure),
   Glow (premium neon green — clean luminous edge, controlled bloom, NOT toxic
   slime / gamer-RGB) and Energy (molten red→amber plasma) each got a distinct
   premium palette and noticeably more pronounced motion. Reduced-motion drops
   each to a tasteful static state below. */
.pb-ring-host[data-pb="glow"]::after{
  inset:-5px;
  background:conic-gradient(from 210deg, #0F9E52, #34F58A, #7CFFB4, #2BE86B, #0F9E52);
  box-shadow:0 0 24px -2px rgba(52,245,138,0.7),
             0 0 12px 0 rgba(124,255,180,0.55);
  animation:pbGlowBreathe 3.2s ease-in-out infinite;
}
.pb-ring-host[data-pb="orbit"]::after{
  inset:-5px;
  background:conic-gradient(from 0deg, #0B1E3F 0deg, #1E60D6 120deg, #4FC3FF 200deg, #1E60D6 280deg, #0B1E3F 360deg);
  box-shadow:0 0 20px -3px rgba(46,131,247,0.7);
  animation:pbOrbitSpin 3.4s linear infinite;
}
/* QC P6 — PULSE redesign (ONLY this preset changed). Dominant premium PURPLE
   with an electric/deep-blue undertone, a steady luminous ring, and ONE visible
   pulse wave that expands and settles every ~2.6s — calm, not frantic, no spin,
   no giant bloom, never pink. ::after = the ring + a gentle brightness breathe;
   ::before = the single expanding ripple. */
.pb-ring-host[data-pb="pulse"]::after{
  inset:-5px;
  background:conic-gradient(from 215deg,
    #7C3AED 0deg, #9D5CF5 66deg, #5B21B6 140deg, #4F46E5 208deg, #8B5CF6 286deg, #7C3AED 360deg);
  box-shadow:0 0 16px -3px rgba(124,58,237,0.78), 0 0 7px 0 rgba(79,70,229,0.5);
  animation:pbPulseBreathe 2.6s ease-in-out infinite;
}
.pb-ring-host[data-pb="pulse"]::before{
  content:""; position:absolute; inset:-5px; border-radius:50%; z-index:-1; pointer-events:none;
  border:2px solid rgba(139,92,246,0.65);
  box-shadow:0 0 12px 1px rgba(124,58,237,0.5);
  animation:pbPulseWave 2.6s cubic-bezier(.22,.7,.3,1) infinite;
}
.pb-ring-host[data-pb="energy"]::after{
  inset:-5px;
  background:linear-gradient(115deg, #FF3B2F, #FF9F1C, #FF3B2F, #C81E1E);
  background-size:280% 280%;
  box-shadow:0 0 22px -3px rgba(255,95,45,0.7);
  animation:pbEnergyFlow 2.6s linear infinite;
}
/* QC#8 — FIRE: two counter-rotating conic layers (a solid hot band + a
   translucent "licking flames" layer with transparent gaps) plus an
   irregular brightness/glow flicker — reads as flame moving around the edge,
   not a plain spinning gradient. Deep-orange/red outer, amber/yellow-hot
   highlights. The flicker only touches filter/opacity/box-shadow so it never
   fights the rotation transform. */
.pb-ring-host[data-pb="fire"]::after{
  inset:-6px;
  background:conic-gradient(from 0deg,
    #7A1500 0deg, #FF4500 42deg, #FF8C00 92deg, #FFC61A 132deg, #FFE9A6 158deg,
    #FF9E1F 200deg, #FF4A0A 262deg, #B31A00 318deg, #7A1500 360deg);
  box-shadow:0 0 28px -3px rgba(255,110,20,0.8), 0 0 13px 0 rgba(255,196,70,0.55);
  animation:pbFireSpin 6.5s linear infinite, pbFireFlicker 0.9s ease-in-out infinite;
}
.pb-ring-host[data-pb="fire"]::before{
  content:""; position:absolute; inset:-6px; border-radius:50%; z-index:-1; pointer-events:none;
  background:conic-gradient(from 140deg,
    transparent 0deg, rgba(255,214,110,0.92) 26deg, rgba(255,132,20,0.55) 66deg, transparent 104deg,
    rgba(255,90,12,0.75) 168deg, transparent 206deg, rgba(255,224,150,0.9) 258deg, rgba(255,120,20,0.5) 300deg, transparent 344deg);
  animation:pbFireSpinRev 4s linear infinite, pbFireFlicker 0.7s ease-in-out infinite reverse;
}
/* QC#8 — 24K: polished-gold conic (deep gold → bright metallic → champagne
   highlight → deep gold) with a separate bright specular band that travels
   around the ring at a different rate, so a highlight visibly sweeps the
   metal. Warm gold bloom. Rich and jewelry-like, never orange/brown/flat. */
.pb-ring-host[data-pb="gold24k"]::after{
  inset:-5px;
  background:conic-gradient(from 0deg,
    #8A671C 0deg, #D9AE3E 48deg, #F6DE86 90deg, #FFF6D2 116deg, #EBC85C 150deg,
    #B98A28 210deg, #E4BE4C 258deg, #FFF1C4 300deg, #A67A20 342deg, #8A671C 360deg);
  box-shadow:0 0 20px -3px rgba(232,192,92,0.72), 0 0 9px 0 rgba(255,244,200,0.5);
  animation:pb24kRotate 9s linear infinite, pb24kSheen 3s ease-in-out infinite;
}
.pb-ring-host[data-pb="gold24k"]::before{
  content:""; position:absolute; inset:-5px; border-radius:50%; z-index:-1; pointer-events:none;
  background:conic-gradient(from 0deg,
    transparent 0deg, rgba(255,253,240,0.95) 18deg, rgba(255,241,196,0.35) 34deg, transparent 62deg, transparent 360deg);
  animation:pb24kSweep 4.6s linear infinite;
}
/* QC P6 — DIAMOND: a faceted crystal ring (many alternating white / icy-blue /
   silver stops = cut facets) that rotates slowly, a bright specular highlight
   that travels around it faster (light crossing the cuts), and a fine spectral
   flash on the filter (refraction). Icy-white bloom, no glitter. */
.pb-ring-host[data-pb="diamond"]::after{
  inset:-5px;
  background:conic-gradient(from 0deg,
    #FFFFFF 0deg, #C7D6EA 14deg, #FFFFFF 26deg, #E6EFFF 40deg, #B9C8DC 54deg,
    #FFFFFF 70deg, #D8E6FF 86deg, #FFFFFF 100deg, #C0D0E6 116deg, #F2F6FF 132deg,
    #FFFFFF 150deg, #CBD8EC 168deg, #EEF4FF 186deg, #B7C6DA 202deg, #FFFFFF 220deg,
    #D6E2F5 238deg, #FFFFFF 256deg, #C4D3E8 274deg, #F0F5FF 292deg, #FFFFFF 312deg,
    #BDCCE0 330deg, #E9F1FF 348deg, #FFFFFF 360deg);
  box-shadow:0 0 22px -2px rgba(214,230,255,0.85), 0 0 11px 0 rgba(255,255,255,0.6);
  animation:pbDiamondRotate 11s linear infinite, pbDiamondFlash 2.4s ease-in-out infinite;
}
.pb-ring-host[data-pb="diamond"]::before{
  content:""; position:absolute; inset:-5px; border-radius:50%; z-index:-1; pointer-events:none;
  background:conic-gradient(from 0deg,
    transparent 0deg, rgba(255,255,255,0.98) 12deg, rgba(210,200,255,0.4) 22deg,
    rgba(200,240,255,0.4) 30deg, transparent 46deg, transparent 200deg,
    rgba(255,255,255,0.7) 210deg, transparent 226deg, transparent 360deg);
  animation:pbDiamondSweep 3.2s linear infinite;
}
@keyframes pbDiamondRotate{ to{ transform:rotate(360deg); } }
@keyframes pbDiamondSweep{ to{ transform:rotate(360deg); } }
@keyframes pbDiamondFlash{
  0%, 100%{ filter:brightness(1) saturate(1) hue-rotate(0deg); }
  30%     { filter:brightness(1.16) saturate(1.1) hue-rotate(-6deg); }
  55%     { filter:brightness(0.97) saturate(1) hue-rotate(4deg); }
  80%     { filter:brightness(1.2) saturate(1.15) hue-rotate(8deg); }
}
@keyframes pbFireSpin{ to{ transform:rotate(360deg); } }
@keyframes pbFireSpinRev{ to{ transform:rotate(-360deg); } }
@keyframes pb24kRotate{ to{ transform:rotate(360deg); } }
@keyframes pb24kSweep{ to{ transform:rotate(360deg); } }
@keyframes pb24kSheen{
  0%, 100%{ filter:brightness(1) saturate(1.05); }
  50%     { filter:brightness(1.12) saturate(1.18); }
}
@keyframes pbFireFlicker{
  0%, 100%{ opacity:0.9;  filter:brightness(1) saturate(1.1); }
  20%     { opacity:1;    filter:brightness(1.18) saturate(1.3); }
  45%     { opacity:0.82; filter:brightness(0.94) saturate(1.05); }
  70%     { opacity:1;    filter:brightness(1.22) saturate(1.35); }
  85%     { opacity:0.88; filter:brightness(1.02) saturate(1.15); }
}
@keyframes pbOrbitSpin{ to{ transform:rotate(360deg); } }
@keyframes pbPulseBreathe{
  0%, 100%{ box-shadow:0 0 12px -3px rgba(124,58,237,0.62), 0 0 6px 0 rgba(79,70,229,0.4); filter:brightness(0.97); }
  45%     { box-shadow:0 0 24px -1px rgba(139,92,246,0.92), 0 0 12px 1px rgba(99,102,241,0.62); filter:brightness(1.13); }
}
@keyframes pbPulseWave{
  0%   { transform:scale(1);     opacity:0.7; }
  55%  { opacity:0; }
  70%, 100%{ transform:scale(1.24); opacity:0; }
}
@keyframes pbEnergyFlow{ 0%{ background-position:0% 50%; } 100%{ background-position:280% 50%; } }
@keyframes pbGlowBreathe{
  0%, 100%{ box-shadow:0 0 15px -3px rgba(52,245,138,0.55), 0 0 8px 0 rgba(124,255,180,0.4); opacity:0.82; }
  50%{ box-shadow:0 0 30px 0 rgba(52,245,138,0.85), 0 0 15px 2px rgba(124,255,180,0.6); opacity:1; }
}
/* #15 — animated presets fall back to an attractive STATIC state, not a
   frozen mid-frame, under reduced motion (the site-wide *{animation-duration:
   0.01ms} rule alone would just stop them at whatever frame that lands on). */
@media (prefers-reduced-motion:reduce){
  .pb-ring-host[data-pb="orbit"]::after{ animation:none; background:conic-gradient(from 45deg, #0B1E3F, #1E60D6, #4FC3FF, #1E60D6, #0B1E3F); }
  /* QC P6 — static premium purple/blue ring */
  .pb-ring-host[data-pb="pulse"]::after{
    animation:none; filter:none; opacity:1;
    box-shadow:0 0 16px -2px rgba(124,58,237,0.72), 0 0 8px 0 rgba(79,70,229,0.5);
  }
  .pb-ring-host[data-pb="pulse"]::before{ animation:none; opacity:0; }
  .pb-ring-host[data-pb="glow"]::after{ animation:none; opacity:1; box-shadow:0 0 22px -1px rgba(52,245,138,0.8), 0 0 11px 0 rgba(124,255,180,0.6); }
  .pb-ring-host[data-pb="energy"]::after{ animation:none; background-position:50% 50%; }
  /* QC#8 — static hot ember/flame ring */
  .pb-ring-host[data-pb="fire"]::after{
    animation:none; opacity:1; filter:none;
    background:conic-gradient(from 18deg, #7A1500, #FF4500, #FF9E1F, #FFD966, #FF9E1F, #FF4500, #7A1500);
    box-shadow:0 0 22px -2px rgba(255,110,20,0.7), 0 0 11px 0 rgba(255,196,70,0.5);
  }
  .pb-ring-host[data-pb="fire"]::before{ animation:none; opacity:0.55; }
  /* QC#8 — static polished-gold ring */
  .pb-ring-host[data-pb="gold24k"]::after{
    animation:none; filter:none;
    background:conic-gradient(from 20deg, #8A671C, #D9AE3E, #FFF6D2, #EBC85C, #B98A28, #E4BE4C, #FFF1C4, #8A671C);
    box-shadow:0 0 20px -3px rgba(232,192,92,0.72), 0 0 9px 0 rgba(255,244,200,0.5);
  }
  .pb-ring-host[data-pb="gold24k"]::before{ animation:none; opacity:0.6; }
  /* QC P6 — static faceted diamond ring */
  .pb-ring-host[data-pb="diamond"]::after{
    animation:none; filter:none;
    background:conic-gradient(from 12deg,
      #FFFFFF, #C7D6EA, #FFFFFF, #E6EFFF, #B9C8DC, #FFFFFF, #D8E6FF, #FFFFFF,
      #C0D0E6, #F2F6FF, #FFFFFF, #CBD8EC, #EEF4FF, #B7C6DA, #FFFFFF, #D6E2F5, #FFFFFF);
    box-shadow:0 0 20px -2px rgba(214,230,255,0.8), 0 0 10px 0 rgba(255,255,255,0.55);
  }
  .pb-ring-host[data-pb="diamond"]::before{ animation:none; opacity:0.55; }
}
/* QC P7 — the profile border is deliberately NOT rendered on the tiny in-Orbit
   "me" owner/author chips: at 15–18px there is no clean version (a 2px ring
   behind the chip reads as an offset/clipped artifact; animation spills past
   the circle). ownerAvatarHtml() no longer emits pb-ring-host/data-pb on them.
   The border still shows on every large avatar. Guard rule below, in case a
   stray data-pb ever lands on a .lead-owner-ini. */
.lead-owner-ini[data-pb]::after,
.lead-owner-ini[data-pb]::before{ display:none !important; }

/* selector UI — #3 (Stage 3B): sits directly under the photo row, inside the
   same Profile card block, reading as one continuous profile-picture area
   (shared left inset, hairline tie to the controls above) rather than a
   detached Settings section. */
.profile-border-picker{ margin-top:14px; padding-top:14px; border-top:1px solid var(--line); }
.profile-border-label{ font-size:12px; font-weight:600; color:var(--text-secondary); margin-bottom:10px; display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; }
.profile-border-hint{ font-size:11px; font-weight:500; color:var(--text-tertiary); }
.profile-border-opts{ display:flex; flex-wrap:wrap; gap:4px; }
.pb-swatch{
  display:flex; flex-direction:column; align-items:center; gap:6px; width:46px; padding:7px 2px 8px;
  background:none; border:1px solid transparent; border-radius:12px; cursor:pointer; font:inherit;
  transition:background .14s ease, border-color .14s ease;
}
.pb-swatch:hover{ background:var(--surface-hover); }
.pb-swatch:focus-visible{ outline:2px solid var(--violet); outline-offset:1px; }
.pb-swatch.is-active{ border-color:color-mix(in srgb, var(--violet) 45%, transparent); background:color-mix(in srgb, var(--violet) 8%, transparent); }
.pb-swatch-ring{ width:26px; height:26px; border-radius:50%; background:var(--surface-2); border:1px solid var(--line-strong); }
.pb-swatch-ring[data-pb="none"]{ display:flex; align-items:center; justify-content:center; }
.pb-swatch-name{ font-size:10px; font-weight:600; color:var(--text-tertiary); white-space:nowrap; }
.pb-swatch.is-active .pb-swatch-name{ color:var(--violet); }
@media (max-width:420px){ .pb-swatch{ width:47px; } }
@media (max-width:520px){
  .settings-photo-btns{ width:100%; }
  .settings-photo-btn{ flex:1 1 auto; justify-content:center; }
}

/* =====================================================================
   SMART ACCESSORIES — FLAGSHIP REDESIGN
   ---------------------------------------------------------------------
   A single authoritative ruleset (replaces four historical, increasingly
   patched layers — stat strip, idcol/statcol strip rows, compact-row
   grid, 2-up grid — that had accumulated in this file; all dead CSS from
   the earlier layouts has been removed, not just superseded).

   Composition, top to bottom:
     LEVEL 1  .sa-hero-row   — Tap Intelligence hero chart (major module)
                                beside Traffic Share + Device Health
     .sa-insight-strip        — deterministic derived-observation strip
     LEVEL 2  .sa-grid        — 2-up device management cards
     LEVEL 3  .sa-recent      — Recent Taps event stream

   Design DNA borrowed deliberately from Overview rather than invented:
   the .kpi-card top accent edge + icon-well glow, the .rank-row /
   feed-item grammar (reused directly, not approximated), and the same
   Catmull-Rom glow-line chart recipe as the KPI sparklines (see
   saGlowChart() in app.js) — scaled up for the hero, kept small for the
   Traffic Share bars. Five device identity colors (cyan / violet / azure
   / magenta / periwinkle) stay inside the brand's existing cool family —
   no green or gold, which the product already reserves for status.
   ===================================================================== */
/* item 12/density-audit — tighter module-to-module rhythm, matching
   Overview's OWN real inter-section rhythm (.iq-hero/.journey-row/.ops-grid
   all use margin-bottom:12px — this reuses that exact value rather than
   inventing a new one) instead of the previous pass's 14px guess. Card/row
   internals are untouched; this only changes the space BETWEEN modules and
   between a heading and its own content (via the section-head's own
   negative margin-bottom below). */
.sa-manager{ display:flex; flex-direction:column; gap:12px; }
/* #saMetrics reuses the shared .kpi-grid class, whose own margin-bottom:16px
   exists for Overview's plain block-flow layout (#viewOverview has no gap —
   .kpi-grid's margin IS the spacing there). Inside .sa-manager's flex gap,
   that margin stacks ON TOP of the 12px gap instead of replacing it,
   producing a 28px gap where every other transition gets 12px. Zeroed here,
   scoped to this page only — #kpiGrid on Overview is untouched. */
#saMetrics.kpi-grid{ margin-bottom:0; }

/* ---- LEVEL 1 — hero analytics zone ---- */
.sa-hero-row{ display:flex; gap:14px; align-items:stretch; }
.sa-hero-card{
  flex:1.6 1 0; min-width:0; padding:22px 24px 20px; position:relative; overflow:hidden;
  display:flex; flex-direction:column;
}
/* Right-hand column (§4/§15, Revision 3) — insight badges THEN Accessory
   Traffic Share, stacked, reading as intelligence leading into the
   visualization below it. */
.sa-hero-side{ flex:1 1 0; min-width:0; display:flex; flex-direction:column; gap:14px; }
.sa-hero-card::before{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(ellipse 120% 70% at 0% 0%, color-mix(in srgb, var(--cyan) 10%, transparent), transparent 62%);
}
.sa-hero-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; margin-bottom:18px; position:relative; z-index:1; }
.sa-hero-eyebrow{ font-size:var(--fs-section-title); font-weight:700; }
.sa-hero-sub{ font-size:13px; color:var(--text-secondary); margin-top:3px; }
.sa-live-chip{
  display:flex; align-items:center; gap:6px; flex:0 0 auto; font-size:11px; font-weight:800;
  letter-spacing:0.04em; text-transform:uppercase; color:var(--good); background:var(--good-dim);
  border:1px solid color-mix(in srgb, var(--good) 32%, transparent); border-radius:99px; padding:6px 12px 5px;
}
.sa-live-dot{
  width:7px; height:7px; border-radius:50%; background:var(--good);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--good) 25%, transparent);
  animation:saLiveDotPulse 2.2s ease-in-out infinite;
}
@keyframes saLiveDotPulse{ 0%,100%{ opacity:1; } 50%{ opacity:0.4; } }
.sa-hero-head-r{ display:flex; align-items:center; gap:10px; flex:0 0 auto; flex-wrap:wrap; position:relative; z-index:1; }
/* Timeframe control (§3, Revision 3) — the existing #datePresets pill-group
   language (segmented control, tabular mono labels), sized down to fit
   inside the hero card instead of the topbar. */
.sa-tf-select{ display:flex; gap:2px; padding:3px; border-radius:10px; background:var(--surface-2); border:1px solid var(--line); }
.sa-tf-btn{
  font-family:'JetBrains Mono', ui-monospace, monospace; font-size:10.5px; font-weight:700; letter-spacing:0.02em;
  padding:5px 10px; border-radius:7px; border:none; background:transparent; color:var(--text-tertiary); cursor:pointer;
  transition:background .14s ease, color .14s ease;
}
.sa-tf-btn:hover{ color:var(--text-primary); }
.sa-tf-btn.is-active{ background:var(--surface-1); color:var(--text-primary); box-shadow:0 1px 3px rgba(0,0,0,0.3); }

.sa-hero-stats{ display:flex; gap:30px; flex-wrap:wrap; margin-bottom:14px; position:relative; z-index:1; }
.sa-hero-stat-v{ font-size:28px; font-weight:800; letter-spacing:-0.02em; line-height:1; }
.sa-hero-stat-of{ font-size:16px; font-weight:700; color:var(--text-tertiary); }
.sa-hero-stat-l{ font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:0.04em; color:var(--text-tertiary); margin-top:5px; }
.sa-hero-stat .kpi-change{ margin-top:5px; font-size:12px; }
.sa-hero-chart{ flex:1 1 auto; min-height:150px; position:relative; z-index:1; }
.sa-hero-svg{ width:100%; height:100%; display:block; }
/* Upgraded chart dressing (§2, Revision 3) — restrained reference grid, a
   violet→cyan→mint line gradient instead of one flat hue, and a soft
   pulsing marker on the most recent point (the chart's own "this is live"
   cue, distinct from the header's Live chip). */
.sa-hero-grid-line{ stroke:var(--line); stroke-width:1; }
.sa-hero-line{ filter:drop-shadow(0 0 6px rgba(47,208,255,0.55)); }
.sa-hero-marker{
  fill:#fff; stroke:#2FD0FF; stroke-width:2;
  filter:drop-shadow(0 0 6px rgba(47,208,255,0.8));
  transform-box:fill-box; transform-origin:center;
  animation:saHeroMarkerPulse 2.2s ease-in-out infinite;
}
@keyframes saHeroMarkerPulse{ 0%,100%{ transform:scale(1); opacity:1; } 50%{ transform:scale(1.35); opacity:0.7; } }
@media (prefers-reduced-motion:reduce){ .sa-hero-marker{ animation:none; } }
.sa-hero-axis{ display:flex; justify-content:space-between; font-size:10.5px; color:var(--text-tertiary); margin-top:7px; position:relative; z-index:1; }
.sa-hero-axis span{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.sa-hero-empty{
  height:100%; min-height:160px; display:flex; flex-direction:column; align-items:center;
  justify-content:center; text-align:center; gap:7px; color:var(--text-tertiary);
}
.sa-hero-empty svg{ width:26px; height:26px; stroke:var(--text-tertiary); fill:none; stroke-width:1.7; opacity:0.55; }
.sa-hero-empty-t{ font-size:14px; font-weight:700; color:var(--text-secondary); }
.sa-hero-empty-d{ font-size:12.5px; max-width:270px; line-height:1.5; }

/* #saShare is a direct copy of #trafficPanel's shell (.panel.glass +
   .panel-head) — its density/flex treatment comes from extending the
   SAME shared ID rules #trafficPanel/#livePanel already use, a few
   sections up (search "#saShare" in this file), rather than a second
   ruleset. #saShareList reuses the real, shared rankRow() rows verbatim —
   no .sa-rank-list wrapper needed. Device Health (a conic gauge + legend)
   was removed in the Revision 2 pass: its one non-redundant fact ("N
   active devices") already lives in the hero's own stat row above.

   ---- deterministic intelligence strip ---- */
.sa-insight-strip{ display:flex; gap:10px; flex-wrap:wrap; }
/* Same richer tinted-material language as .sa-micro below — a controlled
   gradient wash + tinted border + soft inner highlight instead of a flat
   surface, kept compact (no taller than the previous plain version). */
.sa-insight{
  flex:1 1 210px; display:flex; align-items:center; gap:10px; min-width:0;
  padding:10px 13px; border-radius:12px;
  background:linear-gradient(180deg, color-mix(in srgb, var(--sa-micro-c, var(--cyan)) 9%, transparent), transparent 72%), var(--surface-1);
  border:1px solid color-mix(in srgb, var(--sa-micro-c, var(--cyan)) 26%, var(--line));
  box-shadow:inset 0 1px 0 color-mix(in srgb, var(--sa-micro-c, var(--cyan)) 10%, transparent);
  font-size:12.5px; color:var(--text-secondary); line-height:1.4;
}
.sa-insight.is-cyan{ --sa-micro-c:#2FD0FF; }
.sa-insight.is-green{ --sa-micro-c:#22C55E; }
.sa-insight.is-violet{ --sa-micro-c:#8B6CF7; }
.sa-insight.is-amber{ --sa-micro-c:#FF8A3D; }
.sa-insight b{ color:var(--text-primary); }
.sa-insight-ic{
  flex:0 0 auto; width:26px; height:26px; border-radius:8px; display:flex; align-items:center; justify-content:center;
  background:color-mix(in srgb, var(--sa-micro-c, var(--cyan)) 16%, transparent);
  border:1px solid color-mix(in srgb, var(--sa-micro-c, var(--cyan)) 30%, transparent);
}
.sa-insight-ic svg{ width:13px; height:13px; stroke:var(--sa-micro-c, var(--cyan)); fill:none; stroke-width:2; }

/* #8 — micro-insight badges between My Accessories and Accessory Performance */
.sa-microinsights{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); gap:10px;
  margin:14px 0 6px;
}
.sa-micro{
  display:flex; align-items:center; gap:10px; min-width:0;
  padding:10px 13px; border-radius:12px;
  background:linear-gradient(180deg, color-mix(in srgb, var(--sa-micro-c, var(--cyan)) 8%, transparent), transparent 70%), var(--surface-1);
  border:1px solid color-mix(in srgb, var(--sa-micro-c, var(--cyan)) 24%, var(--line));
}
.sa-micro.is-cyan{ --sa-micro-c:#2FD0FF; }
.sa-micro.is-green{ --sa-micro-c:#22C55E; }
.sa-micro.is-violet{ --sa-micro-c:#8B6CF7; }
.sa-micro.is-amber{ --sa-micro-c:#FF8A3D; }
.sa-micro-ic{
  flex:0 0 auto; width:30px; height:30px; border-radius:9px; display:flex; align-items:center; justify-content:center;
  background:color-mix(in srgb, var(--sa-micro-c, var(--cyan)) 16%, transparent);
  border:1px solid color-mix(in srgb, var(--sa-micro-c, var(--cyan)) 30%, transparent);
}
.sa-micro-ic svg{ width:14px; height:14px; stroke:var(--sa-micro-c, var(--cyan)); fill:none; stroke-width:2; }
.sa-micro-t{ display:flex; flex-direction:column; min-width:0; line-height:1.25; }
.sa-micro-k{ font-size:14px; font-weight:800; color:var(--text-primary); letter-spacing:-0.01em; white-space:nowrap; }
.sa-micro-d{ font-size:11px; color:var(--text-tertiary); overflow:hidden; text-overflow:ellipsis; }
.sa-micro-d b{ color:var(--text-secondary); font-weight:700; }
#saNote.is-demo{ color:var(--warn); font-weight:600; }
/* #10 (Stage 3B) — self-explaining micro-insight badges. The badge is a
   [data-tip] anchor; the row and grid allow overflow so the bubble is never
   clipped by Accessory Performance below it. Unlike the icon-action tips,
   these hold a full sentence, so they wrap to a readable column. */
.sa-microinsights{ overflow:visible; }
.sa-micro[data-tip]{ cursor:help; }
.sa-micro[data-tip]:focus-visible{ outline:2px solid color-mix(in srgb, var(--sa-micro-c, var(--cyan)) 70%, transparent); outline-offset:2px; }
.sa-micro[data-tip]::after{
  white-space:normal; width:max-content; max-width:260px; text-align:left; font-weight:600; line-height:1.4;
}
.sa-micro[data-tip]:focus-visible::after,
.sa-micro[data-tip]:focus-visible::before{ opacity:1; transition-delay:0s; }
.sa-micro[data-tip]:focus-visible::after{ transform:translateX(-50%) translateY(0); }
@media (max-width:640px){ .sa-microinsights{ grid-template-columns:1fr 1fr; } }
@media (max-width:420px){ .sa-microinsights{ grid-template-columns:1fr; } }

/* ---- section heading above the device grid ---- */
/* item 12 — pulls the heading down close to its OWN content while leaving
   the (now-tighter) .sa-manager gap above it to separate it from the
   previous module — headings read as attached to what they head. */
.sa-section-head{ margin-top:2px; margin-bottom:-6px; }

/* ---- LEVEL 2 — My Accessories — horizontally browsable card rail ---- */
/* item 7, Refinement Pass Part 2 — My Accessories is a horizontal scroller:
   a Mac trackpad two-finger swipe and a touch drag both move through the
   cards naturally. Cards keep their existing size/design; the scrollbar is
   slimmed (and hidden where the platform allows). The rail ends with a
   dashed "Add Accessory" tile (the activation flow itself is a later MVP
   item — the tile is a stub for now). No page-level horizontal overflow:
   the flex row clips to the panel and scrolls inside itself. */
.sa-grid{
  display:flex; gap:12px; align-items:stretch;
  overflow-x:auto; overflow-y:hidden;
  scroll-snap-type:x proximity; -webkit-overflow-scrolling:touch;
  overscroll-behavior-x:contain;
  padding-bottom:6px; margin-bottom:-6px;
  scrollbar-width:thin; scrollbar-color:var(--line-strong) transparent;
}
.sa-grid::-webkit-scrollbar{ height:6px; }
.sa-grid::-webkit-scrollbar-thumb{ background:var(--line-strong); border-radius:99px; }
.sa-grid::-webkit-scrollbar-track{ background:transparent; }
.sa-grid > .sa-device{ flex:0 0 clamp(228px, 23vw, 264px); scroll-snap-align:start; }
.sa-device-add{
  flex:0 0 clamp(196px, 18vw, 224px); scroll-snap-align:start;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:9px;
  padding:14px 16px; border-radius:var(--radius-md); text-align:center; cursor:pointer; font:inherit;
  color:var(--text-secondary);
  border:1.5px dashed color-mix(in srgb, var(--cyan) 42%, var(--line-strong));
  background:radial-gradient(ellipse 130% 80% at 50% 0%, color-mix(in srgb, var(--cyan) 9%, transparent), transparent 66%), var(--surface-1);
  transition:border-color .14s ease, color .14s ease, box-shadow .14s ease;
}
.sa-device-add:hover{
  border-color:color-mix(in srgb, var(--cyan) 72%, transparent); color:var(--text-primary);
  box-shadow:0 0 26px -12px color-mix(in srgb, var(--cyan) 75%, transparent);
}
.sa-device-add.is-armed{ border-color:color-mix(in srgb, var(--cyan) 72%, transparent); color:var(--text-primary); }
.sa-device-add-ic{
  width:40px; height:40px; border-radius:13px; display:flex; align-items:center; justify-content:center;
  background:linear-gradient(150deg, color-mix(in srgb, var(--cyan) 26%, transparent), color-mix(in srgb, var(--cyan) 8%, transparent));
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--cyan) 34%, transparent);
}
.sa-device-add-ic svg{ width:20px; height:20px; stroke:var(--cyan); fill:none; stroke-width:2.4; }
.sa-device-add-t{ font-size:13px; font-weight:800; letter-spacing:0.01em; }
.sa-device-add-d{ font-size:11px; color:var(--text-tertiary); line-height:1.4; }
/* #11 — Activate Accessory tile (violet accent, sits right of Add) */
.sa-device-activate{ border-color:color-mix(in srgb, var(--violet) 44%, var(--line-strong));
  background:radial-gradient(ellipse 130% 80% at 50% 0%, color-mix(in srgb, var(--violet) 10%, transparent), transparent 66%), var(--surface-1); }
.sa-device-activate:hover{ border-color:color-mix(in srgb, var(--violet) 72%, transparent);
  box-shadow:0 0 26px -12px color-mix(in srgb, var(--violet) 75%, transparent); }
.sa-device-activate .sa-device-add-ic{
  background:linear-gradient(150deg, color-mix(in srgb, var(--violet) 26%, transparent), color-mix(in srgb, var(--violet) 8%, transparent));
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--violet) 34%, transparent); }
.sa-device-activate .sa-device-add-ic svg{ stroke:var(--violet); }
/* #11 — activation wizard modal */
.sa-act-steps{ display:flex; align-items:center; flex-wrap:wrap; gap:4px; margin-bottom:14px; font-size:10.5px; font-weight:700; color:var(--text-tertiary); }
.sa-act-step.is-cur{ color:var(--violet); }
.sa-act-step.is-done{ color:var(--text-secondary); }
.sa-act-step-sep{ opacity:0.4; font-style:normal; }
.sa-act-scan{ display:flex; align-items:center; gap:8px; width:100%; margin-top:10px; padding:10px 12px; border:1px dashed var(--line-strong); border-radius:9px; background:var(--surface-1); font:inherit; font-size:12px; font-weight:700; color:var(--text-tertiary); cursor:not-allowed; }
.sa-act-scan svg{ width:16px; height:16px; stroke:currentColor; fill:none; stroke-width:2; }
.sa-act-scan span{ font-weight:500; }
.sa-act-identified{ display:flex; align-items:center; gap:12px; padding:13px; border:1px solid color-mix(in srgb, var(--violet) 30%, var(--line)); border-radius:10px; background:color-mix(in srgb, var(--violet) 7%, var(--surface-1)); }
.sa-act-identified-ic{ width:36px; height:36px; flex:0 0 auto; border-radius:10px; display:flex; align-items:center; justify-content:center; background:color-mix(in srgb, var(--violet) 18%, transparent); }
.sa-act-identified-ic svg{ width:18px; height:18px; stroke:var(--violet); fill:none; stroke-width:2.2; }
.sa-act-identified b{ display:block; font-size:13px; color:var(--text-primary); }
.sa-act-identified span{ display:block; font-size:11px; color:var(--text-tertiary); margin-top:1px; }
.sa-act-hint, .sa-act-cardline{ font-size:11.5px; color:var(--text-tertiary); line-height:1.5; margin-top:10px; }
.sa-act-cardline{ margin-top:4px; color:var(--text-secondary); font-weight:600; }
.sa-act-list{ display:flex; flex-direction:column; gap:7px; max-height:280px; overflow-y:auto; }
.sa-act-opt{ display:flex; align-items:center; gap:10px; width:100%; text-align:left; font:inherit; padding:9px 10px; border:1px solid var(--line); border-radius:10px; background:var(--surface-1); cursor:pointer; transition:border-color .12s ease, background .12s ease; }
.sa-act-opt:hover{ border-color:color-mix(in srgb, var(--violet) 40%, var(--line)); }
.sa-act-opt.is-sel{ border-color:var(--violet); background:color-mix(in srgb, var(--violet) 8%, var(--surface-1)); }
.sa-act-opt-ini{ width:26px; height:26px; flex:0 0 auto; border-radius:8px; display:flex; align-items:center; justify-content:center; font-size:10px; font-weight:800; color:#0A0A16; background:var(--ch-accent, var(--violet)); }
[data-theme="light"] .sa-act-opt-ini{ color:#fff; }
.sa-act-opt-main{ min-width:0; }
.sa-act-opt-main b{ display:block; font-size:12.5px; color:var(--text-primary); }
.sa-act-opt-main span{ display:block; font-size:10.5px; color:var(--text-tertiary); margin-top:1px; }
.sa-act-summary{ display:grid; grid-template-columns:1fr 1fr; gap:8px 14px; margin-bottom:14px; }
.sa-act-kv{ display:flex; flex-direction:column; gap:1px; min-width:0; }
.sa-act-kv span{ font-size:9.5px; font-weight:700; letter-spacing:0.04em; text-transform:uppercase; color:var(--text-tertiary); }
.sa-act-kv b{ font-size:12px; font-weight:700; color:var(--text-primary); word-break:break-word; }
.sa-act-done{ text-align:center; padding:6px 0 14px; }
.sa-act-done-ic{ width:44px; height:44px; margin:0 auto 10px; border-radius:13px; display:flex; align-items:center; justify-content:center; background:color-mix(in srgb, var(--warn) 16%, transparent); }
.sa-act-done-ic svg{ width:22px; height:22px; stroke:var(--warn); fill:none; stroke-width:2; }
.sa-act-done-t{ font-size:14px; font-weight:800; color:var(--text-primary); }
.sa-act-done-d{ font-size:11.5px; color:var(--text-tertiary); line-height:1.5; margin-top:5px; }
/* PRE-LIVE BUILD 3 — real provisioning outcome tones (default above is the
   existing amber "not connected" look, untouched). */
.sa-act-done.is-good .sa-act-done-ic{ background:color-mix(in srgb, var(--good) 16%, transparent); }
.sa-act-done.is-good .sa-act-done-ic svg{ stroke:var(--good); }
.sa-act-done.is-bad .sa-act-done-ic{ background:color-mix(in srgb, var(--bad) 16%, transparent); }
.sa-act-done.is-bad .sa-act-done-ic svg{ stroke:var(--bad); }
.sa-device{
  position:relative; overflow:hidden; display:flex; flex-direction:column; gap:10px;
  padding:14px 16px 13px; border-radius:var(--radius-md);
  background:radial-gradient(ellipse 120% 70% at 100% 0%, color-mix(in srgb, var(--dev, var(--violet)) 10%, transparent), transparent 60%), var(--surface-1);
  border:1px solid var(--line-strong);
  transition:border-color .14s ease, box-shadow .14s ease, transform .14s cubic-bezier(.22,1,.36,1);
}
.sa-device::before{
  content:""; position:absolute; left:15px; right:15px; top:0; height:2px; border-radius:0 0 3px 3px;
  background:var(--dev, var(--violet)); opacity:0.85;
}
@media (hover:hover) and (pointer:fine){
  .sa-device:hover{
    border-color:color-mix(in srgb, var(--dev, var(--violet)) 45%, var(--line-strong)); transform:translateY(-1px);
    box-shadow:0 0 0 1px color-mix(in srgb, var(--dev, var(--violet)) 18%, transparent), 0 18px 34px -22px rgba(0,0,0,0.5);
  }
}
.sa-device-off{ opacity:0.6; }
.sa-device-off::before{ opacity:0.32; }
.sa-device > *{ position:relative; z-index:1; }

.sa-device-hd{ display:flex; align-items:center; gap:12px; }
.sa-device-ic{
  position:relative; flex:0 0 auto; width:42px; height:42px; border-radius:13px; display:flex; align-items:center; justify-content:center;
  background:linear-gradient(150deg, color-mix(in srgb, var(--dev,var(--violet)) 28%, transparent), color-mix(in srgb, var(--dev,var(--violet)) 8%, transparent));
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--dev,var(--violet)) 36%, transparent), 0 0 14px -5px color-mix(in srgb, var(--dev,var(--violet)) 55%, transparent);
}
.sa-device-ic svg{
  width:21px; height:21px; stroke:var(--dev,var(--violet)); fill:none; stroke-width:2;
  filter:drop-shadow(0 0 4px color-mix(in srgb, var(--dev,var(--violet)) 55%, transparent));
}
/* Active-device "this is live hardware" cue — one soft radiating ring per
   card, not a page-wide animation. */
.sa-pulse-ring{
  position:absolute; inset:-5px; border-radius:inherit; border:1.5px solid var(--dev, var(--violet));
  opacity:0; animation:saPulseRing 2.8s ease-out infinite;
}
@keyframes saPulseRing{
  0%{ transform:scale(0.7); opacity:0.55; }
  65%{ opacity:0; }
  100%{ transform:scale(1.4); opacity:0; }
}
.sa-device-id{ flex:1 1 auto; min-width:0; }
.sa-device-name{ font-size:14.5px; font-weight:800; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.sa-device-kind{ font-size:10.5px; color:var(--text-tertiary); text-transform:uppercase; letter-spacing:0.03em; font-weight:700; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; margin-top:2px; }
.sa-device-hd .sa-badge{ flex:0 0 auto; align-self:flex-start; }

.sa-badge{
  font-size:10.5px; font-weight:800; letter-spacing:0.03em; text-transform:uppercase;
  padding:3px 9px; border-radius:99px; color:var(--text-tertiary); background:var(--surface-2); border:1px solid var(--line);
}
.sa-badge.is-active{ color:var(--good); background:color-mix(in srgb, var(--good) 14%, transparent); border-color:color-mix(in srgb, var(--good) 32%, transparent); }

/* One dense stat line — deliberately not a "figure" block with a giant
   number. Device management cards are secondary to the analytics above;
   this is what keeps five-plus of them from turning into five-plus mini
   dashboards. */
.sa-device-stats{ display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 12px; font-size:11px; color:var(--text-tertiary); }
.sa-device-taps{ font-size:15px; font-weight:800; color:var(--text-primary); display:inline-flex; align-items:baseline; gap:4px; }
.sa-device-taps i{ font-style:normal; font-size:10px; font-weight:700; color:var(--text-tertiary); text-transform:uppercase; letter-spacing:0.03em; }


.sa-device-foot{ display:flex; align-items:center; gap:8px; padding-top:9px; border-top:1px solid var(--line); }
.sa-device-url-c{
  flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  font-family:'JetBrains Mono', ui-monospace, monospace; font-size:10.5px; color:var(--text-secondary);
  background:var(--surface-2); border:1px solid var(--line); border-radius:6px; padding:4px 8px;
}
.sa-copy-btn{
  flex:0 0 auto; width:26px; height:26px; display:flex; align-items:center; justify-content:center;
  border-radius:7px; background:var(--surface-2); border:1px solid var(--line); color:var(--text-secondary);
  cursor:pointer; transition:background .14s ease, color .14s ease, border-color .14s ease;
}
.sa-copy-btn svg{ width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.sa-copy-btn:hover{ background:var(--surface-hover); color:var(--text-primary); border-color:var(--line-strong); }
.sa-copy-btn.is-copied{ color:var(--good); border-color:color-mix(in srgb, var(--good) 45%, transparent); background:color-mix(in srgb, var(--good) 14%, transparent); }
.sa-switch{
  flex:0 0 auto; width:38px; height:21px; border-radius:99px; background:var(--surface-2); border:1px solid var(--line-strong);
  position:relative; padding:0; cursor:pointer; transition:background .18s ease, border-color .18s ease;
}
.sa-switch:disabled{ opacity:0.55; cursor:default; }
.sa-switch > span{ position:absolute; top:1px; left:1px; width:17px; height:17px; border-radius:50%; background:var(--text-tertiary); transition:transform .18s ease, background .18s ease; }
.sa-switch.is-on{ background:color-mix(in srgb, var(--good) 32%, transparent); border-color:color-mix(in srgb, var(--good) 48%, transparent); }
.sa-switch.is-on > span{ transform:translateX(17px); background:var(--good); }

/* LEVEL 3 — Recent Taps is now a direct #saRecent transplant of #livePanel
   (.live-panel-compact / .feed-list / .feed-item / .live-badge / pager —
   all reused verbatim, see the shared ID rules above). The bespoke
   .sa-recent-* row styles this page used before Revision 2 are gone. */
/* item 8, Refinement Pass Part 2 — Top Actions and Recent Taps now share a
   height (see .sa-actions-row below). #saRecent is a flex column; its feed
   list takes the slack so the pager stays pinned to the bottom edge and the
   two panels' bottoms line up. */
#saRecent{ display:flex; flex-direction:column; }
#saLiveFeedList{ flex:1 1 auto; }
#saRecent .feed-pager{ margin-top:auto; }

@media (prefers-reduced-motion:reduce){
  .sa-live-dot{ animation:none; }
  .sa-pulse-ring{ animation:none; display:none; }
}

/* item 13 (+ item 8, Refinement Pass Part 2) — Top Actions + Recent Taps
   share one row at a 1:2 width ratio (same ratio Overview's .ops-grid uses
   for a rank list beside #livePanel). align-items:stretch now equalises
   their height: aligned top edge, aligned bottom edge. Each panel is a flex
   column — Top Actions lets its rank list breathe into the extra height
   with even spacing (space-evenly, so the 4 rows stay their natural size,
   not "absurdly stretched"); Recent Taps lets its feed take the slack with
   the pager pinned to the bottom. */
.sa-actions-row{ display:flex; gap:14px; align-items:stretch; }
.sa-actions-row > #saTopActions{ flex:1 1 0; min-width:0; display:flex; flex-direction:column; }
.sa-actions-row > #saRecent{ flex:2 1 0; min-width:0; }
.sa-actions-row > #saTopActions > #saTopActionsList{
  flex:1 1 auto; display:flex; flex-direction:column; justify-content:space-evenly; gap:4px;
}
#saTopActions .feed-pager{ margin-top:auto; }

/* ---- responsive ---- */
@media (max-width:1240px){
  .sa-hero-stats{ gap:22px; }
}
@media (max-width:1024px){
  .sa-hero-row{ flex-direction:column; }
  /* align-items:flex-start (desktop) is a cross-axis (height) rule; once
     flex-direction flips to column the cross-axis becomes width, so
     flex-start alone would shrink both panels to their content width
     instead of filling the row. Reset explicitly for the stacked case. */
  .sa-actions-row{ flex-direction:column; align-items:stretch; }
  .sa-actions-row > #saTopActions, .sa-actions-row > #saRecent{ flex:none; }
  /* stacked: no shared-height pressure, so let both lists be content-sized */
  .sa-actions-row > #saTopActions > #saTopActionsList{ justify-content:flex-start; }
  #saLiveFeedList{ flex:0 1 auto; }
}
@media (max-width:640px){
  .sa-hero-stats{ gap:16px 24px; }
  .sa-hero-card{ padding:18px 16px 16px; }
  .sa-insight{ flex-basis:100%; }
}

/* ---- light mode ---- */
/* The section's own outer .panel would otherwise be a second white slab
   stacked behind the already-white cards below it — drop it so every
   card sits directly on the page's lavender ground (dark mode keeps its
   intentional dark-island panel). #saShare/#saRecent are direct copies of
   Overview's own panels and correctly inherit Overview's light-mode
   treatment for free — nothing SA-specific to add for them here. */
[data-theme="light"] #viewSmartAccessories > .mock-shell,
[data-theme="light"] #viewSmartAccessories > .mock-shell:hover{
  background:transparent; border-color:transparent; box-shadow:none;
}
[data-theme="light"] .sa-hero-card,
[data-theme="light"] .sa-device,
[data-theme="light"] .sa-insight{
  background-color:#fff; box-shadow:var(--shadow-card);
}
[data-theme="light"] .sa-hero-card::before{
  background:radial-gradient(ellipse 120% 70% at 0% 0%, color-mix(in srgb, var(--cyan) 7%, transparent), transparent 62%);
}
[data-theme="light"] .sa-device{
  background-image:radial-gradient(ellipse 120% 70% at 100% 0%, color-mix(in srgb, var(--dev, var(--violet)) 7%, transparent), transparent 60%);
}



/* ============================================================================
   QC (this pass) — CLIENT HUB (mockup, Platform Admin only) + CARD STUDIO
   (internal, mockup, Platform Admin only). Reuses existing tokens/components
   (.panel.glass, .crm-integ-badge, .sa-tf-select, .lead-input/.lead-select,
   .lead-cbx2, .sa-switch, .lead-sheet, .lead-backend-note) rather than a
   parallel design system — see renderClientHub()/renderCardStudioAdmin() in
   app.js for the "why" behind each surface. Both are fixture-data mockups;
   no real backend is touched by anything styled here.
   ============================================================================ */

/* ---- Client Hub — stat row -------------------------------------------- */
.ch-stats{ display:grid; grid-template-columns:repeat(6, 1fr); gap:10px; margin-bottom:14px; }
.ch-stats-detail{ grid-template-columns:repeat(4, 1fr); margin-bottom:0; }
/* #11 (follow-up pass) — restrained per-tile identity accent (--stat-accent,
   set inline per tile in renderChStats), visual language borrowed from
   Overview's kpi-card top-edge + glow — own property, Overview untouched. */
/* #8 (Dock freeze pass) — a soft ambient tint IN the surface (radial wash
   from the top), not just the border/glow — "ambient illuminated glass"
   rather than a flat solid accent fill. */
.ch-stat{
  background:
    radial-gradient(140% 165% at 35% -25%, color-mix(in srgb, var(--stat-accent, var(--surface-1)) 30%, transparent), transparent 72%),
    var(--surface-1);
  border:1px solid var(--line); border-top:2px solid color-mix(in srgb, var(--stat-accent, var(--line)) 65%, var(--line)); border-radius:var(--radius-md); padding:13px 13px 12px; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; gap:2px; min-height:70px; box-shadow:0 8px 18px -15px color-mix(in srgb, var(--stat-accent, transparent) 55%, transparent); transition:transform .14s ease, box-shadow .14s ease, border-color .14s ease, background .14s ease;
}
.ch-stat-v{ font-size:20px; font-weight:800; letter-spacing:-0.015em; color:var(--text-primary); line-height:1.1; }
.ch-stat-v.is-bad{ color:var(--bad); }
.ch-stat-v.is-pending{ color:var(--warn); }
/* #16 (Dock freeze pass) — Open Balance is pending revenue, not a problem;
   Overdue keeps its own is-bad (red) warning treatment untouched. */
.ch-stat-v.is-good{ color:var(--good); }
.ch-stat-l{ font-size:10.5px; color:var(--text-tertiary); margin-top:1px; font-weight:600; line-height:1.35; }
.ch-stat-sub{ color:var(--text-tertiary); font-weight:500; }
/* #15 (Dock freeze pass) — dark mode only: labels read near-white at reduced
   opacity (hierarchy via opacity, not a dim gray token) instead of
   var(--text-tertiary), which was reading as too-dark/low-contrast here.
   #5 (Dock final visual freeze) — same fix, same reasoning, extended to the
   Client Detail metric labels (Card Views/Leads/Contacts/Booked Calls) —
   a visually similar but separate card type that hadn't gotten this yet. */
:root:not([data-theme="light"]) .ch-stat-l,
:root:not([data-theme="light"]) .ch-stat-sub,
:root:not([data-theme="light"]) .ch360-metric-l{ color:color-mix(in srgb, var(--text-primary) 68%, transparent); }
.ch-stat.is-actionable{ cursor:pointer; }
/* #6/#7/#8/#9 (Dock final pass) — every tile's hover/active state now
   derives from ITS OWN --stat-accent, not a hardcoded shared violet. This
   applies to ALL tiles (not just .is-actionable ones), so Recurring — which
   is display-only, never a filter — still gets the same accent-aware hover
   response as Clients/Setup/Overdue/Open balance; only the clickable
   affordance (lift + cursor) stays actionable-only. */
.ch-stat:hover{
  border-color:color-mix(in srgb, var(--stat-accent, var(--violet)) 45%, var(--line));
  box-shadow:0 8px 22px -12px color-mix(in srgb, var(--stat-accent, var(--violet)) 55%, transparent),
             0 0 0 1px color-mix(in srgb, var(--stat-accent, var(--violet)) 14%, transparent) inset;
}
.ch-stat.is-actionable:hover{ transform:translateY(-2px); }
.ch-stat.is-filtering{
  border-color:var(--stat-accent, var(--violet));
  box-shadow:0 0 0 1px var(--stat-accent, var(--violet)) inset, 0 8px 22px -12px color-mix(in srgb, var(--stat-accent, var(--violet)) 60%, transparent);
}
.ch-stat.is-filtering .ch-stat-l{ color:var(--stat-accent, var(--violet)); }
[data-theme="light"] .ch-stat:hover{ box-shadow:0 8px 20px -12px color-mix(in srgb, var(--stat-accent, var(--violet)) 40%, transparent); }
.ch-pager{ display:flex; align-items:center; justify-content:center; gap:14px; padding:10px 4px 2px; margin-top:8px; border-top:1px solid var(--line); }
.ch-pager-arrow{ font:inherit; font-size:17px; line-height:1; width:26px; height:26px; display:flex; align-items:center; justify-content:center; border:1px solid var(--line); border-radius:7px; background:var(--surface-1); color:var(--text-primary); cursor:pointer; transition:border-color .12s ease, opacity .12s ease; }
.ch-pager-arrow:hover:not([disabled]){ border-color:var(--violet); color:var(--violet); }
.ch-pager-arrow[disabled]{ opacity:0.3; cursor:default; }
.ch-pager-pos{ font-size:11px; font-weight:600; color:var(--text-tertiary); letter-spacing:0.01em; }
.ch-pager-sep{ opacity:0.5; }
@media (max-width:1180px){ .ch-stats{ grid-template-columns:repeat(3, 1fr); } }
@media (max-width:640px){ .ch-stats, .ch-stats-detail{ grid-template-columns:repeat(2, 1fr); } }

/* ---- Client Hub — list card (fixed height, internal scroll) ----------- */
/* #10/#11 — sized for exactly 5 rows: the card shrinks to its content and
   the sections below pull up, no dead space where rows 6–7 used to be. */
.ch-table-card{ padding:15px 16px 4px; display:flex; flex-direction:column; max-height:none; }
.ch-list-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:14px; flex-wrap:wrap; margin-bottom:12px; }
.ch-list-title{ display:flex; align-items:baseline; gap:9px; }
.ch-list-title h2{ margin:0; }
.ch-list-title span{ font-size:11.5px; color:var(--text-tertiary); font-weight:600; }
.ch-list-controls{ display:flex; align-items:center; gap:9px; flex-wrap:wrap; }
.ch-search{ position:relative; display:flex; align-items:center; }
.ch-search svg{ position:absolute; left:9px; width:13px; height:13px; stroke:var(--text-tertiary); fill:none; stroke-width:2; pointer-events:none; }
.ch-search input{
  width:240px; max-width:44vw; font:inherit; font-size:12px; padding:7px 10px 7px 28px; border-radius:9px;
  background:var(--input-bg); border:1px solid var(--line-strong); color:var(--text-primary);
}
.ch-search input:focus{ outline:none; border-color:var(--violet); box-shadow:0 0 0 3px color-mix(in srgb, var(--violet) 15%, transparent); }
/* Priority-5J — segmented filter with a sliding "jelly" active indicator,
   reusing the navThumbJelly keyframe. #chFilterThumb is absolutely positioned
   inside .ch-filters and moved by positionChFilterThumb() (translateX + width);
   the inner .ch-filter-thumb-jelly runs the one-shot squash on each move.
   Readability: brighter idle text, clear active contrast, both themes. */
.ch-filters{ position:relative; display:flex; gap:2px; background:var(--surface-2); border:1px solid var(--line); border-radius:9px; padding:3px; }
.ch-filter{ position:relative; z-index:1; font:inherit; font-size:11px; font-weight:700; color:var(--text-secondary); background:none; border:none; border-radius:7px; padding:5px 10px; cursor:pointer; white-space:nowrap; transition:color .18s ease; }
.ch-filter:hover{ color:var(--text-primary); }
.ch-filter.is-active{ color:var(--violet); }
[data-theme="light"] .ch-filter.is-active{ color:var(--violet); }
.ch-filter-thumb{
  position:absolute; top:3px; left:0; height:calc(100% - 6px); border-radius:7px; z-index:0;
  opacity:0; pointer-events:none;
  transition:transform .34s cubic-bezier(.4,0,.15,1), width .34s cubic-bezier(.4,0,.15,1), opacity .2s ease;
}
.ch-filter-thumb.is-ready{ opacity:1; }
.ch-filter-thumb-jelly{
  position:absolute; inset:0; border-radius:inherit;
  background:var(--surface-1);
  box-shadow:0 1px 3px rgba(0,0,0,0.22), inset 0 0 0 1px color-mix(in srgb, var(--violet) 22%, transparent);
}
[data-theme="light"] .ch-filter-thumb-jelly{ background:#fff; box-shadow:0 1px 4px rgba(46,32,96,0.14), inset 0 0 0 1px color-mix(in srgb, var(--violet) 20%, transparent); }
.ch-filter-thumb-jelly.is-jelly{ animation:navThumbJelly .34s cubic-bezier(.4,0,.15,1) both; }
@media (prefers-reduced-motion:reduce){
  .ch-filter-thumb{ transition:opacity .2s ease; }
  .ch-filter-thumb-jelly.is-jelly{ animation:none; }
}
.ch-table-wrap{ overflow-y:auto; overflow-x:auto; flex:1 1 auto; min-height:0; margin:0 -16px; padding:0 16px; }
.ch-table{ width:100%; border-collapse:collapse; font-size:12px; min-width:860px; }
.ch-table th{
  position:sticky; top:0; z-index:2; background:var(--surface-1);
  text-align:left; font-size:10px; font-weight:800; letter-spacing:0.04em; text-transform:uppercase; color:var(--text-tertiary);
  padding:8px 10px; border-bottom:1px solid var(--line-strong);
}
.ch-table td{ padding:9px 10px; border-bottom:1px solid var(--line); color:var(--text-secondary); vertical-align:middle; }
.ch-table tr:last-child td{ border-bottom:none; }
.ch-row{ cursor:pointer; transition:background .12s ease; }
.ch-row:hover{ background:var(--surface-hover); }
.ch-row:hover td{ color:var(--text-primary); }
.ch-row-client{ display:flex; align-items:center; gap:9px; }
.ch-row-cn{ display:flex; flex-direction:column; min-width:0; }
.ch-row-cn b{ font-weight:700; color:var(--text-primary); font-size:12px; }
.ch-row-cn span{ font-size:10px; color:var(--text-tertiary); }
.ch-table td.ch-bad{ color:var(--bad); font-weight:700; }
.ch-empty-row{ text-align:center; color:var(--text-tertiary); padding:26px 0; }
.ch-row-ini{
  flex:0 0 auto; width:28px; height:28px; border-radius:9px; display:flex; align-items:center; justify-content:center;
  font-size:11px; font-weight:800; color:#0A0A16; background:var(--ch-accent, var(--violet));
}
[data-theme="light"] .ch-row-ini{ color:#fff; }

/* ---- Client Hub — operating widgets below the list ------------------- */
.ch-widgets{ display:grid; grid-template-columns:repeat(2, 1fr); gap:14px; margin-top:14px; }
@media (max-width:960px){ .ch-widgets{ grid-template-columns:1fr; } }
.ch-widget{ padding:15px 16px; }
.ch-widget-h{ font-size:10.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary); margin-bottom:10px; }
.ch-widget-b{ display:flex; flex-direction:column; gap:3px; max-height:236px; overflow-y:auto; }
.ch-w-row{
  display:flex; align-items:center; gap:9px; width:100%; text-align:left; background:none; border:none; font:inherit;
  padding:7px 6px; border-radius:8px; cursor:pointer; transition:background .12s ease;
}
.ch-w-row:hover{ background:var(--surface-hover); }
.ch-w-ini{ flex:0 0 auto; width:24px; height:24px; border-radius:7px; display:flex; align-items:center; justify-content:center; font-size:9.5px; font-weight:800; color:#0A0A16; background:var(--ch-accent, var(--violet)); }
[data-theme="light"] .ch-w-ini{ color:#fff; }
.ch-w-main{ flex:1 1 auto; min-width:0; display:flex; flex-direction:column; }
.ch-w-main b{ font-size:11.5px; font-weight:700; color:var(--text-primary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ch-w-main span{ font-size:10.5px; color:var(--text-tertiary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ch-w-amt{ flex:0 0 auto; font-size:11.5px; font-weight:800; color:var(--text-primary); font-family:'JetBrains Mono',monospace; }
.ch-w-amt.is-bad{ color:var(--bad); }
.ch-w-act{ display:flex; align-items:flex-start; gap:8px; padding:6px 6px; font-size:11px; }
.ch-w-dot{ flex:0 0 auto; width:7px; height:7px; margin-top:5px; border-radius:50%; background:var(--tl-color, var(--violet)); }
.ch-w-when{ flex:0 0 auto; font-size:10px; color:var(--text-tertiary); font-family:'JetBrains Mono',monospace; }
.ch-w-empty{ font-size:12px; color:var(--text-tertiary); padding:6px; }

/* ---- Client Hub — visual intelligence (#15) --------------------------- */
.ch-viz-grid{ grid-column:1 / -1; display:grid; grid-template-columns:repeat(4, 1fr); gap:14px; }
@media (max-width:1180px){ .ch-viz-grid{ grid-template-columns:repeat(2, 1fr); } }
@media (max-width:640px){ .ch-viz-grid{ grid-template-columns:1fr; } }
.ch-viz-grid .ch-widget-b{ max-height:none; overflow:visible; gap:11px; }
.ch-viz-bar{ display:flex; height:12px; border-radius:6px; overflow:hidden; background:var(--surface-2, var(--surface-1)); gap:1.5px; }
.ch-viz-seg{ display:block; height:100%; border:none; padding:0; background:var(--seg); min-width:3px; }
.ch-viz-seg.is-actionable{ cursor:pointer; transition:filter .12s ease; }
.ch-viz-seg.is-actionable:hover{ filter:brightness(1.18); }
.ch-viz-legend{ display:flex; flex-wrap:wrap; gap:4px 12px; }
.ch-viz-lg{ display:flex; align-items:center; gap:5px; font-size:10.5px; color:var(--text-tertiary); font-weight:600; }
.ch-viz-lg i{ width:8px; height:8px; border-radius:2px; flex:0 0 auto; }
.ch-viz-lg b{ color:var(--text-secondary); }
.ch-viz-note{ font-size:10.5px; color:var(--text-tertiary); font-weight:600; margin-top:2px; }
.ch-viz-prow-h{ display:flex; justify-content:space-between; align-items:baseline; font-size:11px; font-weight:600; color:var(--text-secondary); margin-bottom:5px; }
.ch-viz-prow-h b{ font-size:10.5px; color:var(--text-tertiary); }
.ch-viz-track{ height:8px; border-radius:5px; background:var(--surface-2, var(--surface-1)); overflow:hidden; }
.ch-viz-fill{ height:100%; border-radius:5px; transition:width .3s ease; }

/* ---- Client Hub — New Client modal (Priority-4) ----------------------- */
.ch-mock-check-row{ display:flex; align-items:center; gap:8px; font-size:12.5px; color:var(--text-secondary); padding:6px 0; }
.lead-req{ font-size:9.5px; font-weight:700; text-transform:uppercase; letter-spacing:0.04em; color:var(--violet); margin-left:6px; }
.lead-input.is-invalid, .lead-select.is-invalid{ border-color:var(--bad); box-shadow:0 0 0 3px color-mix(in srgb, var(--bad) 16%, transparent); }
.lead-sheet-hint{ font-size:11.5px; color:var(--text-tertiary); line-height:1.5; }
#chNewClientMsg{ color:var(--bad); font-weight:600; }
.ch-ncf-more{ border:1px solid var(--line); border-radius:10px; padding:0 12px; margin:12px 0 0; background:var(--surface-2); }
.ch-ncf-more > summary{ cursor:pointer; font-size:12px; font-weight:700; color:var(--text-secondary); padding:11px 0; list-style:none; }
.ch-ncf-more > summary::-webkit-details-marker{ display:none; }
.ch-ncf-more > summary::before{ content:"›"; display:inline-block; margin-right:8px; transition:transform .16s ease; color:var(--text-tertiary); }
.ch-ncf-more[open] > summary::before{ transform:rotate(90deg); }
.ch-ncf-more[open]{ padding-bottom:12px; }
.ch-ncf-prod{ display:flex; align-items:center; gap:9px; font-size:12px; color:var(--text-secondary); padding:6px 2px; cursor:pointer; }
.ch-ncf-prod input{ flex:0 0 auto; }
.ch-ncf-prod > span:first-of-type{ flex:1 1 auto; }
.ch-ncf-prod-p{ font-size:11px; color:var(--text-tertiary); font-family:'JetBrains Mono',ui-monospace,monospace; }

/* ---- Client Hub — Client 360 detail ------------------------------------ */
.ch-detail-head{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin-bottom:16px; }
.ch-detail-id{ display:flex; align-items:center; gap:10px; margin-right:auto; }
.ch-detail-id .ch-row-ini{ width:38px; height:38px; border-radius:11px; font-size:14px; }
.ch-detail-name{ font-size:15px; font-weight:800; color:var(--text-primary); }
.ch-detail-sub{ font-size:12px; color:var(--text-tertiary); margin-top:1px; }
.ch-detail-body{ display:flex; gap:18px; align-items:flex-start; }
.ch-detail-tabs{ display:flex; flex-direction:column; gap:2px; flex:0 0 168px; }
.ch-detail-tab{
  text-align:left; font:inherit; font-size:12.5px; font-weight:700; color:var(--text-secondary); cursor:pointer;
  background:none; border:none; border-radius:9px; padding:9px 12px; transition:background .12s ease, color .12s ease;
}
.ch-detail-tab:hover{ background:var(--surface-hover); color:var(--text-primary); }
.ch-detail-tab.is-active{ background:color-mix(in srgb, var(--violet) 14%, transparent); color:var(--violet); }
.ch-detail-panel{ flex:1 1 auto; min-width:0; padding:20px; }
@media (max-width:860px){
  .ch-detail-body{ flex-direction:column; }
  .ch-detail-tabs{ flex-direction:row; flex-wrap:wrap; flex:0 0 auto; }
}

.ch-kv-grid{ display:grid; grid-template-columns:1fr 1fr; gap:14px 24px; }
.ch-kv-k{ font-size:10.5px; font-weight:700; letter-spacing:0.03em; text-transform:uppercase; color:var(--text-tertiary); }
.ch-kv-v{ font-size:13.5px; font-weight:600; color:var(--text-primary); margin-top:2px; }
@media (max-width:560px){ .ch-kv-grid{ grid-template-columns:1fr; } }

.ch-product-list{ display:flex; flex-direction:column; gap:1px; border:1px solid var(--line); border-radius:12px; overflow:hidden; }
.ch-product-row{ display:flex; align-items:center; justify-content:space-between; gap:12px; padding:12px 14px; background:color-mix(in srgb, var(--surface-1) 40%, transparent); border-bottom:1px solid var(--line); }
.ch-product-row:last-child{ border-bottom:none; }
.ch-product-name{ font-size:13px; font-weight:700; color:var(--text-primary); }
.ch-product-desc{ font-size:11.5px; color:var(--text-tertiary); margin-top:1px; }

.ch-checklist{ display:flex; flex-direction:column; gap:2px; }
.ch-check-row{ display:flex; align-items:center; gap:10px; font-size:13px; color:var(--text-secondary); padding:8px 0; border-bottom:1px solid var(--line); }
.ch-check-row:last-child{ border-bottom:none; }

.ch-notes{ display:flex; flex-direction:column; gap:12px; }
.ch-note{ padding:12px 14px; border:1px solid var(--line); border-radius:10px; background:color-mix(in srgb, var(--surface-1) 40%, transparent); }
.ch-note-meta{ font-size:10.5px; font-weight:700; letter-spacing:0.03em; text-transform:uppercase; color:var(--text-tertiary); margin-bottom:4px; }
.ch-note-body{ font-size:13px; line-height:1.5; color:var(--text-primary); }

/* ===== Client 360 — mirrors Full Contact's lane system ================= */
#chDetail{ display:block; }
.ch360-grid{ margin-top:2px; }
/* #11/#12 — at desktop width the 3-lane workspace anchors top→bottom
   (JS sets an explicit height), lanes scroll INSIDE, and the two
   .lead-record-divider handles between lanes drag to resize (widths in
   --lane-l / --lane-r, persisted to leadsPrefs.ch360Lanes). Same 5-child
   grid shape Full Contact's own ≥1181px rule already targets. */
@media (min-width:1181px){
  /* #A (Dock final visual freeze) — ROOT CAUSE of the outer page scroll +
     trailing empty space below the three lanes: .main carries a global
     60px bottom padding (needed by normally-scrolling pages like the Dock
     LIST/widgets view — untouched, still gets it). chLayoutDetail()'s
     JS-measured grid height (window.innerHeight - top - 12) has no way to
     know about that extra padding, so the page was always exactly 60px
     short of the grid actually filling the viewport — the body became
     scrollable by that same 60px, with nothing but padding to show for it.
     Orbit's own Full Contact record hit this identical issue already:
     #leadRecordPane{margin-bottom:-60px}, same @media breakpoint as
     chLayoutDetail()'s own JS check (only >=1181px height-locks the grid at
     all — below that it's natural height and SHOULD scroll normally, so
     this must not apply there). Inert while [hidden] (display:none
     !important beats any margin), so the Dock LIST view is unaffected. */
  #chDetail{ margin-bottom:-60px; }
  /* #2 — tighter three-lane workspace (Full Contact density) */
  .ch360-grid{
    grid-template-columns:var(--lane-l,320px) 5px minmax(360px,1fr) 5px var(--lane-r,340px);
    gap:0; align-items:stretch; overflow:hidden;
  }
  .ch360-grid .lead-record-lane{ min-width:0; min-height:0; max-height:100%; }
  .ch360-grid .lead-lane-left, .ch360-grid .lead-lane-right{
    overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain;
    display:flex; flex-direction:column; gap:10px;
  }
  .ch360-grid .lead-lane-left{ padding-right:5px; }
  .ch360-grid .lead-lane-right{ padding-left:5px; }
  /* #17 (Dock freeze pass) — left/right lanes each show their OWN internal
     scrollbar right next to their divider-facing edge, but the left lane's
     4 stacked cards overflow far more consistently than center's tab
     content does, so its scrollbar is visible there more often — reading as
     a bigger left↔middle gap than middle↔right. Shifting the center lane's
     padding (same 6px total, just redistributed) rather than the grid's own
     column/divider tracks keeps total gutter width unchanged. */
  .ch360-grid .lead-lane-center{ padding:0 5px 0 1px; }
  .ch360-grid .lead-lane-center > .lead-record-card.is-timeline{ height:100%; display:flex; flex-direction:column; }
  .ch360-grid .ch360-scroll{ flex:1 1 auto; min-height:0; overflow-y:auto; }
  .ch360-grid .lead-record-divider{ display:block; }
  #chDetail .lead-record-bar{ margin-bottom:8px; }
}
@media (max-width:1180px){
  .ch360-grid{ display:grid; grid-template-columns:minmax(0,1.25fr) minmax(0,1fr); gap:14px; }
  .ch360-grid .lead-record-divider{ display:none; }
  .ch360-grid .lead-lane-right{ grid-column:1 / -1; display:grid; grid-template-columns:1fr 1fr; gap:12px; align-content:start; }
}
@media (max-width:820px){ .ch360-grid{ grid-template-columns:1fr; } .ch360-grid .lead-lane-right{ grid-template-columns:1fr; } }
.ch360-idcard, .ch360-acctcard{ display:flex; flex-direction:column; gap:12px; align-items:stretch; }
.ch360-idcard > .crm-integ-badge, .ch360-acctcard > .crm-integ-badge{ align-self:flex-start; }
.ch360-idhead{ display:flex; align-items:center; gap:11px; }
.ch360-ava{ width:40px; height:40px; border-radius:12px; font-size:14px; flex:0 0 auto; }
.ch360-idname{ font-size:14.5px; font-weight:800; color:var(--text-primary); line-height:1.25; min-width:0; }
.ch360-idname span{ display:block; font-size:11px; font-weight:600; color:var(--text-tertiary); margin-top:2px; }
.ch360-cardtitle{ font-size:10.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary); }
.ch360-props{ display:flex; flex-direction:column; }
.ch360-prop{ padding:8px 0; border-bottom:1px solid var(--line); }
.ch360-prop:last-child{ border-bottom:none; padding-bottom:0; }
.ch360-prop-k{ font-size:10px; font-weight:700; letter-spacing:0.03em; text-transform:uppercase; color:var(--text-tertiary); }
.ch360-prop-v{ font-size:12.5px; font-weight:600; color:var(--text-primary); margin-top:2px; word-break:break-word; }
.ch360-prop-v a{ color:var(--violet); }
.ch360-prop.is-editable{ cursor:pointer; border-radius:7px; margin:0 -6px; padding-left:6px; padding-right:6px; transition:background .12s ease; }
.ch360-prop.is-editable:hover{ background:var(--surface-hover); }
.ch360-prop-v{ display:flex; align-items:center; gap:6px; justify-content:space-between; }
.ch360-prop-pen{ width:12px; height:12px; stroke:var(--text-tertiary); fill:none; stroke-width:2; flex:0 0 auto; opacity:0; transition:opacity .12s ease; }
.ch360-prop.is-editable:hover .ch360-prop-pen{ opacity:1; }
.ch360-muted{ font-size:12px; color:var(--text-tertiary); }
/* #14-16 (Dock final visual freeze) — Attribution card: label left / value
   right, comfortable internal padding and row spacing (nothing sits on the
   card border), value gets the typography weight so it reads as the actual
   answer rather than a flat two-column dump. */
.ch360-attr{ display:flex; flex-direction:column; gap:10px; padding:2px 2px 4px; }
.ch360-attr-row{ display:flex; align-items:baseline; justify-content:space-between; gap:14px; font-size:12px; }
.ch360-attr-k{ flex:0 0 auto; color:var(--text-tertiary); font-weight:600; }
.ch360-attr-v{ color:var(--text-primary); font-weight:700; text-align:right; overflow-wrap:anywhere; }
.ch360-attr-empty{ padding:8px 2px 4px; }
.ch360-attr-empty-t{ font-size:12.5px; font-weight:700; color:var(--text-secondary); margin-bottom:4px; }
.ch360-attr-empty-s{ font-size:11px; color:var(--text-tertiary); line-height:1.5; }

/* #7 — the client workspace shell is FIXED geometry: the tab bar never
   moves; switching tabs only swaps .ch360-scroll's content, which scrolls
   internally. A min-height stops a short tab from collapsing the shell. */
.ch360-workspace{ display:flex; flex-direction:column; min-height:0; height:100%; }
.ch360-tabs{
  flex:0 0 auto; display:flex; gap:1px; flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none;
  border-bottom:1px solid var(--line); padding-bottom:0; margin-bottom:0;
}
.ch360-tabs::-webkit-scrollbar{ display:none; }
.ch360-tabs .lead-tl-tab{ padding:10px 12px; flex:0 0 auto; }
/* #8 — the active underline hugs the tab label and sits exactly ON the
   tab-bar border (no floating gap above it). */
.ch360-tabs .lead-tl-tab.is-active::after{ left:12px; right:12px; bottom:-1px; height:2.5px; }
.ch360-tabcount{ display:inline-flex; align-items:center; justify-content:center; min-width:16px; height:16px; padding:0 4px; border-radius:8px; font-size:9.5px; font-weight:800; background:color-mix(in srgb, var(--violet) 18%, transparent); color:var(--violet); vertical-align:1px; }
.lead-tl-tab.is-active .ch360-tabcount{ background:color-mix(in srgb, var(--violet) 26%, transparent); }
/* #8/#13 (Dock UX/safety pass) — ONE shared middle-content inset (8px)
   instead of one-off per-tab padding, applied to the scroll wrapper itself
   so EVERY tab (Activity, Notes, Digital Cards, Accessories, Orders,
   Billing) inherits the same "professional breathing room" automatically —
   this replaces the earlier Activity-only .lead-timeline padding rule
   (removed below) with the actual shared token the audit asked for. */
.ch360-scroll{ flex:1 1 auto; min-height:180px; overflow-y:auto; overflow-x:hidden; padding:12px 8px 16px; }

/* #1 — COMPACT one-line email/URL values: single line + ellipsis (the full
   value stays available via title=). Wrapping is only for EXPANDED detail
   blocks where vertical space is appropriate. */
.ch360-prop-v.is-oneline, .ch360-prop-v.is-oneline a{ display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }
.ch360-person-id span, .ch360-person-open{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ch360-person-more .ch360-oneline{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* #1 (Dock final pass) — fixed header sibling of .ch360-scroll (never
   inside it — see chMetricsFixedHtml/renderChDetail); flex:0 0 auto keeps
   it pinned at natural height while .ch360-scroll absorbs all growth,
   same pattern as .lead-note-composer below it. The bottom border is the
   divider — decorative only, not draggable, not a resizer. */
/* #4 (Dock final visual freeze) — 0 top padding vs. 12px bottom read as the
   cards sitting too high/pushed against the tab strip above them; a small
   top inset balances it without meaningfully growing the header. */
.ch360-metrics-fixed{ flex:0 0 auto; padding:10px 8px 12px; margin-bottom:12px; border-bottom:1px solid var(--line); }
.ch360-metrics{ display:grid; grid-template-columns:repeat(4,1fr); gap:10px; margin-bottom:6px; }
/* #5/#6 (Dock freeze pass) — more breathing room between the border and the
   content, and the value/label centered rather than leaning left. Same
   card, same grid — spacing/alignment only. */
.ch360-metric{ background:var(--surface-1); border:1px solid var(--line); border-radius:11px; padding:16px 14px; text-align:center; }
.ch360-metric-v{ font-size:17px; font-weight:800; color:var(--text-primary); }
.ch360-metric-l{ font-size:10px; font-weight:600; color:var(--text-tertiary); margin-top:3px; }
/* #7 (Dock freeze pass) — Dock's activity icon chips only (Orbit's own
   Full Contact timeline is untouched): a bit more room around the icon so
   it reads as an intentional chip rather than an emoji touching its frame.
   Icon size (svg) is unchanged; the chip + its connector line grid column
   grow together so the timeline's vertical rule stays centered on it. */
.ch360-scroll .lead-tl-item{ grid-template-columns:30px 1fr; }
.ch360-scroll .lead-tl-item::before{ left:14.25px; }
.ch360-scroll .lead-tl-dot{ width:30px; height:30px; }
/* the per-tab inset now comes from .ch360-scroll's own padding (shared
   token, see above) — no per-tab override needed here anymore. */
/* #3/#19 (Dock freeze pass) — an invoice activity row with a resolvable
   invoiceId renders as a <button>; reset just what the browser's UA button
   style would otherwise add (background/border/font/alignment) — layout
   (grid/gap/padding-bottom) still comes from .lead-tl-item above. */
button.lead-tl-item{ width:100%; margin:0; padding-top:0; padding-left:0; padding-right:0; background:none; border:none; font:inherit; text-align:left; cursor:pointer; -webkit-appearance:none; appearance:none; }
.lead-tl-item.is-openable{ padding-right:22px; }
.lead-tl-item.is-openable:hover{ background:var(--surface-hover); border-radius:8px; }
.lead-tl-open-ic{ position:absolute; right:2px; top:8px; width:14px; height:14px; stroke:var(--text-tertiary); fill:none; stroke-width:2.2; }
.lead-tl-item.is-openable:hover .lead-tl-open-ic{ stroke:var(--violet); }
/* #12 (Dock freeze pass) — the generic [data-tip]::after/::before is
   position:absolute against the tile itself, so it gets clipped by
   .ch360-scroll's overflow (the tile's clipping ancestor) whenever the
   popup would land past the currently-visible scroll viewport — silently
   "not appearing" exactly as reported. Suppressed here; chShowMetricTip /
   .ch360-metric-tip (app.js) render a real fixed-position tooltip appended
   to <body> instead, which no ancestor's overflow can clip. data-tip stays
   on the element only as the JS tooltip's text source. */
.ch360-metric[data-tip]::after, .ch360-metric[data-tip]::before{ content:none; display:none; }
/* #14-16 (Dock UX/safety pass) — same suppression for the Dock ROOT page's
   4 intelligence widget cards (the ACTUAL "four small intelligence cards" —
   see chWidgetCard/chWireTooltips in app.js), so they use the same portal
   tooltip instead of the generic clip-prone CSS-only one. */
/* #19/#20 (data-safety pass) — data-tip lives on the outer .ch-widget card
   now (see chWidgetCard in app.js), not just its .ch-widget-h title, so the
   whole visual card is the hover target. cursor:help only on the card
   itself (not inherited weirdly onto interactive children — the segment/
   row buttons inside set their own cursor via .is-actionable etc.). */
.ch-widget[data-tip]::after, .ch-widget[data-tip]::before{ content:none; display:none; }
.ch-widget[data-tip]{ cursor:help; }
.ch360-metric-tip{
  position:fixed; z-index:500; max-width:220px; padding:8px 11px; border-radius:9px;
  font-size:11px; font-weight:600; line-height:1.4; color:var(--text-primary); text-align:left;
  background:color-mix(in srgb, var(--ink-800) 82%, transparent);
  -webkit-backdrop-filter:blur(14px) saturate(1.4); backdrop-filter:blur(14px) saturate(1.4);
  border:1px solid color-mix(in srgb, var(--cyan) 24%, var(--line-strong));
  box-shadow:0 16px 34px -14px rgba(0,0,0,0.6);
  opacity:0; transform:translateY(4px); transition:opacity .12s ease, transform .12s ease;
  pointer-events:none;
}
.ch360-metric-tip.is-visible{ opacity:1; transform:translateY(0); }
[data-theme="light"] .ch360-metric-tip{
  background:color-mix(in srgb, #fff 94%, transparent); color:#181a22;
  border-color:color-mix(in srgb, var(--violet) 30%, var(--line-strong));
  box-shadow:0 16px 34px -14px rgba(20,20,30,0.25);
}
.ch360-section-h{ font-size:10.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary); margin:16px 0 8px; }
/* #3 (Dock final visual freeze) — "Account timeline" as a footer label
   below the newest item: understated on purpose (lighter weight, no
   uppercase/letter-spacing shout), a quiet close to the history rather
   than a heading floating at the bottom of the page. */
.ch360-section-f{ font-size:10.5px; font-weight:600; color:var(--text-tertiary); text-align:center; margin:14px 0 2px; opacity:0.7; }
.ch360-morelink{ margin-top:8px; background:none; border:none; color:var(--violet); font:inherit; font-size:12px; font-weight:700; cursor:pointer; padding:4px 0; }

.ch360-list{ display:flex; flex-direction:column; gap:8px; }
.ch360-cardrow{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; padding:12px 13px; border:1px solid var(--line); border-radius:11px; background:var(--surface-1); }
.ch360-cardrow-main{ min-width:0; flex:1 1 auto; }
.ch360-cardrow-t{ font-size:13px; font-weight:700; color:var(--text-primary); }
.ch360-cardrow-role{ font-weight:600; font-size:11px; color:var(--text-tertiary); }
.ch360-cardrow-url{ font-size:11px; color:var(--text-secondary); margin-top:2px; font-family:'JetBrains Mono',ui-monospace,monospace; overflow:hidden; text-overflow:ellipsis; }
.ch360-cardrow-url a{ color:var(--cyan); }
.ch360-cardrow-meta{ font-size:11px; color:var(--text-tertiary); margin-top:5px; display:flex; align-items:center; gap:5px; flex-wrap:wrap; }
/* #9 (Dock UX/safety pass) — 5px→7px: a "tight premium toolbar" still
   needs a hair more room than this before adjacent buttons stop reading as
   glued together. */
.ch360-cardrow-acts{ display:flex; flex-direction:column; gap:7px; flex:0 0 auto; align-items:stretch; }
/* #9 — Accessories: denser rows, and a compact 2×2 action grid (rather than
   4 stacked buttons) so accessory type never distorts the card's height. */
.ch360-cardrow.is-compact{ padding:10px 12px; }
.ch360-cardrow-acts.is-grid{ display:grid; grid-template-columns:1fr 1fr; gap:8px; width:188px; }
.ch360-cardrow-acts.is-grid .ch360-mini{ width:100%; height:30px; padding:0 8px; display:flex; align-items:center; justify-content:center; text-align:center; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ch360-mini{
  font:inherit; font-size:11px; font-weight:700; color:var(--text-secondary); white-space:nowrap;
  background:var(--surface-2); border:1px solid var(--line-strong); border-radius:8px; padding:6px 10px; cursor:pointer;
  transition:border-color .12s ease, color .12s ease, background .12s ease;
}
.ch360-mini:hover{ color:var(--violet); border-color:var(--violet-dim); background:var(--surface-hover); }
.ch360-addbtn{
  display:inline-flex; align-items:center; gap:7px; margin-top:12px; font:inherit; font-size:12px; font-weight:700;
  color:var(--violet); background:color-mix(in srgb, var(--violet) 10%, transparent); border:1px solid var(--violet-dim);
  border-radius:9px; padding:8px 14px; cursor:pointer; transition:background .12s ease;
}
.ch360-addbtn:hover{ background:color-mix(in srgb, var(--violet) 16%, transparent); }
.ch360-addbtn svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.4; }
/* #8 — Digital Cards tab format: NEW CARD (and the other tab "add" actions)
   sit bottom-right of the tab content, not hugging the left edge. */
.ch360-tabfoot{ display:flex; justify-content:flex-end; }
.ch360-tabfoot .ch360-addbtn{ margin-top:12px; }
/* #8/#9/#11 (refinement pass) — Digital Cards / Accessories / Orders: the
   create action anchors to the BOTTOM-right of the whole tab content area
   (not just after the last row) whenever there's spare vertical room.
   .ch360-tabpanel stretches to the scroll container's height so
   margin-top:auto on the footer can push down; with no spare room it just
   sits after the content, same as .ch360-tabfoot. */
/* #10/#13 (Dock UX/safety pass) — shared token: 12px between EVERY direct
   child (list → warning note → footer button) instead of the 0px it had
   (no per-tab one-off spacing needed for Digital Cards/Accessories/Orders —
   this is the reusable class Accessories' "warning touching content" and
   Orders' equivalent both come from). margin-top:auto on .ch360-tabfoot-
   anchor still works normally alongside a flex gap. */
.ch360-tabpanel{ display:flex; flex-direction:column; min-height:100%; gap:12px; }
.ch360-tabfoot-anchor{ display:flex; justify-content:flex-end; margin-top:auto; padding-top:12px; }
.ch360-tabfoot-anchor .ch360-addbtn{ margin-top:0; }

.ch360-orderrow{
  display:flex; align-items:center; justify-content:space-between; gap:12px; width:100%; text-align:left;
  padding:12px 13px; border:1px solid var(--line); border-radius:11px; background:var(--surface-1); cursor:pointer; font:inherit;
  transition:border-color .12s ease, background .12s ease;
}
.ch360-orderrow:hover{ border-color:var(--violet-dim); background:var(--surface-hover); }
.ch360-orderrow-l{ min-width:0; }
.ch360-orderrow-l b{ font-size:13px; font-weight:800; color:var(--text-primary); }
.ch360-orderrow-l span{ display:block; font-size:11px; color:var(--text-tertiary); margin-top:2px; }
.ch360-orderrow-r{ display:flex; flex-direction:column; align-items:flex-end; gap:5px; flex:0 0 auto; }
.ch360-orderrow-r b{ font-size:13px; font-weight:800; color:var(--text-primary); }
.ch360-orderrow-amt{ display:flex; align-items:baseline; gap:6px; }
.ch360-orderrow-rec{ font-size:10px; font-weight:700; color:var(--text-tertiary); white-space:nowrap; }
.ch360-orderrow-badges{ display:flex; align-items:center; gap:5px; }

.ch360-empty{ text-align:center; padding:34px 20px; }
.ch360-empty-ic{ width:44px; height:44px; margin:0 auto 12px; border-radius:13px; background:var(--surface-2); display:flex; align-items:center; justify-content:center; }
.ch360-empty-ic svg{ width:20px; height:20px; stroke:var(--text-tertiary); fill:none; stroke-width:2; }
.ch360-empty-t{ font-size:14px; font-weight:800; color:var(--text-primary); }
.ch360-empty-s{ font-size:12px; color:var(--text-tertiary); margin-top:4px; max-width:320px; margin-left:auto; margin-right:auto; }

.ch360-ctxcard{ display:flex; flex-direction:column; gap:11px; padding:15px; }
/* #5 (refinement pass) — Digital Cards right-rail card: reuses Orbit's own
   .lead-dc-widget-body row (see chDigitalCardsCardBody) for each card, but
   that class was tuned for exactly one occurrence — this list context
   overrides its single-widget margin so multiple rows stack cleanly. */
.ch360-dc-list{ display:flex; flex-direction:column; gap:2px; margin-top:2px; }
.ch360-dc-list .lead-dc-widget-body{ margin:0; }
.ch360-health{ display:flex; flex-direction:column; gap:1px; }
.ch360-health-row{ display:flex; align-items:center; justify-content:space-between; font-size:12px; color:var(--text-secondary); padding:7px 0; border-bottom:1px solid var(--line); }
.ch360-health-row:last-child{ border-bottom:none; }
.ch360-health-row b{ color:var(--text-primary); font-weight:800; }
.ch360-health-row b.is-bad{ color:var(--bad); }
.ch360-health-row b.is-good{ color:var(--good); }
.ch360-qa{ display:flex; flex-direction:column; gap:6px; }
.ch360-qabtn{
  display:flex; align-items:center; gap:8px; font:inherit; font-size:12px; font-weight:700; color:var(--text-secondary);
  background:var(--surface-1); border:1px solid var(--line-strong); border-radius:9px; padding:9px 11px; cursor:pointer;
  transition:border-color .12s ease, color .12s ease;
}
.ch360-qabtn:hover{ color:var(--violet); border-color:var(--violet-dim); }
.ch360-qabtn svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.4; }
.ch360-notes{ display:flex; flex-direction:column; gap:8px; max-height:230px; overflow-y:auto; }
.ch360-note{ padding:9px 11px; border:1px solid var(--line); border-radius:9px; background:var(--surface-1); }
.ch360-note-meta{ font-size:9.5px; font-weight:700; letter-spacing:0.03em; text-transform:uppercase; color:var(--text-tertiary); margin-bottom:3px; }
.ch360-note div:last-child{ font-size:12px; line-height:1.45; color:var(--text-primary); }
.ch360-inline-add{ display:flex; gap:6px; }
.ch360-inline-add .lead-input{ flex:1 1 auto; min-width:0; font-size:12px; padding:7px 9px; }
.ch360-tasks{ display:flex; flex-direction:column; gap:2px; }
.ch360-task{ display:flex; align-items:center; gap:8px; font-size:12px; color:var(--text-secondary); padding:6px 0; }
.ch360-task.is-done span:last-child{ text-decoration:line-through; color:var(--text-tertiary); }
.ch360-task-cbx{ background:none; border:none; padding:0; cursor:pointer; flex:0 0 auto; }

/* order / invoice builder lines */
.ch360-lines-h, .ch360-line{ display:grid; grid-template-columns:minmax(0,1fr) 58px 74px 74px 28px; gap:8px; align-items:center; }
.ch360-lines-h{ font-size:9.5px; font-weight:800; letter-spacing:0.04em; text-transform:uppercase; color:var(--text-tertiary); padding:0 2px 6px; }
.ch360-lines{ display:flex; flex-direction:column; gap:7px; }
.ch360-line .lead-select, .ch360-line .lead-input{ font-size:12px; padding:7px 8px; }
.ch360-line-total{ font-size:12px; font-weight:700; color:var(--text-primary); text-align:right; }
.ch360-line-del{ background:none; border:none; color:var(--text-tertiary); font-size:17px; line-height:1; cursor:pointer; padding:0; }
.ch360-line-del:hover{ color:var(--bad); }
/* #3/#19 (Dock freeze pass) — a wizard-only line item (see chBuilderLineHtml)
   still lines up under the Item/Qty/·/Total/× header — it just has no
   editable controls, and no Unit $ (its real price includes setup/recurring
   context folded into the name instead of a single per-unit figure). */
.ch360-line-readonly{ min-height:32px; }
.ch360-line-roname{ grid-column:1; font-size:12px; color:var(--text-primary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ch360-line-roqty{ grid-column:2; font-size:12px; color:var(--text-tertiary); text-align:right; }
.ch360-line-readonly .ch360-line-total{ grid-column:4; }
.ch360-line-readonly .ch360-line-del{ grid-column:5; }
/* #6 (Dock freeze pass) — Order receipt line items (chOrderReceiptLineHtml) */
.ch360-receipt-lines{ display:flex; flex-direction:column; gap:8px; }
.ch360-receipt-line{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; padding:10px 12px; border:1px solid var(--line); border-radius:10px; background:var(--surface-1); }
.ch360-receipt-line-main{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.ch360-receipt-line-main b{ font-size:12.5px; color:var(--text-primary); }
.ch360-receipt-line-meta, .ch360-receipt-line-extra{ font-size:11px; color:var(--text-tertiary); }
.ch360-receipt-line-note{ font-size:11px; color:var(--text-secondary); font-style:italic; }
.ch360-receipt-line-qty{ flex:0 0 auto; font-size:12px; color:var(--text-tertiary); align-self:center; }
.ch360-receipt-line-amt{ flex:0 0 auto; text-align:right; display:flex; flex-direction:column; gap:2px; }
.ch360-receipt-line-amt b{ font-size:12.5px; color:var(--text-primary); }
.ch360-additem{ margin-top:9px; }
.ch360-totals{ margin-top:14px; border-top:1px solid var(--line); padding-top:10px; display:flex; flex-direction:column; gap:6px; }
.ch360-total-row{ display:flex; align-items:center; justify-content:space-between; font-size:12.5px; color:var(--text-secondary); }
.ch360-total-row b{ color:var(--text-primary); font-weight:800; }
.ch360-total-row.is-grand{ font-size:15px; padding-top:6px; border-top:1px solid var(--line); }
.ch360-total-row.is-grand b{ font-size:16px; }
.ch360-discount{ width:100px; text-align:right; font-size:12px; padding:5px 8px; }

/* #9 — users / team card */
.ch360-teamcard{ display:flex; flex-direction:column; gap:10px; }
.ch360-team{ display:flex; flex-direction:column; gap:6px; }
.ch360-person{ border:1px solid var(--line); border-radius:10px; background:var(--surface-1); overflow:hidden; }
.ch360-person-h{ display:flex; align-items:center; gap:9px; padding:9px 10px; cursor:pointer; }
.ch360-person:hover .ch360-person-h{ background:var(--surface-hover); }
.ch360-person-ava{ flex:0 0 auto; width:26px; height:26px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:9.5px; font-weight:800; color:#fff; background:linear-gradient(135deg,var(--violet),var(--cyan)); }
.ch360-person-id{ flex:1 1 auto; min-width:0; display:flex; flex-direction:column; line-height:1.3; }
.ch360-person-id b{ font-size:12px; font-weight:700; color:var(--text-primary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ch360-person-id span{ font-size:10px; color:var(--text-tertiary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ch360-person-tag{ flex:0 0 auto; font-size:9px; font-weight:800; letter-spacing:0.03em; text-transform:uppercase; color:var(--text-tertiary); background:var(--surface-2); border:1px solid var(--line); border-radius:99px; padding:2px 7px; }
/* #1 (polish pass) — long emails / card URLs must never escape the card:
   wrap anywhere, and stop indenting the detail block on narrow lanes. */
.ch360-person-more{ display:none; padding:0 12px 10px 12px; font-size:11px; line-height:1.7; color:var(--text-secondary); min-width:0; overflow-wrap:anywhere; word-break:break-word; }
.ch360-person-more > div{ min-width:0; overflow-wrap:anywhere; }
.ch360-person-more a{ color:var(--violet); overflow-wrap:anywhere; word-break:break-word; }
.ch360-person.is-expanded .ch360-person-more{ display:block; }
.ch360-person-card{ margin-top:4px; padding-top:4px; border-top:1px solid var(--line); }
.ch360-inline-tag{ font-size:9.5px; font-weight:800; letter-spacing:0.03em; text-transform:uppercase; color:var(--cyan); }

/* #1 (Dock freeze pass) — Schedule Meeting's up-to-5-contact list. Each row
   is the SAME .ch360-person card Users & Team uses (border/background/
   radius come from that shared class); only the browser's native <button>
   defaults need resetting here so a clickable row looks identical to the
   plain-div rows elsewhere. */
.ch360-sched-contacts{ display:flex; flex-direction:column; gap:6px; margin-bottom:10px; }
button.ch360-sched-contact{ display:block; width:100%; margin:0; padding:0; font:inherit; text-align:left; cursor:pointer; -webkit-appearance:none; appearance:none; }
.ch360-sched-more{ font-size:11px; text-align:center; padding-top:2px; }

/* #10 — address block inside a prop value */
.ch360-prop-v br + *{ }
.ch360-acctcard .ch360-prop-v{ font-weight:500; line-height:1.55; }

/* order/invoice builder — bill-to, quick-adds, ship, pay actions */
.ch-builder-bill{ display:flex; gap:12px; font-size:11.5px; line-height:1.55; color:var(--text-secondary); background:var(--surface-1); border:1px solid var(--line); border-radius:10px; padding:10px 12px; margin-bottom:12px; }
.ch-builder-bill-k{ flex:0 0 auto; font-size:9.5px; font-weight:800; letter-spacing:0.04em; text-transform:uppercase; color:var(--text-tertiary); padding-top:2px; }
.ch-builder-adds{ display:flex; gap:7px; margin-top:9px; }
.ch-builder-ship{ margin-top:12px; padding:10px 12px; border:1px solid var(--line); border-radius:10px; background:var(--surface-1); }
.ch-builder-ship-l{ display:flex; align-items:center; gap:8px; font-size:12px; font-weight:600; color:var(--text-secondary); cursor:pointer; }
.ch-builder-ship-addr{ font-size:11px; color:var(--text-tertiary); line-height:1.5; margin-top:6px; padding-left:24px; }
.ch-pay-actions{ display:flex; gap:6px; flex-wrap:wrap; }
.ch-pay-actions .leads-btn{ font-size:11px; padding:7px 10px; }

/* Client 360 — Billing footer */
/* #1/#3 (Dock freeze pass) — the note composer itself is Orbit's own
   .lead-note-composer (see chNoteComposerHtml); this only fits that fixed
   footer into Dock's workspace shell, matching Full Contact's own
   .ch360-grid .lead-lane-center rules (this file, ~line 7490): the scroll
   region (.ch360-scroll) is flex:1 1 auto/min-height:0 and already sits
   ABOVE this in the DOM, so .lead-note-composer's flex:0 0 auto is all it
   needs to stay pinned — its own top border is the "visual divider". */
.ch360-workspace{ display:flex; flex-direction:column; }
.ch360-workspace > .lead-note-composer{ margin-left:0; margin-right:0; }
.ch360-notes-lg{ display:flex; flex-direction:column; gap:9px; }
/* #12 (Dock UX/safety pass) — Billing's content (invoice list → warning →
   New Invoice → balances) is NOT wrapped in .ch360-tabpanel like Cards/
   Accessories/Orders are (its own layout, built #6), so it doesn't inherit
   that shared gap — these are direct children of .ch360-scroll specifically
   there, scoped narrowly so it doesn't double up with .ch360-tabpanel's own
   gap on the tabs that DO use it. */
.ch360-scroll > .lead-backend-note, .ch360-scroll > .ch360-tabfoot{ margin-top:12px; }
.ch360-billfoot{ margin-top:14px; border-top:1px solid var(--line); padding-top:10px; display:flex; flex-direction:column; gap:5px; }
/* #6 (follow-up pass) — Billing tab only: extra breathing room above the
   Open balance/Overdue block now that New Invoice/the warning note sit
   above it, so balances read as a distinct closing summary. */
.ch360-billfoot-spaced{ margin-top:28px; }
.ch360-billfoot-row{ display:flex; align-items:center; justify-content:space-between; font-size:12.5px; color:var(--text-secondary); }
.ch360-billfoot-row b{ color:var(--text-primary); font-weight:800; }
.ch360-billfoot-row b.is-bad{ color:var(--bad); }
/* #16 (Dock freeze pass) — Open Balance = pending revenue, not a problem. */
.ch360-billfoot-row b.is-good{ color:var(--good); }

@media (max-width:1180px){
  .ch360-metrics{ grid-template-columns:repeat(2,1fr); }
  .ch360-cardrow{ flex-direction:column; }
  .ch360-cardrow-acts{ flex-direction:row; flex-wrap:wrap; }
}

/* ===== Dock — New Order wizard (#11-#17) ================================
   Customer → Order → Payment, inside the shared .lead-sheet / .lead-sheet-xl
   dialog. Provider-specific payment code stays out of this styling too —
   the "collect now" panel is an honest placeholder, not a real form. */
.ch-wiz-steps{ display:flex; align-items:center; gap:6px; padding:14px 20px 4px; }
.ch-wiz-step{
  display:flex; align-items:center; gap:7px; font:inherit; background:none; border:none; padding:2px 0; cursor:pointer;
  color:var(--text-tertiary); opacity:0.6;
}
.ch-wiz-step:disabled{ cursor:default; }
.ch-wiz-step.is-active, .ch-wiz-step.is-done{ opacity:1; }
.ch-wiz-step-n{
  flex:0 0 auto; width:20px; height:20px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-size:10.5px; font-weight:800; background:var(--surface-2); border:1px solid var(--line-strong); color:var(--text-tertiary);
}
.ch-wiz-step.is-active .ch-wiz-step-n{ background:var(--violet); border-color:var(--violet); color:#fff; }
.ch-wiz-step.is-done .ch-wiz-step-n{ background:color-mix(in srgb, var(--violet) 18%, transparent); border-color:var(--violet-dim); color:var(--violet); }
.ch-wiz-step-l{ font-size:12px; font-weight:700; color:inherit; }
.ch-wiz-step.is-active .ch-wiz-step-l{ color:var(--text-primary); }
.ch-wiz-step-line{ flex:1 1 24px; height:1px; background:var(--line); min-width:16px; }
.ch-wiz-body{ max-height:60vh; overflow-y:auto; }
.ch-wiz-sechead{ font-size:10.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary); margin:14px 0 8px; }
.ch-wiz-sechead:first-child{ margin-top:0; }

.ch-wf-grid{ display:grid; grid-template-columns:1fr 1fr; gap:10px 14px; }
.ch-wf-row{ display:flex; flex-direction:column; gap:4px; grid-column:1 / -1; }
.ch-wf-row.is-half{ grid-column:span 1; }
.ch-wf-row label{ font-size:10.5px; font-weight:700; color:var(--text-tertiary); }
.ch-wf-opt{ font-weight:500; text-transform:none; letter-spacing:0; color:var(--text-tertiary); }
.ch-wf-row .lead-input, .ch-wf-row .lead-select{ font-size:12.5px; }
.ch-wf-row.is-invalid .lead-input, .ch-wf-row.is-invalid .lead-select{ border-color:var(--bad); }
.ch-wf-err{ font-size:10.5px; font-weight:600; color:var(--bad); }
.ch-wf-err-block{ margin:-4px 0 10px; }
.ch-wiz-samecheck{ display:flex; align-items:center; gap:8px; font-size:12px; font-weight:600; color:var(--text-secondary); margin:12px 0 2px; cursor:pointer; }

.ch-wiz-items{ display:flex; flex-direction:column; gap:10px; }
.ch-wiz-line{ border:1px solid var(--line); border-radius:11px; background:var(--surface-1); padding:11px 12px; display:flex; flex-direction:column; gap:8px; }
.ch-wiz-line-top{ display:grid; grid-template-columns:1.1fr 1.4fr 1.2fr auto; gap:8px; align-items:center; }
.ch-wiz-line-top .lead-select, .ch-wiz-line-top .lead-input{ font-size:12px; }
.ch-wiz-line-grid{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:8px 10px; }
.ch-wiz-line-grid .ch-wf-row{ grid-column:span 1; gap:3px; }
.ch-wiz-line-grid .lead-input, .ch-wiz-line-grid .lead-select{ font-size:12px; padding:6px 8px; }
/* #14 — Taxable: label + .sa-switch, matching the platform's existing
   toggle language instead of a raw checkbox. */
.ch-wf-taxrow{ flex-direction:row; align-items:center; justify-content:space-between; gap:8px; padding-top:16px; }
.ch-wf-taxrow label{ margin:0; }
/* #15 — per-line internal note + the order-level note: real multiline
   fields, vertical-only resize so they can never widen the wizard column. */
.ch-wiz-line-note{ font-size:11.5px; resize:vertical; min-height:44px; }
.ch-wiz-ordernote{ resize:vertical; min-height:84px; }
.ch-wiz-additem{ align-self:flex-start; margin:2px 0 0; }

.ch-wiz-summary{ margin-top:16px; border-top:1px solid var(--line); padding-top:12px; }
.ch-wiz-summary-h{ font-size:10.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary); margin-bottom:8px; }
.ch-wiz-summary-row{ display:flex; align-items:center; justify-content:space-between; font-size:12.5px; color:var(--text-secondary); padding:4px 0; }
.ch-wiz-summary-row b{ color:var(--text-primary); font-weight:700; }
.ch-wiz-summary-row.is-total{ border-top:1px solid var(--line); margin-top:5px; padding-top:8px; font-size:13.5px; }
.ch-wiz-summary-row.is-total b{ font-weight:800; font-size:14.5px; }

.ch-wiz-paytabs{ display:flex; gap:8px; margin-bottom:12px; }
.ch-wiz-paytab{
  flex:1 1 0; font:inherit; font-size:12.5px; font-weight:700; color:var(--text-secondary); text-align:center;
  background:var(--surface-1); border:1px solid var(--line-strong); border-radius:10px; padding:11px; cursor:pointer;
  transition:border-color .12s ease, color .12s ease, background .12s ease;
}
.ch-wiz-paytab.is-active{ color:var(--violet); border-color:var(--violet-dim); background:color-mix(in srgb, var(--violet) 10%, transparent); }
.ch-wiz-paymethods{ display:flex; gap:8px; margin-bottom:12px; }
.ch-wiz-paymethod{
  flex:1 1 0; font:inherit; font-size:12.5px; font-weight:700; color:var(--text-secondary); text-align:center;
  background:var(--surface-2); border:1px solid var(--line); border-radius:9px; padding:9px; cursor:pointer;
  transition:border-color .12s ease, color .12s ease;
}
.ch-wiz-paymethod.is-active{ color:var(--violet); border-color:var(--violet-dim); }
.ch-wiz-payplaceholder{ margin-bottom:4px; }
.ch-wiz-invoicepreview{ display:flex; flex-direction:column; gap:8px; margin-bottom:4px; }
/* #16 — provider-hosted-element placeholder: a distinct "secure zone" so it
   reads as an intentional integration point, not an unfinished form. Fields
   inside are disabled (see chWizardSecureFieldsHtml) — nothing here is ever
   collected or persisted. */
.ch-wiz-securebox{
  border:1px dashed var(--line-strong); border-radius:11px; background:var(--surface-1); padding:12px 14px; margin-bottom:10px;
}
.ch-wiz-securebox-head{
  display:flex; align-items:center; gap:7px; font-size:11px; font-weight:800; letter-spacing:0.03em; color:var(--text-secondary);
  margin-bottom:10px;
}
.ch-wiz-securebox-head svg{ width:13px; height:13px; stroke:var(--text-tertiary); fill:none; stroke-width:2; }
.ch-wiz-securebox-tag{
  margin-left:auto; font-size:9.5px; font-weight:800; letter-spacing:0.03em; text-transform:uppercase; color:var(--text-tertiary);
  background:var(--surface-2); border:1px solid var(--line); border-radius:99px; padding:3px 8px;
}
.ch-wiz-securebox .lead-input:disabled, .ch-wiz-securebox .lead-select:disabled{ opacity:0.55; cursor:not-allowed; }

.ch-wiz-foot{ flex-direction:column; align-items:stretch; gap:10px; }
.ch-wiz-foot-sum{ display:flex; gap:16px; font-size:12px; color:var(--text-secondary); }
.ch-wiz-foot-sum b{ color:var(--text-primary); font-weight:800; }
.ch-wiz-foot-btns{ display:flex; justify-content:flex-end; gap:8px; }

@media (max-width:720px){
  .ch-wf-grid, .ch-wiz-line-grid{ grid-template-columns:1fr; }
  .ch-wf-row.is-half{ grid-column:1 / -1; }
  .ch-wiz-line-top{ grid-template-columns:1fr; }
  .ch-wiz-foot-sum{ flex-direction:column; gap:4px; }
}

/* ---- Card Studio — top bar --------------------------------------------- */
#viewCardStudio{ display:flex; flex-direction:column; gap:8px; }
/* Card Studio is a fully anchored application workspace:
   - #1 — the page keeps its "CARD STUDIO" identity upper-left, but in a
     COMPACT single-line treatment (title only, no description, tight) so it
     costs ~20px, not ~60px.
   - #2 — .main's bottom padding is killed and the document locked so the
     page can NEVER scroll into empty space below the panels; only the
     internal panels scroll. The phone is scaled-to-fit in JS (csLayout) so
     it is always fully visible without a stage scrollbar.
   Scoped entirely to body/html.is-card-studio, desktop only. */
body.is-card-studio .page-title{ padding-top:0; gap:0; }
body.is-card-studio #pageDescText{ display:none; }
/* FINAL PASS — "Card Studio" is now the header's centerpiece: sized up from
   the prior compact 16px to 22px (the SAME size this exact type scale
   already uses one breakpoint down — see the shared .topbar-title h1,
   .page-title h1 tablet rule — a real step in the existing scale, not an
   arbitrary number) and taken out of the titlegroup's flex flow entirely so
   it can be centered against the FULL header width rather than whatever
   space is left over between the hamburger and the right-side controls
   (which differ in width from every other page). position:absolute +
   left:50%/top:50% + translate(-50%,-50%) on the title, anchored to
   .topbar itself (position:relative below, offset-free so it doesn't move),
   centers it mathematically regardless of how wide either side's controls
   are — true optical/page centering, not flex-leftover centering. */
body.is-card-studio .page-title h1{ font-size:22px; letter-spacing:0.08em; line-height:1.15; justify-content:center; text-align:center; }
body.is-card-studio .topbar{ margin:0 0 10px; min-height:44px; align-items:center; position:relative; }
body.is-card-studio #pageTitleGroup{ position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); margin:0; max-width:60%; }
@media (min-width:1181px){
  html.is-card-studio, body.is-card-studio{ overflow:hidden; height:100%; }
  body.is-card-studio .main{ padding-top:4px; padding-bottom:7px; height:100vh; overflow:hidden; display:flex; flex-direction:column; }
  body.is-card-studio #viewCardStudio{ flex:1 1 auto; min-height:0; }
}
.cs-topbar{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; padding:7px 12px; background:var(--surface-1); border:1px solid var(--line); border-radius:var(--radius-lg); }
/* MANUAL QA item-5 — the four header data blocks (Client / Card holder /
   Digital Card / State) now share ONE label+value scale: labels 10px,
   values 13px, so nothing reads as an afterthought. Still compact enough
   not to overflow the wrapping topbar. */
body.is-card-studio .cs-topbar-k{ font-size:10px; }
body.is-card-studio .cs-ctx-field{ gap:3px; }
body.is-card-studio .cs-client-select, body.is-card-studio .cs-status-select{ padding-top:5px; padding-bottom:5px; }
.cs-ctx{ display:flex; align-items:flex-end; gap:16px; flex-wrap:wrap; }
.cs-ctx-field{ display:flex; flex-direction:column; gap:4px; }
.cs-topbar-k{ font-size:10px; font-weight:700; letter-spacing:0.05em; text-transform:uppercase; color:var(--text-tertiary); }
/* Priority-2E — Card Studio HEADER selects only: centre the visible value.
   Symmetric horizontal padding so "centered" reads visually centered even
   with the chevron; native control, chevron, hover/focus, dimensions and
   dropdown behavior all unchanged. Not applied to any other select. */
.cs-client-select{ width:auto; min-width:150px; max-width:220px; padding:6px 28px; font-size:13px; text-align:center; text-align-last:center; }
.cs-status-select{ width:auto; min-width:110px; padding:6px 28px; font-size:13px; font-weight:700; text-align:center; text-align-last:center; }
.cs-client-select option, .cs-status-select option{ text-align:left; }   /* the open list stays left-aligned/native */
.cs-status-select.is-good{ color:var(--good); }
.cs-url{ display:inline-flex; align-items:center; gap:6px; max-width:230px; padding:6px 10px; border:1px solid var(--line); border-radius:8px; background:var(--surface-2); font:inherit; font-size:12.5px; font-weight:600; color:var(--text-secondary); cursor:pointer; }
.cs-url svg{ width:12px; height:12px; flex:0 0 auto; stroke:var(--violet); fill:none; stroke-width:2; }
.cs-url span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cs-url:hover{ border-color:var(--violet); }
.cs-ctx-acc{ display:inline-flex; align-items:center; gap:5px; padding:6px 9px; border-radius:8px; background:color-mix(in srgb, var(--cyan) 12%, transparent); font-size:11px; font-weight:700; color:var(--text-secondary); align-self:center; }
.cs-ctx-acc svg{ width:13px; height:13px; stroke:var(--cyan); fill:none; stroke-width:2; }
/* VQA — the action cluster is Card Studio's TOP-RIGHT header spot. On a
   laptop-width viewport the topbar wraps to two rows; margin-left:auto keeps
   this cluster pinned to the right edge whether it's inline or wrapped, so
   Save/Publish never fall back to a left-aligned "old placement". */
.cs-topbar-r{ display:flex; align-items:center; justify-content:flex-end; gap:8px; flex-wrap:wrap; margin-left:auto; }
.cs-topbar-r > *{ flex:0 0 auto; }
/* FINAL QA — the action cluster is ALWAYS last and right-aligned, even if the
   whole .cs-topbar-r wraps to its own row. */
.cs-action-group{ margin-left:auto; }
/* #9-13 (Dock final visual freeze) — Card-Studio-specific action styling,
   replacing the generic cross-app leads-btn classes that made these read
   as lower-quality than the rest of the page. Same top-right header spot
   (.cs-topbar-r is already Card Studio's own header/actions area — this
   is a visual refinement, not a relocation). */
.cs-action-group{ display:flex; align-items:center; gap:8px; }
.cs-action-btn{
  display:inline-flex; align-items:center; gap:6px; font:inherit; font-size:12.5px; font-weight:700;
  padding:8px 15px; border-radius:9px; cursor:pointer; white-space:nowrap;
  border:1px solid var(--line-strong); background:var(--surface-2); color:var(--text-secondary);
  transition:background .14s ease, border-color .14s ease, color .14s ease, transform .14s ease, box-shadow .14s ease;
}
.cs-action-btn svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.6; }
.cs-action-btn:hover{ color:var(--text-primary); border-color:var(--violet-dim); background:var(--surface-hover); }
.cs-action-btn:active{ transform:translateY(1px); }
/* CORRECTION PASS 9 — the violet/purple design from Correction Pass 5 is
   eliminated per explicit direction: green (the SAME --good token
   .cs-action-btn.is-publish below already uses — not touched, not
   redesigned) is the approved Save color, never violet/blue. ONE
   authoritative component selector still owns every paint property for
   this button: .cs-action-btn.cs-save-primary / #csSaveDraftBtn.cs-save-primary.
   .is-save (still on the button, see csActionGroupInnerHtml()) remains a
   pure identity/state marker with zero visual declarations of its own —
   nothing for it to fall back to. .cs-action-btn stays layout/typography
   only. Fixed regardless of accent/theme/preset/icon-style, since none of
   those are referenced here. */
.cs-action-btn.cs-save-primary,
#csSaveDraftBtn.cs-save-primary{
  background:var(--good);
  border:1px solid transparent;
  color:#04120c;
  box-shadow:
    0 1px 0 0 rgba(255,255,255,0.22) inset,
    0 4px 14px -6px rgba(51,214,159,0.55);
}
.cs-action-btn.cs-save-primary:hover{
  transform:translateY(-1px);
  box-shadow:
    0 1px 0 0 rgba(255,255,255,0.26) inset,
    0 6px 18px -6px rgba(51,214,159,0.62);
}
.cs-action-btn.cs-save-primary:active{
  transform:translateY(1px);
  box-shadow:
    0 1px 0 0 rgba(255,255,255,0.18) inset,
    0 3px 10px -6px rgba(51,214,159,0.5);
}
.cs-action-btn.cs-save-primary:focus-visible{ outline:2px solid var(--good); outline-offset:2px; }
.cs-action-btn.cs-save-primary svg{ stroke:#04120c; }
/* FINAL FREEZE — while the card is DIRTY, Publish steps back to a quiet
   outline (never the flat grey filled .cs-action-btn base, which is what the
   user was reading as "the old plain grey Save button"). Save is the single
   loud action; Publish returns to its green pulse the moment the card is
   clean again. */
.cs-action-btn.is-ghost{
  background:transparent; border-color:var(--line); color:var(--text-tertiary);
  box-shadow:none;
}
.cs-action-btn.is-ghost:hover{ color:var(--text-secondary); border-color:var(--line-strong); background:transparent; }
/* Publish, only visually "primary" once there's nothing left to save —
   Save and Publish are never both the loud action at the same time, so
   which one to reach for is never ambiguous. */
/* #14/#15 (data-safety pass) — a slow, restrained ambient glow, not a
   flashing badge: the box-shadow breathes between a tight and a wider soft
   green halo. Paused (not just slowed) on hover so it never fights the
   hover state's own shadow, and removed entirely under
   prefers-reduced-motion — the static green fill/emphasis stays either way.
   #H (font pass follow-up) — made more noticeable per feedback: bigger
   blur/spread swing on the ambient layer so it actually reads as a halo
   "blooming" behind the button rather than a thin fading ring; the button's
   own fill/text never animate (no flashing), only the shadow does. */
.cs-action-btn.is-publish{
  background:var(--good); color:#04120c; border-color:transparent;
  animation:csPublishPulse 2.4s ease-in-out infinite;
}
.cs-action-btn.is-publish:hover{
  transform:translateY(-1px); box-shadow:0 10px 26px -6px color-mix(in srgb, var(--good) 65%, transparent);
  animation-play-state:paused;
}
@keyframes csPublishPulse{
  0%, 100% {
    box-shadow:
      0 0 14px 2px color-mix(in srgb, var(--good) 35%, transparent),
      0 4px 14px -6px color-mix(in srgb, var(--good) 48%, transparent);
  }
  50% {
    box-shadow:
      0 0 36px 10px color-mix(in srgb, var(--good) 58%, transparent),
      0 6px 20px -4px color-mix(in srgb, var(--good) 65%, transparent);
  }
}
@media (prefers-reduced-motion: reduce){
  .cs-action-btn.is-publish{ animation:none; box-shadow:0 0 22px 4px color-mix(in srgb, var(--good) 45%, transparent), 0 4px 16px -6px color-mix(in srgb, var(--good) 55%, transparent); }
}
/* Restrained amber dot + label — not a banner, not a giant pill. */
.cs-unsaved-pill{
  display:inline-flex; align-items:center; gap:6px; font-size:11.5px; font-weight:700; color:var(--warn);
  padding:5px 10px; border-radius:99px; background:color-mix(in srgb, var(--warn) 14%, transparent);
  border:1px solid color-mix(in srgb, var(--warn) 30%, transparent);
  animation:csUnsavedIn .16s cubic-bezier(.22,1,.36,1);
}
.cs-unsaved-dot{ width:6px; height:6px; border-radius:50%; background:var(--warn); flex:0 0 auto; }
@keyframes csUnsavedIn{ from{ opacity:0; transform:translateY(-2px) scale(.96); } to{ opacity:1; transform:none; } }

/* #E (data-safety pass) — unsaved-leave confirmation. Explicitly NOT
   window.confirm() and NOT a full-screen takeover: a small centered GLASS
   FLOAT card, same material as .cs-cpick's popover, sized to its content. */
.cs-leave-scrim{
  position:fixed; inset:0; z-index:260; background:rgba(4,5,10,0.44);
  display:flex; align-items:center; justify-content:center; padding:20px;
  opacity:0; pointer-events:none; transition:opacity .16s ease;
}
[data-theme="light"] .cs-leave-scrim{ background:rgba(28,27,64,0.28); }
.cs-leave-scrim.is-open{ opacity:1; pointer-events:auto; }
.cs-leave-dialog{
  width:min(320px, 100%); padding:18px 18px 16px; border-radius:16px;
  background:var(--glass-float-glare), var(--glass-float-bg);
  border:1px solid var(--glass-float-edge);
  box-shadow:var(--glass-float-shadow);
  -webkit-backdrop-filter:blur(var(--glass-float-blur)) saturate(var(--glass-float-sat));
  backdrop-filter:blur(var(--glass-float-blur)) saturate(var(--glass-float-sat));
  transform:translateY(6px) scale(.98); opacity:0;
  transition:transform .16s cubic-bezier(.22,1,.36,1), opacity .16s ease;
}
.cs-leave-scrim.is-open .cs-leave-dialog{ transform:none; opacity:1; }
.cs-leave-t{ font-size:14px; font-weight:800; color:var(--text-primary); margin-bottom:5px; }
.cs-leave-s{ font-size:12px; color:var(--text-secondary); line-height:1.45; margin-bottom:15px; }
.cs-leave-actions{ display:flex; flex-direction:column; gap:7px; }
.cs-leave-btn{
  font:inherit; font-size:12.5px; font-weight:700; padding:9px 14px; border-radius:9px; cursor:pointer;
  border:1px solid var(--glass-control-edge); background:var(--glass-control-bg); color:var(--text-secondary);
  transition:background .14s ease, border-color .14s ease, color .14s ease, transform .14s ease;
}
.cs-leave-btn:hover{ color:var(--text-primary); border-color:var(--line-strong); }
.cs-leave-btn:active{ transform:translateY(1px); }
.cs-leave-btn.is-discard{ color:var(--bad); border-color:color-mix(in srgb, var(--bad) 32%, transparent); }
.cs-leave-btn.is-discard:hover{ background:color-mix(in srgb, var(--bad) 12%, transparent); border-color:var(--bad); }
.cs-leave-btn.is-save{
  color:#fff; border-color:transparent;
  background:linear-gradient(135deg, var(--violet), color-mix(in srgb, var(--violet) 55%, var(--cyan)));
  box-shadow:0 6px 16px -8px color-mix(in srgb, var(--violet) 65%, transparent);
}
.cs-leave-btn.is-save:hover{ transform:translateY(-1px); box-shadow:0 9px 20px -8px color-mix(in srgb, var(--violet) 70%, transparent); }
.cs-leave-btn.is-save:active{ transform:translateY(1px); }

/* ---- Card Studio — three-panel workspace (#17 full height) ------------- */
/* #21-23 (Dock freeze pass) — --cs-lane-l/--cs-lane-r (set inline per
   render, see renderCardStudioAdmin/csLaneW) replace the old fixed 250px/
   310px; the 12px gaps become explicit grid tracks (same 12px, NOT wider)
   so a .cs-resize-handle can live inside each one without adding any new
   space between panels. */
.cs-workspace{ display:grid; grid-template-columns:var(--cs-lane-l,300px) 12px minmax(0,1fr) 12px var(--cs-lane-r,320px); gap:0; align-items:stretch; min-height:0; }
@media (min-width:1181px){ .cs-workspace{ flex:1 1 auto; } }
/* At rest: nearly invisible — a thin line only appears on hover/drag, and
   only inside the existing gutter (no gap-widening). */
.cs-resize-handle{ position:relative; cursor:col-resize; }
.cs-resize-handle::after{
  content:""; position:absolute; top:10px; bottom:10px; left:50%; width:2px; transform:translateX(-50%);
  border-radius:2px; background:var(--line-strong); opacity:0; transition:opacity .15s ease, background-color .15s ease;
}
.cs-resize-handle:hover::after, .cs-resize-handle.is-dragging::after{ opacity:1; background:var(--violet); }
.cs-resize-handle.is-dragging{ cursor:col-resize; }
body.is-lane-resizing{ cursor:col-resize; user-select:none; }
/* min-width:0 — .cs-panel is a grid item of .cs-workspace; grid/flex items
   default to min-width:auto (won't shrink below their content's intrinsic
   width), which is exactly what let the swatch strip's wide content push
   the Inspector panel wider instead of scrolling inside it (see
   .cs-inspector-body below). */
.cs-panel{ background:var(--surface-1); border:1px solid var(--line); border-radius:var(--radius-lg); padding:14px; display:flex; flex-direction:column; min-height:0; min-width:0; overflow:hidden; }
.cs-panel-h{ font-size:10.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary); margin-bottom:9px; flex:0 0 auto; display:flex; align-items:center; gap:8px; }
.cs-preview-state{ font-size:9px; font-weight:800; letter-spacing:0.04em; padding:2px 7px; border-radius:99px; background:var(--surface-2); color:var(--text-tertiary); }
.cs-preview-state.is-good{ background:color-mix(in srgb, var(--good) 18%, transparent); color:var(--good); }
/* #12 (Dock final pass) — vertical scroll stays fully functional (wheel/
   trackpad/touch all still hit the native overflow:auto scroll); only the
   visible scrollbar chrome is hidden — it was sitting on top of content
   and reading as cheap. scrollbar-width:none covers Firefox, the
   ::-webkit-scrollbar rule covers Chrome/Safari. */
.cs-left-scroll{ overflow-y:auto; flex:1 1 auto; min-height:0; display:flex; flex-direction:column; gap:11px; scrollbar-width:none; -ms-overflow-style:none; }
.cs-left-scroll::-webkit-scrollbar{ display:none; }
.cs-section-list{ display:flex; flex-direction:column; gap:2px; }
.cs-panel-center{ align-items:stretch; }
/* #3/#6 — phone vertically CENTERED in the free space = balanced breathing
   room above & below. csLayout() scales it to fit, so overflow:hidden is
   safe (no stray scrollbar, no clipping). */
.cs-preview-stage{ flex:1 1 auto; min-height:0; overflow:hidden; width:100%; display:flex; justify-content:center; align-items:center; padding:0; }
/* #13 (Dock final pass) — overflow-y:auto alone computes overflow-x as
   'auto' too per spec (an axis left at its 'visible' initial value gets
   forced to 'auto' the moment the OTHER axis is non-visible), so any
   over-wide descendant (the accent swatch strip's width:max-content row —
   see .cs-swatch-scroll below) was surfacing as a horizontal scrollbar on
   the whole Inspector body. min-width:0 breaks the flex/grid "min-width:auto"
   chain that let that width escape upward in the first place; overflow-x:
   hidden is the explicit backstop so this panel can never scroll sideways
   even if some other future control is briefly too wide. */
.cs-inspector-body{ overflow-y:auto; overflow-x:hidden; flex:1 1 auto; min-height:0; min-width:0; }

/* #4 — left-panel card-details block */
.cs-meta{ flex:0 0 auto; border:1px solid var(--line); border-radius:10px; padding:11px 12px; background:var(--surface-2); display:flex; flex-direction:column; gap:8px; }
.cs-meta-h{ font-size:9.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary); }
.cs-meta-field{ display:flex; flex-direction:column; gap:3px; }
.cs-meta-field span{ font-size:10px; font-weight:700; color:var(--text-tertiary); }
.cs-meta-field .lead-input{ padding:6px 9px; font-size:12px; }
.cs-meta-row{ display:flex; justify-content:space-between; gap:8px; font-size:10.5px; color:var(--text-tertiary); }
.cs-meta-row b{ color:var(--text-secondary); font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.cs-section-sub{ flex:0 0 auto; font-size:9.5px; font-weight:800; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-tertiary); }
.cs-section-sub-c{ font-weight:600; letter-spacing:0; text-transform:none; opacity:0.7; }

/* #4 — right-panel readiness widget (pinned below the inspector) */
.cs-ready{ flex:0 0 auto; margin-top:12px; padding-top:12px; border-top:1px solid var(--line); }
.cs-ready-h{ display:flex; justify-content:space-between; align-items:baseline; font-size:10px; font-weight:800; letter-spacing:0.05em; text-transform:uppercase; color:var(--text-tertiary); margin-bottom:6px; }
.cs-ready-h b{ font-size:12px; color:var(--text-primary); }
.cs-ready-track{ height:6px; border-radius:4px; background:var(--surface-2); overflow:hidden; margin-bottom:9px; }
.cs-ready-fill{ height:100%; border-radius:4px; background:linear-gradient(90deg,var(--violet),var(--cyan)); transition:width .3s ease; }
.cs-ready-list{ display:flex; flex-direction:column; gap:4px; }
.cs-ready-row{ display:flex; align-items:center; gap:7px; font-size:11px; color:var(--text-tertiary); }
.cs-ready-row.is-ok{ color:var(--text-secondary); }
.cs-ready-dot{ width:14px; height:14px; flex:0 0 auto; border-radius:50%; border:1px solid var(--line-strong); display:flex; align-items:center; justify-content:center; }
.cs-ready-row.is-ok .cs-ready-dot{ background:var(--good); border-color:var(--good); }
.cs-ready-dot svg{ width:9px; height:9px; stroke:#04120c; fill:none; stroke-width:3.2; }
.cs-ready-hint{ font-size:9.5px; color:var(--text-tertiary); opacity:0.8; }

@media (max-width:1180px){
  .cs-workspace{ grid-template-columns:1fr; height:auto !important; }
  .cs-panel{ overflow:visible; }
  .cs-left-scroll, .cs-section-list, .cs-preview-stage, .cs-inspector-body{ overflow:visible; max-height:none; }
  .cs-panel-left, .cs-panel-right{ order:2; }
  .cs-panel-center{ order:1; }
  /* #28 (Dock freeze pass) — single-column stack has no side-by-side lanes
     to resize; same pattern as Dock's own .lead-record-divider at this
     breakpoint. */
  .cs-resize-handle{ display:none; }
}

/* ---- Card Studio — centered preview composition (#3/#4/#6/#7) ---------
   top: pulse + "Live preview" + Draft/Published + device (centered)
   mid: phone (flex:1, vertically centered = balanced breathing room)
   bottom: action icon row (centered, below the phone) */
.cs-panel-center{ align-items:stretch; position:relative; }
/* FINAL PASS — the accessories badge's third and final home: absolutely
   positioned in the Live Preview panel's own top-right corner, comfortably
   inset from both edges. position:relative above is the ONLY change to
   .cs-panel-center itself (establishes the containing block; no offset, so
   it doesn't move) — an absolutely positioned element is removed from
   normal flow entirely, so it cannot affect .cs-preview-top's centered
   content, the phone's measured size, or csLayout()'s fit math. */
.cs-panel-acc{ position:absolute; top:14px; right:14px; z-index:2; }
.cs-preview-top{ flex:0 0 auto; display:flex; flex-direction:column; align-items:center; gap:6px; margin-bottom:6px; }
.cs-preview-head-t{ display:inline-flex; align-items:center; gap:7px; font-size:10.5px; font-weight:800; letter-spacing:0.07em; text-transform:uppercase; color:var(--text-tertiary); }
.cs-preview-badges{ display:inline-flex; align-items:center; gap:7px; }
/* #7 — pulsing status light. RED = draft / not published, GREEN = the card
   is in the Published/Live state per Card Studio's status model. */
.cs-preview-pulse{ width:8px; height:8px; border-radius:50%; flex:0 0 auto; position:relative; }
.cs-preview-pulse.is-draft{ background:var(--bad); box-shadow:0 0 0 0 color-mix(in srgb, var(--bad) 60%, transparent); animation:csPulse 2.2s ease-out infinite; }
.cs-preview-pulse.is-live{ background:var(--live-green, var(--good)); box-shadow:0 0 0 0 color-mix(in srgb, var(--good) 60%, transparent); animation:csPulse 2.2s ease-out infinite; }
@keyframes csPulse{
  0%{ box-shadow:0 0 0 0 currentColor; }
  70%{ box-shadow:0 0 0 7px transparent; }
  100%{ box-shadow:0 0 0 0 transparent; }
}
.cs-preview-pulse.is-draft{ color:color-mix(in srgb, var(--bad) 55%, transparent); }
.cs-preview-pulse.is-live{ color:color-mix(in srgb, var(--good) 55%, transparent); }
@media (prefers-reduced-motion:reduce){ .cs-preview-pulse{ animation:none; } }

.cs-preview-tools{ flex:0 0 auto; display:flex; gap:9px; justify-content:center; padding-top:11px; margin-top:9px; border-top:1px solid var(--line); }
.cs-ptool{ display:inline-flex; align-items:center; justify-content:center; width:32px; height:32px; font:inherit; color:var(--text-secondary); background:var(--surface-2); border:1px solid var(--line); border-radius:9px; cursor:pointer; transition:border-color .12s ease, color .12s ease, background .12s ease; }
.cs-ptool svg{ width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:2; }
.cs-ptool:hover{ border-color:var(--violet); color:var(--violet); }
.cs-ptool.is-on{ border-color:var(--violet); color:var(--violet); background:color-mix(in srgb, var(--violet) 10%, var(--surface-2)); }
/* #5 — the preview action hover labels ~30% bigger + pointing UP (the row
   sits at the bottom of the panel). */
.cs-preview-tools [data-tip]::after{
  top:auto; bottom:calc(100% + 10px); font-size:13px; padding:8px 13px; line-height:1.4; border-radius:9px;
}
.cs-preview-tools [data-tip]::before{ top:auto; bottom:calc(100% + 5px); transform:translateX(-50%) rotate(225deg); }
.cs-qr-panel{ flex:0 0 auto; display:flex; flex-direction:column; align-items:center; gap:6px; padding-top:10px; margin-top:9px; border-top:1px solid var(--line); }
.cs-qr-panel img{ width:150px; height:150px; border-radius:10px; background:#fff; padding:8px; }
.cs-qr-cap{ font-size:10.5px; color:var(--text-tertiary); font-weight:600; }
.cs-preview-phone, .cs-preview-desktop{ --cs-weight:600; --cs-scale:1; --cs-font-optical:1; --cs-btn-radius:9px; --cs-card-border:1px; --cs-card-glow:none; --cs-section-gap:14px; }
/* FINAL QA #9 — Heading weight reaches every MAJOR heading, not just the
   display name. Body copy is deliberately left alone. */
.cs-preview-phone .dc-card-name, .cs-preview-desktop .dc-card-name,
.cs-preview-phone .dc-card-company, .cs-preview-desktop .dc-card-company,
.cs-preview-phone .cs-preview-text b, .cs-preview-desktop .cs-preview-text b,
.cs-preview-phone .cs-preview-footer b, .cs-preview-desktop .cs-preview-footer b,
.cs-preview-phone .cs-preview-offer b, .cs-preview-desktop .cs-preview-offer b{ font-weight:var(--cs-weight); }
/* FINAL QA #8 — Text scale. The preview's typography is in px, so a single
   em-based rule on .dc-card did nothing. Each relevant text element is now
   scaled explicitly from its own base size. Icons / boxes are NOT scaled. */
/* CORRECTION PASS #1 — --cs-font-optical is a PER-FONT compensation
   multiplier (CS_FONT_LIB's `sizeAdj`, default 1), multiplied alongside
   --cs-scale (the operator's own Text Scale, untouched by this) so switching
   fonts keeps the holder's name/title reading as roughly the same size even
   though each family's real x-height/cap-height differs. Scoped to the
   identity heading only — body copy elsewhere is deliberately left alone. */
.cs-preview-phone .dc-card-name, .cs-preview-desktop .dc-card-name{ font-size:calc(16px * var(--cs-scale) * var(--cs-font-optical, 1)); }
.cs-preview-phone .dc-card-title, .cs-preview-desktop .dc-card-title{ font-size:calc(9px * var(--cs-scale) * var(--cs-font-optical, 1)); }
.cs-preview-phone .dc-card-company, .cs-preview-desktop .dc-card-company{ font-size:calc(11.5px * var(--cs-scale)); }
.cs-preview-phone .cs-preview-text b, .cs-preview-desktop .cs-preview-text b{ font-size:calc(11px * var(--cs-scale)); }
.cs-preview-phone .cs-preview-text p, .cs-preview-desktop .cs-preview-text p{ font-size:calc(10.5px * var(--cs-scale)); }
.cs-preview-phone .cs-preview-btn, .cs-preview-desktop .cs-preview-btn{ font-size:calc(10.5px * var(--cs-scale)); }
.cs-preview-phone .cs-preview-chip, .cs-preview-desktop .cs-preview-chip{ font-size:calc(9.5px * var(--cs-scale)); }
.cs-preview-phone .cs-preview-formfield, .cs-preview-desktop .cs-preview-formfield{ font-size:calc(10px * var(--cs-scale)); }
.cs-preview-phone .cs-preview-footer b, .cs-preview-desktop .cs-preview-footer b{ font-size:calc(11px * var(--cs-scale)); }
.cs-preview-phone .cs-preview-footer span, .cs-preview-desktop .cs-preview-footer span{ font-size:calc(10px * var(--cs-scale)); }
/* Button shape / Card border / Section spacing / Soft-glow all drive the live
   preview via CSS vars set in csPreviewVars(). */
.cs-preview-phone .dc-card-body, .cs-preview-desktop .dc-card-body{ gap:var(--cs-section-gap); }
.cs-preview-phone .dc-card, .cs-preview-desktop .dc-card{
  border:var(--cs-card-border) solid rgba(255,255,255,0.16);
  box-shadow:var(--cs-card-glow);
}
.cs-preview-cta{ display:flex; flex-direction:column; gap:6px; padding:10px 4px; }
.cs-preview-btn{ display:block; text-align:center; font-size:10.5px; font-weight:700; color:#fff; border-radius:var(--cs-btn-radius, 9px); padding:8px; }
.cs-preview-chip{ border-radius:var(--cs-btn-radius, 99px); }
/* FINAL QA #10 — button radius also reaches the form fields (they're the only
   other genuinely button/input-shaped surfaces in the preview). */
.cs-preview-phone .cs-preview-formfield, .cs-preview-desktop .cs-preview-formfield{ border-radius:var(--cs-btn-radius, 7px); }
.cs-preview-btn.is-ghost{ background:rgba(255,255,255,0.08); }
/* MANUAL QA item-10 — Style tab grouping so the inspector isn't a wall. */
.cs-style-group{ margin-top:14px; padding-top:12px; border-top:1px solid var(--line); }
.cs-style-group:first-of-type{ margin-top:10px; }
.cs-style-group-h{ font-size:10px; font-weight:800; letter-spacing:0.09em; text-transform:uppercase; color:var(--text-tertiary); margin-bottom:9px; }
.cs-pb-opts{ display:grid; grid-template-columns:repeat(4, 1fr); gap:8px 6px; }
.cs-pb-opts .pb-swatch{ padding:4px 2px; }
.cs-cover-upload{ width:100%; justify-content:center; }

/* MANUAL QA item-7 — cover image control */
.cs-cover-ctrl{ display:flex; flex-direction:column; gap:8px; }
.cs-cover-thumb{ position:relative; width:100%; height:88px; border-radius:9px; overflow:hidden; border:1px solid var(--line); cursor:pointer; background:var(--surface-2); }
.cs-cover-thumb img{ position:absolute; top:50%; left:50%; width:100%; height:100%; object-fit:cover; }
.cs-cover-thumb-edit{
  position:absolute; inset:auto 0 0 0; display:flex; align-items:center; justify-content:center; gap:5px;
  padding:5px; font-size:10px; font-weight:700; color:#fff; background:linear-gradient(transparent, rgba(0,0,0,0.6));
}
.cs-cover-thumb-edit svg{ width:11px; height:11px; stroke:currentColor; fill:none; stroke-width:2.2; }
.cs-cover-thumb:hover{ border-color:var(--violet); }
.cs-cover-btns{ display:flex; gap:8px; }
.cs-cover-btns .leads-btn{ flex:1 1 0; justify-content:center; }
.cs-cover-remove{ color:var(--bad); }

/* FINAL QA #6 — Card-Studio-only hero geometry: more cover on top, avatar
   sits lower and overlaps the cover/body seam. Digital Card's own preview
   mini keeps its established proportions (not scoped here). */
.cs-preview-phone .dc-card-cover, .cs-preview-desktop .dc-card-cover{ height:118px; }
.cs-preview-phone .dc-card-photorow, .cs-preview-desktop .dc-card-photorow{ margin-top:-26px; }
.cs-preview-phone .dc-card-avatar, .cs-preview-desktop .dc-card-avatar{ width:74px; height:74px; }
/* FINAL QA #5 — cover is an <img> transformed by the positioning editor. */
.dc-card-cover-img{ position:absolute; top:50%; left:50%; width:100%; height:100%; object-fit:cover; }
.dc-card-cover-fill{ position:absolute; inset:0; }
/* FINAL QA #4 — card-holder photo fills the avatar (initials hidden by the
   existing .dc-card-avatar.has-photo span rule). */
.dc-card-avatar.has-photo::before{ background-image:var(--dc-preview-photo, none); }
/* CORRECTION PASS #3 — ROOT CAUSE of "only some border presets show the
   avatar correctly": .dc-card-avatar uses its OWN ::before for the actual
   photo/color fill (inset:2px, sits just inside the outer ring). Four of the
   eight profile-border presets (Pulse/Fire/24K/Diamond) ALSO redefine
   ::before on .pb-ring-host for a secondary highlight-sweep layer — and
   because this avatar is a .pb-ring-host, that preset rule's higher
   specificity silently replaced the avatar's own photo layer with the
   preset's decorative sweep, hiding the real/fallback avatar for exactly
   those four presets. (None/Orbit/Glow/Energy only ever used ::after, never
   touched ::before, which is why they always looked correct.) Restore the
   avatar's own ::before here with higher specificity than any preset rule so
   the real/fallback avatar always shows — the main ::after ring/glow for
   every preset is untouched and still fully surrounds it. */
.dc-card-avatar.pb-ring-host[data-pb]::before{
  content:""; position:absolute; inset:2px; border-radius:50%; z-index:auto;
  background:#0B0D16 var(--dc-preview-photo, none) center / cover no-repeat;
  box-shadow:none; animation:none; opacity:1; filter:none;
}

/* FINAL QA #2/#3 — Profile border as a horizontal swatch strip (like Accent
   color), with HALO swatches (transparent centre) instead of filled coins. */
.cs-pb-strip{ margin-top:2px; padding-top:9px; padding-bottom:9px; }
.cs-pb-strip-row{ display:flex; flex-wrap:nowrap; gap:5px; width:max-content; padding:2px; }
.cs-pb-strip .pb-swatch{ width:52px; flex:0 0 auto; padding:6px 2px 7px; }
.cs-pb-strip .pb-swatch-ring{ width:24px; height:24px; }
.cs-pb-strip .pb-swatch-ring{ position:relative; background:transparent; border:none; overflow:visible; }
.cs-pb-strip .pb-swatch-ring[data-pb="none"]{ border:1.5px dashed var(--line-strong); background:transparent; }
.cs-pb-strip .pb-swatch-hole{
  position:absolute; inset:4px; border-radius:50%; z-index:1;
  background:var(--surface-1);
  box-shadow:0 0 0 1px var(--surface-1);
}
/* 24K + Diamond keep a filled material centre — no punched hole. */
.cs-pb-strip .pb-swatch-ring[data-pb="gold24k"] .pb-swatch-hole,
.cs-pb-strip .pb-swatch-ring[data-pb="diamond"] .pb-swatch-hole,
.cs-pb-strip .pb-swatch-ring[data-pb="none"] .pb-swatch-hole{ display:none; }
[data-theme="light"] .cs-pb-strip .pb-swatch-hole{ background:var(--surface-2); box-shadow:0 0 0 1px var(--surface-2); }
/* FINAL FREEZE #8 — the real/fallback card-holder avatar previewed inside
   every ring (shown for ALL presets, including 24K/Diamond's filled-material
   look, unlike .pb-swatch-hole above which those two hide). Replaces the
   abstract coin/halo center with the identity the border will actually sit
   around. */
.cs-pb-strip .pb-swatch-avatar{
  position:absolute; inset:3px; border-radius:50%; z-index:2;
  background-size:cover; background-position:center;
  display:flex; align-items:center; justify-content:center;
  font-size:9px; font-weight:700; color:#fff; letter-spacing:0.01em;
}

/* FINAL QA #5 — COVER POSITIONING EDITOR (glass modal) */
.cs-cover-edit-scrim{
  position:fixed; inset:0; z-index:1200; display:flex; align-items:center; justify-content:center;
  padding:20px; background:rgba(6,6,12,0.62); -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
}
.cs-cover-edit{
  width:min(420px, 94vw); border-radius:16px; padding:18px; display:flex; flex-direction:column; gap:14px;
  background:var(--surface-1); border:1px solid var(--glass-panel-edge, var(--line-strong));
  box-shadow:0 24px 60px -12px rgba(0,0,0,0.6);
}
.cs-cover-edit-h{ font-size:14px; font-weight:800; color:var(--text-primary); }
.cs-cover-edit-viewport{
  position:relative; width:100%; aspect-ratio:2.1 / 1; border-radius:12px; overflow:hidden;
  background:#0b0b12; cursor:grab; touch-action:none; user-select:none;
}
.cs-cover-edit-viewport:active{ cursor:grabbing; }
.cs-cover-edit-viewport img{
  position:absolute; top:50%; left:50%; width:100%; height:100%; object-fit:cover; pointer-events:none;
}
/* The profile photo overlay — a true HALF-circle bump on the bottom edge,
   centred horizontally, matching where the real card avatar overlaps the
   cover. Its circle centre sits exactly on the bottom edge, so only the top
   half shows inside the viewport. Everything in this arc is hidden behind
   the photo on the live card. */
.cs-cover-edit-avatar{
  position:absolute; left:50%; bottom:0; transform:translate(-50%, 50%);
  width:42%; aspect-ratio:1; border-radius:50%;
  background:rgba(8,8,14,0.44); border:2px dashed rgba(255,255,255,0.92);
  box-shadow:0 0 0 2px rgba(0,0,0,0.35);
  pointer-events:none; display:flex; align-items:flex-start; justify-content:center;
}
.cs-cover-edit-avatar span{
  margin-top:14%; font-size:9px; font-weight:800; letter-spacing:0.05em; text-transform:uppercase;
  color:rgba(255,255,255,0.92); text-shadow:0 1px 3px rgba(0,0,0,0.7);
}
.cs-cover-edit-grid{
  position:absolute; inset:0; pointer-events:none;
  background-image:linear-gradient(rgba(255,255,255,0.14) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.14) 1px, transparent 1px);
  background-size:33.33% 33.33%;
}
.cs-cover-edit-hint{ margin:8px 0 0; font-size:11px; color:var(--text-tertiary); line-height:1.4; }
.cs-cover-edit-zoom{ display:flex; align-items:center; gap:10px; font-size:11px; font-weight:700; color:var(--text-secondary); }
.cs-cover-edit-zoom input[type="range"]{ flex:1 1 auto; accent-color:var(--violet); }
.cs-cover-edit-zoom span:last-child{ min-width:38px; text-align:right; color:var(--text-tertiary); }
.cs-cover-edit-btns{ display:flex; align-items:center; gap:8px; }

/* ---- Card Studio — theme presets (#18) ------------------------------- */
.cs-preset-row{ display:flex; flex-wrap:wrap; gap:6px; }
.cs-preset{ display:inline-flex; align-items:center; gap:6px; font:inherit; font-size:11px; font-weight:700; color:var(--text-secondary); background:var(--surface-2); border:1px solid var(--line); border-radius:8px; padding:5px 9px; cursor:pointer; }
.cs-preset:hover{ border-color:var(--violet); color:var(--text-primary); }
.cs-preset.is-active{ border-color:var(--violet); color:var(--text-primary); background:color-mix(in srgb, var(--violet) 12%, var(--surface-2)); box-shadow:0 0 0 1px var(--violet) inset; }
.cs-preset-dot{ width:9px; height:9px; border-radius:50%; flex:0 0 auto; }
.cs-note{ font-size:10.5px; color:var(--text-tertiary); line-height:1.5; margin:4px 0 0; }

/* #14/#16 — Card Studio selectors use the GLASS CONTROL material (closed
   control only; the native <select> option list is OS-rendered). Chevron
   arrows are layered on top of the glare gradient. */
#viewCardStudio .lead-select, #viewCardStudio .cs-client-select, #viewCardStudio .cs-status-select{
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  background-color:var(--glass-control-bg);
  background-image:var(--glass-control-glare),
    linear-gradient(45deg,transparent 50%,var(--text-tertiary) 50%),
    linear-gradient(135deg,var(--text-tertiary) 50%,transparent 50%);
  background-position:0 0, calc(100% - 16px) center, calc(100% - 11px) center;
  background-size:auto, 5px 5px, 5px 5px; background-repeat:no-repeat;
  border:1px solid var(--glass-control-edge);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.14);
  -webkit-backdrop-filter:blur(var(--glass-control-blur)) saturate(var(--glass-control-sat));
  backdrop-filter:blur(var(--glass-control-blur)) saturate(var(--glass-control-sat));
}
#viewCardStudio .lead-select:hover{ border-color:color-mix(in srgb, var(--violet) 40%, var(--glass-control-edge)); }
[data-theme="light"] #viewCardStudio .lead-select{ box-shadow:inset 0 1px 0 rgba(255,255,255,0.95), 0 1px 2px rgba(28,27,64,0.06); }

.cs-section-list{ display:flex; flex-direction:column; gap:2px; }
.cs-section-row{
  display:flex; align-items:center; gap:9px; padding:8px 8px 8px 9px; border-radius:9px; cursor:pointer;
  border:1px solid transparent; transition:background .12s ease, border-color .12s ease;
}
.cs-section-row:hover{ background:var(--surface-hover); }
.cs-section-row.is-selected{ background:color-mix(in srgb, var(--violet) 12%, transparent); border-color:color-mix(in srgb, var(--violet) 30%, transparent); }
.cs-section-row.is-hidden{ opacity:0.5; }
.cs-section-ic{ width:15px; height:15px; flex:0 0 auto; stroke:var(--text-secondary); fill:none; stroke-width:1.9; }
.cs-section-row.is-selected .cs-section-ic{ stroke:var(--violet); }
.cs-section-label{ flex:1 1 auto; font-size:12.5px; font-weight:600; color:var(--text-primary); }
.cs-section-actions{ display:flex; align-items:center; gap:2px; opacity:0; transition:opacity .12s ease; }
.cs-section-row:hover .cs-section-actions, .cs-section-row.is-selected .cs-section-actions{ opacity:1; }
.cs-mini-btn{
  width:20px; height:20px; border-radius:6px; display:flex; align-items:center; justify-content:center; cursor:pointer;
  background:none; border:none; color:var(--text-tertiary); transition:color .12s ease, background .12s ease;
}
.cs-mini-btn:hover{ color:var(--text-primary); background:var(--surface-2); }
.cs-mini-btn:disabled{ opacity:0.3; cursor:default; }
.cs-mini-btn svg{ width:12px; height:12px; stroke:currentColor; fill:none; stroke-width:2.2; }
.cs-add-section-btn{
  display:flex; align-items:center; justify-content:center; gap:6px; width:100%; margin-top:12px; padding:9px; border-radius:9px;
  font:inherit; font-size:12px; font-weight:700; color:var(--text-secondary); background:none; border:1px dashed var(--line-strong); cursor:pointer;
  transition:color .12s ease, border-color .12s ease, background .12s ease;
}
.cs-add-section-btn:hover{ color:var(--violet); border-color:var(--violet-dim); background:var(--surface-hover); }
.cs-add-section-btn svg{ width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:2.4; }

/* ---- Card Studio — center preview stage --------------------------------- */
.cs-panel-center{ display:flex; flex-direction:column; }
/* #4 — prominent preview device (real width, not a blurry base scale). A
   fit-to-stage scale is applied by csLayout() only when the viewport is
   genuinely short, so the whole phone is always visible. */
/* #21/#22 (Dock UX/safety pass) — a modest, Card-Studio-only bump over the
   shared .dc-phone base width (230px → 250px, ~9%) — a "small perceptible
   increase," not a new layout. The EXISTING shrink-to-fit logic in
   csLayout() (unchanged) still derives its scale from the actual stage's
   available height/width every render, so this bigger base still shrinks
   correctly on a short viewport or a narrowed middle lane — it never
   overrides that safety net, just gives it a slightly larger starting
   point to work from. The client-facing .dc-phone elsewhere is untouched.
   */
.cs-preview-phone{ width:250px; transform-origin:top center; margin:0 auto; flex:0 0 auto; }
.cs-preview-phone.dc-phone{ width:268px; }
.cs-preview-phone .dc-phone-screen{ box-shadow:inset 0 0 0 1px rgba(0,0,0,0.7), inset 0 0 26px rgba(0,0,0,0.5); }
.cs-preview-phone .dc-phone-screen::before{
  content:""; position:absolute; inset:0; z-index:7; pointer-events:none; border-radius:inherit;
  background:linear-gradient(146deg, rgba(255,255,255,0.11) 0%, rgba(255,255,255,0.03) 20%, rgba(255,255,255,0) 44%);
}
.cs-preview-phone, .cs-preview-phone *{ font-family:var(--cs-font, inherit); }
.cs-preview-devlabel{ font-size:9px; font-weight:800; letter-spacing:0.06em; color:var(--text-tertiary); padding:2px 7px; border-radius:99px; border:1px solid var(--line); }
@media (max-width:1180px){ .cs-preview-phone.dc-phone{ width:250px; } }
.cs-preview-block{ padding:10px 4px; border-top:1px solid rgba(255,255,255,0.08); }
.cs-preview-text b{ display:block; font-size:11px; color:#fff; margin-bottom:3px; }
.cs-preview-text p{ margin:0; font-size:10.5px; color:rgba(255,255,255,0.6); line-height:1.4; }
.cs-preview-video{ display:flex; align-items:center; justify-content:center; height:70px; border-radius:10px; background:rgba(255,255,255,0.06); }
.cs-preview-video svg{ width:26px; height:26px; fill:rgba(255,255,255,0.7); }
.cs-preview-social{ display:flex; gap:10px; justify-content:center; padding:12px 0; }
.cs-preview-social i{ width:28px; height:28px; border-radius:50%; display:flex; align-items:center; justify-content:center; background:rgba(255,255,255,0.08); }
.cs-preview-social svg{ width:13px; height:13px; stroke:#fff; fill:none; stroke-width:1.8; }
/* #19 (Dock final pass) — new canonical section types (offer/trust/
   projects/form/footer). Same dark-card phone aesthetic as the existing
   preview blocks above (hardcoded white/rgba — this mini-preview isn't
   theme-aware, matching the client-facing card it mocks). */
.cs-preview-offer{ margin-bottom:2px; }
.cs-preview-chips{ display:flex; flex-wrap:wrap; gap:6px; margin-top:4px; }
.cs-preview-chip{ font-size:9.5px; font-weight:700; padding:4px 8px; border-radius:99px; background:rgba(255,255,255,0.08); color:rgba(255,255,255,0.85); }
.cs-preview-form{ display:flex; flex-direction:column; gap:6px; margin-top:6px; }
.cs-preview-formfield{ font-size:10px; padding:7px 9px; border-radius:7px; background:rgba(255,255,255,0.06); color:rgba(255,255,255,0.45); }
.cs-preview-footer{ text-align:center; }
.cs-preview-footer span{ display:block; font-size:10px; color:rgba(255,255,255,0.5); margin-top:2px; }
.cs-preview-footer-social{ display:flex; gap:8px; justify-content:center; margin-top:8px; }
.cs-preview-footer-social i{ width:20px; height:20px; border-radius:50%; display:flex; align-items:center; justify-content:center; background:rgba(255,255,255,0.08); }
.cs-preview-footer-social svg{ width:10px; height:10px; stroke:#fff; fill:none; stroke-width:1.8; }
.cs-preview-desktop{ width:100%; max-width:520px; flex:0 0 auto; margin:0 auto; transform-origin:center center; border-radius:12px; overflow:hidden; border:1px solid var(--line-strong); font-family:var(--cs-font, inherit); }
/* Priority-3 parity with .cs-preview-phone * — force the chosen family onto
   every descendant so a client-card sub-rule can't shadow it in Desktop. */
.cs-preview-desktop *{ font-family:var(--cs-font, inherit); }
.cs-preview-desktop-chrome{ display:flex; gap:5px; padding:9px 11px; background:var(--surface-2); }
.cs-preview-desktop-chrome span{ width:8px; height:8px; border-radius:50%; background:var(--line-strong); }
/* CORRECTION PASS 2 #1 — ROOT CAUSE of "the preview sometimes shrinks after
   a preset": unlike .dc-phone-screen (fixed via aspect-ratio, content
   scrolls inside it — see .dc-phone-scroll), .cs-preview-desktop-body had NO
   height of its own; its height was whatever the card's content added up to.
   csLayout() scales the WHOLE frame down as one unit whenever its measured
   offsetHeight exceeds the available stage height — so a preset that simply
   enabled more/longer sections made the frame measure taller, which made
   csLayout() shrink the entire desktop mockup to compensate. Giving this
   body a FIXED height (matching the phone's own fixed-frame-content-scrolls
   pattern) means the frame's outer geometry is now content-independent in
   Desktop mode too — extra content scrolls inside it instead of resizing
   the whole preview. align-items:flex-start (not the flex default `stretch`)
   keeps a SHORT card sitting naturally at the top instead of being stretched
   to fill the fixed height. */
.cs-preview-desktop-body{
  padding:24px; background:#0e0e18; display:flex; justify-content:center; align-items:flex-start;
  height:600px; overflow-y:auto; overflow-x:hidden; -webkit-overflow-scrolling:touch; scrollbar-width:none;
}
.cs-preview-desktop-body::-webkit-scrollbar{ display:none; }
.cs-preview-desktop-card{ width:100%; max-width:300px; border-radius:16px; overflow:hidden; flex:0 0 auto; }

/* ---- Card Studio — right inspector --------------------------------------- */
.cs-inspector-tabs{ width:100%; margin-bottom:14px; }
.cs-inspector-tabs .sa-tf-btn{ flex:1 1 0; }
/* #13 (Dock final pass) — .lead-form-row (a flex column item here) also
   defaults to min-width:auto; without this, the swatch strip's intrinsic
   width:max-content content pushes ITS row wider instead of scrolling
   inside .cs-swatch-scroll, even with min-width:0 set higher up the chain. */
.cs-inspector-body{ display:flex; flex-direction:column; gap:12px; }
.cs-inspector-body .lead-form-row{ min-width:0; }
.cs-inspector-badge{ display:inline-flex; padding:6px 11px; border-radius:8px; background:var(--surface-2); font-size:12.5px; font-weight:700; color:var(--text-primary); }
.cs-layout-order{ display:flex; flex-direction:column; gap:4px; padding:10px 12px; border:1px solid var(--line); border-radius:9px; background:var(--surface-2); }
.cs-layout-order-row{ font-size:12px; color:var(--text-secondary); }
.cs-muted{ color:var(--text-tertiary); }
/* #8 — accent swatches live in a clean horizontal scroll row; the scroll
   container has side padding so the first & last swatch are never clipped by
   the panel edge. */
.cs-swatch-scroll{
  overflow-x:auto; overflow-y:hidden; margin:0 -4px; padding:3px 4px 6px; min-width:0;
  scrollbar-width:thin; scrollbar-color:var(--line-strong) transparent;
  overscroll-behavior-x:contain; -webkit-overflow-scrolling:touch;
}
.cs-swatch-scroll::-webkit-scrollbar{ height:5px; }
.cs-swatch-scroll::-webkit-scrollbar-thumb{ background:var(--line-strong); border-radius:99px; }
.cs-swatch-scroll::-webkit-scrollbar-track{ background:transparent; }
.cs-swatch-row{ display:flex; flex-wrap:nowrap; gap:9px; width:max-content; padding:2px; }
.cs-swatch{
  flex:0 0 auto; width:26px; height:26px; border-radius:50%; cursor:pointer; background:var(--sw); border:2px solid transparent;
  box-shadow:0 0 0 1px var(--line-strong); transition:transform .1s ease, box-shadow .12s ease;
  display:flex; align-items:center; justify-content:center; padding:0;
}
.cs-swatch:hover{ transform:scale(1.08); }
.cs-swatch.is-active{ border-color:var(--surface-1); box-shadow:0 0 0 2px var(--sw); }
/* #9 — the custom "+" swatch: a ring showing the current custom colour with
   a "+" (or a tick once a custom colour is active). */
.cs-swatch-custom{ background:var(--surface-1); box-shadow:0 0 0 1.5px var(--sw), inset 0 0 0 2px var(--surface-1); }
.cs-swatch-custom svg{ width:13px; height:13px; stroke:var(--text-secondary); fill:none; stroke-width:2.4; }
.cs-swatch-custom.is-active{ background:var(--sw); box-shadow:0 0 0 2px var(--sw); border-color:var(--surface-1); }
.cs-swatch-custom.is-active .cs-swatch-customtick{ stroke:#fff; }

/* #9 — in-app custom colour picker popover (GLASS FLOAT material) */
.cs-cpick{
  position:fixed; z-index:245; width:232px; padding:12px; border-radius:14px;
  background:var(--glass-float-glare), var(--glass-float-bg);
  border:1px solid var(--glass-float-edge);
  box-shadow:var(--glass-float-shadow);
  -webkit-backdrop-filter:blur(var(--glass-float-blur)) saturate(var(--glass-float-sat));
  backdrop-filter:blur(var(--glass-float-blur)) saturate(var(--glass-float-sat));
  animation:profileMenuIn .12s ease;
}
.cs-cpick-sv{
  position:relative; width:208px; height:132px; border-radius:9px; cursor:crosshair; touch-action:none;
  background:linear-gradient(to top, #000, rgba(0,0,0,0)), linear-gradient(to right, #fff, rgba(255,255,255,0)), var(--hue, #7C5CF6);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,0.25);
}
.cs-cpick-svknob{
  position:absolute; width:14px; height:14px; border-radius:50%; transform:translate(-50%,-50%);
  border:2px solid #fff; box-shadow:0 0 0 1px rgba(0,0,0,0.4), 0 2px 5px rgba(0,0,0,0.4); pointer-events:none;
}
.cs-cpick-hue{
  position:relative; width:208px; height:14px; margin-top:10px; border-radius:99px; cursor:pointer; touch-action:none;
  background:linear-gradient(to right,#f00 0%,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,#f00 100%);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,0.2);
}
.cs-cpick-hueknob{
  position:absolute; top:50%; width:16px; height:16px; border-radius:50%; transform:translate(-50%,-50%);
  background:#fff; box-shadow:0 0 0 1px rgba(0,0,0,0.3), 0 2px 5px rgba(0,0,0,0.4); pointer-events:none;
}
.cs-cpick-foot{ display:flex; align-items:center; gap:7px; margin-top:11px; }
.cs-cpick-prev{ flex:0 0 auto; width:24px; height:24px; border-radius:7px; box-shadow:inset 0 0 0 1px rgba(0,0,0,0.25); }
.cs-cpick-hex{ flex:1 1 auto; min-width:0; padding:6px 8px; font-size:12px; font-family:'JetBrains Mono',monospace; text-transform:uppercase; }
.cs-cpick-done{ flex:0 0 auto; padding:6px 10px; font-size:11.5px; }

[data-theme="light"] .ch-stat, [data-theme="light"] .ch-note, [data-theme="light"] .cs-topbar, [data-theme="light"] .cs-panel{ box-shadow:var(--shadow-card); }
