/* ─────────────────────────────────────────────────────────────────────────
   ZDIV2 — App-shell chrome design tokens.
   Adopted 1:1 from the STRUCZ Data Hub prototype (2026-05-14) so ZDIV2 +
   STRUCZ + ZED form one visual product family. Hex values, sizes, and class
   names match STRUCZ/wwwroot/css/site.css exactly — drift here means drift
   across the product, not just a single page.

   Layout: 220px navy sidebar (left) + 54px white topbar + light content +
   optional 340px ZED right rail (purple).
   ───────────────────────────────────────────────────────────────────────── */
:root {
    /* Chrome — dark navy sidebar + topbar accent */
    --dh-navy:       #071426;
    --dh-navy2:      #0D1E38;
    --dh-blue:       #1565BE;
    --dh-blue2:      #2178D4;
    --dh-blue-pale:  #EDF4FB;
    --dh-blue-mid:   #B0CEEC;
    --dh-silver:     #8AAED4;

    /* Content (light) */
    --dh-bg:         #EEF3F8;
    --dh-white:      #FFFFFF;
    --dh-text:       #1A2535;
    --dh-text2:      #4A6A8A;
    --dh-text3:      #8AAED4;
    --dh-border:     rgba(0,0,0,0.09);

    /* Status — muted forest tones, not the Tailwind defaults */
    --dh-green:      #27500A;
    --dh-green-pale: #EAF3DE;
    --dh-green-mid:  #3B6D11;
    --dh-amber:      #633806;
    --dh-amber-pale: #FAEEDA;
    --dh-amber-mid:  #BA7517;
    --dh-red:        #791F1F;
    --dh-red-pale:   #FCEBEB;
    --dh-red-mid:    #A32D2D;
    --dh-purple:     #3C3489;
    --dh-purple-pale:#EEEDFE;
    --dh-teal:       #085041;
    --dh-teal-pale:  #E1F5EE;

    /* ZED right-rail panel tokens (canonical mockup) */
    --dh-zed-bg:     #1a1030;
    --dh-zed-purple: #7B2FBE;
    --dh-zed-light:  #A855F7;
    --dh-zed-width:  340px;
}

/* Body baseline — DM Sans gives the enterprise-grade vibe Craig's after.
   Falls back through the macOS native stack if the webfont isn't loaded. */
html, body { height: 100%; margin: 0; padding: 0; }
body {
    font-family: 'DM Sans', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
                 "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background: var(--dh-bg);
    color: var(--dh-text);
    font-size: 14px;
    -webkit-font-smoothing: antialiased;
}
.font-mono, code, kbd, samp {
    font-family: 'DM Mono', ui-monospace, "SFMono-Regular", Menlo, Monaco, Consolas, monospace;
}

/* ─────────────────────────────────────────────────────────────────────────
   Left sidebar (220px navy)
   ───────────────────────────────────────────────────────────────────────── */
.dh-shell { display: flex; min-height: 100vh; }

.dh-sidebar {
    position: fixed; top: 0; left: 0; bottom: 0;
    width: 220px;
    background: var(--dh-navy2);
    border-right: 1px solid rgba(255,255,255,0.06);
    display: flex; flex-direction: column;
    z-index: 100;
    overflow-y: auto;
}
.dh-sidebar-logo {
    padding: 22px 18px 16px;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    /* Subtle radial highlight behind the wordmark gives it a hint of
       embossed presence on the flat navy — keeps the mark from feeling
       like a sticker. */
    background:
        radial-gradient(circle at 50% 35%, rgba(33,120,212,0.16) 0%, rgba(33,120,212,0) 65%),
        var(--dh-navy2);
    display: flex; flex-direction: column; align-items: center; gap: 6px;
    position: relative;   /* anchor for the absolute-positioned close ✕ */
}
/* Sidebar close (✕) — sits in the upper-right of the logo header. Mirrors
   .dh-zed-close exactly for visual parity between left and right rails. */
.dh-sidebar-close {
    position: absolute;
    top: 6px; right: 6px;
    background: transparent; border: none; padding: 4px 7px;
    border-radius: 5px;
    color: rgba(255,255,255,0.5);
    font-size: 14px;
    cursor: pointer;
    transition: color .12s, background .12s;
    font-family: inherit;
}
.dh-sidebar-close:hover {
    color: #fff;
    background: rgba(255,255,255,0.08);
}

/* "Open Menu" trigger in AppTopBar when the sidebar is closed. Mirrors
   .dh-zed-toggle in shape so the two left/right "I'm closed, click to open"
   affordances feel like a matched pair. */
.dh-menu-open {
    display: flex; align-items: center; gap: 8px;
    background: rgba(21,101,190,0.10);
    border: 1px solid rgba(21,101,190,0.30);
    color: var(--dh-blue, #2178D4);
    font-weight: 600; font-size: 12px;
    padding: 5px 11px 5px 8px;
    border-radius: 6px;
    cursor: pointer;
    font-family: inherit;
    flex: 0 0 auto;
    margin-right: 14px;
    transition: background .12s, color .12s, border-color .12s;
}
.dh-menu-open:hover {
    background: rgba(21,101,190,0.20);
    color: #1565be;
    border-color: rgba(21,101,190,0.50);
}
.dh-menu-open img {
    width: 22px; height: auto;
    /* Wordmark ships white-on-transparent; tint blue for the light topbar. */
    filter: brightness(0) saturate(100%) invert(34%) sepia(64%)
            saturate(900%) hue-rotate(190deg) brightness(85%) contrast(92%);
}

/* ── Universal back button (AppTopBar.razor) ─────────────────────────────
   Sits between the Open-Menu chip and the page title. Wired to
   window.history.back() — gives every page a uniform back affordance
   without each page having to declare its own parent route. Hidden on
   /, /v9/log-in, and /v9/today-track (no meaningful "back" there).
   Visual style matches the data-hub's "← Back to Hub" button so the
   chrome and the data-hub's contextual back button feel like a set. */
.dh-topbar-back {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: #fff;
    border: 1px solid rgba(0,0,0,0.12);
    color: #1a2535;
    font-weight: 700;
    font-size: 12px;
    padding: 5px 12px;
    border-radius: 7px;
    cursor: pointer;
    font-family: inherit;
    flex: 0 0 auto;
    margin-right: 14px;
    transition: background .12s, color .12s, border-color .12s;
}
.dh-topbar-back:hover {
    background: rgba(21,101,190,0.08);
    color: #1565be;
    border-color: rgba(21,101,190,0.40);
}
.dh-topbar-back:active {
    background: rgba(21,101,190,0.16);
}
/* Wordmark — center, capped width so it doesn't bleed into the sidebar
   edge on the 220px chrome. The SVG is white-on-transparent so a soft
   drop-shadow gives it a tiny lift without changing the artwork. */
.dh-sidebar-logo img {
    display: block;
    width: 150px; height: auto; max-height: 38px;
    object-fit: contain;
    filter: drop-shadow(0 1px 1px rgba(0,0,0,0.35));
}
.dh-logo-sub {
    font-size: 9px;
    color: var(--dh-silver);
    letter-spacing: 0.22em;
    text-transform: uppercase;
    font-weight: 700;
    /* Tiny separator above the subtitle anchors it to the wordmark. */
    padding-top: 4px;
    border-top: 1px solid rgba(138,174,212,0.18);
    width: 100%;
    text-align: center;
}
.dh-sidebar-section {
    padding: 14px 12px 4px;
    font-size: 9px; font-weight: 700;
    color: rgba(255,255,255,0.25);
    letter-spacing: 0.12em; text-transform: uppercase;
}
/* Toggle variant — clickable section header that expands/collapses its items. */
.dh-sidebar-section--toggle {
    display: flex; align-items: center; gap: 6px;
    background: transparent; border: 0;
    width: calc(100% - 16px);
    margin: 0 8px;
    border-radius: 6px;
    text-align: left;
    cursor: pointer;
    font-family: inherit;
    transition: color 0.12s, background 0.12s;
}
.dh-sidebar-section--toggle:hover {
    color: rgba(255,255,255,0.55);
    background: rgba(255,255,255,0.04);
}
.dh-sidebar-section--toggle.is-open {
    color: rgba(255,255,255,0.5);
}
.dh-sidebar-section--toggle.has-active {
    color: rgba(255,255,255,0.65);
}
.dh-sec-caret {
    font-size: 9px; opacity: 0.55;
    min-width: 10px;
    transition: transform 0.15s;
}
.dh-sidebar-section--toggle.is-open .dh-sec-caret { opacity: 0.85; }
.dh-sec-label { flex: 1; }
.dh-sec-dot {
    display: inline-block;
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--dh-blue2);
    box-shadow: 0 0 6px 1px rgba(74, 144, 226, 0.45);
}

/* Sub-section header (inside Admin's 6-bucket nesting) — smaller, indented,
   distinct from top-level section headers but visually subordinate. */
.dh-sidebar-subsection {
    display: flex; align-items: center; gap: 5px;
    background: transparent; border: 0;
    width: calc(100% - 24px);
    margin: 2px 8px 0 16px;
    padding: 5px 8px 4px;
    border-radius: 5px;
    text-align: left;
    cursor: pointer;
    font-family: inherit;
    font-size: 9.5px; font-weight: 600;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: rgba(255,255,255,0.22);
    transition: color 0.12s, background 0.12s;
}
.dh-sidebar-subsection:hover {
    color: rgba(255,255,255,0.45);
    background: rgba(255,255,255,0.03);
}
.dh-sidebar-subsection.is-open { color: rgba(255,255,255,0.4); }
.dh-sidebar-subsection.has-active { color: rgba(255,255,255,0.55); }
.dh-sub-caret { font-size: 8px; opacity: 0.5; min-width: 9px; }
.dh-sidebar-subsection.is-open .dh-sub-caret { opacity: 0.8; }
.dh-sub-label { flex: 1; }

/* Nav items inside a sub-group: indented one notch deeper so the visual
   hierarchy reads "section > sub-group > item". The .is-nested class is
   stamped on items rendered under a NavSubGroup; CSS adjacent-sibling
   trickery would over-match into the next top-level section. */
.dh-nav-item.is-nested { margin-left: 16px; }

.dh-nav-item {
    display: flex; align-items: center; gap: 9px;
    padding: 8px 14px;
    font-size: 12px; font-weight: 500;
    color: rgba(255,255,255,0.45);
    cursor: pointer; border-radius: 6px; margin: 1px 8px;
    transition: all 0.12s;
    text-decoration: none;
    border-left: 2px solid transparent;
}
.dh-nav-item:hover { background: rgba(255,255,255,0.06); color: rgba(255,255,255,0.8); }
.dh-nav-item.active {
    background: rgba(21,101,190,0.2);
    color: #fff;
    border-left-color: var(--dh-blue2);
}
/* Muted variant — low-traffic items (e.g. Phone Report, Non-Conforming Rpt,
   Employee Track). Smaller font + dimmer color so the eye glides past them
   in the collapsed-by-default section, but they remain accessible. */
.dh-nav-item.is-muted {
    color: rgba(255,255,255,0.32);
    font-weight: 400;
    font-size: 11.5px;
}
.dh-nav-item.is-muted:hover {
    color: rgba(255,255,255,0.7);
}
.dh-nav-icon { width: 18px; text-align: center; flex: 0 0 18px; }
.dh-nav-badge {
    margin-left: auto;
    font-size: 9px; padding: 1px 6px; border-radius: 10px;
    background: var(--dh-blue); color: #fff; font-weight: 700;
}

.dh-sidebar-footer {
    margin-top: auto;
    padding: 14px 12px;
    border-top: 1px solid rgba(255,255,255,0.06);
    font-size: 11px;
    color: rgba(255,255,255,0.5);
}
.dh-sidebar-footer .name { font-weight: 600; color: #fff; }
.dh-sidebar-footer .role { font-size: 10px; color: var(--dh-silver); margin-top: 2px; }
.dh-sidebar-footer .signout {
    display: block; margin-top: 6px;
    font-size: 10px; color: var(--dh-silver); text-decoration: underline;
}

/* ─────────────────────────────────────────────────────────────────────────
   Top bar (54px white, offset 220px to clear the sidebar)
   ───────────────────────────────────────────────────────────────────────── */
.dh-topbar {
    position: fixed; top: 0; left: 220px; right: 0; height: 54px;
    background: var(--dh-white);
    border-bottom: 1px solid var(--dh-border);
    display: flex; align-items: center; justify-content: space-between;
    padding: 0 1.5rem;
    z-index: 99;
}
.dh-topbar-title { font-size: 15px; font-weight: 700; color: var(--dh-text); flex: 0 0 auto; line-height: 1.2; }

/* Title + version chip stacked vertically. The 54px topbar has enough
   room for a 15px title + an 11px caption beneath without crowding. */
.dh-topbar-title-block {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 1px;
    flex: 0 0 auto;
    min-width: 0;
}

/* Version chip — click to copy SHA. Looks like a caption, behaves like a
   button. Muted color, no border (to avoid competing with the title), but
   shows a subtle hover so users know it's interactive. */
.dh-version {
    font-family: 'DM Mono', ui-monospace, monospace;
    font-size: 10px;
    font-weight: 500;
    color: rgba(0, 0, 0, 0.42);
    background: transparent;
    border: 0;
    padding: 0;
    cursor: pointer;
    letter-spacing: 0.01em;
    line-height: 1;
    transition: color .12s;
}
.dh-version:hover { color: var(--dh-blue, #1565BE); }
.dh-version-sha {
    font-weight: 600;
    color: rgba(0, 0, 0, 0.55);
}
.dh-version:hover .dh-version-sha { color: var(--dh-blue, #1565BE); }
.dh-topbar-right { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; }
.dh-topbar-search {
    flex: 1 1 auto; max-width: 560px; margin: 0 24px;
    position: relative;
    display: flex; align-items: center;
}
.dh-topbar-search-icon {
    position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
    font-size: 13px; opacity: 0.55; pointer-events: none;
}
.dh-topbar-search input[type="search"] {
    width: 100%;
    padding: 6px 12px 6px 30px;
    border: 1px solid var(--dh-border);
    border-radius: 8px;
    font-size: 13px;
    background: var(--dh-bg);
    transition: border-color 0.1s, background 0.1s;
    font-family: inherit;
}
.dh-topbar-search input[type="search"]:focus {
    outline: none;
    border-color: var(--dh-blue);
    background: var(--dh-white);
    box-shadow: 0 0 0 2px rgba(27, 58, 107, 0.12);
}
.dh-icon-btn {
    width: 32px; height: 32px; border-radius: 8px;
    border: 1px solid var(--dh-border);
    background: var(--dh-white);
    display: flex; align-items: center; justify-content: center;
    font-size: 15px; cursor: pointer; transition: background 0.1s;
    position: relative; /* anchor for the bell badge */
}
.dh-icon-btn:hover { background: var(--dh-bg); }

/* Bell badge — small red count on the top-right of the bell button.
   Animates a subtle pulse when count > 0 so it draws the eye without
   being obnoxious. Cap at 99+ to keep the pill narrow. */
.dh-icon-btn-bell .dh-bell-badge {
    position: absolute;
    top: -4px; right: -4px;
    min-width: 18px; height: 18px;
    padding: 0 4px;
    background: #DC2626; /* red-600 */
    color: #FFFFFF;
    border: 2px solid var(--dh-white);
    border-radius: 999px;
    font-size: 10px; font-weight: 700;
    line-height: 14px;
    display: inline-flex; align-items: center; justify-content: center;
    pointer-events: none; /* clicks fall through to the bell */
    animation: dh-bell-pulse 2.4s ease-in-out infinite;
}
@keyframes dh-bell-pulse {
    0%, 100% { transform: scale(1.0); box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.35); }
    50%      { transform: scale(1.06); box-shadow: 0 0 0 4px rgba(220, 38, 38, 0); }
}
.dh-env-pill {
    font-size: 10px; padding: 2px 9px; border-radius: 20px;
    font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
}
.dh-env-pill.dev  { background: #FAEEDA; color: var(--dh-amber); border: 1px solid #E0B97A; }
.dh-env-pill.prod { background: var(--dh-red-pale); color: var(--dh-red); border: 1px solid #E08989; }
.dh-env-pill.sandbox { background: var(--dh-purple-pale); color: var(--dh-purple); border: 1px solid #B7B0E0; }

/* EN/ES language toggle — segmented pill, matches the zdic.com header switch. */
.dh-lang {
    display: inline-flex; align-items: center;
    border: 1px solid #D5DAE0; border-radius: 7px; overflow: hidden;
    background: #fff;
}
.dh-lang-opt {
    appearance: none; border: 0; background: transparent; cursor: pointer;
    font-size: 11px; font-weight: 700; letter-spacing: 0.04em;
    padding: 4px 9px; color: var(--dh-ink-soft, #6b7280); line-height: 1;
}
.dh-lang-opt + .dh-lang-opt { border-left: 1px solid #E3E7EC; }
.dh-lang-opt:hover { background: #F3F5F8; color: #111827; }
.dh-lang-opt.on {
    background: var(--dh-blue, #1B4F8A); color: #fff;
}
.dh-lang-opt.on:hover { background: var(--dh-blue, #1B4F8A); color: #fff; }

.dh-zed-toggle {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 11px; border-radius: 7px;
    font-size: 12px; font-weight: 700;
    background: rgba(123,47,190,0.12);
    color: var(--dh-zed-purple);
    border: 1px solid rgba(123,47,190,0.28);
    cursor: pointer; transition: background 0.1s;
    font-family: inherit;
}
.dh-zed-toggle:hover { background: rgba(123,47,190,0.2); }

/* Active state — ZED panel is currently open. Filled purple background
   + white text reads as "pressed/on" without needing extra geometry.
   Same shape and size so the topbar layout doesn't shift on toggle. */
.dh-zed-toggle--active {
    background: var(--dh-zed-purple, #7B2FBE);
    color: #fff;
    border-color: var(--dh-zed-purple, #7B2FBE);
}
.dh-zed-toggle--active:hover {
    background: #6826A4;
    border-color: #6826A4;
}

.dh-zed-toggle-count {
    background: var(--dh-zed-purple); color: #fff;
    font-size: 9px; padding: 1px 6px; border-radius: 10px; font-weight: 700;
}
.dh-avatar {
    width: 32px; height: 32px; border-radius: 50%;
    background: var(--dh-navy2); color: var(--dh-silver);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 11px; font-weight: 700; cursor: pointer;
}

/* ─────────────────────────────────────────────────────────────────────────
   Main content area — fills the space sidebar + topbar leave behind.
   When the ZED panel is open, content width shrinks by --dh-zed-width
   so panel is fixed-width and content reflows (mirrors STRUCZ behavior).
   ───────────────────────────────────────────────────────────────────────── */
.dh-main {
    margin-left: 220px;
    margin-top: 54px;
    padding: 1.5rem;
    min-height: calc(100vh - 54px);
    width: calc(100% - 220px);
}
.dh-main--with-zed { width: calc(100% - 220px - var(--dh-zed-width)); }

/* Sidebar collapsed — main content reclaims the 220px left rail. */
.dh-main--no-sidebar {
    margin-left: 0;
    width: 100%;
}
.dh-main--no-sidebar.dh-main--with-zed {
    width: calc(100% - var(--dh-zed-width));
}

/* AppTopBar follows: when sidebar is closed, the topbar shifts left to use
   the freed-up space. Without this the title would float oddly indented. */
.dh-topbar--full { left: 0; }

/* ─────────────────────────────────────────────────────────────────────────
   Mobile collapse — sidebar to a 60px icon-rail, hide topbar search/title.
   Same breakpoint STRUCZ uses (900px).
   ───────────────────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
    .dh-sidebar { width: 60px; }
    .dh-sidebar .dh-logo-sub,
    .dh-sidebar .dh-nav-item span:not(.dh-nav-badge),
    .dh-sidebar-section,
    .dh-sidebar-footer { display: none; }
    .dh-main   { margin-left: 60px; width: calc(100% - 60px); }
    .dh-main--with-zed { width: calc(100% - 60px - var(--dh-zed-width)); }
    .dh-topbar { left: 60px; }
}

/* ─────────────────────────────────────────────────────────────────────────
   ZED right-rail panel (340px, dark purple — canonical mockup §renderZed)
   Scaffolded for ZDIV2 even though ZED's LLM wiring isn't live. Toggling
   the panel + page-context-awareness lands now; live responses come when
   Cameron's LiteLLM (or our existing Grok GrokZedClient) is plumbed in.
   ───────────────────────────────────────────────────────────────────────── */
.dh-zed {
    position: fixed;
    top: 54px;
    right: 0;
    bottom: 0;
    width: var(--dh-zed-width);
    background: var(--dh-zed-bg);
    border-left: 1px solid rgba(123,47,190,0.28);
    color: #E6E2F3;
    display: flex;
    flex-direction: column;
    z-index: 10;
    overflow: hidden;
}
.dh-zed-hdr {
    padding: 14px 15px;
    border-bottom: 1px solid rgba(123,47,190,0.2);
    display: flex; align-items: center; gap: 11px;
    flex-shrink: 0;
}
.dh-zed-mark {
    width: 33px; height: 33px; border-radius: 8px;
    background: rgba(123,47,190,0.28);
    border: 1px solid rgba(123,47,190,0.45);
    display: flex; align-items: center; justify-content: center;
    color: var(--dh-zed-light);
    font-size: 16px; font-weight: 700;
    flex-shrink: 0;
}
.dh-zed-title { font-weight: 700; font-size: 14px; color: var(--dh-zed-light); }
.dh-zed-sub   { font-size: 10px; color: rgba(168,85,247,0.65); }
.dh-zed-close {
    background: transparent; border: none; padding: 5px; border-radius: 5px;
    color: rgba(168,85,247,0.65); cursor: pointer;
    transition: color .12s;
    font-size: 16px;
}
.dh-zed-close:hover { color: var(--dh-zed-light); }

/* Speaker toggle — global on/off for ZED voice (ElevenLabs Brian).
   Sits in the header next to the X close button. Muted state shows
   🔇 in low-opacity purple; on-state shows 🔊 in bright purple with
   a subtle glow so it's clear at a glance that ZED is "active." */
.dh-zed-speaker {
    background: transparent; border: none; padding: 5px; border-radius: 5px;
    color: rgba(168,85,247,0.55); cursor: pointer;
    transition: color .12s, text-shadow .12s, background .12s;
    font-size: 14px;
    margin-right: 4px;
}
.dh-zed-speaker:hover { color: var(--dh-zed-light); background: rgba(168,85,247,0.12); }
.dh-zed-speaker.is-on {
    color: #DDD6FE;
    text-shadow: 0 0 8px rgba(168,85,247,0.7);
}
.dh-zed-speaker.is-on:hover {
    color: #FFFFFF;
    background: rgba(168,85,247,0.18);
}

/* Bubble wrapper hosts the answer + the LLM-style bottom action row.
   align-self moves to the bubble itself so the wrapper sizes to its
   content; the action row inherits the same left alignment. */
.dh-zed-chat-a-wrap {
    align-self: flex-start;
    max-width: 95%;
    display: flex;
    flex-direction: column;
}

/* Action row — replay + copy buttons sit BELOW the answer bubble,
   matching ChatGPT/Claude's pattern of "tools for this message." Always
   visible (not hover-only) so the affordance is discoverable, but kept
   subtle so they don't dominate the chat. */
.dh-zed-chat-actions {
    display: flex;
    gap: 4px;
    margin-top: 3px;
    padding-left: 4px;
}
.dh-zed-chat-action {
    background: transparent;
    border: 1px solid rgba(123,47,190,0.20);
    border-radius: 4px;
    color: rgba(230,226,243,0.55);
    cursor: pointer;
    padding: 2px 6px;
    font-size: 11px;
    line-height: 1.3;
    transition: background .12s, color .12s, border-color .12s;
}
.dh-zed-chat-action:hover {
    background: rgba(168,85,247,0.18);
    color: rgba(230,226,243,0.95);
    border-color: rgba(168,85,247,0.4);
}
.dh-zed-chat-action:active {
    background: rgba(168,85,247,0.30);
}

/* Inline "↻ Refresh" link tucked into the .dh-zed-sub line right after the
   timestamp. Reads as a clear action label, not a tiny icon. */
.dh-zed-refresh-inline {
    background: transparent; border: none; padding: 0;
    color: var(--dh-zed-light);
    font-size: 10px; font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
    transition: color .12s;
}
.dh-zed-refresh-inline:hover:not(:disabled) {
    color: #fff;
}
.dh-zed-refresh-inline:disabled {
    color: rgba(168,85,247,0.45);
    cursor: not-allowed;
    text-decoration: none;
}

.dh-zed-sec {
    padding: 12px 14px;
    border-bottom: 1px solid rgba(123,47,190,0.12);
    flex-shrink: 0;
}
.dh-zed-sec.scroll { flex: 1; overflow-y: auto; border-bottom: none; }

/* Per-bucket accent — distinguishes OEM (warm gold) from Stale (coral)
   from the rest of the purple panel chrome. Left border + colored label
   makes the two candidate sections instantly differentiable at a glance.
   OEM = primary outreach target (gold = priority); Stale = lost-customer
   follow-up (coral = attention). */
.dh-zed-sec--oem {
    border-left: 3px solid #FBBF24;
    padding-left: 11px;   /* compensate for 3px border so content stays at 14px from edge */
}
.dh-zed-sec--oem > .dh-zed-lbl {
    color: #FBBF24;
}

.dh-zed-sec--stale {
    border-left: 3px solid #FB7185;
    padding-left: 11px;
}
.dh-zed-sec--stale > .dh-zed-lbl {
    color: #FB7185;
}

/* Michelle's reactivation queue — distinct purple accent so Craig can
   tell her briefing apart from ZED's at a glance. Task #106. */
.dh-zed-sec--michelle {
    border-left: 3px solid #A78BFA;
    padding-left: 11px;
}
.dh-zed-sec--michelle > .dh-zed-lbl {
    color: #A78BFA;
}

/* Phase Z scroll wrapper: NEEDS YOU + Morning Briefing + Ask + Overnight
   share one scroll surface so the mouse wheel / trackpad works on the
   whole panel body. Header and disclaimer stay pinned outside. */
.dh-zed-body {
    flex: 1;
    overflow-y: auto;
    min-height: 0;   /* required so flex children may shrink and scroll */
}
.dh-zed-lbl {
    font-size: 10px;
    color: var(--dh-zed-light);
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    margin-bottom: 9px;
}
.dh-zed-need {
    background: rgba(123,47,190,0.09);
    border: 1px solid rgba(123,47,190,0.18);
    border-radius: 8px;
    padding: 10px 11px;
    margin-bottom: 8px;
}
.dh-zed-need.high { border-left: 3px solid #E04C4C; }
.dh-zed-need.medium { border-left: 3px solid #E0A04C; }
.dh-zed-need.low { border-left: 3px solid #6A6A7A; }
.dh-zed-need-body { font-size: 12px; line-height: 1.45; color: #E6E2F3; }
.dh-zed-need-meta {
    margin-top: 7px;
    display: flex; justify-content: space-between; align-items: center;
    font-size: 10px; color: rgba(230,226,243,0.55);
}
.dh-zed-briefing { font-size: 12px; line-height: 1.55; color: rgba(230,226,243,0.85); }
.dh-zed-briefing p { margin: 0 0 8px; }
.dh-zed-briefing-meta {
    font-size: 10px; color: rgba(230,226,243,0.5);
    margin-top: 6px !important;
    font-family: 'DM Mono', monospace;
}

/* Phase Z — stale-account candidates list inside ZED Needs You. */
.dh-zed-needs { display: flex; flex-direction: column; gap: 0; }
.dh-zed-need-co {
    display: flex; justify-content: space-between; align-items: baseline;
    gap: 8px;
    font-size: 12px; color: #fff;
}
.dh-zed-need-co strong { font-weight: 600; }
.dh-zed-need-val {
    font-family: 'DM Mono', monospace;
    font-size: 11px;
    color: var(--dh-zed-light);
    flex-shrink: 0;
}
.dh-zed-need-sub {
    margin-top: 4px;
    font-size: 10px; color: rgba(230,226,243,0.55);
    line-height: 1.4;
}
.dh-zed-need-action {
    margin-top: 6px;
    font-size: 11px; color: #E6E2F3;
    line-height: 1.4;
}
.dh-zed-need-flag { color: #E0A04C; }

/* Swap notice — appears under the "Draft ready for X" line when ZED
   auto-replaced a bad-email primary with a viable alternate. Coral-
   tinted to read as a caution (recipient changed) without screaming
   like a full-blown error. */
.dh-zed-need-swap {
    margin-top: 4px;
    font-size: 10.5px;
    color: #F8B4C3;
    line-height: 1.45;
    background: rgba(251, 113, 133, 0.10);
    border-left: 2px solid rgba(251, 113, 133, 0.40);
    padding: 5px 8px;
    border-radius: 0 4px 4px 0;
}
.dh-zed-need-swap code {
    background: rgba(251, 113, 133, 0.10);
    padding: 0 4px;
    border-radius: 3px;
    font-family: 'DM Mono', ui-monospace, monospace;
    font-size: 10px;
}
.dh-zed-need-swap strong { color: #FCD3DD; }

/* Cc list — comma-separated alternates that will be on the cc:
   line of the mailto:. Muted so it doesn't compete with the
   primary "Draft ready for X" header. */
.dh-zed-need-cc {
    margin-top: 4px;
    font-size: 10.5px;
    color: rgba(230, 226, 243, 0.62);
    line-height: 1.45;
}

/* Phase-1 liveness chip — small tier indicator next to the company
   name. The emoji carries the color signal; the text is for screen-
   readers / the title attribute. Inline-flex so it sits cleanly with
   the company name and $ value. */
.dh-zed-liveness {
    display: inline-flex;
    align-items: center;
    font-size: 9px;
    font-weight: 700;
    padding: 1px 6px;
    border-radius: 8px;
    margin-left: 6px;
    line-height: 1.5;
    letter-spacing: 0.02em;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.08);
    cursor: help;
}
.dh-zed-liveness--active { color: #5FC470; border-color: rgba(95,196,112,0.25); }
.dh-zed-liveness--aging  { color: #E0A04C; border-color: rgba(224,160,76,0.25); }
.dh-zed-liveness--zombie { color: #F08080; border-color: rgba(240,128,128,0.28); background: rgba(240,128,128,0.06); }

/* Post-send greyed-out state. Applied to a candidate card after the
   user clicks Open Email (IZedSendLogger flips the IZedSidebarState
   flag, the panel re-renders with the modifier). Reduces the
   double-send confusion Craig flagged: visually muted, buttons
   still functional but it's CLEAR you already acted on this one. */
.dh-zed-need--sent {
    opacity: 0.45;
    filter: grayscale(60%);
}
.dh-zed-need--sent .dh-zed-need-btn.primary {
    pointer-events: none;
    cursor: default;
}
.dh-zed-sent-chip {
    display: inline-flex;
    align-items: center;
    font-size: 9px;
    font-weight: 700;
    padding: 1px 7px;
    border-radius: 8px;
    margin-left: 6px;
    background: rgba(95, 196, 112, 0.18);
    color: #7BD68A;
    border: 1px solid rgba(95, 196, 112, 0.40);
    letter-spacing: 0.02em;
}

/* Batch send button — sits next to ↻ Refresh on each briefing
   section header. Same chip size + family as Refresh so the
   header doesn't feel crowded. */
.dh-zed-batch {
    margin-left: 4px;
    background: rgba(123, 47, 190, 0.18);
    color: #D9B6F5;
    border: 1px solid rgba(168, 85, 247, 0.40);
}
.dh-zed-batch:hover:not(:disabled) {
    background: rgba(123, 47, 190, 0.30);
    color: #fff;
}

/* Batch modal — full-screen overlay + centered card. Same backdrop
   pattern as the rollback confirm modal in the Data Hub. */
.dh-zed-batch-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.dh-zed-batch-modal {
    background: var(--dh-zed-bg, #1a1030);
    color: #E6E2F3;
    border: 1px solid rgba(168, 85, 247, 0.30);
    border-radius: 12px;
    width: 100%;
    max-width: 640px;
    max-height: 86vh;
    display: flex;
    flex-direction: column;
    box-shadow: 0 24px 80px rgba(0, 0, 0, 0.45);
    overflow: hidden;
}
.dh-zed-batch-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 18px;
    border-bottom: 1px solid rgba(168, 85, 247, 0.20);
}
.dh-zed-batch-title {
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0.01em;
}
.dh-zed-batch-x {
    background: transparent;
    border: 0;
    color: rgba(230, 226, 243, 0.55);
    font-size: 16px;
    cursor: pointer;
    padding: 0 4px;
}
.dh-zed-batch-x:hover { color: #fff; }

.dh-zed-batch-sub {
    padding: 10px 18px 12px;
    font-size: 11.5px;
    line-height: 1.55;
    color: rgba(230, 226, 243, 0.66);
    border-bottom: 1px solid rgba(168, 85, 247, 0.10);
}
.dh-zed-batch-sub strong { color: #fff; }

.dh-zed-batch-list {
    flex: 1;
    overflow-y: auto;
    padding: 6px 8px;
}
.dh-zed-batch-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: 6px;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background .12s, border-color .12s;
}
.dh-zed-batch-row:hover { background: rgba(168, 85, 247, 0.06); }
.dh-zed-batch-row input[type=checkbox] {
    accent-color: var(--dh-zed-purple, #7B2FBE);
    width: 16px;
    height: 16px;
    cursor: pointer;
    flex-shrink: 0;
}
.dh-zed-batch-row.is-sending { opacity: 0.7; }
.dh-zed-batch-row-co { flex: 1; min-width: 0; }
.dh-zed-batch-row-name {
    font-size: 12.5px;
    font-weight: 700;
    color: #fff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dh-zed-batch-row-meta {
    font-size: 10.5px;
    color: rgba(230, 226, 243, 0.62);
    margin-top: 2px;
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}
.dh-zed-batch-row-meta code {
    font-family: 'DM Mono', ui-monospace, monospace;
    color: #D9B6F5;
    background: transparent;
}
.dh-zed-batch-swap {
    color: #F8B4C3;
}
.dh-zed-batch-row-status {
    flex-shrink: 0;
    min-width: 70px;
    text-align: right;
    font-size: 10px;
}
.dh-zed-batch-pulse {
    color: #5FC470;
    font-weight: 700;
}

.dh-zed-batch-foot {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    padding: 12px 18px;
    border-top: 1px solid rgba(168, 85, 247, 0.18);
    background: rgba(0, 0, 0, 0.20);
}
.dh-zed-batch-summary {
    flex: 1;
    font-size: 11px;
    color: rgba(230, 226, 243, 0.70);
    line-height: 1.45;
}
.dh-zed-bad-email {
    display: inline-block;
    margin: 0 4px;
    font-family: 'DM Mono', monospace;
    font-size: 10px;
    color: rgba(230,226,243,0.65);
    background: rgba(0,0,0,0.18);
    padding: 1px 5px;
    border-radius: 3px;
}
.dh-zed-bad-tag {
    color: #E0A04C;
    font-style: italic;
    font-size: 10px;
    margin-left: 6px;
}

/* Intel brief — Grok-synthesized 2-3 sentence paragraph on OEM cards,
   sits between the "Last sale …" sub-line and the email-state action
   lines. The 🧠 mark anchors the eye to the AI-generated content. */
.dh-zed-intel {
    margin-top: 8px;
    padding: 8px 10px;
    background: rgba(123,47,190,0.08);
    border-left: 2px solid var(--dh-zed-purple);
    border-radius: 0 5px 5px 0;
    font-size: 11px;
    line-height: 1.5;
    color: rgba(230,226,243,0.92);
    display: flex; gap: 7px; align-items: flex-start;
}
.dh-zed-intel-mark {
    flex: 0 0 auto;
    font-size: 13px;
    line-height: 1.3;
}
.dh-zed-intel-text { flex: 1; min-width: 0; }
.dh-zed-intel-err {
    background: rgba(224,76,76,0.10);
    border-left-color: #E04C4C;
    color: #E0A04C;
    font-style: italic;
    font-size: 10px;
}

/* Web findings section — sits between the "Last sale …" sub-line and the
   email-state action lines on OEM cards. Only renders when WebFindings
   is populated (Day 2 DDG output). Toggleable to keep the card compact. */
.dh-zed-web {
    margin-top: 8px;
    padding-top: 6px;
    border-top: 1px dashed rgba(123,47,190,0.20);
}
.dh-zed-web-err, .dh-zed-web-empty {
    font-size: 10px;
    color: rgba(230,226,243,0.55);
    font-style: italic;
}
.dh-zed-web-err { color: #E0A04C; }
.dh-zed-web-toggle {
    background: transparent;
    border: none;
    padding: 0;
    color: var(--dh-zed-light);
    font-size: 10px; font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.dh-zed-web-toggle:hover { color: #fff; }
.dh-zed-web-list {
    margin-top: 8px;
    display: flex; flex-direction: column;
    gap: 8px;
    font-size: 11px;
}
.dh-zed-web-group {
    background: rgba(0,0,0,0.18);
    border-radius: 5px;
    padding: 6px 8px;
}
.dh-zed-web-query {
    font-family: 'DM Mono', monospace;
    font-size: 9px;
    color: rgba(168,85,247,0.7);
    margin-bottom: 4px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.dh-zed-web-hit {
    display: block;
    padding: 4px 6px;
    margin: 2px 0;
    border-radius: 3px;
    text-decoration: none;
    color: #E6E2F3;
    transition: background .08s;
}
.dh-zed-web-hit:hover { background: rgba(123,47,190,0.18); }
.dh-zed-web-title {
    font-weight: 600;
    color: #fff;
    font-size: 11px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dh-zed-web-snippet {
    font-size: 10px;
    color: rgba(230,226,243,0.65);
    line-height: 1.4;
    margin-top: 2px;
}

/* Per-row action buttons: mailto: link + company link + preview toggle. */
.dh-zed-need-btns {
    display: flex; gap: 6px; flex-wrap: wrap;
    margin-top: 8px;
}
.dh-zed-need-btn {
    display: inline-block;
    background: rgba(123,47,190,0.14);
    color: var(--dh-zed-light);
    border: 1px solid rgba(123,47,190,0.32);
    border-radius: 4px;
    padding: 4px 9px;
    font-size: 10px; font-weight: 600;
    text-decoration: none;
    font-family: inherit;
    cursor: pointer;
    line-height: 1.3;
}
.dh-zed-need-btn:hover {
    background: rgba(123,47,190,0.28);
    color: #fff;
}
.dh-zed-need-btn.primary {
    background: var(--dh-zed-purple);
    color: #fff;
    border-color: var(--dh-zed-purple);
}
.dh-zed-need-btn.primary:hover {
    background: #9450d0;
    border-color: #9450d0;
}
/* Tertiary destructive variant — Dismiss should be visually softer than
   "Open in mail" / "Open company" so the eye doesn't land on it first. */
.dh-zed-need-btn.dismiss {
    background: transparent;
    color: rgba(230,226,243,0.55);
    border-color: rgba(123,47,190,0.20);
}
.dh-zed-need-btn.dismiss:hover {
    background: rgba(224,76,76,0.12);
    color: #E04C4C;
    border-color: rgba(224,76,76,0.40);
}

/* "🔍 Research web" — OEM-card-only button to fire on-demand DDG +
   intel re-synthesis. Looks like a tertiary action but with a hint of
   blue so it reads as a "fetch more info" affordance, not destructive. */
.dh-zed-need-btn.research {
    background: rgba(33,120,212,0.10);
    color: #8ab8e4;
    border-color: rgba(33,120,212,0.28);
}
.dh-zed-need-btn.research:hover:not(:disabled) {
    background: rgba(33,120,212,0.22);
    color: #c9deef;
    border-color: rgba(33,120,212,0.50);
}
.dh-zed-need-btn.research:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}
.dh-zed-need-colink {
    text-decoration: none;
    color: #fff;
    flex: 1; min-width: 0;
}
.dh-zed-need-colink:hover strong { text-decoration: underline; }

/* Inline draft preview — subject + body shown in the row when "Preview" clicked. */
.dh-zed-need-preview {
    margin-top: 8px;
    padding: 8px 10px;
    background: rgba(0,0,0,0.25);
    border: 1px solid rgba(123,47,190,0.22);
    border-radius: 6px;
    font-size: 11px;
    color: #E6E2F3;
}
.dh-zed-preview-row {
    display: flex; gap: 8px;
    margin-bottom: 4px;
    line-height: 1.4;
}
.dh-zed-preview-lbl {
    flex-shrink: 0;
    width: 52px;
    color: rgba(230,226,243,0.55);
    text-transform: uppercase;
    font-size: 9px;
    letter-spacing: 0.05em;
    padding-top: 2px;
}
.dh-zed-preview-body {
    margin: 6px 0 0;
    padding: 8px 10px;
    background: rgba(0,0,0,0.3);
    border-radius: 4px;
    font-family: 'DM Mono', monospace;
    font-size: 11px;
    line-height: 1.55;
    color: rgba(230,226,243,0.9);
    white-space: pre-wrap;
    word-break: break-word;
}

/* Heartbeat log — timestamped bullets in OVERNIGHT section. */
.dh-zed-log {
    list-style: none; margin: 0; padding: 0;
    font-family: 'DM Mono', monospace;
    font-size: 10px;
    color: rgba(230,226,243,0.7);
    line-height: 1.6;
}
.dh-zed-log li { padding: 2px 0; }

/* "Run now" dev button under the empty NEEDS YOU section. */
.dh-zed-runbtn {
    display: inline-block;
    margin-left: 8px;
    background: rgba(123,47,190,0.18);
    color: var(--dh-zed-light);
    border: 1px solid rgba(123,47,190,0.35);
    border-radius: 4px;
    padding: 2px 9px;
    font-size: 10px; font-weight: 600;
    font-family: inherit;
    cursor: pointer;
}
.dh-zed-runbtn:hover:not(:disabled) { background: rgba(123,47,190,0.32); color: #fff; }
.dh-zed-runbtn:disabled { opacity: 0.5; cursor: not-allowed; }
.dh-zed-ask {
    display: flex; gap: 6px; margin-top: 6px;
    align-items: flex-end;  /* button hugs the bottom as textarea grows */
}
.dh-zed-ask textarea {
    flex: 1;
    background: rgba(123,47,190,0.12);
    border: 1px solid rgba(123,47,190,0.24);
    border-radius: 6px;
    padding: 7px 10px;
    color: #E6E2F3; font-size: 12px;
    font-family: inherit;
    resize: none;             /* user-resize handle off — auto-grow handles it */
    line-height: 1.45;
    /* field-sizing: content lets the textarea grow with its content
       (Chrome 123+, Edge 123+). max-height caps at ~6 lines so a
       long question doesn't push the conversation history off-screen.
       Older browsers fall back to a single visible row from rows="1". */
    field-sizing: content;
    min-height: 32px;
    max-height: 140px;
    overflow-y: auto;
    /* Word wrap — the explicit reason this stopped being an <input>. */
    white-space: pre-wrap;
    word-break: break-word;
}
.dh-zed-ask textarea::placeholder { color: rgba(230,226,243,0.4); }
.dh-zed-ask button {
    background: var(--dh-zed-purple); color: #fff;
    border: none; border-radius: 6px; padding: 6px 14px;
    font-size: 11px; font-weight: 700; cursor: pointer;
    font-family: inherit;
    /* Stays compact even when the textarea grows tall. */
    align-self: flex-end;
    height: 32px;
    flex-shrink: 0;
}
.dh-zed-ask button:disabled { opacity: 0.5; cursor: not-allowed; }

/* "New chat" pill in the Ask ZED label row — only shows when history exists. */
.dh-zed-chat-clear {
    margin-left: 8px;
    background: transparent;
    color: rgba(168,85,247,0.65);
    border: 1px solid rgba(123,47,190,0.30);
    border-radius: 3px;
    padding: 1px 7px;
    font-size: 9px;
    font-weight: 600;
    text-transform: none;          /* override .dh-zed-lbl all-caps */
    letter-spacing: 0;
    font-family: inherit;
    cursor: pointer;
}
.dh-zed-chat-clear:hover {
    background: rgba(123,47,190,0.18);
    color: var(--dh-zed-light);
}

/* Conversation history pane — Q bubbles right-aligned, A bubbles left. */
.dh-zed-chat {
    margin: 4px 0 8px;
    display: flex; flex-direction: column;
    gap: 6px;
    font-size: 11.5px;
    line-height: 1.5;
    /* Bound the chat area + give it its own scroll. Without this a long
       ZED answer (e.g., a 60-row company list) pushed the OEM/Stale
       sections below the visible viewport with no way to reach them.
       Now the chat history scrolls independently while the rest of the
       panel chrome stays in place. Cap at 65vh so even the chat area
       itself doesn't dominate; if even more history is needed, the
       scrollbar handles it. */
    max-height: 65vh;
    overflow-y: auto;
    /* Slim scrollbar — matches the dark panel chrome. */
    scrollbar-width: thin;
    scrollbar-color: rgba(123,47,190,0.35) transparent;
}
.dh-zed-chat::-webkit-scrollbar { width: 6px; }
.dh-zed-chat::-webkit-scrollbar-track { background: transparent; }
.dh-zed-chat::-webkit-scrollbar-thumb {
    background: rgba(123,47,190,0.35);
    border-radius: 3px;
}
.dh-zed-chat::-webkit-scrollbar-thumb:hover {
    background: rgba(123,47,190,0.55);
}
.dh-zed-chat-q {
    align-self: flex-end;
    max-width: 88%;
    background: var(--dh-zed-purple);
    color: #fff;
    padding: 6px 10px;
    border-radius: 10px 10px 2px 10px;
    white-space: pre-wrap;
    word-break: break-word;
}
.dh-zed-chat-a {
    align-self: flex-start;
    max-width: 95%;
    background: rgba(123,47,190,0.10);
    color: #E6E2F3;
    border: 1px solid rgba(123,47,190,0.18);
    padding: 6px 10px;
    border-radius: 10px 10px 10px 2px;
    /* word-break stays; pre-wrap removed because RenderChatMessage now
       emits <p> / <br> so the browser already handles paragraphing. */
    word-break: break-word;
}
/* Paragraph spacing inside ZED chat bubbles — first/last margins
   trimmed so the bubble doesn't get extra padding from the <p>. */
.dh-zed-chat-a p {
    margin: 0 0 8px 0;
}
.dh-zed-chat-a p:last-child {
    margin-bottom: 0;
}
/* Inline code (`like_this`) — monospaced chip on a slightly darker
   background to stand out from the bubble. */
.dh-zed-chat-a code {
    background: rgba(0, 0, 0, 0.25);
    color: #E6E2F3;
    border: 1px solid rgba(123,47,190,0.18);
    border-radius: 3px;
    padding: 1px 4px;
    font-family: 'DM Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 11px;
}
/* Clickable record references and explicit markdown links. Underlined
   on hover only so prose stays clean. Light purple to read against the
   dark bubble. */
.dh-zed-chat-link {
    color: #C4B5FD;
    text-decoration: none;
    border-bottom: 1px dotted rgba(196, 181, 253, 0.4);
    cursor: pointer;
}
.dh-zed-chat-link:hover {
    color: #DDD6FE;
    border-bottom-color: rgba(221, 214, 254, 0.9);
}
.dh-zed-chat-link:active {
    color: #A78BFA;
}
.dh-zed-chat-thinking {
    margin: 4px 0 8px;
    font-size: 11px;
    color: rgba(168,85,247,0.7);
    font-style: italic;
    padding: 4px 0;
    /* Preserve the single-space-inside-span characters; otherwise the
       browser is free to collapse the whitespace between "ZED" and "is",
       breaking the cascade rhythm. */
    white-space: pre;
}

/* Cascading per-letter pulse for the thinking indicator. Each .dh-zed-
   thinking-letter pulses opacity + a small lift, with animation-delay
   assigned inline per character (index * 80ms in ZedPanel.razor). The
   animation-iteration-count is infinite so the cascade keeps rolling
   until the parent .dh-zed-chat-thinking is removed (i.e., the answer
   arrives). prefers-reduced-motion respected. */
.dh-zed-thinking-letter {
    display: inline-block;
    /* Pre-letter spacing kept to 0 — width comes from the letter itself
       plus any space character inside the span. */
    animation: dh-zed-thinking-pulse 1.4s ease-in-out infinite;
    transform-origin: center bottom;
    will-change: opacity, transform;
}

@keyframes dh-zed-thinking-pulse {
    0%, 60%, 100% {
        opacity: 0.35;
        transform: translateY(0) scale(1);
        color: rgba(168,85,247,0.7);
    }
    25% {
        opacity: 1;
        transform: translateY(-1px) scale(1.06);
        color: rgba(216,180,254,1);  /* brighter pop at the peak */
    }
}

@media (prefers-reduced-motion: reduce) {
    /* Operators with motion sensitivity get a steady glow instead of
       the cascade — still communicates "ZED is processing" without
       the per-letter movement. */
    .dh-zed-thinking-letter {
        animation: none;
        opacity: 0.7;
    }
}
.dh-zed-disc {
    padding: 9px 14px;
    font-size: 9px; color: rgba(230,226,243,0.45);
    border-top: 1px solid rgba(123,47,190,0.18);
    text-align: center;
    flex-shrink: 0;
}

/* ============================================================
   V9 Twinkle — Credit Hold / ERA Hold / Credit Pending pulse
   Applies to ANY pill with class is-hold or is-pending (cm-pill,
   qt-pill, po-pill, so-pill etc.). V9 fired TLMDDBSimpleLabel.Twinkle
   := True on these labels via SOGridDblClick / QuoteGridDblClick /
   POGridDblClick handlers — reps used the blink as peripheral-vision
   cue for risky accounts. Honors prefers-reduced-motion.
   ============================================================ */
.is-hold, .is-pending {
    animation: v9-twinkle 1.4s ease-in-out infinite;
}
@keyframes v9-twinkle {
    0%, 100% { opacity: 1.0; }
    50%      { opacity: 0.55; }
}
@media (prefers-reduced-motion: reduce) {
    .is-hold, .is-pending { animation: none; }
}

/* ============================================================
   V9 Dimensional Tablature — shared tab CSS
   Used by ContactManager, SalesOrder, PurchaseOrder, Quote,
   Invoice, Inventory, Requirements, RMA, TodayTrack, etc.
   Each form mirrors V9's PageControl* nesting with these classes.
   ============================================================ */

/* Top tab strip (PageControl3 level). Heavier emphasis. */
.v9-tabs-top {
    display: flex; flex-wrap: wrap; gap: 2px;
    background: linear-gradient(180deg, #FFFFFF, #F4F8FE);
    padding: 4px 8px 0;
    border: 1px solid #DBE6F5;
    border-radius: 8px 8px 0 0;
    border-bottom: 2px solid #1B3A6B;
    margin-bottom: 0;
}
.v9-tab-top {
    background: transparent;
    border: 1px solid transparent; border-bottom: none;
    padding: 8px 16px;
    font: inherit; font-size: 13px; font-weight: 700;
    color: #64748B; cursor: pointer;
    border-radius: 6px 6px 0 0;
    letter-spacing: 0.02em;
}
.v9-tab-top:hover { color: #1B3A6B; background: #F4F8FE; }
.v9-tab-top.is-active {
    color: #1B3A6B; background: #FFFFFF;
    border-color: #1B3A6B #1B3A6B #FFFFFF;
    border-bottom: 2px solid #FFFFFF;
    margin-bottom: -2px;
    box-shadow: 0 -2px 0 0 #1B3A6B inset;
}

/* Sub tab strip (PageControl4/7/2/etc.). Lives in lower quadrant. */
.v9-tabs-sub {
    display: flex; flex-wrap: wrap; gap: 1px;
    background: #F4F8FE;
    padding: 6px 14px 0;
    border: 1px solid #DBE6F5;
    border-bottom: 1px solid #DBE6F5;
    margin: 12px 0 0;
    border-radius: 8px 8px 0 0;
}
.v9-tab-sub {
    background: transparent;
    border: 1px solid transparent; border-bottom: none;
    padding: 5px 11px;
    font: inherit; font-size: 11.5px; font-weight: 600;
    color: #64748B; cursor: pointer;
    border-radius: 6px 6px 0 0;
    display: inline-flex; align-items: center; gap: 6px;
}
.v9-tab-sub:hover { background: #FFFFFF; color: #1B3A6B; }
.v9-tab-sub.is-active {
    background: #FFFFFF; color: #1B3A6B;
    border-color: #DBE6F5;
    border-bottom: 1px solid #FFFFFF;
}
.v9-tab-count {
    background: #DBE6F5; color: #1B3A6B;
    font-size: 10px; font-weight: 700;
    padding: 1px 7px; border-radius: 999px;
}
.v9-tab-sub.is-active .v9-tab-count { background: #1B3A6B; color: #FFFFFF; }

/* Tab content stub — for tabs documented in V9 spec but not yet ported. */
.v9-tab-stub {
    background: #FFFBEB;
    border: 1px solid #FCD34D;
    border-radius: 0 0 8px 8px;
    border-top: none;
    padding: 18px 24px;
    color: #78350F;
}
.v9-tab-stub h3 { margin: 0 0 8px; font-size: 14px; color: #92400E; }
.v9-tab-stub p { margin: 6px 0; font-size: 12px; }
.v9-tab-stub code { background: #FDF1C8; padding: 1px 5px; border-radius: 4px; font-size: 11px; }

/* TodayTrack Setup tab — two-column layout: active filter snapshot on the
   left, the four V9 tier-4 reports on the right. Renders inside .tt-tab-body. */
.tt-setup-grid {
    display: grid;
    grid-template-columns: minmax(220px, 1fr) 2fr;
    gap: 16px;
    padding: 14px 18px 18px;
}
.tt-setup-panel {
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 6px;
    padding: 12px 14px;
}
.tt-setup-panel h4 {
    margin: 0 0 8px;
    font-size: 12px;
    font-weight: 600;
    color: #374151;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.tt-setup-panel dl { display: grid; grid-template-columns: 90px 1fr; gap: 4px 10px; margin: 0; font-size: 12px; }
.tt-setup-panel dt { color: #6B7280; }
.tt-setup-panel dd { margin: 0; color: #111827; font-weight: 500; }
.tt-setup-reports { margin: 0; padding: 0 0 0 18px; font-size: 12px; line-height: 1.6; color: #374151; }
.tt-setup-reports strong { color: #111827; }
.tt-setup-note { margin: 10px 0 0; font-size: 11px; color: #6B7280; }
.tt-setup-note code { background: #F3F4F6; padding: 1px 4px; border-radius: 3px; }

/* ─────────────────────────────────────────────────────────────────────────
   RequireRight — page-mode "Not authorized" notice. Used at the top of
   gated Razor pages when the user lacks the required EmployeeRights flag.
   ───────────────────────────────────────────────────────────────────────── */
.rr-deny-page {
    max-width: 560px;
    margin: 48px auto;
    padding: 24px 28px;
    background: #FFF7ED;
    border: 1px solid #FDBA74;
    border-left: 4px solid #EA580C;
    border-radius: 8px;
    color: #7C2D12;
    font-size: 13px;
    line-height: 1.6;
}
.rr-deny-page h2 {
    margin: 0 0 8px;
    font-size: 18px;
    font-weight: 700;
    color: #9A3412;
}
.rr-deny-page p { margin: 6px 0; }
.rr-deny-page code {
    background: #FFEDD5;
    padding: 1px 6px;
    border-radius: 4px;
    font-family: 'DM Mono', monospace;
    font-size: 11.5px;
}
.rr-deny-page a {
    color: #C2410C;
    font-weight: 600;
    text-decoration: none;
}
.rr-deny-page a:hover { text-decoration: underline; }

/* ─────────────────────────────────────────────────────────────────────────
   "UI not wired" pattern — cross-page utility (used by Data Hub and any
   future feature that needs to ship a UI element ahead of its wire-up).

   Visual mute (.dh-not-wired) + small amber chip (.dh-nw-badge / .dh-nw-row)
   replaces fallback toasts that would otherwise pretend a stub is wired.
   The dashboard-specific look-and-feel lives in wwwroot/css/data-hub.css.
   ───────────────────────────────────────────────────────────────────────── */

/* ─────────────────────────────────────────────────────────────────────────
   Shell-switch footer — universal "Use desktop version" /
   "Use mobile version" toggle. Rendered by AppShellFooter, included
   from both MainLayout (.dh-main) and LiteLayout.

   Stays subtle: small, muted, no visual weight competing with the
   page content. Hover shows the underline so it reads as a link.
   ───────────────────────────────────────────────────────────────────────── */

.dh-shell-footer {
    margin-top: auto;
    padding: 14px 16px 18px;
    text-align: center;
    font-size: 11px;
    color: var(--dh-text2, #4a6a8a);
}
.dh-shell-switch {
    background: transparent;
    border: 1px solid rgba(0, 0, 0, 0.08);
    color: var(--dh-text2, #4a6a8a);
    font-size: 11px;
    font-weight: 500;
    padding: 6px 14px;
    border-radius: 16px;
    cursor: pointer;
    font-family: inherit;
    transition: all .12s;
}
.dh-shell-switch:hover {
    color: var(--dh-blue, #1565BE);
    border-color: rgba(21, 101, 190, 0.40);
    background: rgba(21, 101, 190, 0.04);
}
.dh-shell-switch--mobile {
    /* Same look for now; placeholder hook if we want to differentiate later. */
}

/* ── "UI not wired" pattern ──
   .dh-not-wired       — visual mute applied to a wrapper around the unwired
                         element; disables interaction and grays out colors
   .dh-nw-badge        — small amber chip used as a label beneath/beside it
   .dh-nw-row          — fallback chip when the row itself acts as the
                         badge container (compact lists, entity-card footer)
*/
.dh-not-wired {
    pointer-events: none;
    opacity: 0.45;
    filter: grayscale(70%);
}

.dh-nw-badge {
    display: inline-block;
    font-size: 9px;
    line-height: 1.2;
    background: #FEF3C7;
    color: #92400E;
    padding: 1px 6px;
    border-radius: 3px;
    white-space: nowrap;
    font-weight: 600;
    pointer-events: none;
}

.dh-nw-row {
    color: #92400E;
    font-weight: 600;
    font-size: 9px;
    opacity: 0.7;
}

/* ─────────────────────────────────────────────────────────────────────
   Dual-scroll grids — V9 fingerprint: every wide grid exposes a
   horizontal scrollbar at BOTH the top and the bottom of the table.
   Powered by /js/dual-scroll.js which auto-wraps every cm-table /
   tt-table / qt-table / inv-table / invc-table / rma-table / st-table /
   qt-avail-table at runtime (idempotent — MutationObserver watches for
   tab switches + row loads).

   The top scrollbar holds a single empty spacer whose width matches
   the table's natural scrollWidth, so the scrollbar thumb size and
   position track the bottom scrollbar exactly.
   ───────────────────────────────────────────────────────────────────── */
.dh-scroll-x {
    overflow-x: auto;
    overflow-y: hidden;
    /* Keep vertical layout natural; only horizontal needs the scroller. */
}
.dh-scroll-x-top {
    overflow-x: auto;
    overflow-y: hidden;
    /* macOS only shows scrollbars on hover by default. min-height 12px
       reserves a stable strip so the table doesn't jump on hover. */
    height: 14px;
    margin-bottom: 2px;
    /* Subtle hairline to separate from the table's own border-top, so
       the top scrollbar reads as a UI element rather than a stray strip. */
    border-bottom: 1px solid #EEF4FC;
}
.dh-scroll-x-top-spacer {
    /* Width is set imperatively by dual-scroll.js to match table.scrollWidth.
       1px height keeps it a no-content strip — only the scrollbar shows. */
    height: 1px;
}
/* Style the WebKit scrollbar so the top strip looks like a deliberate
   control rather than an OS artifact. Falls back to OS default on
   Firefox where these pseudos don't apply. */
.dh-scroll-x-top::-webkit-scrollbar,
.dh-scroll-x::-webkit-scrollbar {
    height: 10px;
}
.dh-scroll-x-top::-webkit-scrollbar-thumb,
.dh-scroll-x::-webkit-scrollbar-thumb {
    background: #C7D5EA;
    border-radius: 4px;
}
.dh-scroll-x-top::-webkit-scrollbar-thumb:hover,
.dh-scroll-x::-webkit-scrollbar-thumb:hover {
    background: #1B3A6B;
}
.dh-scroll-x-top::-webkit-scrollbar-track,
.dh-scroll-x::-webkit-scrollbar-track {
    background: #F4F8FE;
}

/* ── Document seal (read-only lock) + FieldTip — added 2026-06-06 ───────────── */
.doc-seal-bar {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin: 0 0 12px; padding: 8px 12px; border-radius: 8px;
    font-size: 13px; line-height: 1.3;
    background: #FBEAEA; color: #7A1F1F; border: 1px solid #E0A3A3;
}
.doc-seal-bar--override { background: #FAF1DA; color: #7A5A12; border-color: #E0C77A; }
.doc-seal-bar--open     { background: transparent; color: var(--dh-ink-soft,#6b7280);
                          border: 1px dashed #D5DAE0; padding: 5px 10px; }
.doc-seal-ico  { font-size: 15px; }
.doc-seal-msg  { flex: 1 1 auto; min-width: 180px; }
.doc-seal-sub  { font-weight: 400; opacity: 0.8; }
.doc-seal-hint { font-size: 12px; opacity: 0.8; }
.doc-seal-btn {
    appearance: none; cursor: pointer; white-space: nowrap;
    font-size: 12px; font-weight: 700; padding: 4px 11px; border-radius: 6px;
    background: #fff; color: #7A1F1F; border: 1px solid #E0A3A3;
}
.doc-seal-btn:hover { background: #7A1F1F; color: #fff; }
.doc-seal-btn--lock { color: var(--dh-ink-soft,#6b7280); border-color: #C9CFD6; }
.doc-seal-btn--lock:hover { background: #4A5568; color: #fff; border-color: #4A5568; }

/* FieldTip — a tiny, low-key "?" beside a field label or doc title. */
.field-tip {
    display: inline-flex; align-items: center; justify-content: center;
    width: 14px; height: 14px; margin-left: 4px; border-radius: 50%;
    font-size: 9px; font-weight: 700; line-height: 1; cursor: help;
    color: #9aa3 af; color: #9aa3af; background: transparent;
    border: 1px solid #cfd5dd; vertical-align: middle; user-select: none;
    transition: color .12s, border-color .12s, background .12s;
}
.field-tip:hover, .field-tip:focus { color: #fff; background: var(--dh-blue,#1B4F8A);
                                     border-color: var(--dh-blue,#1B4F8A); outline: none; }

/* Read-only document wrapper — <fieldset disabled> with no visual box. */
.doc-fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.doc-fieldset[disabled] { opacity: 0.97; }
