/* Max360 Theme System — theme tokens live in themes.css, loaded as a
   FINGERPRINTED <link> in App.razor <head> (before this file). Do NOT re-add an
   `@import url('./themes.css')` here: that URL is not fingerprinted, so when only
   themes.css changes (app.css unchanged), the browser keeps serving app.css and
   its @imported themes.css from immutable cache — token edits silently go stale. */

html, body {
    font-family: var(--max360-font-body);
    margin: 0;
    padding: 0;
    height: 100%;
    background-color: var(--max360-bg);
    color: var(--max360-text);
}

/* Body as a flex column so the impersonation bar (when present) sits in
   normal flow above the layout, and the layout itself flexes to fill the
   remaining viewport. This is what keeps the chat input bar above the
   bottom of the viewport regardless of the bar's height. */
body {
    display: flex;
    flex-direction: column;
}

h1, h2, h3, .max360-page-header h1 {
    font-family: var(--max360-font-heading);
    font-weight: var(--max360-heading-weight);
    letter-spacing: var(--max360-heading-tracking);
}

/* Shared lead-article headline — the big serif title on the Today and Desk
   "brief-letter"/hero surfaces. Defined once here so the surfaces can't drift
   apart. Color uses the page-scoped --t-ink token, which each surface's root
   (.today / .desk) defines and the headline inherits. Page-specific
   bits (margin, cursor, hover, <em> accent) stay in each page's scoped CSS. */
.max360-lead-headline {
    font-family: var(--max360-font-heading, 'Fraunces', Georgia, serif);
    font-weight: 400;
    font-size: 42px;
    line-height: 1.05;
    letter-spacing: -0.025em;
    font-variation-settings: 'opsz' 144;
    color: var(--t-ink);
}
@media (max-width: 900px) {
    .max360-lead-headline { font-size: 44px; }
}

.eyebrow {
    font-family: var(--max360-font-body);
    font-size: .78rem;
    letter-spacing: .22em;
    text-transform: uppercase;
    color: var(--accent);
    font-weight: 500;
    margin-bottom: 1rem;
}

/* Layout */
.max360-layout {
    display: flex;
    flex: 1 1 auto;
    min-height: 0;
}

.max360-main {
    flex: 1;
    padding: 1.5rem 2rem;
    overflow-y: auto;
}

/* Max Live at a desk is as tall as what the main area has left under any banner */
@media (min-width: 701px) {
    .max360-main:has(> .mt-page) {
        display: flex;
        flex-direction: column;
    }
}

/* Impersonation bar is hidden by default (no flash on first paint).
   The rail toggle toggles `body.max360-impersonation-bar-show` to reveal it,
   beating Bootstrap's `d-flex` (display:flex !important) on the bar.
   When actively impersonating (.max360-impersonation-active), the bar is always
   visible regardless of the toggle — the user must be able to reset it. */
.max360-impersonation-bar { flex: 0 0 auto; display: none !important; }
body.max360-impersonation-bar-show .max360-impersonation-bar { display: flex !important; }
.max360-impersonation-bar.max360-impersonation-active { display: flex !important; }

/* Sidebar Navigation */
.max360-sidebar {
    width: var(--max360-sidebar-width);
    background-color: var(--surface);
    color: var(--ink);
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    height: 100%;
    position: sticky;
    top: 0;
    overflow: hidden;
}

.max360-sidebar-brand {
    padding: 1rem 1.25rem;
    font-size: 1.25rem;
    font-weight: 700;
    border-bottom: 1px solid var(--rule);
    color: var(--ink);
}

.max360-sidebar-nav {
    list-style: none;
    padding: 0.5rem 0;
    margin: 0;
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: rgba(255,255,255,0.2) transparent;
}

.max360-sidebar-nav::-webkit-scrollbar {
    width: 6px;
}
.max360-sidebar-nav::-webkit-scrollbar-thumb {
    background: rgba(255,255,255,0.2);
    border-radius: 3px;
}
.max360-sidebar-nav::-webkit-scrollbar-thumb:hover {
    background: rgba(255,255,255,0.35);
}

.max360-sidebar-section {
    padding: 0.75rem 1.25rem 0.25rem;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--max360-text-muted);
}

.max360-sidebar-nav a {
    display: block;
    padding: 0.5rem 1.25rem;
    color: var(--ink-dim);
    text-decoration: none;
    font-size: 0.9rem;
    transition: background-color 0.15s;
}

.max360-sidebar-nav a:hover {
    background-color: var(--surface-2);
    color: var(--ink);
}

.max360-sidebar-nav a.active {
    background-color: var(--max360-primary);
    color: var(--max360-on-primary);
}

.max360-sidebar-group-toggle {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: transparent;
    border: 0;
    padding: 0.75rem 1.25rem 0.5rem;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--max360-text-muted);
    cursor: pointer;
    text-align: left;
}

.max360-sidebar-group-toggle:hover {
    color: var(--ink);
}

.max360-sidebar-group-toggle i {
    font-size: 0.75rem;
}

.max360-sidebar-subnav {
    list-style: none;
    padding: 0;
    margin: 0;
}

.max360-sidebar-subnav a {
    padding-left: 2rem;
    font-size: 0.85rem;
}

.max360-sidebar-user {
    padding: 0.75rem 1.25rem;
    border-top: 1px solid var(--rule);
    font-size: 0.8rem;
    color: var(--max360-text-muted);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* Two-tier nav: icon rail + secondary panel */
.max360-nav {
    display: flex;
    flex-shrink: 0;
    height: 100%;
    position: sticky;
    top: 0;
    /* Without an explicit z-index, this sticky element sits at the same
       "auto" stack level as any transformed content in .max360-main (e.g.
       Today's handwritten signoff, which uses `transform: rotate(...)` and
       thereby forms its own stacking context per the CSS transforms spec).
       Tied stack levels resolve by DOM order, and <main> renders after this
       nav, so that content would paint OVER the nav's own popovers (theme
       picker, scope/group picker) whenever they visually overlap — e.g. on
       the Today route, where the secondary panel collapses to width 0 and
       the page content sits flush against the icon rail. A positive z-index
       here unambiguously outranks any unpositioned/auto-level content. */
    z-index: 10;
}

.max360-rail {
    width: var(--max360-rail-width);
    background-color: var(--surface-2);
    color: var(--ink-dim);
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding: 0.5rem 0;
    border-right: 1px solid var(--rule);
    min-height: 0;
}

/* Only the nav scrolls. Making the whole rail scroll put the version number and the impersonation
   toggle below a fold you had to scroll to reach -- which is the footer problem the rail placement
   was chosen to avoid. Brand and foot are pinned; this middle absorbs the shortfall. */
.max360-rail-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    scrollbar-width: thin;
    scrollbar-color: var(--rule) transparent;
}
.max360-rail-scroll::-webkit-scrollbar { width: 4px; }
.max360-rail-scroll::-webkit-scrollbar-track { background: transparent; }
.max360-rail-scroll::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 2px; }
.max360-rail-scroll::-webkit-scrollbar-thumb:hover { background: var(--ink-dim); }

.max360-rail-brand {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0.65rem 0 0.5rem;
    border-bottom: 1px solid var(--rule);
    margin-bottom: 0.5rem;
}

/* The scope picker sits in this block, draws its own top rule and carries its own
   bottom padding — so the brand must not add a second gap under it. The picker
   renders nothing when there is no signed-in identity, hence :has() rather than a
   flat padding-bottom: 0 that would leave the signature sitting on the rule. */
.max360-rail-brand:has(.scope-lens) {
    padding-bottom: 0;
}

.max360-brand-signature {
    font-family: 'Caveat', 'Segoe Script', cursive;
    font-weight: 600;
    font-size: 1.65rem;
    line-height: 1;
    color: var(--max360-brand-accent, var(--accent));
    white-space: nowrap;
}

.max360-brand-dot {
    margin: 0 .12em;
    color: var(--max360-brand-accent, var(--accent));
    font-size: .7em;
    vertical-align: -.02em;
}

.max360-brand-num {
    font-size: .72em;
}

.max360-rail-btn {
    background: transparent;
    border: 0;
    color: var(--max360-text-muted);
    padding: 0.6rem 0.25rem;          /* the longest label, OPERATIONS, is 80px at 12px; the rail leaves 85 */
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.2rem;
    cursor: pointer;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    border-left: 3px solid transparent;
    transition: background-color 0.15s, color 0.15s;
}

.max360-rail-btn i {
    font-size: 1.25rem;
}

a.max360-rail-btn {
    position: relative;
}

.max360-rail-btn .chat-unread-rail {
    background-color: var(--max360-primary);
    color: var(--max360-on-primary);
    position: absolute;
    top: 0.25rem;
    right: 0.3rem;
    font-size: 0.7rem;
}

.max360-rail-btn:hover {
    color: var(--ink);
    background-color: var(--surface-2);
}

.max360-rail-btn.active {
    color: var(--max360-primary);
    background-color: var(--surface-2);
    border-left-color: var(--max360-primary);
}

/* the full menu's More pages button while its panel is showing; not .active, which marks where you are */
.max360-rail-btn.open {
    color: var(--ink);
    background-color: var(--surface);
}

/* the full menu's divider between the links both menus share and the More section */
.max360-rail-divider {
    margin: 0.5rem 0.6rem 0.15rem;
    padding-top: 0.35rem;
    border-top: 1px solid var(--rule);
    font-size: 0.625rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    text-align: center;
    color: var(--max360-text-muted);
}

/* More pages' list inside the phone's sheet; only drawn on a phone */
.max360-sheet-pages {
    list-style: none;
    margin: 0.25rem 0;
    padding: 0.25rem 0.5rem;
    background-color: var(--surface);
    border: 1px solid var(--rule);
    border-radius: 10px;
    columns: 2;
    column-gap: 0.75rem;
}
.max360-sheet-pages a,
.max360-sheet-pages a:visited {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 44px;
    color: var(--ink);
    text-decoration: none;
    font-size: 0.95rem;
    break-inside: avoid;
}
.max360-sheet-pages a.active { color: var(--max360-primary); }

.max360-rail-spacer {
    flex: 1;
}

.max360-rail-user {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    padding: 0.5rem 0;
    color: var(--max360-text-muted);
    border-top: 1px solid var(--rule);
    font-size: 1.25rem;
}

.max360-rail-user-btn {
    background: transparent;
    border: 0;
    color: inherit;
    padding: 0.25rem 0.5rem;
    cursor: pointer;
    line-height: 1;
    border-radius: 4px;
}
.max360-rail-user-btn:hover { color: var(--ink); background-color: var(--surface-2); }
.max360-rail-user-btn i { font-size: 1.25rem; }

/* The build number under the user block. Smallest, dimmest thing in the rail: it is a receipt,
   not a control, and it must not compete with anything a person came here to click. */
.max360-rail-version {
    background: transparent;
    border: 0;
    padding: 0.15rem 0.3rem;
    margin-top: 0.1rem;
    font-family: var(--bs-font-monospace, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 0.75rem;
    line-height: 1.2;
    letter-spacing: 0.01em;
    color: var(--max360-text-muted);
    opacity: 0.95;
    cursor: pointer;
    border-radius: 3px;
}
.max360-rail-version:hover,
.max360-rail-version:focus-visible { opacity: 1; background-color: var(--surface-2); }
.max360-rail-version--skew {
    color: var(--max360-warning);
    opacity: 1;
    font-weight: 600;
}

.max360-schema-skew code {
    font-size: 0.8em;
    white-space: nowrap;
}

.max360-rail-impersonation-toggle {
    background: transparent;
    border: 0;
    color: var(--max360-text-muted);
    padding: 0.4rem 0.25rem 0.2rem;
    margin-top: 0.25rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
    font-size: 0.75rem;
    line-height: 1;
    cursor: pointer;
    width: 100%;
}
.max360-rail-impersonation-toggle i { font-size: 1rem; }
.max360-rail-impersonation-toggle:hover { color: var(--ink); background-color: var(--surface-2); }
.max360-rail-impersonation-toggle.on { color: var(--max360-warning-ink); }

/* A desk rail holds twelve links, and at 68px each they overran a laptop-height window and drew a
   scrollbar beside the icons. The space between links now shrinks with the window's height, the
   foot's small controls share rows, and a window shorter still scrolls the links without a bar. */
@media (min-width: 701px) {
    .max360-rail-btn {
        padding-top: clamp(0.25rem, 0.7vh, 0.6rem);
        padding-bottom: clamp(0.25rem, 0.7vh, 0.6rem);
        line-height: 1.2;
    }
    .max360-rail-btn i { line-height: 1; }
    /* the full menu's More section is smaller, so an admin's longer rail still fits a laptop window */
    .max360-rail-btn.max360-rail-more {
        padding-top: clamp(0.15rem, 0.4vh, 0.4rem);
        padding-bottom: clamp(0.15rem, 0.4vh, 0.4rem);
        gap: 0.1rem;
        font-size: 0.66rem;
    }
    .max360-rail-btn.max360-rail-more i { font-size: 1.05rem; }
    .max360-rail-scroll { scrollbar-width: none; }
    .max360-rail-scroll::-webkit-scrollbar { display: none; }
    .max360-rail-user {
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: center;
        align-items: center;
        column-gap: 0.1rem;
    }
    .max360-rail-impersonation-toggle,
    .max360-rail-version { flex-basis: 100%; }
}

/* a laptop-height window: every rail button tighter, the same in both menus; an admin's full rail still scrolls below 830px */
@media (min-width: 701px) and (max-height: 1000px) {
    .max360-rail-btn { padding-top: 0.2rem; padding-bottom: 0.2rem; gap: 0.1rem; }
    .max360-rail-btn i { font-size: 1.1rem; }
    .max360-rail-btn.max360-rail-more { padding-top: 0.1rem; padding-bottom: 0.1rem; }
    .max360-rail-btn.max360-rail-more i { font-size: 0.95rem; }
}

/* The short rail's entries are links, not buttons, so they need the underline removed. */
a.max360-rail-btn,
a.max360-rail-btn:hover,
a.max360-rail-btn:visited { text-decoration: none; }

/* Pinned light banner, so it pins its own ink too: the framework's error bar has to stay legible even when theme CSS
   is what failed to load. */
#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    color: #3d2f00;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}
/* above the phone bar, which covers the foot of the page */
@media (max-width: 700px) {
    #blazor-error-ui { z-index: 1100; }
}
/* The global link rule paints anchors with --max360-primary, which is unreadable on this banner. */
#blazor-error-ui .reload { color: #6b4e00; }
#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
    color: #3d2f00;
}

/* The first connection failed: nothing else is on the page, so this is the page. */
#max-no-connection {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px 16px;
    background: var(--surface, #fff);
    color: var(--ink, #1a1f2b);
    text-align: center;
    font-family: system-ui, sans-serif;
}
#max-no-connection[hidden] { display: none; }
.max-no-connection-card { max-width: 22rem; }
.max-no-connection-card h1 { margin: 0 0 0.5rem; font-size: 1.35rem; font-weight: 600; }
.max-no-connection-card p { margin: 0 0 1.25rem; line-height: 1.45; }

/* What Max said about Call me. It sits beside the rail on a desk and above the bottom bar on a phone. */
.max360-callme-notice {
    position: fixed;
    left: calc(var(--max360-rail-width) + 1rem);
    bottom: 1rem;
    z-index: 1045;
    max-width: min(26rem, calc(100vw - var(--max360-rail-width) - 2rem));
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.75rem 0.5rem 0.75rem 0.9rem;
    background-color: var(--surface);
    color: var(--ink);
    border: 1px solid var(--rule);
    border-left: 4px solid var(--max360-warning);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    font-size: 0.9rem;
    line-height: 1.4;
}
.max360-callme-notice.ringing { border-left-color: var(--max360-primary); }
.max360-callme-notice > .bi { font-size: 1.1rem; line-height: 1.3; }
.max360-callme-notice > span { flex: 1 1 auto; min-width: 0; }
.max360-callme-notice-close {
    flex: 0 0 auto;
    min-width: 2.75rem;
    min-height: 2.75rem;
    margin: -0.7rem 0 -0.7rem 0;
    background: transparent;
    border: 0;
    color: var(--ink-dim);
}
@media (max-width: 700px) {
    .max360-callme-notice {
        left: 0.75rem;
        right: 0.75rem;
        max-width: none;
        bottom: calc(var(--max360-phonebar-height) + env(safe-area-inset-bottom) + 0.75rem);
    }
}

/* Phone: the rail gives way to a bar along the bottom, and More opens the rail as a sheet above
   it. 700px is ShortRail.PhoneMaxWidthPx; ShortRailTests holds the two together. */
.max360-phonebar,
.max360-phone-backdrop,
.max360-backbar { display: none; }

@media (max-width: 700px) {
    /* an iPhone's rubber-band bounce drags fixed panels, such as Today's Talk panel, along with the page */
    html:has(.tt-page), body:has(.tt-page) { overscroll-behavior-y: none; }
    .max360-layout { flex-direction: column; }
    /* 1.5rem at the sides because Today, Desk and Library bleed exactly that far past it */
    .max360-main { order: 1; min-height: 0; padding: 1rem 1.5rem; }

    .max360-nav {
        order: 2;
        height: auto;
        position: relative;
        flex-direction: column;
        z-index: 1030;
    }
    .max360-rail,
    .max360-panel-reopen { display: none; }

    .max360-phonebar {
        display: flex;
        position: relative;
        z-index: 3;
        align-items: stretch;
        background-color: var(--surface-2);
        border-top: 1px solid var(--rule);
        padding-bottom: env(safe-area-inset-bottom);
    }
    .max360-phonebar-btn {
        flex: 1 1 0;
        min-width: 0;
        min-height: var(--max360-phonebar-height);
        position: relative;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 0.15rem;
        padding: 0.35rem 0.15rem;
        background: transparent;
        border: 0;
        color: var(--max360-text-muted);
        font-size: 0.75rem;
        letter-spacing: 0.01em;
        text-decoration: none;
        white-space: nowrap;
    }
    .max360-phonebar-btn i { font-size: 1.35rem; line-height: 1; }
    .max360-phonebar-btn:hover,
    .max360-phonebar-btn:visited { color: var(--max360-text-muted); text-decoration: none; }
    .max360-phonebar-btn.active,
    .max360-phonebar-btn.active:visited { color: var(--max360-primary); }
    .max360-phonebar-btn .chat-unread-rail {
        position: absolute;
        top: 0.3rem;
        left: calc(50% + 0.5rem);
        font-size: 0.7rem;
        background-color: var(--max360-primary);
        color: var(--max360-on-primary);
    }

    .max360-phone-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.35);
        z-index: 1;
    }

    /* the home-screen app's Back: a row of its own above the page, where an iPhone app keeps it; a
       browser has its own back button, so it shows only in the app */
    html.max360-standalone .max360-backbar {
        display: flex;
        align-items: center;
        flex: 0 0 auto;
        min-height: 44px;
        padding: 0 0.5rem;
        background-color: var(--surface-2);
        border-bottom: 1px solid var(--rule);
    }
    .max360-backbar-btn {
        display: inline-flex;
        align-items: center;
        gap: 0.15rem;
        min-width: 44px;
        min-height: 44px;
        padding: 0 0.5rem 0 0.1rem;
        background: transparent;
        border: 0;
        color: var(--max360-primary);
        font-size: 1.0625rem;
    }
    .max360-backbar-btn i { font-size: 1.25rem; line-height: 1; }
    /* Max Live with its menus hidden keeps its own way back */
    .max360-layout:has(.mt-page-bare) > .max360-backbar { display: none; }

    .max360-nav.phone-more-open .max360-rail {
        display: flex;
        position: fixed;
        left: 0;
        right: 0;
        bottom: calc(var(--max360-phonebar-height) + env(safe-area-inset-bottom));
        width: auto;
        max-height: calc(100% - var(--max360-phonebar-height) - 2.5rem);
        overflow-y: auto;
        padding: 0.5rem 0.75rem 0;
        border-right: 0;
        border-top: 1px solid var(--rule);
        border-radius: 14px 14px 0 0;
        box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.18);
        z-index: 2;
    }
    .max360-nav.phone-more-open .max360-rail-brand {
        flex-direction: row;
        justify-content: space-around;
        align-items: center;
        padding: 0.25rem 0 0.5rem;
    }
    .max360-nav.phone-more-open .max360-brand-signature { display: none; }
    .max360-nav.phone-more-open .scope-lens,
    .max360-nav.phone-more-open .menu-mode { width: auto; margin-top: 0; border-top: 0; }
    .max360-nav.phone-more-open .max360-rail-scroll {
        flex: 0 0 auto;
        overflow: visible;
        display: grid;
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 0.25rem;
    }
    .max360-nav.phone-more-open .max360-rail-spacer,
    .max360-nav.phone-more-open .off-phone-sheet { display: none; }
    .max360-nav.phone-more-open .max360-rail-divider,
    .max360-nav.phone-more-open .max360-sheet-pages { grid-column: 1 / -1; }
    .max360-nav.phone-more-open .max360-rail-btn.open { background-color: var(--surface); }
    .max360-nav.phone-more-open .max360-rail-btn {
        border-left: 0;
        border-radius: 10px;
        min-height: 64px;
        justify-content: center;
        font-size: 0.75rem;
    }
    .max360-nav.phone-more-open .max360-rail-btn.active { background-color: var(--surface); }
    /* the foot is a row, and its right end is left clear for the help and feedback buttons below */
    .max360-nav.phone-more-open .max360-rail-user {
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: flex-start;
        gap: 0.5rem 0.75rem;
        min-height: 64px;
        margin-top: 0.5rem;
        padding: 0.5rem 124px 0.5rem 0.25rem;
    }
    .max360-nav.phone-more-open .max360-rail-impersonation-toggle { width: auto; margin-top: 0; }
    /* the rail's pop-ups open to the right of a 96px rail; in the sheet that is off the screen */
    .max360-nav.phone-more-open .scope-lens-menu,
    .max360-nav.phone-more-open .user-menu-popup,
    .max360-nav.phone-more-open .bell-popover,
    .max360-nav.phone-more-open .theme-toggle-menu {
        position: fixed;
        left: 0.75rem;
        right: 0.75rem;
        top: auto;
        bottom: calc(var(--max360-phonebar-height) + env(safe-area-inset-bottom) + 0.75rem);
        width: auto;
        min-width: 0;
        max-width: none;
        margin: 0;
    }

    /* help and feedback float over the page on a desk; on a phone they would cover its controls, so
       they show only while More is open, in the corner the sheet's foot leaves clear */
    .max360-layout .contextual-help-btn,
    .max360-layout .product-feedback-btn { display: none; }
    body:has(.max360-nav.phone-more-open) .max-fab-dock { display: none; }
    body:has(.max360-nav.phone-more-open) .max360-layout .contextual-help-btn {
        display: flex;
        right: 1rem;
        bottom: calc(var(--max360-phonebar-height) + env(safe-area-inset-bottom) + 8px);
    }
    body:has(.max360-nav.phone-more-open) .max360-layout .product-feedback-btn {
        display: flex;
        right: calc(1rem + 60px);
        bottom: calc(var(--max360-phonebar-height) + env(safe-area-inset-bottom) + 12px);
    }

    .max360-lead-headline { font-size: 32px; }

    /* Max Live pads its own head and pins its own bottom panel */
    .max360-main:has(> .mt-page) { padding: 0; }

    /* Max Live, empty board, or a conversation still opening before the board has drawn: the
       transcript takes the middle and the controls pin under it, so they do not start at the top and
       drop once the board arrives. the prefix must outrank MaxTalk.razor.css's scoped phone rules */
    .max360-layout .max360-main .mt-page.mt-page-board:has(.mtb-empty) > .mtb { display: none; }
    .max360-layout .max360-main .mt-page.mt-page-board:is(:has(.mtb-empty), :not(.mt-page-start):not(:has(.mtb))) .mt-shell-body {
        position: static;
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
        gap: 0.75rem;
        max-height: none;
        overflow: visible;
        background: transparent;
        border-top: 0;
        padding: 0.75rem 1rem 0;
    }
    .max360-layout .max360-main .mt-page.mt-page-board:is(:has(.mtb-empty), :not(.mt-page-start):not(:has(.mtb))) .mt-strip {
        order: 99;
        margin-top: auto;
        position: sticky;
        top: auto;
        bottom: 0;
        margin-left: -1rem;
        margin-right: -1rem;
        padding: 0.75rem 1rem;
        border-top: 1px solid var(--max360-border);
        border-bottom: 0;
    }
    /* with nothing on the board, or no conversation yet, there is no transcript to fold away */
    .max360-layout .max360-main .mt-page.mt-page-board:is(:has(.mtb-empty), :not(:has(.mtb))) .mt-strip-toggle { display: none; }
    .max360-layout .max360-main .mt-page.mt-page-board:is(:has(.mtb-empty), :not(:has(.mtb))):not(:has(.mt-mute)) .mt-level-row { display: none; }

    /* the folded header stays in reach while the transcript scrolls under it; one above the panel's 10
       below, which comes later in the page and otherwise paints over the title */
    .max360-layout .max360-main .mt-page.mt-page-board .mt-head {
        position: sticky;
        top: 0;
        z-index: 11;
        background: var(--max360-surface);
    }
    /* a chart on the board draws its canvas layers at z-index 1 to 5; the pinned panel sits above them */
    .max360-layout .max360-main .mt-page.mt-page-board .mt-shell-body { z-index: 10; }
    /* iPhone Safari draws a board card that scrolls sideways on a layer of its own, over a sticky header
       or panel that has none, whatever their z-index. opacity, not transform: a transform here would
       pin the send-for-review dialog inside the header instead of the screen */
    .max360-layout .max360-main .mt-page.mt-page-board .mt-head,
    .max360-layout .max360-main .mt-page.mt-page-board .mt-shell-body { will-change: opacity; }
    /* the review dialog and the what-you-sent panel open inside the header, whose 11 would leave them
       under the phone's menu bar at 1030; while one is open the header goes above it */
    .max360-layout .max360-main .mt-page.mt-page-board .mt-head:has(.rsd, .ras) { z-index: 1061; }
    .max360-layout .max360-main .mt-page .mt-read-only,
    .max360-layout .max360-main .mt-page .mt-awake-intent { font-size: 0.8125rem; line-height: 1.4; margin: 0; }

    /* before Start the level bar has nothing to show */
    .max360-layout .max360-main .mt-page:not(:has(.mt-mute)) .mt-level { display: none; }

    /* iPhone Safari zooms the whole page into any field whose text is under 16px, and stays zoomed;
       important because every page styles its own fields more specifically than this can */
    input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]):not([type=file]),
    select,
    textarea { font-size: 16px !important; }

    /* Calendar is a fixed frame whose header fills a phone, leaving the events no height at all;
       on a phone the page scrolls as one instead. */
    .cal-page .cal-grid-area,
    .cal-page .cal-view-container { flex: 0 0 auto; overflow: visible; }
    .cal-page .cal-agenda { overflow: visible; }
}

/* When the Ask page is mounted, let it consume the full main area — no
   parent padding letterboxing, no parent scroll. The page itself owns
   the viewport height and lays out its internal scroll regions. Same
   pattern as the existing AIAssistantPanel hook. */
.max360-main:has(.ask) {
    padding: 0;
    overflow: hidden;
    height: 100%;
    display: flex;
    flex-direction: column;
}
.max360-main:has(.ask) > .ask {
    flex: 1;
    min-height: 0;
}

/* Same viewport-bound treatment for the knowledge document viewer — lets each
   pane (document + chat) own its own scroll region independently. */
.max360-main:has(.kbdoc-page) {
    padding: 0;
    overflow: hidden;
    height: 100%;
    display: flex;
    flex-direction: column;
}
.max360-main:has(.kbdoc-page) > .kbdoc-page {
    flex: 1;
    min-height: 0;
}

/* ── Calendar & Entity-detail: full-height dock pages ─────────────────────
   Same edge-to-edge, own-scroll treatment as .ask / .kbdoc-page: strip the
   main padding, fill the viewport, and let the left workarea and the right
   ChatDock each own their scroll. The chat dock thereby reaches the very top
   of the page rather than sitting below the header. */
.max360-main:has(.cal-page),
.max360-main:has(.ent-detail-grid) {
    padding: 0;
    overflow: hidden;
    height: 100%;
    display: flex;
    flex-direction: column;
}
.max360-main:has(.cal-page) > .cal-page,
.max360-main:has(.ent-detail-grid) > .ent-detail-grid {
    flex: 1;
    min-height: 0;
}

/* Flex row: scrollable workarea on the left, full-height dock on the right. */
.cal-page,
.ent-detail-grid {
    display: flex;
    align-items: stretch;
    height: 100%;
    min-height: 0;
    gap: 0;
}
.cal-workarea,
.ent-detail-main {
    flex: 1 1 auto;
    min-width: 0;
    overflow-y: auto;
    padding: 1.5rem 2rem;
}
/* The calendar workarea is itself a flex column so the grid area fills the
   height below the (non-scrolling) page header. */
.cal-workarea { display: flex; flex-direction: column; }

/* ── Shared ChatDock chrome (Calendar + Entity-detail) ───────────────────── */
.chat-dock {
    flex: 0 0 auto;
    width: 380px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--surface);
    border-left: 1px solid var(--rule);
}
.chat-dock.chat-dock-collapsed { width: 40px; }
.chat-dock-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.6rem 0.85rem;
    border-bottom: 1px solid var(--rule);
    color: var(--ink);
    flex: 0 0 auto;
}
.chat-dock-collapse-phone { display: none; }
/* a dock open on a phone fills the screen, so its way out is a word, at a size a thumb can hit */
@media (max-width: 700px) {
    .chat-dock-collapse { display: inline-flex; align-items: center; }
    .chat-dock-collapse-desk { display: none; }
    .chat-dock-collapse-phone { display: inline-flex; align-items: center; gap: 0.35rem; }
}
.chat-dock-body { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }
/* Collapsed: a thin vertical rail that reopens the dock. */
.chat-dock-rail {
    width: 100%;
    height: 100%;
    background: transparent;
    border: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 12px 0;
    cursor: pointer;
    color: var(--ink-dim);
}
.chat-dock-rail:hover { color: var(--accent); }
.chat-dock-rail-label {
    writing-mode: vertical-rl;
    text-orientation: mixed;
    font-family: var(--max360-font-label);
    font-size: 10px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
}
/* the event drawer is modal, so Calendar's Max button stays off it while it is open */
body:has(.cal-page.cal-drawer-active) .max-fab-dock { display: none; }
/* Maxbox on a phone: the round Max button, and the Talk panel while Max is not talking, stay off an open email and the
   page's own bottom sheets, and the Undo toasts rise above the button */
@media (max-width: 700px) {
    body:has(.mbs-row.is-full) .max-fab-dock,
    body:has(.mb-sheet-veil) .max-fab-dock,
    body:has(.mbs-split-veil) .max-fab-dock,
    body:has(.mbs-row.is-full) .tt-bar[data-dock="idle"],
    body:has(.mb-sheet-veil) .tt-bar[data-dock="idle"],
    body:has(.mbs-split-veil) .tt-bar[data-dock="idle"] { display: none; }
    body:has(.max-fab-dock) .mbs-toasts { bottom: calc(var(--max360-phonebar-height) + env(safe-area-inset-bottom) + 12px + 56px + 12px); }
}
/* The fixed help and feedback buttons would sit on the open dock's Send button, so they move left of it. */
@media (min-width: 701px) {
    body:has(.chat-dock:not(.chat-dock-collapsed)):not(:has(.cal-drawer-active)) .contextual-help-btn { right: calc(380px + 24px); }
    body:has(.chat-dock:not(.chat-dock-collapsed)):not(:has(.cal-drawer-active)) .product-feedback-btn { right: calc(380px + 28px); }
}

/* Generalized dock-page shell for list pages (Entities, Knowledge): a
   scrollable workarea on the left + the shared .chat-dock on the right,
   full-height like the calendar/entity-detail pages. */
.max360-main:has(.cdock-page) {
    padding: 0;
    overflow: hidden;
    height: 100%;
    display: flex;
    flex-direction: column;
}
.max360-main:has(.cdock-page) > .cdock-page { flex: 1; min-height: 0; }
.cdock-page { display: flex; align-items: stretch; height: 100%; min-height: 0; }
.cdock-workarea { flex: 1 1 auto; min-width: 0; overflow-y: auto; padding: 1.5rem 2rem; }

@media (max-width: 700px) {
    .chat-dock { display: none; }
    .cdock-workarea { padding: 1rem; }
}

.max360-panel {
    width: var(--max360-panel-width);
    background-color: var(--surface-2);
    color: var(--ink);
    display: flex;
    flex-direction: column;
    align-self: flex-start;
    max-height: calc(100vh - 2.5rem);
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--rule) transparent;
    padding: 24px 20px;
    margin: 1.25rem 0 1.25rem 1.25rem;
    position: relative;
}
.max360-panel::-webkit-scrollbar { width: 4px; }
.max360-panel::-webkit-scrollbar-track { background: transparent; }
.max360-panel::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 2px; }
.max360-panel::-webkit-scrollbar-thumb:hover { background: var(--ink-dim); }

/* User-toggled collapse: panel slides away entirely; reopen tab sits
   in its place on the inner edge of the icon rail. */
.max360-panel.max360-panel-hidden {
    width: 0;
    margin: 0;
    padding: 0;
    border: none;
    overflow: hidden;
}
/* a phone has no room beside the page for the submenu, which otherwise takes the page's whole height */
@media (max-width: 700px) {
    .max360-panel { display: none; }
}
.max360-panel-collapse {
    position: absolute;
    top: 6px;
    right: 6px;
    background: transparent;
    border: none;
    color: var(--ink-dim);
    font-size: 16px;
    line-height: 1;
    padding: 4px 8px;
    cursor: pointer;
    z-index: 2;
}
.max360-panel-collapse:hover { color: var(--accent); }
.max360-panel-hidden .max360-panel-collapse { display: none; }

.max360-panel-reopen {
    position: absolute;
    top: 1.25rem;
    left: var(--max360-rail-width);
    z-index: 6;
    width: 18px;
    height: 44px;
    background: var(--surface-2);
    border: 1px solid var(--rule);
    border-left: none;
    color: var(--ink);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    padding: 0;
    border-radius: 0 4px 4px 0;
}
.max360-panel-reopen:hover { color: var(--accent); border-color: var(--accent); }

/* ─── Scoped Admin panel: section switcher + search overlay ─────────── */
.max360-admin-switcher {
    display: flex; align-items: center; gap: 8px; width: calc(100% - 12px);
    margin: 6px; padding: 7px 10px; background: var(--surface); border: 1px solid var(--rule);
    border-radius: 6px; color: var(--ink); cursor: pointer; font-size: 12px;
}
.max360-admin-switcher-label { flex: 1; text-align: left; font-weight: 500; }
.max360-admin-switcher-menu { list-style: none; margin: 0 6px 6px; padding: 4px; background: var(--surface-2); border: 1px solid var(--rule); border-radius: 6px; }
.max360-admin-switcher-menu button {
    display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 8px;
    background: transparent; border: none; color: var(--ink-dim); border-radius: 4px;
    cursor: pointer; font-size: 12px; text-align: left;
}
.max360-admin-switcher-menu button:hover { color: var(--accent); }
.max360-admin-switcher-menu button.active { color: var(--ink); }
.max360-admin-switcher-menu button span:first-of-type { flex: 1; }
.max360-admin-search-toggle {
    display: flex; align-items: center; gap: 8px; width: calc(100% - 12px); margin: 4px 6px;
    padding: 6px 10px; background: transparent; border: none; color: var(--ink-dim);
    cursor: pointer; font-size: 11px;
}
.max360-admin-search-toggle:hover { color: var(--accent); }
.max360-admin-search-input {
    width: calc(100% - 12px); margin: 0 6px 6px; padding: 6px 8px; background: var(--surface);
    border: 1px solid var(--rule); border-radius: 6px; color: var(--ink); font-size: 12px;
}

/* ─── Panel brand block (top-of-card identity) ─────────── */
.max360-panel-brand {
    padding: 0 0.25rem 1rem;
    margin: 0 0 0.25rem;
    border-bottom: 1px solid var(--rule);
}

.max360-panel-brand-meta {
    font-family: var(--max360-font-label);
    font-size: 9px;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--ink-dim);
    margin-bottom: 14px;
}




.max360-panel-brand-name {
    font-family: var(--max360-font-heading, 'Fraunces', Georgia, serif);
    font-style: italic;
    font-weight: 500;
    font-size: 1.5rem;
    letter-spacing: -0.015em;
    line-height: 1;
    color: var(--ink);
    font-variation-settings: 'opsz' 144;
}


.max360-panel-brand-eyebrow {
    margin-top: 6px;
    font-family: var(--max360-font-label);
    font-size: 9px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--ink-dim);
}

/* ─── Panel foot (handwritten sign-off + meta) ─────────── */
.max360-panel-foot {
    padding-top: 16px;
    margin-top: 24px;
    border-top: 1px solid var(--rule);
    font-family: var(--max360-font-label);
    font-size: 9px;
    color: var(--ink-dim);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    line-height: 1.7;
}

.max360-panel-foot-sig {
    font-family: 'Caveat', 'Segoe Script', cursive;
    font-size: 22px;
    font-weight: 600;
    color: var(--accent);
    letter-spacing: 0;
    text-transform: none;
    line-height: 1;
    margin-bottom: 6px;
    transform: rotate(-3deg) translateX(-2px);
    display: inline-block;
}

.max360-panel-section {
    padding: 0.5rem 0.5rem 0.4rem;
    margin: 1.25rem 0.5rem 0.5rem 1.4rem;
    font-family: var(--max360-font-label);
    font-size: 0.625rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.28em;
    color: var(--ink-dim);
    border-bottom: 1px solid var(--rule);
}

.max360-panel-nav {
    list-style: none;
    padding: 0;
    margin: 0;
}

.max360-panel-nav a,
.max360-panel-nav a:visited {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.4rem 0.85rem 0.4rem 1.4rem;
    color: var(--ink-dim);
    text-decoration: none;
    font-size: 0.9rem;
    position: relative;
    transition: color 0.15s;
}

.max360-panel-nav a i {
    display: none;
}

.max360-panel-nav a:hover,
.max360-panel-nav a:visited:hover {
    color: var(--accent);
    background: transparent;
}

.max360-panel-nav a.active {
    color: var(--ink);
    background: transparent;
}

.max360-panel-nav a.active::before {
    content: '';
    position: absolute;
    left: 0.4rem;
    top: 50%;
    transform: translateY(-50%);
    width: 6px;
    height: 6px;
    background: var(--accent);
}

/* Page headers */
.max360-page-header {
    margin-bottom: 1.5rem;
}

.max360-page-header h1 {
    font-size: 1.5rem;
    font-weight: 600;
    margin: 0 0 0.25rem;
}

.max360-page-header p {
    color: var(--max360-text-muted);
    margin: 0;
}

/* Second header row on entity / relationship detail pages: type + status
   badges, confidence, and inline actions. Was previously unstyled, so the
   items rendered with no horizontal separation. */
.max360-entity-meta {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-top: 0.4rem;
}

/* Cards / Panels */
.max360-card {
    background: var(--max360-surface);
    border: 1px solid var(--max360-border);
    border-radius: 0.5rem;
    padding: 1.25rem;
    margin-bottom: 1rem;
}

/* Tables */
.max360-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--max360-surface);
    border: 1px solid var(--max360-border);
    border-radius: 0.5rem;
    overflow: hidden;
}

.max360-table th {
    background: var(--max360-bg);
    font-weight: 600;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--max360-text-muted);
    padding: 0.75rem 1rem;
    text-align: left;
    border-bottom: 1px solid var(--max360-border);
}

.max360-table td {
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--max360-border);
    font-size: 0.9rem;
}

.max360-table tbody tr:hover {
    background-color: var(--surface-2);
}

.max360-table tbody tr:last-child td {
    border-bottom: none;
}

/* The row a table has exactly one of. The tint is what stops somebody reading
   seventeen rows to find it; the left edge is what survives a theme where the tint
   is nearly invisible, and a forced-colours mode where background tints are dropped
   entirely. Both derive from the success tokens, so the row and the badge inside it
   carry one signal rather than two. */
.max360-table tbody tr.max360-row-current > td {
    background: var(--max360-success-soft);
}

.max360-table tbody tr.max360-row-current > td:first-child {
    box-shadow: inset 3px 0 0 0 var(--max360-success-ink);
}

/* Hover must not read as "this one is now the default". */
.max360-table tbody tr.max360-row-current:hover > td {
    background: color-mix(in srgb, var(--max360-success-soft) 70%, var(--surface-2));
}

/* One unbreakable token in a cell -- a Teams thread id, a directory GUID, a
   machine name, a voice name -- sets that column's MIN-CONTENT width, and in an
   auto-layout table that minimum becomes the whole table's, so every other
   column is squeezed to fit it. `overflow-wrap: anywhere` is what lowers
   min-content; `break-word` does not, because it breaks the word for painting
   and still reserves the unbroken width. Wrapping is wanted wherever one of
   these values renders, so it is unconditional; use -token for identifiers and
   -prose for free text such as a display name. */
.max360-cell-token,
.max360-cell-prose {
    overflow-wrap: anywhere;
}

/* The cap is a TABLE concern and is scoped to one. A token that cannot break
   still bulges past its share of an auto-layout table, so the wrap alone leaves
   the column wider than it should be. Outside a table there is no column to
   crush: a `dd` is full width, and capping the page subtitle at 34ch wrapped
   "A Teams meeting <middot> 28 Aug 2026 16:21:29" onto two lines. */
.max360-table .max360-cell-token { max-width: 20ch; }
.max360-table .max360-cell-prose { max-width: 34ch; }

/* Editorial cream theme: card surfaces blend with the paper. The white
   default (--max360-surface = #FFFFFF) reads as a contrasting raised
   card on cream; in this theme the design language is "everything sits
   on one paper", so cards take the page tone and rely on their border
   for definition. Table headers use --surface-2 (recessed cream) so
   they remain visually distinct from body rows. */
.theme-max-deck-light .max360-card,
.theme-max-deck-light .max360-table,
.theme-max-deck-light .max360-thread-card,
.theme-max-deck-light .max360-admin-hub-card {
    background: var(--bg);
    border-color: var(--rule);
}

/* Modal dialogs reuse .max360-card on top of a backdrop. The theme override
   above blends inline cards into the page; for modals it would make the
   dialog appear transparent over its own backdrop. Restore an opaque
   surface for any card that follows a modal backdrop in the DOM. */
.theme-max-deck-light .max360-modal-backdrop ~ .max360-card {
    background: var(--max360-surface);
}

/* A page that is one long stack of .max360-card sections. On the default theme
   --max360-bg and --max360-surface are both #ffffff, so a 1px hairline was the
   only thing between two sections and the stack read as one sheet. Three signals,
   because no one of them survives every theme: the tinted title band shows where
   a section starts, the darkened edge holds on a theme whose --surface-2 is close
   to its surface, and the shadow is dropped by forced colors where both tints go.
   Must come after the .theme-max-deck-light card override above, which has the
   same specificity. */
.max360-stacked-sections > .max360-card {
    margin-bottom: 2rem;
    border-color: color-mix(in srgb, var(--max360-border) 80%, var(--max360-text) 20%);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05), 0 2px 6px rgba(15, 23, 42, 0.05);
}

/* h2 as well as h3: two of the sections come from child components under
   Pages/Sources/ and one of them heads itself with an h2.
   the negative margin and the radius restate .max360-card's padding and radius;
   change them together, and keep the radius one border-width smaller.
   rounding the band rather than clipping the card leaves the quick tour's
   spotlight glow, which draws outside a highlighted inner div, unclipped. */
.max360-stacked-sections > .max360-card > h2:first-child,
.max360-stacked-sections > .max360-card > h3:first-child {
    margin: -1.25rem -1.25rem 1.125rem;
    padding: 0.8125rem 1.25rem;
    font-size: 1.05rem;
    font-weight: 600;
    background: var(--surface-2);
    border-bottom: 1px solid color-mix(in srgb, var(--max360-border) 80%, var(--max360-text) 20%);
    border-radius: calc(0.5rem - 1px) calc(0.5rem - 1px) 0 0;
}

.theme-max-deck-light .max360-table th {
    background: var(--surface-2);
    border-bottom-color: var(--rule);
}

.theme-max-deck-light .max360-table tbody tr:hover {
    background-color: var(--surface-2);
}

/* Bootstrap .table override — same intent as .max360-table above. The
   white --bs-table-bg default fights the cream paper. Token overrides
   apply only inside this theme. */
.theme-max-deck-light .table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--ink);
    --bs-table-striped-bg: var(--surface-2);
    --bs-table-striped-color: var(--ink);
    --bs-table-hover-bg: var(--surface-2);
    --bs-table-hover-color: var(--ink);
    --bs-table-border-color: var(--rule);
    color: var(--ink);
    border-color: var(--rule);
}
.theme-max-deck-light .table > thead {
    background: var(--surface-2);
}
.theme-max-deck-light .table > thead th {
    background: var(--surface-2);
    border-bottom-color: var(--rule);
    color: var(--ink-dim);
    font-weight: 600;
}

/* Form inputs in the editorial theme: bootstrap defaults to white,
   which contrasts harshly with the cream paper. Use --surface-2 as a
   recessed-cream well so inputs read as inset on the page, with the
   accent picked up on focus. Pages that style their own inputs to be
   transparent (Ask Max composer, Knowledge filter search, graph
   popover dates) win on specificity and stay as-is. */
.theme-max-deck-light .form-control,
.theme-max-deck-light .form-select,
.theme-max-deck-light .form-control-sm,
.theme-max-deck-light .form-select-sm {
    background-color: var(--surface-2);
    border-color: var(--rule);
    color: var(--ink);
}
.theme-max-deck-light .form-control::placeholder {
    color: var(--ink-dim);
    opacity: 0.7;
}
.theme-max-deck-light .form-control:focus,
.theme-max-deck-light .form-select:focus {
    background-color: var(--surface-2);
    border-color: var(--accent);
    color: var(--ink);
    box-shadow: 0 0 0 0.15rem color-mix(in srgb, var(--accent) 22%, transparent);
}
.theme-max-deck-light .form-control:disabled,
.theme-max-deck-light .form-select:disabled {
    background-color: color-mix(in srgb, var(--surface-2) 70%, var(--bg) 30%);
    color: var(--ink-dim);
}
/* Bootstrap input-group addons inherit white; align them with inputs. */
.theme-max-deck-light .input-group-text {
    background-color: var(--surface-2);
    border-color: var(--rule);
    color: var(--ink-dim);
}

/* Raw HTML form elements (no bootstrap class) — same cream treatment.
   Pages that intentionally style their inputs transparent over a tinted
   parent use higher-specificity Blazor-scoped selectors, so they win. */
.theme-max-deck-light input:not([type]),
.theme-max-deck-light input[type="text"],
.theme-max-deck-light input[type="email"],
.theme-max-deck-light input[type="password"],
.theme-max-deck-light input[type="search"],
.theme-max-deck-light input[type="url"],
.theme-max-deck-light input[type="tel"],
.theme-max-deck-light input[type="number"],
.theme-max-deck-light input[type="date"],
.theme-max-deck-light input[type="datetime-local"],
.theme-max-deck-light input[type="time"],
.theme-max-deck-light input[type="month"],
.theme-max-deck-light input[type="week"],
.theme-max-deck-light select,
.theme-max-deck-light textarea {
    background-color: var(--surface-2);
    border-color: var(--rule);
    color: var(--ink);
}
.theme-max-deck-light input:focus,
.theme-max-deck-light select:focus,
.theme-max-deck-light textarea:focus {
    border-color: var(--accent);
    outline: none;
}
/* Checkboxes and radios use the accent color so the brand carries
   through; the cream rules above don't apply to these (they have
   their own paint model). */
.theme-max-deck-light input[type="checkbox"],
.theme-max-deck-light input[type="radio"] {
    accent-color: var(--accent);
}

/* Bootstrap form-check (checkboxes + .form-switch toggles) paints its
   own background; override the relevant tokens so it picks up cream
   and the accent on :checked. */
.theme-max-deck-light .form-check-input {
    background-color: var(--surface-2);
    border-color: var(--rule);
}
.theme-max-deck-light .form-check-input:checked {
    background-color: var(--accent);
    border-color: var(--accent);
}
.theme-max-deck-light .form-check-input:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 0.15rem color-mix(in srgb, var(--accent) 22%, transparent);
}

/* Bootstrap modal: panel surface, header, footer. White by default. */
.theme-max-deck-light .modal-content {
    background-color: var(--bg);
    border-color: var(--rule);
    color: var(--ink);
}
.theme-max-deck-light .modal-header,
.theme-max-deck-light .modal-footer {
    border-color: var(--rule);
}

/* Filters bar */
.max360-filters {
    display: flex;
    gap: 0.75rem;
    align-items: end;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.max360-filters label {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--max360-text-muted);
    display: block;
    margin-bottom: 0.25rem;
}

.max360-filters select,
.max360-filters input {
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--max360-border);
    border-radius: 0.375rem;
    font-size: 0.875rem;
}

/* Pagination */
.max360-pagination {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    margin-top: 1rem;
}

.max360-pagination button {
    padding: 0.4rem 0.8rem;
    border: 1px solid var(--max360-border);
    border-radius: 0.375rem;
    background: var(--max360-surface);
    cursor: pointer;
    font-size: 0.85rem;
}

.max360-pagination button:disabled {
    opacity: 0.5;
    cursor: default;
}

.max360-pagination span {
    font-size: 0.85rem;
    color: var(--max360-text-muted);
}

/* Knowledge Base layout */
.kb-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
    align-items: flex-end;
    background: var(--max360-surface);
    border: 1px solid var(--max360-border);
    border-radius: 0.5rem;
    padding: 0.85rem 1rem;
    margin-bottom: 1rem;
}
.kb-filter-group { display: flex; flex-direction: column; min-width: 160px; }
.kb-filter-group.kb-filter-narrow { min-width: 140px; }
.kb-filter-group.kb-filter-search { min-width: 240px; flex: 1 1 240px; }
.kb-filter-group.kb-filter-apply { min-width: auto; }
.kb-filter-group input[type=search] {
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--max360-border);
    border-radius: 0.375rem;
    font-size: 0.85rem;
    background: var(--max360-surface);
    color: var(--max360-text);
}
.kb-filter-group label {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--max360-text-muted);
    margin-bottom: 0.3rem;
}
.kb-filter-group select,
.kb-filter-group input[type=date] {
    padding: 0.4rem 0.55rem;
    border: 1px solid var(--max360-border);
    border-radius: 0.375rem;
    font-size: 0.85rem;
    background: var(--max360-surface);
    color: var(--max360-text);
}
.kb-filter-group select[multiple] { min-height: 5.25rem; }

.kb-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
.kb-card {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 0.75rem 1rem;
    align-items: start;
    background: var(--max360-surface);
    border: 1px solid var(--max360-border);
    border-radius: 0.6rem;
    padding: 0.9rem 1rem;
    transition: border-color 0.15s, box-shadow 0.15s, transform 0.05s;
}
.kb-card:hover {
    border-color: var(--max360-primary);
    box-shadow: 0 2px 8px rgba(37, 99, 235, 0.08);
}
.kb-card-selected {
    border-color: var(--max360-primary);
    background: rgba(201,152,106,0.1);
}
.kb-card-check { padding-top: 0.15rem; }
.kb-card-check input[type=checkbox] { width: 1rem; height: 1rem; cursor: pointer; }
.kb-card-body { min-width: 0; cursor: pointer; }
.kb-card-title-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-bottom: 0.3rem;
}
.kb-card-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--max360-text);
    margin: 0;
    line-height: 1.3;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    word-break: break-word;
}
.inline-title-editor { display: inline-flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.inline-title-editor .inline-title-text { /* inherit existing kb-card-title typography by class application at caller */ }
.inline-title-pencil {
    background: none; border: none; padding: 0 0.2rem; cursor: pointer;
    opacity: 0; transition: opacity 0.15s;
    color: var(--max360-text-muted); font-size: 0.75em; vertical-align: middle;
}
.inline-title-editor:hover .inline-title-pencil { opacity: 0.7; }
.inline-title-pencil:focus-visible { opacity: 1; outline: 1px dotted var(--max360-text-muted); outline-offset: 2px; }
.inline-title-input {
    font: inherit; padding: 0.1rem 0.3rem; min-width: 24rem;
    border: 1px solid var(--max360-border); border-radius: 3px; background: inherit;
}
.inline-title-badge {
    font-size: 0.65em; padding: 0.05em 0.35em; border-radius: 3px;
    margin-left: 0.5rem; color: var(--max360-text-muted);
    background: transparent;
    text-transform: lowercase; letter-spacing: 0; font-weight: normal;
    vertical-align: middle;
}
.inline-title-error {
    font-size: 0.8em; color: var(--max360-danger); margin-left: 0.4rem;
}
.kb-card-meta {
    font-size: 0.8rem;
    color: var(--max360-text-muted);
    margin-bottom: 0.4rem;
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}
.kb-card-summary {
    font-size: 0.875rem;
    color: var(--max360-text);
    margin: 0;
    line-height: 1.45;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
}
.kb-card-actions {
    display: flex;
    gap: 0.35rem;
    align-items: center;
    flex-shrink: 0;
}

/* Channel badges */
.kb-badge {
    display: inline-block;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.18rem 0.5rem;
    border-radius: 999px;
    border: 1px solid transparent;
    white-space: nowrap;
    flex-shrink: 0;
}
.kb-badge-file   { background: #eef2ff; color: #4338ca; border-color: #c7d2fe; }
.kb-badge-web    { background: #ecfdf5; color: #047857; border-color: #a7f3d0; }
.kb-badge-email  { background: #fef3c7; color: #92400e; border-color: #fde68a; }
.kb-badge-chat   { background: #fae8ff; color: #86198f; border-color: #f5d0fe; }
.kb-badge-api    { background: #e0f2fe; color: #075985; border-color: #bae6fd; }
.kb-badge-manual { background: #f1f5f9; color: #334155; border-color: #e2e8f0; }
.kb-badge-other  { background: var(--surface-2, #f8fafc); color: var(--max360-text-muted); border-color: var(--max360-border); }
.kb-badge-kind   { background: #eef9f0; color: #166534; border-color: #bbf7d0; }

@media (max-width: 720px) {
    .kb-card { grid-template-columns: auto 1fr; }
    .kb-card-actions { grid-column: 1 / -1; justify-content: flex-end; }
}

/* Alert */
.max360-alert-warning {
    background: var(--max360-warning-soft);
    border: 1px solid var(--max360-warning);
    color: var(--max360-warning-ink);
    padding: 0.75rem 1rem;
    border-radius: 0.375rem;
    margin-bottom: 1rem;
}

/* Subtle informational notice (the notes backfill advisory, etc.). */
.max360-alert-info {
    background: var(--max360-info-soft);
    border: 1px solid var(--max360-info-ink);
    color: var(--max360-info-ink);
    padding: 0.75rem 1rem;
    border-radius: 0.375rem;
    margin-bottom: 1rem;
}

/* Bootstrap's .alert-* still sits on about 55 older call sites, with its utility classes beside it.
   Its colors come from --bs-alert-* variables, so pointing those at the theme tokens makes every
   one of them follow the five themes without touching the sites. New code uses .max360-alert-*. */
.alert-info    { --bs-alert-bg: var(--max360-info-soft);    --bs-alert-color: var(--max360-info-ink);    --bs-alert-border-color: var(--max360-info-ink);    --bs-alert-link-color: var(--max360-info-ink); }
.alert-warning { --bs-alert-bg: var(--max360-warning-soft); --bs-alert-color: var(--max360-warning-ink); --bs-alert-border-color: var(--max360-warning); --bs-alert-link-color: var(--max360-warning-ink); }
.alert-success { --bs-alert-bg: var(--max360-success-soft); --bs-alert-color: var(--max360-success-ink); --bs-alert-border-color: var(--max360-success); --bs-alert-link-color: var(--max360-success-ink); }
.alert-danger  { --bs-alert-bg: var(--max360-danger-soft);  --bs-alert-color: var(--max360-danger-ink, var(--max360-danger)); --bs-alert-border-color: var(--max360-danger); --bs-alert-link-color: var(--max360-danger-ink, var(--max360-danger)); }
.alert-light   { --bs-alert-bg: var(--max360-surface);      --bs-alert-color: var(--max360-text);        --bs-alert-border-color: var(--max360-border);      --bs-alert-link-color: var(--max360-text); }

/* ── Theme-safe surfaces & chips ─────────────────────────────────────────────
   Every rule below sets BOTH halves — background AND color — from theme tokens.
   A tinted background with no paired color keeps inheriting the active theme's
   text, so a hardcoded light panel goes pale-on-white the moment a dark theme
   is active; that was the expanded-detail-panel bug. Color lives here; layout
   (padding/margin/width/height) stays at the call site. */

/* Recessed surface for expanded table rows, inline add/edit forms and code
   blocks. Uses --surface-2, the per-theme "recessed" alias defined in all five
   theme blocks — --max360-surface would match the card these sit inside and
   erase the inset look the original #f8fafc was there to create. */
.max360-inset-panel {
    background: var(--surface-2);
    color: var(--max360-text);
}

/* Tinted fills — chips, badges and callout panels. Same color contract at any
   size: pick the tint that matches the meaning, never a bare background. */
.max360-tint-info {
    background: var(--max360-info-soft);
    color: var(--max360-info-ink);
}

.max360-tint-warning {
    background: var(--max360-warning-soft);
    color: var(--max360-warning-ink);
}

/* danger-soft is translucent by design (its seven consumers composite it over
   whatever surface they sit on), so the ink is tuned against that composite over
   --max360-bg / --max360-surface rather than against a flat fill. */
.max360-tint-danger {
    background: var(--max360-danger-soft);
    color: var(--max360-danger-ink);
}

.max360-tint-success {
    background: var(--max360-success-soft);
    color: var(--max360-success-ink);
}

/* De-emphasised state labels — deleted, archived, suggested. */
.max360-tint-neutral {
    background: var(--max360-border);
    color: var(--max360-text);
}

/* ── Badges ──────────────────────────────────────────────────────────────────
   The tint block above has always said it was for "chips, badges and callout
   panels". The color half was written; the SHAPE half never was, so 326 call
   sites across 59 files carried .max360-badge and rendered as plain text —
   a status label indistinguishable from the sentence beside it. Measured and
   deferred 2026-08-03 (see Negotiations.razor.css); this is that deferral paid.

   .max360-badge is shape only and sets no color, so it inherits and stays
   theme-safe on its own. Every variant sets BOTH halves from a token pair,
   which is the same contract .max360-tint-* holds. A badge with no variant is
   deliberately uncoloured — it reads as a quiet label, not an error. */
.max360-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 2px 8px;
    border-radius: 999px;
    font-family: var(--max360-font-label);
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
    vertical-align: middle;
}

/* --max360-text, not -text-muted: measured across the five themes, muted on the
   recessed surface bottoms out at 4.28:1, under AA. The badge is already quiet
   from its size — it does not need a quiet color too. */
.max360-badge-secondary,
.max360-badge-muted {
    background: var(--surface-2);
    color: var(--max360-text);
}

/* No --max360-primary-soft token exists, and adding one would mean editing all
   five theme blocks for this one use. color-mix derives the tint from the
   primary token instead, so it tracks the theme without a new token.
   The hue carries the "primary" signal and the TEXT stays --max360-text: tinting
   the ink toward primary measured 3.66:1 on the light themes, and deriving it
   from the text color instead inverted to 1.10:1 on the dark ones — the same
   direction-agnostic break the paired-colour guard exists to catch. Plain text
   on a slightly stronger tint is >=5.92:1 everywhere. */
.max360-badge-primary {
    background: color-mix(in srgb, var(--max360-primary) 18%, transparent);
    color: var(--max360-text);
}

.max360-badge-warning {
    background: var(--max360-warning-soft);
    color: var(--max360-warning-ink);
}

/* a confirmation row inside a table that scrolls sideways on a phone stays on screen */
.models-confirm-body {
    position: sticky;
    left: 0;
    max-width: min(100%, calc(100vw - 3rem));
    white-space: normal;
}

.models-confirm-actions { display: flex; flex-wrap: wrap; gap: 0.6rem; margin: 0.6rem 0 0 0; }

.max360-badge-danger {
    background: var(--max360-danger-soft);
    color: var(--max360-danger-ink);
}

.max360-badge-success,
.max360-badge-active,
.max360-status-verified {
    background: var(--max360-success-soft);
    color: var(--max360-success-ink);
}

/* For a badge naming the ONE row a table has only one of -- the model Max answers
   with, in a list of seventeen. The base badge is deliberately quiet, which is right
   for a status label beside a sentence and wrong for one somebody has to find.
   FILLED, not soft: this badge sits on a row that already carries the soft tint, and
   the first cut used .max360-badge-active there -- identical color, so the chip
   disappeared into its own row. Ink on surface inverts correctly in both directions,
   because ink is already the token chosen to contrast with soft. */
.max360-badge-current {
    background: var(--max360-success-ink);
    color: var(--max360-surface);
    font-weight: 700;
    letter-spacing: 0.1em;
}

.max360-badge-topic {
    background: var(--max360-info-soft);
    color: var(--max360-info-ink);
}

.max360-status-rejected {
    background: var(--max360-danger-soft);
    color: var(--max360-danger-ink);
}

/* ── Page furniture ──────────────────────────────────────────────────────────
   .max360-page-header already styles its own h1 and p. These are the same two
   roles named explicitly, for the pages that reach for the class instead of
   relying on the descendant selector — plus the container, the action group
   that sits opposite the title, and the empty/section/stat primitives that
   were coined alongside them and never defined. Nothing here invents a look:
   each takes the value its neighbor in .max360-page-header already uses. */
.max360-page,
.max360-page-wrap {
    display: block;
    margin-bottom: 1.5rem;
}

.max360-page-title {
    font-size: 1.5rem;
    font-weight: 600;
    margin: 0 0 0.25rem;
}

.max360-page-subtitle {
    color: var(--max360-text-muted);
    margin: 0;
}

/* Title on the left, actions hard right, wrapping rather than colliding on a
   narrow viewport. */
.max360-page-header-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-left: auto;
}

.max360-section {
    margin-bottom: 1.5rem;
}

/* The title row of a .max360-card — the card owns the padding, so this only
   has to close the gap its heading would otherwise open. */
.max360-card-header {
    margin-bottom: 0.75rem;
}

.max360-card-header h2,
.max360-card-header h3,
.max360-card-header h4 {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 600;
}

/* Empty states — "nothing here yet" text, quieter than body copy. */
.max360-empty {
    color: var(--max360-text-muted);
    padding: 1rem 0;
}

/* Stat tiles inside a .max360-card: a small muted label over a large figure. */
.max360-stat-label {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--max360-text-muted);
    margin-bottom: 0.25rem;
}

.max360-stat-value {
    font-size: 1.75rem;
    font-weight: 600;
    line-height: 1.1;
}

.max360-stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 1rem;
}

/* A quiet inset note — softer than .max360-alert-info, which is for something
   the reader has to act on. */
.max360-callout {
    background: var(--surface-2);
    color: var(--max360-text);
    border-left: 3px solid var(--max360-border);
    padding: 0.75rem 1rem;
    border-radius: 0.375rem;
}

.max360-breadcrumbs {
    font-size: 0.9rem;
    color: var(--max360-text-muted);
    margin-bottom: 0.25rem;
}

/* Trailing table cell holding row actions — never wraps a button set onto two
   lines, and keeps the buttons off the cell edge. */
.max360-actions-cell {
    white-space: nowrap;
    text-align: right;
}

/* The "done / failed" line a form drops under itself after an action. Color
   is left to the caller (they add an alert or tint class when it matters). */
.max360-action-result {
    font-size: 0.875rem;
    color: var(--max360-text-muted);
}
.max360-action-result.is-error { color: var(--max360-danger-ink, var(--max360-danger)); }
.max360-action-result[role="status"] { margin: 0; }

/* Admin form fields: a label above its input, fields side by side on a desk
   and stacked on a phone, the row's action aligned to the inputs' baseline. */
.max360-field {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    min-width: 0;
}
.max360-field > label {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--max360-text);
}
.max360-field > input,
.max360-field > select,
.max360-field-inline > input,
.max360-field-inline > select {
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
}
.max360-field-hint {
    font-size: 0.85rem;
    color: var(--max360-text-muted);
    margin: 0.35rem 0 0;
    max-width: 65ch;
}
.max360-field-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: 0.75rem 1rem;
    max-width: 48rem;
}
/* one input with its action on the same line, for a single-value setting */
.max360-field-inline {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    max-width: 32rem;
}
.max360-field-inline > input,
.max360-field-inline > select { flex: 1 1 12rem; width: auto; }
.max360-form-actions {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 0.75rem;
}

/* Tables that can be wider than a phone scroll inside their own box, never the page. */
.max360-table-scroll {
    overflow-x: auto;
    max-width: 100%;
    /* holds an absolutely placed child, such as a visually-hidden column label, inside the box */
    position: relative;
}
.max360-table-scroll > .max360-table { margin-bottom: 0; }

/* ── Operational dashboard (/admin/ops, /my/ops) ─────────────────────────────
   Both pages shipped referencing 23 class names with no stylesheet anywhere in
   the Ops folder, so every rail, panel, issue row and trace hop rendered as a
   bare stacked div. The two pages carry deliberately duplicated markup (see the
   header comment in MyOperational.razor), which is exactly why these rules live
   in app.css and not in a scoped .razor.css: CSS isolation rewrites scoped
   selectors per component, so a page-scoped file could only ever reach one of
   the two.

   Widths are not arbitrary. OperationalChatPanel pins itself to width:360px and
   height:100% in its own <style> block, so the rail column is 360px and must
   give it a DEFINITE height or its flex:1 message list never becomes
   scrollable. .max360-main is the scrolling ancestor (flex:1; overflow-y:auto),
   which is what makes the sticky rail stick. */
.max360-ops-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: 1.5rem;
    align-items: start;
}

.max360-ops-main {
    min-width: 0;   /* without this a long trace label makes the grid overflow instead of wrapping */
}

.max360-ops-rail {
    position: sticky;
    top: 0;
    height: calc(100vh - 10rem);
    min-height: 400px;
}

/* One column once the rail would squeeze the main content. The chat keeps a
   fixed height here because it still needs a definite one to scroll. */
@media (max-width: 1100px) {
    .max360-ops-layout { grid-template-columns: minmax(0, 1fr); }
    /* max-width matches the chat panel's own pinned 360px — without it the rail
       stretches to the full column and the panel floats in dead space. */
    .max360-ops-rail { position: static; height: 560px; max-width: 360px; }
}

/* Small stat cards. The card's own margin-bottom would fight the grid gap. */
.max360-ops-panels {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
}

.max360-ops-panels > .max360-card {
    margin-bottom: 0;
}

.max360-ops-panel-metric {
    font-size: 1.75rem;
    font-weight: 600;
    line-height: 1.1;
    margin: 0;
}

.max360-ops-panel-sub {
    font-size: 0.8rem;
    color: var(--max360-text-muted);
    margin: 0.15rem 0 0;
}

/* label left, count badge hard right */
.max360-ops-panel-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.max360-ops-panel-list > li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.35rem 0;
    border-bottom: 1px solid var(--max360-border);
}

.max360-ops-panel-list > li:last-child { border-bottom: none; }

/* Needs attention: a severity glyph in a fixed-width gutter, then the body.
   The glyph is monospace so "!!" and "i" occupy the same column — severity is
   carried by the character and the title attribute, since the markup emits no
   per-severity class for CSS to color against. */
.max360-ops-issue-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.max360-ops-issue {
    display: flex;
    gap: 0.75rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--max360-border);
}

.max360-ops-issue:last-child { border-bottom: none; }

.max360-ops-issue-glyph {
    flex: 0 0 1.75rem;
    font-family: var(--max360-font-label);
    font-weight: 600;
    text-align: center;
    color: var(--max360-text-muted);
}

.max360-ops-issue-body { min-width: 0; }

.max360-ops-issue-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    font-weight: 600;
}

.max360-ops-issue-cause {
    font-size: 0.875rem;
    margin-top: 0.15rem;
}

.max360-ops-issue-action {
    font-size: 0.8rem;
    color: var(--max360-text-muted);
    margin-top: 0.2rem;
}

/* Trace lookup: query row, then one block per matched item with its hop chain. */
.max360-ops-trace-form {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    margin-bottom: 0.75rem;
}

.max360-ops-trace-form .form-control { flex: 1; min-width: 0; }

.max360-ops-trace-list,
.max360-ops-hops {
    list-style: none;
    margin: 0;
    padding: 0;
}

.max360-ops-trace-item {
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--max360-border);
}

.max360-ops-trace-item:last-child { border-bottom: none; }

.max360-ops-trace-label {
    font-weight: 600;
    overflow-wrap: anywhere;   /* a matched filename or subject can be very long */
}

.max360-ops-hops { margin-top: 0.35rem; }

/* One hop per row: status glyph, stage, and the reason it stopped if it did. */
.max360-ops-hop {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.15rem 0;
    font-size: 0.875rem;
}

.max360-ops-hop-glyph {
    flex: 0 0 2.25rem;
    font-family: var(--max360-font-label);
    font-size: 0.75rem;
    color: var(--max360-text-muted);
}

.max360-ops-hop-stage { font-weight: 500; }

.max360-ops-hop-reason {
    color: var(--max360-warning-ink);
    overflow-wrap: anywhere;
}

/* Progress bar track + fill. Neither carries text, but both halves are token
   driven so the track can't vanish into a dark page. */
.max360-progress-track {
    background: var(--max360-border);
    color: var(--max360-text);
}

.max360-progress-fill {
    background: var(--max360-primary);
    color: var(--max360-primary-ink, var(--max360-bg));
}

/* Document Viewer Panel */
.max360-viewer-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.3);
    z-index: 100;
}

.max360-viewer-panel {
    position: fixed;
    top: 0;
    right: 0;
    width: min(600px, 90vw);
    height: 100vh;
    background: var(--max360-surface);
    border-left: 1px solid var(--max360-border);
    box-shadow: -4px 0 12px rgba(0,0,0,0.1);
    z-index: 101;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}

/* Drag-resize handle — sits at the left edge of the overlay panel. */
.max360-viewer-resize-handle {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 6px;
    cursor: ew-resize;
    touch-action: none;
    z-index: 1;
    transition: background-color 0.15s;
}
.max360-viewer-resize-handle:hover,
.max360-viewer-resize-handle:active {
    background-color: color-mix(in srgb, var(--accent, #C9986A) 30%, transparent);
}

.max360-viewer-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--max360-border);
}

.max360-viewer-header h2 {
    font-size: 1.1rem;
    font-weight: 600;
    margin: 0;
}

.max360-viewer-header-actions {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    flex: 0 0 auto;
}

.max360-viewer-body {
    padding: 1.25rem;
    flex: 1;
}

.max360-viewer-meta {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-bottom: 0.75rem;
    font-size: 0.85rem;
    color: var(--max360-text-muted);
}
.max360-meta-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
}
.max360-meta-item {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    white-space: nowrap;
}
.max360-meta-value-inline {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    flex-wrap: nowrap;
}

.max360-viewer-content {
    white-space: pre-wrap;
    line-height: 1.6;
    font-size: 0.9rem;
}

.max360-viewer-markdown {
    white-space: normal;
}

/* A diagram body: the SVG is the whole document, so it gets the column's full width and its own
   aspect ratio rather than a thumbnail's. The light plate matters -- most committed diagrams are
   drawn for a white page and use dark strokes with no background of their own, which vanish
   against a dark surface. The text color is PINNED rather than tokenized for the same reason:
   the plate does not follow the theme, so a themed color would go white-on-white in dark mode.
   It reaches SVG text drawn with fill="currentColor". */
.max360-viewer-svg {
    white-space: normal;
    background: #ffffff;
    color: #1f2937;
    border: 1px solid var(--max360-border, #e5e7eb);
    border-radius: 6px;
    padding: 0.75rem;
    text-align: center;
    overflow-x: auto;
}
/* width:100%, NOT max-width:100%. An SVG that carries only a viewBox -- which is how every diagram
   in the repo is authored, so it scales -- has no intrinsic size, and a browser gives it the
   replaced-element default of 150px tall. Measured: doc 12380 rendered at 152x150 under max-width
   alone, a postage stamp of a 760x752 architecture diagram. width:100% + height:auto makes the
   viewBox's ratio do the sizing. */
.max360-viewer-svg-img {
    display: block;
    width: 100%;
    max-width: 100%;
    height: auto;
}

/* A whole HTML page rendered inside the document body. It gets a tall, fixed viewport that scrolls
   internally: the frame is sandboxed WITHOUT allow-same-origin, so it has an opaque origin and
   neither side can reach across to measure the content -- the usual auto-size trick needs exactly
   that reach -- and guessing low would cut the page off.

   Same fixed light plate as .max360-viewer-svg, pinned for the same reason. Here the color
   dresses the element's own box only -- the sandboxed document paints its own text -- so it is
   the pair's second half, not a claim about the embedded page. */
.max360-viewer-html {
    color: #1f2937;
    display: block;
    width: 100%;
    height: 70vh;
    min-height: 24rem;
    border: 1px solid var(--max360-border, #e5e7eb);
    border-radius: 6px;
    background: #ffffff;
}

.max360-meta-file .max360-doc-filename {
    font-family: var(--bs-font-monospace, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 0.9em;
    word-break: break-all;
}
.max360-meta-filesize { color: var(--max360-text-muted, #6b7280); }

/* Body present but not renderable as prose (binary bytes, or an SVG past the inline cap). */
.max360-viewer-nonprose {
    white-space: normal;
    color: var(--max360-text-muted, #6b7280);
    background: var(--max360-surface, #f9fafb);
    border: 1px solid var(--max360-border, #e5e7eb);
    border-radius: 6px;
    padding: 0.75rem;
}
.max360-viewer-nonprose strong { color: var(--max360-text, inherit); }
.max360-viewer-markdown p { margin: 0 0 0.6em; }
.max360-viewer-markdown p:last-child { margin-bottom: 0; }
.max360-viewer-markdown h1 { font-size: 1.4rem; font-weight: 600; margin: 0.75em 0 0.3em; }
.max360-viewer-markdown h2 { font-size: 1.2rem; font-weight: 600; margin: 0.75em 0 0.3em; }
.max360-viewer-markdown h3 { font-size: 1.05rem; font-weight: 600; margin: 0.75em 0 0.3em; }
.max360-viewer-markdown h4, .max360-viewer-markdown h5, .max360-viewer-markdown h6 {
    font-size: 0.95rem; font-weight: 600; margin: 0.75em 0 0.3em;
}
.max360-viewer-markdown ul, .max360-viewer-markdown ol { margin: 0 0 0.6em 1.5em; padding: 0; }
.max360-viewer-markdown li { margin-bottom: 0.2em; }
.max360-viewer-markdown code {
    background: var(--surface-2); border-radius: 3px;
    padding: 0.1em 0.35em; font-size: 0.88em;
}
.max360-viewer-markdown pre {
    background: #1e1e2e; color: #cdd6f4;
    border-radius: 6px; padding: 0.75em 1em;
    overflow-x: auto; margin: 0.5em 0;
}
.max360-viewer-markdown pre code { background: none; padding: 0; font-size: 0.85em; }
.max360-viewer-markdown table { border-collapse: collapse; margin: 0.5em 0; font-size: 0.9em; width: 100%; }
.max360-viewer-markdown th, .max360-viewer-markdown td {
    border: 1px solid var(--max360-border, #e5e7eb); padding: 0.3em 0.6em;
}
.max360-viewer-markdown th { background: var(--max360-surface, #f9fafb); font-weight: 600; }
.max360-viewer-markdown blockquote {
    border-left: 3px solid var(--max360-border, #e5e7eb);
    margin: 0.5em 0; padding: 0.25em 0.75em;
    color: var(--max360-text-muted, #6b7280);
}
.max360-viewer-markdown a { color: var(--max360-link, var(--max360-primary, #2563eb)); }

.markdown-body h1 { font-size: 1.4rem; font-weight: 600; margin: 0.75em 0 0.3em; }
.markdown-body h2 { font-size: 1.2rem; font-weight: 600; margin: 0.75em 0 0.3em; }
.markdown-body h3 { font-size: 1.05rem; font-weight: 600; margin: 0.75em 0 0.3em; }
.markdown-body h4, .markdown-body h5, .markdown-body h6 { font-size: 0.95rem; font-weight: 600; margin: 0.75em 0 0.3em; }

/* =============================================================================
   BUTTONS — unified editorial "kicker-link" system. Every kind of control is styled here and nowhere
   else: link, link-out, action, icon-btn, chip, remove, filter, choice, tab, send. Sizes come from the
   --max360-control-* tokens in themes.css. Spec: docs/superpowers/specs/2026-06-08-unified-button-style-design.md
   ============================================================================= */

/* --- Text actions --- */
.max360-action {
    --_bar: var(--max360-action-accent);
    --_barH: var(--max360-control-underline);
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    box-sizing: border-box;
    min-height: var(--max360-control-hit);
    padding: 6px 1px;
    background: none;
    border: 0;
    color: var(--max360-text);
    font-family: var(--max360-font-body, 'Inter', system-ui, sans-serif);
    font-size: var(--max360-control-font-size);
    font-weight: var(--max360-control-font-weight);
    letter-spacing: 0;
    line-height: 1;
    text-transform: none;
    text-decoration: none;            /* reset for <a> */
    cursor: pointer;
    transition: color 0.15s ease;
}
.max360-action::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 6px;
    height: var(--_barH);
    width: 100%;
    background: var(--_bar);
    opacity: 1;                       /* accent underline at rest, so an action never reads as plain text */
    transform: scaleX(1);
    transform-origin: left;
    transition: background 0.15s ease, opacity 0.15s ease, height 0.15s ease;
}
.max360-action:hover:not(:disabled):not(.is-loading) { color: var(--max360-action-ink); }
.max360-action:hover:not(:disabled):not(.is-loading)::after { background: var(--max360-action-accent); height: var(--max360-control-underline-strong); }

/* primary: tan label + solid 2px tan underline at rest */
.max360-action-primary { color: var(--max360-action-ink); }
.max360-action-primary::after { background: var(--max360-action-accent); height: var(--max360-control-underline-strong); opacity: 1; }

/* quiet: muted label, dotted accent underline at rest, solid on hover; a quiet danger action keeps danger's solid line */
.max360-action-quiet { color: var(--max360-text-muted); }
.max360-action-quiet:not(.max360-action-danger)::after { height: 0; background: none; border-bottom: 1px dotted var(--_bar); }
.max360-action-quiet:hover:not(:disabled):not(.is-loading) { color: var(--max360-text); }
.max360-action-quiet:not(.max360-action-danger):hover:not(:disabled):not(.is-loading)::after { height: 0; background: none; border-bottom-style: solid; }

/* text-color utilities (consume theme tokens from themes.css) */
.max360-text-muted   { color: var(--max360-text-muted); }
.max360-archive-line { color: var(--max360-text-muted); font-size: 0.85rem; margin: 0.1rem 0 0.25rem; }
.max360-text-success { color: var(--max360-success); }
.max360-text-danger  { color: var(--max360-danger); }
.max360-text-warn    { color: var(--max360-warning-ink); }

/* inline field validation error (below the input) */
.max360-field-error { color: var(--max360-danger); font-size: 0.85rem; margin-top: 0.25rem; }

/* confidence meter (entity/memory lists): track + proportional fill */
.max360-confidence-bar { height: 6px; background: var(--max360-border); border-radius: 3px; overflow: hidden; min-width: 60px; }
.max360-confidence-fill { height: 100%; background: var(--max360-primary); border-radius: 3px; }

/* themed grouping box — replaces the browser-default fieldset border on dark themes */
.max360-fieldset { border: 1px solid var(--max360-border); border-radius: 8px; padding: 1rem 1.25rem; margin: 0; }
.max360-fieldset > legend { width: auto; padding: 0 0.5rem; font-size: 0.9rem; font-weight: 600; color: var(--max360-text); }

/* danger: warm terracotta label + underline at rest (label uses the legible "ink" danger) */
.max360-action-danger { color: var(--max360-danger-ink, var(--max360-danger)); }
.max360-action-danger::after { background: var(--max360-danger-ink, var(--max360-danger)); opacity: 1; }
.max360-action-danger:hover:not(:disabled):not(.is-loading) { color: var(--max360-danger-ink, var(--max360-danger)); }
.max360-action-danger:hover:not(:disabled):not(.is-loading)::after { background: var(--max360-danger-ink, var(--max360-danger)); }

/* filled: solid is the one main action on a screen, danger-solid the confirm step of a destructive
   one. The fill is drawn thinner than the tap area, which stays --max360-control-hit tall. */
.max360-action-solid { --_fill: var(--max360-action-ink); --_on-fill: var(--max360-on-action); }
.max360-action-danger-solid { --_fill: var(--max360-danger); --_on-fill: var(--max360-on-danger); }
.max360-action-solid,
.max360-action-danger-solid { padding: 6px 16px; color: var(--_on-fill); isolation: isolate; }
.max360-action.max360-action-solid::after,
.max360-action.max360-action-danger-solid::after {
    top: 50%;
    bottom: auto;
    height: var(--max360-control-fill-height);
    transform: translateY(-50%);
    border-radius: 6px;
    background: var(--_fill);
    opacity: 1;
    z-index: -1;
}
.max360-action.max360-action-solid:hover:not(:disabled):not(.is-loading),
.max360-action.max360-action-danger-solid:hover:not(:disabled):not(.is-loading) { color: var(--_on-fill); }
.max360-action.max360-action-solid:hover:not(:disabled):not(.is-loading)::after,
.max360-action.max360-action-danger-solid:hover:not(:disabled):not(.is-loading)::after {
    height: var(--max360-control-fill-height);
    background: var(--_fill);
    filter: brightness(1.08);
}
.max360-action.max360-action-solid:disabled, .max360-action.max360-action-solid.is-loading,
.max360-action.max360-action-danger-solid:disabled, .max360-action.max360-action-danger-solid.is-loading { color: var(--_on-fill); }
.max360-action.max360-action-solid:disabled::after, .max360-action.max360-action-solid.is-loading::after,
.max360-action.max360-action-danger-solid:disabled::after, .max360-action.max360-action-danger-solid.is-loading::after { opacity: 1; }
/* the focus ring hugs the fill rather than the taller tap area around it */
.max360-action.max360-action-solid:focus-visible,
.max360-action.max360-action-danger-solid:focus-visible { outline: none; }
.max360-action.max360-action-solid:focus-visible::after,
.max360-action.max360-action-danger-solid:focus-visible::after { box-shadow: 0 0 0 2px var(--max360-bg), 0 0 0 4px var(--max360-primary); }

/* sizes */
.max360-action-sm { font-size: 0.8125rem; letter-spacing: 0; gap: 0.35rem; }
/* inside a sentence: no tap-height of its own, so it does not open a gap in the line */
.max360-action-inline { min-height: 0; padding-top: 0; padding-bottom: 0; line-height: inherit; }
.max360-action-inline::after { bottom: -1px; }
/* in a row of small text under a line: keeps a 44px tap area but takes one text line of room, so it opens no gap */
.max360-action-row { min-height: 0; padding-block: 16px; margin-block: -14px; }
.max360-action-row::after { bottom: 14px; }
.max360-action-lg { font-size: 1rem; letter-spacing: 0; }

/* forward arrow */
.max360-action-arrow { transition: transform 0.2s ease; }
.max360-action:hover:not(:disabled):not(.is-loading) .max360-action-arrow { transform: translateX(4px); }

/* states */
.max360-action:disabled, .max360-action.is-loading {
    color: var(--max360-text-muted);
    opacity: 0.55;
    cursor: not-allowed;
    pointer-events: none;
}
.max360-action:disabled::after, .max360-action.is-loading::after { opacity: 0; }
.max360-action:focus-visible {
    outline: 2px solid var(--max360-primary);
    outline-offset: 5px;
    border-radius: 2px;
}

/* adjacent actions: automatic horizontal gap so callers never need inline spacing */
.max360-action + .max360-action { margin-left: 0.75rem; }

/* action bar: flex row of action buttons with consistent gap */
.max360-action-bar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}
/* the bar's gap spaces them; the adjacent margin would indent a wrapped line */
.max360-action-bar > .max360-action + .max360-action { margin-left: 0; }
/* a link standing in a row of actions is a tap target on a phone, so it takes their height */
.max360-action-bar > :is(.max360-link, .max360-link-out) {
    display: inline-flex;
    align-items: center;
    min-height: var(--max360-control-hit);
    padding-block: 0;
}

/* loading spinner glyph (replaces Bootstrap spinner-border inside buttons) */
.max360-spin {
    width: 0.8em; height: 0.8em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    display: inline-block;
    animation: max360-spin 0.7s linear infinite;
}
@keyframes max360-spin { to { transform: rotate(360deg); } }
/* A working action is disabled, and :disabled paints it muted at 0.55 opacity — which reads as a
   dead control, not a busy one. Child opacity cannot escape the parent's, so the spinner earns its
   contrast back through color: the accent survives the dimming where slate does not. */
.max360-action:disabled .max360-spin, .max360-action.is-loading .max360-spin { color: var(--max360-primary); }

/* --- Icon-only buttons (companion family) --- */
.max360-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--max360-control-hit);
    min-height: var(--max360-control-hit);
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: 2px;
    color: var(--max360-text-muted);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    text-decoration: none;
    transition: color 0.15s ease, background 0.15s ease;
}
.max360-icon-btn:hover:not(:disabled) { color: var(--max360-primary); background: var(--surface-2); }
.max360-icon-btn-danger:hover:not(:disabled) { color: var(--max360-danger); background: var(--surface-2); }
.max360-icon-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.max360-icon-btn:focus-visible { outline: 2px solid var(--max360-primary); outline-offset: 3px; }
/* the round Max button in a page's corner: the brand mark on a raised disc */
.max360-icon-btn.max360-icon-btn-fab {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--max360-surface);
    border: 1px solid var(--max360-border);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}
/* the Max mark as the microphone on Today's Talk panel; its glow is drawn by MaxMicButton */
.max360-icon-btn.max360-icon-btn-mic {
    position: relative;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--max360-surface);
    border: 1px solid var(--max360-border);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}
.max360-icon-btn.max360-icon-btn-mic:hover:not(:disabled) { background: var(--max360-surface); }
.max360-icon-btn.max360-icon-btn-fab:hover:not(:disabled) { background: var(--max360-surface); box-shadow: 0 6px 18px rgba(0, 0, 0, 0.24); }

/* --- A checkbox drawn as a switch: put the class on <input type="checkbox" role="switch">.
   the off state has a border and a knob in --ink-dim, which keeps it at 3:1 or better on the surface */
.max360-switch {
    appearance: none;
    -webkit-appearance: none;
    flex: 0 0 auto;
    position: relative;
    width: 36px;
    height: 20px;
    margin: 0;
    border: 1px solid var(--ink-dim);
    border-radius: 10px;
    background: var(--max360-surface);
    cursor: pointer;
    transition: background-color 0.15s, border-color 0.15s;
}
.max360-switch::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--ink-dim);
    transition: transform 0.15s;
}
.max360-switch:checked { background: var(--accent); border-color: var(--accent); }
.max360-switch:checked::after { background: var(--max360-surface); transform: translateX(16px); }
.max360-switch:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.max360-switch:disabled { opacity: 0.5; cursor: not-allowed; }
/* the compact size, for a toolbar with no room to spare */
.max360-switch.max360-switch-sm { width: 28px; height: 16px; }
.max360-switch.max360-switch-sm::after { width: 10px; height: 10px; }
.max360-switch.max360-switch-sm:checked::after { transform: translateX(12px); }
@media (prefers-reduced-motion: reduce) {
    .max360-switch,
    .max360-switch::after { transition: none; }
}
/* forced colors paint every background the page color, so the switch is drawn in system colors */
@media (forced-colors: active) {
    .max360-switch { border-color: ButtonText; }
    .max360-switch::after { background: ButtonText; forced-color-adjust: none; }
    .max360-switch:checked { background: Highlight; border-color: Highlight; }
    .max360-switch:checked::after { background: HighlightText; }
}

/* --- The send button beside a typing box: filled with the accent and worded at a desk, a round
   arrow on a phone. put the word in .max360-send-word and the arrow in .max360-send-arrow */
.max360-send {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 5px 16px;
    border: none;
    border-radius: 6px;
    background: var(--max360-action-ink);
    color: var(--max360-on-action);
    font-family: var(--max360-font-body, 'Inter', system-ui, sans-serif);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.max360-send:hover:not(:disabled) { opacity: 0.88; }
.max360-send:disabled { opacity: 0.4; cursor: not-allowed; }
.max360-send .max360-send-arrow { display: none; }
@media (max-width: 700px) {
    .max360-send {
        width: 34px;
        height: 34px;
        padding: 0;
        border-radius: 50%;
    }
    .max360-send:disabled { background: var(--rule); color: var(--ink-dim); opacity: 1; }
    .max360-send .max360-send-word { display: none; }
    .max360-send .max360-send-arrow { display: inline; font-size: 16px; }
}

/* Created by relationship-graph.js when an expand would breach the client node ceiling,
   so it cannot live in the component's scoped sheet. */
.max360-graph-banner {
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 6;
    max-width: 80%;
    background: var(--max360-warning-soft);
    color: var(--max360-warning-ink);
    border: 1px solid var(--max360-warning);
    border-radius: 999px;
    padding: 5px 14px;
    font-size: 0.75rem;
    text-align: center;
    pointer-events: none;
}

/* --- Filter / segmented chips --- */
.max360-filter {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: var(--max360-chip-height);
    padding: 2px 12px;
    background: transparent;
    border: 1px solid var(--max360-border);
    border-radius: 999px;
    color: var(--max360-text);
    font-family: var(--max360-font-body, 'Inter', system-ui, sans-serif);
    font-size: 0.8rem;
    font-weight: 500;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
}
.max360-filter:hover:not(:disabled) { border-color: var(--max360-text-muted); }
.max360-filter.is-active { color: var(--max360-action-ink); border-color: var(--max360-action-accent); }
.max360-filter:disabled { opacity: 0.55; cursor: not-allowed; }
.max360-filter:focus-visible { outline: 2px solid var(--max360-primary); outline-offset: 2px; }

/* --- Tabs (companion family) ---
   A tab switches which view is shown; a filter narrows a list. They are different
   controls and now look different: chips stay pills, tabs are underlined labels
   sharing the kicker-link voice of .max360-action. Keyboard and ARIA live in
   Components/Library/MaxTabs.razor — markup that hand-rolls this strip gets the
   look without the roving focus. */
.max360-tabs {
    display: flex;
    gap: 1.5rem;
    align-items: stretch;
    margin-bottom: 1rem;
    border-bottom: 1px solid var(--max360-border);
    overflow-x: auto;                 /* narrow viewports scroll; labels never wrap mid-strip */
    overflow-y: hidden;               /* the active underline sits 1px into the rule; without this the strip grows a vertical scrollbar */
    scrollbar-width: thin;
}
.max360-tab {
    flex: 0 0 auto;
    box-sizing: border-box;
    min-height: var(--max360-control-hit);
    padding: 10px 1px;
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;              /* the underline lands ON the strip's rule, not under it */
    color: var(--max360-text-muted);
    font-family: var(--max360-font-label);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    line-height: 1;
    text-transform: uppercase;
    text-decoration: none;            /* reset for <a> */
    white-space: nowrap;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
}
.max360-tab:hover:not(:disabled) { color: var(--max360-text); border-bottom-color: var(--max360-text-muted); }
.max360-tab.is-active { color: var(--max360-action-ink); border-bottom-color: var(--max360-action-accent); }
.max360-tab:disabled { color: var(--max360-text-muted); opacity: 0.55; cursor: not-allowed; }
/* inset so the ring is not clipped by the strip's own overflow-x scroll container */
.max360-tab:focus-visible { outline: 2px solid var(--max360-primary); outline-offset: -2px; border-radius: 2px; }
/* a count/indicator riding along inside the label */
.max360-tab > .max360-badge { margin-left: 0.4rem; }

/* --- Links. A link to another page in Max is underlined in the theme's link color; a plain <a>
   gets the same color from the a rule further down. .max360-link-out ends in an arrow. */
.max360-link,
.max360-link-out {
    color: var(--max360-link);
    text-decoration: underline;
    text-decoration-thickness: var(--max360-control-underline);
    text-underline-offset: 0.15em;
    padding-block: 0.25rem;            /* a taller tap area; inline padding leaves the line height alone */
    cursor: pointer;
}
.max360-link:hover,
.max360-link-out:hover { color: var(--max360-link); text-decoration-thickness: var(--max360-control-underline-strong); }
.max360-link-out::after { content: "\00a0\2197"; display: inline-block; text-decoration: none; }
.max360-link:focus-visible,
.max360-link-out:focus-visible { outline: 2px solid var(--max360-primary); outline-offset: 2px; border-radius: 2px; }

/* --- Chips: a pill for a person, entity or value. Only an <a> or <button> chip takes a click. --- */
.max360-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    box-sizing: border-box;
    max-width: 100%;
    min-height: var(--max360-chip-height);
    padding: 2px 10px;
    background: var(--max360-surface);
    border: 1px solid var(--max360-border);
    border-radius: 999px;
    color: var(--max360-text);
    font-family: var(--max360-font-body, 'Inter', system-ui, sans-serif);
    font-size: 0.8rem;
    font-weight: 500;
    line-height: 1.2;
    text-decoration: none;
    overflow-wrap: anywhere;
    cursor: default;
    transition: border-color 0.15s ease, color 0.15s ease;
}
:is(a, button).max360-chip { cursor: pointer; }
:is(a, button).max360-chip:hover:not(:disabled):not(.is-active) { color: var(--max360-text); border-color: var(--max360-primary); }
.max360-chip.is-active { color: var(--max360-action-ink); border-color: var(--max360-action-accent); }
/* a thin chip, for a row of choices that sits inside a heading without making it taller */
.max360-chip.max360-chip-sm { min-height: 0; padding: 0 8px; font-size: 0.75rem; line-height: 1.5; }
/* a chip that is a control on its own, not one of a row: a firm edge and a full touch height, so it reads as something to press */
.max360-chip.max360-chip-press { min-height: var(--max360-control-hit); padding: 4px 14px; border-color: var(--max360-text-muted); font-size: 0.85rem; font-weight: 600; }
/* a suggestion nobody has accepted yet: an outline, so it never looks like something already there */
.max360-chip.is-suggested { color: var(--max360-text-muted); border-style: dashed; }
.max360-chip:disabled { opacity: 0.55; cursor: not-allowed; }
.max360-chip:focus-visible { outline: 2px solid var(--max360-primary); outline-offset: 2px; }

/* --- Remove: the small x that takes something off a chip or a list row. Always visible,
   because a phone has no hover to reveal it. */
.max360-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    margin-right: -6px;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: 50%;
    color: var(--max360-text-muted);
    font-size: 0.75rem;
    line-height: 1;
    cursor: pointer;
}
.max360-remove:hover:not(:disabled) { color: var(--max360-danger-ink, var(--max360-danger)); }
.max360-remove:focus-visible { outline: 2px solid var(--max360-primary); outline-offset: 1px; }

/* --- List choice: a row you pick from a list, such as the document and meeting pickers.
   .max360-choice-list frames the rows; .max360-choice-meta is the quieter second line. */
.max360-choice-list {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--max360-border);
    border-radius: 6px;
    overflow: hidden;
}
.max360-choice {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.1rem;
    box-sizing: border-box;
    width: 100%;
    min-height: var(--max360-control-hit);
    padding: 0.4rem 0.6rem;
    background: none;
    border: 0;
    border-bottom: 1px solid var(--max360-border);
    color: var(--max360-text);
    font-family: var(--max360-font-body, 'Inter', system-ui, sans-serif);
    font-size: 0.82rem;
    line-height: 1.3;
    text-align: left;
    text-decoration: none;
    overflow-wrap: anywhere;
    cursor: pointer;
}
.max360-choice:last-child { border-bottom: 0; }
.max360-choice:hover:not(:disabled),
.max360-choice.is-active { color: var(--max360-text); background: var(--max360-bg); }
.max360-choice:disabled { opacity: 0.55; cursor: not-allowed; }
.max360-choice:focus-visible { outline: 2px solid var(--max360-primary); outline-offset: -2px; }
.max360-choice-meta { color: var(--max360-text-muted); font-size: 0.72rem; }
.max360-choice-danger { color: var(--max360-danger-ink, var(--max360-danger)); }

/* END BUTTONS. ButtonStyleGuardTests fails on a rule outside this block that changes how a kind looks. */

/* Knowledge filter popover (spec §5.1) — wrapping multi-select grid + type-to-filter. */
.kbs-filter-pop { position: relative; display: inline-block; }
/* z-index 1060/1061: above Bootstrap .modal (1055) so the popover works inside BulkScopeDialog. */
.kbs-filter-pop-backdrop { position: fixed; inset: 0; z-index: 1060; }
.kbs-filter-pop-menu {
    position: absolute; z-index: 1061; top: calc(100% + 4px); left: 0;
    min-width: 260px; max-width: 520px; max-height: 360px; overflow-y: auto;
    background: var(--max360-surface); border: 1px solid var(--max360-border);
    border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,0.18); padding: 0.5rem;
}
.kbs-filter-pop-search { width: 100%; margin-bottom: 0.4rem; }
.kbs-filter-pop-tools { display: flex; gap: 0.4rem; margin-bottom: 0.4rem; }
.kbs-filter-pop-head {
    font-size: 0.62rem; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--max360-text-muted); margin: 0.4rem 0 0.2rem;
}
.kbs-filter-pop-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); gap: 0.25rem 0.5rem; }
.kbs-filter-pop-opt { display: flex; align-items: center; gap: 0.35rem; font-size: 0.72rem; cursor: pointer; }
.kbs-filter-pop-empty { color: var(--max360-text-muted); font-size: 0.72rem; padding: 0.4rem 0.1rem; }

/* ===== Threads page redesign ===== */
.max360-thread-filter-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
    margin-bottom: 1.25rem;
}
.max360-thread-filter-group { display: inline-flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.max360-thread-filter-divider { width: 1px; align-self: stretch; min-height: 24px; background: var(--max360-border); margin: 0 0.25rem; }
.max360-thread-filter-bar .spacer { flex: 1 1 auto; }   /* pushes the view toggle right */

/* Card grid (card view) */
.max360-thread-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 0.85rem; }
.max360-thread-card {
    border: 1px solid var(--max360-border);
    border-radius: 0.6rem;
    padding: 0.85rem 0.95rem;
    background: var(--max360-surface);
    display: flex; flex-direction: column; gap: 0.5rem;
}
.max360-thread-card .tc-title { font-weight: 600; }
.max360-thread-card .tc-meta { font-size: 0.72rem; color: var(--max360-text-muted); display: flex; flex-wrap: wrap; gap: 0.25rem 0.6rem; }
.max360-thread-card .tc-row { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }

/* Shared list/card toggle (ToDos, Ideas). */
.max360-view-toggle { display: inline-flex; align-items: center; gap: 0.4rem; }

/* Generic item-card grid + card surface (ToDos, Ideas card views). */
.max360-item-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 0.85rem; margin-bottom: 1rem; }
.max360-item-card {
    border: 1px solid var(--max360-border);
    border-radius: 0.6rem;
    padding: 0.85rem 0.95rem;
    background: var(--max360-surface);
    display: flex; flex-direction: column; gap: 0.5rem;
}
.max360-item-card .ic-title { font-weight: 600; }
.max360-item-card .ic-meta { font-size: 0.72rem; color: var(--max360-text-muted); display: flex; flex-wrap: wrap; gap: 0.25rem 0.6rem; }
.max360-item-card .ic-row { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.max360-item-card .ic-actions { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; margin-top: auto; }
.max360-item-card .ic-preview { font-size: 0.8rem; color: var(--max360-text-muted); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.max360-item-card.is-overdue { border-color: var(--max360-warning, #d97706); border-left-width: 3px; }
.max360-item-card.is-archived { opacity: 0.6; }

/* Access indicators (row + card) — owner vs shared are visually distinct */
.max360-access { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.72rem; color: var(--max360-text-muted); }
.max360-access .owner { font-weight: 600; color: var(--max360-text); }
.max360-access-sep { color: var(--max360-border); }

/* Bootstrap text-danger folds onto the warm token */
.text-danger { color: var(--max360-danger) !important; }

/* Extraction-quality feedback (thumb up/down) */
.max360-extraction-feedback {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--max360-border, #e5e7eb);
    font-size: 0.85rem;
}

.max360-extraction-feedback-label {
    color: var(--max360-text-muted, #6b7280);
}

.max360-feedback-toast {
    color: var(--max360-text-muted, #6b7280);
    font-size: 0.8rem;
    margin-left: 0.25rem;
}

/* Clickable row */
.max360-clickable {
    cursor: pointer;
}

/* Loading */
.max360-loading {
    color: var(--max360-text-muted);
    padding: 2rem;
    text-align: center;
}

a, a:visited {
    color: var(--max360-link, var(--max360-primary));
}

.form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid var(--max360-danger);
}

.validation-message {
    color: var(--max360-danger);
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* ── Chat Panel ── */
.max360-chat-panel {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--max360-bg);
}

.max360-chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: 1.25rem 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

/* ── User messages: left-aligned bubble ── */
.max360-chat-message {
    display: flex;
    flex-direction: column;
    align-self: flex-start;
}

.max360-chat-message.max360-chat-user {
    max-width: 75%;
}

.max360-chat-message.max360-chat-assistant {
    width: 100%;
}

.max360-chat-meta {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin-bottom: 0.3rem;
    min-height: 0; /* collapses to nothing when empty (private user msgs) */
}

.max360-chat-meta:empty {
    margin-bottom: 0;
}

.max360-chat-role {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--max360-text-muted);
}

/* Timestamp in meta row (assistant messages — always visible) */
.max360-chat-role-timestamp {
    font-size: 0.7rem;
    color: var(--max360-text-muted);
    opacity: 0.6;
    font-weight: 400;
}

/* Timestamp in actions row (user messages — hover only) */
.max360-chat-timestamp {
    font-size: 0.7rem;
    color: var(--max360-text-muted);
    opacity: 0.7;
    margin-left: auto;
    white-space: nowrap;
}

.max360-chat-model-tag {
    font-size: 0.68rem;
    color: var(--max360-text-muted);
    opacity: 0.6;
    background: var(--max360-surface, #f3f4f6);
    border: 1px solid var(--max360-border);
    border-radius: 3px;
    padding: 0.05em 0.35em;
    letter-spacing: 0.02em;
}

/* How long Max took on this turn (wall clock). Quieter than the model tag — it is
   reference information, not an attribute of the answer. */
.max360-chat-turn-duration {
    display: inline-flex;
    align-items: center;
    gap: 0.2em;
    font-size: 0.68rem;
    color: var(--max360-text-muted);
    opacity: 0.6;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    cursor: default;
}

.max360-chat-turn-duration i {
    font-size: 0.72em;
}

/* User bubble */
.max360-chat-user .max360-chat-bubble {
    background: var(--surface-2);
    border: 1px solid var(--max360-border);
    border-radius: 0.75rem;
    padding: 0.6rem 0.9rem;
    font-size: 0.875rem;
    line-height: 1.5;
    word-break: break-word;
    color: var(--max360-text);
}

/* A message the turn runner refused. It is in the transcript but Max never saw it, so it
   must not read as delivered — dimmed, with the reason and a way to send it again always on
   screen rather than behind the hover-only action row. */
.max360-chat-unsent .max360-chat-bubble {
    opacity: 0.6;
    border-style: dashed;
}

.max360-chat-unsent-note {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.4rem;
    font-size: 0.75rem;
    color: var(--max360-text-muted, #6c757d);
}

.max360-chat-unsent-lbl {
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.68rem;
    color: var(--bs-danger, #dc3545);
    flex: none;
}

.max360-chat-unsent-why {
    flex: 1 1 auto;
    min-width: 0;
}

/* Assistant: no bubble — free-form */
.max360-chat-assistant .max360-chat-bubble {
    padding: 0;
    font-size: 0.875rem;
    line-height: 1.5;
    word-break: break-word;
    color: var(--max360-text);
}

.max360-chat-text {
    margin: 0;
}

.max360-chat-actions {
    display: flex;
    align-items: center;
    gap: 0.15rem;
    margin-top: 0.4rem;
    opacity: 0;
    transition: opacity 0.15s;
}

.max360-chat-message:hover .max360-chat-actions {
    opacity: 1;
}

.max360-chat-welcome {
    text-align: center;
    color: var(--max360-text-muted);
    padding: 2rem;
    font-size: 1.1rem;
}

.max360-chat-typing {
    padding: 0.5rem 1rem;
    color: var(--max360-text-muted);
    font-style: italic;
    font-size: 0.9rem;
}

.max360-chat-error {
    padding: 0.75rem 1rem;
    background: var(--max360-danger-soft);
    border: 1px solid var(--max360-danger);
    border-radius: 0.5rem;
    color: var(--max360-danger);
    margin: 0.5rem 1rem;
}

.max360-chat-input-area {
    display: flex;
    gap: 0.5rem;
    padding: 1rem 1rem 1.25rem 1rem;
    border-top: 1px solid var(--max360-border);
    background: var(--max360-surface);
}

.max360-chat-input-area textarea {
    flex: 1;
    resize: none;
    border: 1px solid var(--max360-border);
    border-radius: 0.375rem;
    padding: 0.5rem 0.75rem;
    font-family: inherit;
    font-size: 0.95rem;
    min-height: 2.5rem;
    max-height: 8rem;
    background: var(--max360-bg);
    color: var(--max360-text);
}

.max360-chat-input-area textarea:focus {
    outline: none;
    border-color: var(--max360-primary);
    box-shadow: 0 0 0 2px rgba(201,152,106,0.2);
}

.max360-chat-input-area button {
    align-self: flex-end;
}

/* ── Attachment composer (chat file uploads) ── */
.max360-chat-input-area-with-attach {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.max360-chat-input-area-with-attach.max360-dragging {
    outline: 2px dashed var(--max360-primary);
    outline-offset: -4px;
    background: rgba(201,152,106,0.05);
}
.max360-composer-row {
    display: flex;
    gap: 0.5rem;
    align-items: flex-end;
}
.max360-attachment-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    padding: 0.25rem 0;
}
.max360-attachment-chips-inline {
    margin-bottom: 0.4rem;
}
.max360-attachment-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.2rem 0.45rem;
    border-radius: 999px;
    background: var(--max360-bg);
    border: 1px solid var(--max360-border);
    font-size: 0.85rem;
    color: var(--max360-text);
    text-decoration: none;
}
.max360-attachment-chip.uploading { opacity: 0.6; }
.max360-attachment-chip.uploaded  { border-color: var(--max360-primary); }
.max360-attachment-chip.rejected  {
    border-color: #c0392b;
    background: rgba(192,57,43,0.08);
}
.max360-attachment-chip .chip-icon { font-size: 1rem; }
.max360-attachment-chip .chip-name { max-width: 16rem; overflow: hidden; text-overflow: ellipsis; }
.max360-attachment-chip .chip-size { color: var(--max360-text-muted); font-size: 0.78rem; }
.max360-attachment-chip .chip-error { color: var(--max360-danger); font-size: 0.78rem; margin-left: 0.25rem; }
.max360-attachment-chip .chip-remove {
    appearance: none;
    background: none;
    border: 0;
    cursor: pointer;
    padding: 0 0.15rem;
    font-size: 1rem;
    line-height: 1;
    color: var(--max360-text-muted);
}
.max360-attachment-chip .chip-remove:disabled { opacity: 0.4; cursor: default; }
.max360-paperclip { font-size: 1.1rem; }
/* visually hidden, not display:none: a phone's browser is surest to open a picker for an input that is rendered */
.max360-file-input-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    opacity: 0;
    pointer-events: none;
}

/* ── Alert Success ── */
.max360-alert-success {
    padding: 0.75rem 1rem;
    background: rgba(34,197,94,0.1);
    border-left: 4px solid var(--max360-success);
    border-radius: 0.375rem;
    color: var(--max360-success);
    margin-bottom: 1rem;
}

/* ── Alert Danger ── */
.max360-alert-danger {
    padding: 0.75rem 1rem;
    background: var(--max360-danger-soft);
    border-left: 4px solid var(--max360-danger);
    border-radius: 0.375rem;
    color: var(--max360-danger);
    margin-bottom: 1rem;
}

/* ── Contextual Help Button ── */
.contextual-help-btn {
    position: fixed;
    bottom: 54px;
    right: 24px;
    z-index: 1041;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    border: none;
    background-color: var(--max360-primary);
    color: var(--max360-on-primary);
    font-size: 1.25rem;
    cursor: pointer;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;
}

.contextual-help-btn:hover {
    transform: scale(1.1);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
}

/* a page with the Max button keeps the corner for it; Help and Feedback stack above */
body:has(.max-fab-dock) .contextual-help-btn { bottom: 92px; }
body:has(.max-fab-dock) .product-feedback-btn { bottom: 152px; }

/* ── Help Panel ── */
/* slides on transform, not width, so opening it never re-lays out the page; hidden while shut so
   nothing inside it can take keyboard focus */
.help-panel {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 420px;
    max-width: 100vw;
    overflow: hidden;
    z-index: 1040;
    background-color: var(--max360-surface);
    border-left: 1px solid var(--max360-border);
    box-shadow: -4px 0 16px rgba(0, 0, 0, 0.1);
    transform: translateX(100%);
    visibility: hidden;
    transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s linear 0.25s;
}

.help-panel.panel-open {
    transform: none;
    visibility: visible;
    transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s;
}

.help-panel-content {
    display: flex;
    flex-direction: column;
    height: 100%;
    width: 420px;
}

@media (max-width: 700px) {
    .help-panel.panel-open,
    .help-panel-content { width: 100vw; }
}

/* Header in two rows: identity above, context and actions below. The old single row put the
   title, the feature-area badge, a cache chip, two tour buttons and the close control at one
   weight across 420px, so nothing read as the title and nothing read as an action. */
.help-panel-header {
    background-color: var(--max360-surface);
    flex-shrink: 0;
    border-bottom: 1px solid var(--max360-border);
}

.help-panel-titlebar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem 1rem 0.3rem;
}

.help-panel-mark {
    flex: 0 0 auto;
    color: var(--max360-primary);
    font-size: 0.9rem;
}

.help-panel-title {
    flex: 1 1 auto;
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--max360-text);
}

.help-panel-close { flex: 0 0 auto; }

.help-panel-subbar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0 1rem 0.7rem;
}

/* Provenance for the guide above — pushed to the far end so it reads as a footnote
   beside "Last updated" / "Improve this page" rather than competing with them. */
.help-panel-footer { display: flex; align-items: center; gap: 0.5rem; }
.help-panel-cached { margin-left: auto; opacity: 0.75; white-space: nowrap; }

/* The page this panel is about — an eyebrow, deliberately quieter than the title above it. */
.help-panel-context {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--max360-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Sits in the title row, between the title and the close button, so every control the
   header offers is in one place. margin-left:auto pushes the group right; the title's
   flex:1 already claims the slack, so this only matters if the title ever wraps. */
.help-panel-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 0.2rem;
    position: relative;   /* anchors .help-panel-menu */
}

.help-panel-tour,
.help-panel-more { display: inline-flex; align-items: center; gap: 0.3rem; white-space: nowrap; }

/* Click-outside-to-close. Fixed, so it escapes .help-panel's overflow:hidden and covers the
   whole viewport; transparent, so it is invisible; below the menu but above everything else
   in the panel, so a click anywhere except the menu itself lands here and closes it. */
.help-panel-menu-backdrop {
    position: fixed;
    inset: 0;
    z-index: 9;
    background: transparent;
}

.help-panel-menu {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    z-index: 10;
    min-width: 14rem;
    padding: 0.25rem;
    background-color: var(--max360-surface);
    border: 1px solid var(--max360-border);
    border-radius: 6px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25);
}

.help-panel-menu .help-panel-menu-item { flex-direction: row; align-items: flex-start; gap: 0.5rem; }
.help-panel-menu i { color: var(--max360-primary); margin-top: 0.15rem; }
.help-panel-menu small {
    display: block;
    margin-top: 0.1rem;
    font-size: 0.68rem;
    color: var(--max360-text-muted);
}

.help-panel-body {
    flex: 1;
    overflow-y: auto;
}

.help-guide-content h1 { font-size: 1rem; font-weight: 600; margin-top: 0.5rem; }
.help-guide-content h2 { font-size: 0.9rem; font-weight: 600; margin-top: 0.9rem; color: var(--max360-primary); }
.help-guide-content h3 { font-size: 0.85rem; font-weight: 600; margin-top: 0.75rem; }
.help-guide-content p { font-size: 0.85rem; line-height: 1.6; }
.help-guide-content ul, .help-guide-content ol { font-size: 0.85rem; padding-left: 1.25rem; }
.help-guide-content li { margin-bottom: 0.15rem; }
.help-guide-content code { font-size: 0.8rem; background: var(--max360-bg); padding: 2px 4px; border-radius: 3px; }

.help-center-layout { display: flex; gap: 1rem; }
.help-center-topics { min-width: 260px; }
.help-center-article { flex-grow: 1; min-width: 0; }
.help-center-back { display: none; }
/* a phone shows the list or the article, never both */
@media (max-width: 700px) {
    .help-center-layout { flex-direction: column; }
    .help-center-topics { min-width: 0; }
    .help-center-reading .help-center-topics { display: none; }
    .help-center-layout:not(.help-center-reading) .help-center-article { display: none; }
    .help-center-back { display: inline-flex; margin-bottom: 0.75rem; }
    .help-center-article table { display: block; overflow-x: auto; }
}
.help-center-article h1 { font-size: 1.5rem; font-weight: 600; margin-top: 0; }
.help-center-article h2 { font-size: 1.15rem; font-weight: 600; margin-top: 1.5rem; color: var(--max360-primary); }
.help-center-article h3 { font-size: 1rem; font-weight: 600; margin-top: 1rem; }
.help-center-article p { font-size: 0.95rem; line-height: 1.6; }
.help-center-article ul, .help-center-article ol { font-size: 0.95rem; padding-left: 1.5rem; }
.help-center-article li { margin-bottom: 0.2rem; }
.help-center-article code { font-size: 0.85rem; background: var(--max360-bg); padding: 2px 4px; border-radius: 3px; }
/* ============================================================
   Chat Inspector — behind-the-scenes trace pane
   ============================================================ */
.max360-chat-panel {
    display: flex;
    flex-direction: row;
}
.max360-chat-main {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}
.max360-chat-panel-with-inspector .max360-chat-main {
    flex: 1 1 60%;
}
.max360-model-select {
    font-size: 0.75rem;
    padding: 0.15rem 0.35rem;
    border: 1px solid var(--max360-border, #e5e7eb);
    border-radius: 4px;
    background: var(--max360-surface, #f9fafb);
    color: var(--max360-text-muted);
    cursor: pointer;
    max-width: 160px;
}

.max360-model-menu {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin: 0;
    font-size: 0.75rem;
    color: var(--max360-text-muted);
}
.max360-model-menu-label { white-space: nowrap; }
.max360-model-menu .max360-model-select { max-width: 220px; }

.max360-chat-toolbar {
    display: flex;
    padding: 0.25rem 0.75rem;
    border-bottom: 1px solid var(--max360-border, #e5e7eb);
    font-size: 0.85rem;
    flex-shrink: 0;
}

.max360-chat-inspector {
    flex: 0 0 38%;
    min-width: 280px;
    max-width: 520px;
    display: flex;
    flex-direction: column;
    border-left: 1px solid var(--max360-border, #e5e7eb);
    background: var(--max360-surface, #f9fafb);
    height: 100%;
    overflow: hidden;
}
.max360-chat-inspector-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--max360-border, #e5e7eb);
    background: var(--max360-bg, #fff);
    flex-shrink: 0;
}
.max360-chat-inspector-body {
    flex: 1;
    overflow-y: auto;
    padding: 0.5rem;
    font-size: 0.8rem;
}
.max360-trace-entry {
    padding: 0.35rem 0.5rem;
    margin-bottom: 0.25rem;
    border-left: 3px solid var(--max360-border, #e5e7eb);
    background: var(--max360-bg, #fff);
    border-radius: 3px;
}
.max360-trace-entry.max360-trace-user { border-left-color: #3b82f6; }
.max360-trace-entry.max360-trace-tool { border-left-color: #a855f7; }
.max360-trace-entry.max360-trace-error { border-left-color: var(--max360-danger); background: var(--max360-danger-soft); }
.max360-trace-entry.max360-trace-done { border-left-color: #10b981; }
.max360-trace-entry.max360-trace-info { border-left-color: #9ca3af; }

.max360-trace-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.72rem;
    color: var(--max360-text-muted);
}
.max360-trace-time {
    font-family: monospace;
    font-size: 0.7rem;
}
.max360-trace-step {
    font-weight: 600;
    color: var(--max360-text);
    text-transform: uppercase;
    letter-spacing: 0.02em;
    font-size: 0.7rem;
}
.max360-trace-caret { margin-left: auto; font-size: 0.65rem; }
.max360-trace-message {
    margin-top: 0.15rem;
    color: var(--max360-text);
    word-wrap: break-word;
}
.max360-trace-detail {
    margin: 0.35rem 0 0 0;
    padding: 0.4rem;
    background: var(--surface-2);
    border-radius: 3px;
    font-size: 0.7rem;
    font-family: monospace;
    white-space: pre-wrap;
    word-wrap: break-word;
    max-height: 240px;
    overflow-y: auto;
}

/* ── Compartmentalization Assurance Center: evidence posture + transcripts ──
   Posture banners on the Assurance Center pages (/admin/ops/assurance*) and the
   legacy evidence report (/admin/ops/compartmentalization-evidence). A banner is
   a .max360-card carrying .max360-evidence-status plus ONE posture modifier:
   red = tooling error, amber = stale/incomplete, green = clean, blue =
   provisional (in-process tier verified; live/parity still need an operator run).
   Each posture modifier doubles as a bare text-color class for standalone lines
   (e.g. an INCOMPLETE coverage note). Accent tokens are theme-aware (themes.css);
   the provisional blue matches the hardcoded accent used by .max360-trace-user. */
.max360-evidence-status {
    border-left: 4px solid var(--max360-border);
}

.max360-evidence-status-token {
    margin: 0.25rem 0 0.5rem;
    font-size: 1.05rem;
    letter-spacing: 0.02em;
}

.max360-evidence-caveat {
    margin-top: 0.75rem;
    color: var(--max360-text-muted);
    font-size: 0.85rem;
}

.max360-assurance-group summary { cursor: pointer; margin: 0.35rem 0; }
.max360-assurance-rows { list-style: none; margin: 0 0 0.75rem; padding: 0 0 0 1rem; }
.max360-assurance-rows li { margin: 0.5rem 0; overflow-wrap: anywhere; }
.max360-assurance-rows .max360-evidence-caveat { margin-top: 0.15rem; }
.max360-evidence-status code, .max360-evidence-status li { overflow-wrap: anywhere; }

/* Bare usage: color only this element's own text. */
.max360-evidence-red         { color: var(--max360-danger); }
.max360-evidence-amber       { color: var(--max360-warning); }
.max360-evidence-clean       { color: var(--max360-success); }
.max360-evidence-provisional { color: var(--max360-info-ink); }

/* Banner usage: tint the surface and accent the left border, but reset body text
   to normal ink (the compound selector outranks the bare color rule above on the
   card element) so the banner stays legible — the status token carries the color. */
.max360-evidence-status.max360-evidence-red,
.max360-evidence-status.max360-evidence-amber,
.max360-evidence-status.max360-evidence-clean,
.max360-evidence-status.max360-evidence-provisional {
    color: var(--max360-text);
}

.max360-evidence-status.max360-evidence-red {
    background: var(--max360-danger-soft);
    border-left-color: var(--max360-danger);
}
.max360-evidence-status.max360-evidence-amber {
    background: rgba(217, 119, 6, 0.10);
    border-left-color: var(--max360-warning);
}
.max360-evidence-status.max360-evidence-clean {
    background: rgba(22, 163, 74, 0.10);
    border-left-color: var(--max360-success);
}
.max360-evidence-status.max360-evidence-provisional {
    background: rgba(59, 130, 246, 0.10);
    border-left-color: #3b82f6;
}

.max360-evidence-status.max360-evidence-red         .max360-evidence-status-token { color: var(--max360-danger); }
.max360-evidence-status.max360-evidence-amber       .max360-evidence-status-token { color: var(--max360-warning); }
.max360-evidence-status.max360-evidence-clean       .max360-evidence-status-token { color: var(--max360-success); }
.max360-evidence-status.max360-evidence-provisional .max360-evidence-status-token { color: var(--max360-info-ink); }

/* Adversarial / control transcripts on the Traceability page (<pre> blocks). */
.max360-transcript {
    margin: 0.25rem 0 1rem;
    padding: 0.75rem 1rem;
    background: var(--max360-bg);
    border: 1px solid var(--max360-border);
    border-radius: 0.375rem;
    color: var(--max360-text);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
    font-size: 0.85rem;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 24rem;
    overflow: auto;
}

/* ── SMS admin pages ── */
.max360-person-comm table td:first-child { width: 40%; }

.max360-nav-group-label {
    padding: 0.45rem 1rem 0.2rem;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--max360-text-muted);
    cursor: default;
    pointer-events: none;
}

/* ── Right flyout ── */
.max360-flyout-backdrop {
    position: fixed; inset: 0; background: rgba(0,0,0,0.3); z-index: 1049;
}
.max360-flyout-right {
    position: fixed; top: 0; right: 0; bottom: 0; width: 360px;
    background: var(--max360-surface); border-left: 1px solid var(--max360-border);
    z-index: 1050; display: flex; flex-direction: column;
    box-shadow: -4px 0 16px rgba(0,0,0,0.12);
}
.max360-flyout-header {
    display: flex; justify-content: space-between; align-items: center;
    padding: 1rem 1.25rem; border-bottom: 1px solid var(--max360-border);
    font-weight: 600; font-size: 1rem;
}
.max360-flyout-body { flex: 1; overflow-y: auto; padding: 1.25rem; }

/* ── Recognized Entities chip section ── */
.max360-entity-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    padding: 0.2rem 0.55rem;
    border-radius: 1rem;
    border: 1px solid var(--max360-border);
    background: var(--max360-surface);
    font-size: 0.8rem;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    transition: opacity 0.15s;
}
.max360-entity-chip:hover { opacity: 0.8; }
.max360-entity-chip:focus { outline: 2px solid var(--max360-primary); outline-offset: 2px; }
/* per-entity-type tint. The color is a data value, so the caller passes it in these two
   custom properties and the rules consuming them stay here. */
.max360-entity-chip-tinted {
    /* the base chip's own values: a malformed color drops both declarations and the chip
       must then look exactly like an untinted one. */
    --chip-tint: var(--max360-surface);
    --chip-edge: var(--max360-border);
    background-color: var(--chip-tint);
    border-color: var(--chip-edge);
}
.max360-entity-chip-count {
    font-size: 0.7rem;
    color: var(--max360-text-muted);
    margin-left: 0.2rem;
}
.max360-entity-chip-compact {
    padding: 0.1rem 0.35rem;
    font-size: 0.7rem;
}
/* "pending -- awaiting review" variant (spec 2026-07-24 section 4.2, cross-spec seam 5): a
   subtle treatment, not an alarm -- dashed border + a small italic muted label. */
.max360-entity-chip-pending {
    border-style: dashed;
    opacity: 0.85;
}
.max360-entity-chip-pending-label {
    font-size: 0.7rem;
    font-style: italic;
    color: var(--max360-text-muted);
    margin-left: 0.3rem;
}

/* Task 22 (spec 2026-07-24 section 7.2): struck-through/undo + hover-revealed remove control.
   The remove/undo buttons are SIBLINGS of the chip <button>, not nested inside it (a <button>
   cannot validly contain another <button> -- see RecognizedEntityChip.razor's header comment),
   so hover-reveal targets the shared wrapper span, not a descendant relationship. */
.max360-entity-chip-wrap {
    display: inline-flex;
    align-items: center;
    gap: 0.15rem;
}
.max360-entity-chip-excluded .max360-entity-chip-name {
    text-decoration: line-through;
    opacity: 0.7;
}
.max360-entity-chip-remove,
.max360-entity-chip-undo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    padding: 0;
    background: transparent;
    border: 1px solid var(--max360-border);
    border-radius: 50%;
    color: var(--max360-text-muted);
    font-size: 0.7rem;
    line-height: 1;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
}
/* Hover-revealed (spec 7.2: "A hover-revealed remove control") -- hidden until the wrapper is
   hovered or the button itself gains keyboard focus, so an ordinary/pinned chip stays visually
   unchanged for everyone who isn't actively curating it. */
.max360-entity-chip-remove {
    opacity: 0;
}
.max360-entity-chip-wrap:hover .max360-entity-chip-remove,
.max360-entity-chip-wrap:focus-within .max360-entity-chip-remove {
    opacity: 1;
}
.max360-entity-chip-remove:hover,
.max360-entity-chip-remove:focus-visible {
    color: var(--max360-danger-ink, var(--max360-danger));
    border-color: var(--max360-danger-ink, var(--max360-danger));
}
/* Undo is NOT hover-revealed -- the struck-through chip is already a distinct visual state, and
   its recovery action stays visible rather than hidden behind a second discovery step. */
.max360-entity-chip-undo:hover,
.max360-entity-chip-undo:focus-visible {
    color: var(--max360-primary);
    border-color: var(--max360-primary);
}
.max360-entity-chip-remove:focus-visible,
.max360-entity-chip-undo:focus-visible {
    outline: 2px solid var(--max360-primary);
    outline-offset: 2px;
}

.max360-entity-card-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 9999;
    background: var(--max360-surface, #ffffff);
    color: var(--max360-text, #111);
    border: 1px solid var(--max360-border, #d0d7de);
    border-radius: 6px;
    box-shadow: 0 8px 32px rgba(0,0,0,0.25);
    min-width: 340px;
    max-width: 560px;
    width: 90vw;
    min-height: 200px;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.max360-entity-card-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.35);
    z-index: 9998;
}

.max360-entity-desc-clamped {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Markdown-rendered entity summary: trim leading/trailing paragraph margins so
   the block sits flush in the card, and constrain nested element spacing. */
.max360-entity-desc-md > p:first-child { margin-top: 0; }
.max360-entity-desc-md > p:last-child { margin-bottom: 0; }
.max360-entity-desc-md ul,
.max360-entity-desc-md ol { margin: 0.25rem 0 0.25rem 1.25rem; }
.max360-entity-desc-md h1,
.max360-entity-desc-md h2,
.max360-entity-desc-md h3,
.max360-entity-desc-md h4 { margin: 0.5rem 0 0.25rem; font-size: 1rem; }
.max360-entity-desc-md pre { background: var(--surface-2, #f6f8fa); color: var(--ink, #1f2937); padding: 0.5rem; border-radius: 4px; overflow-x: auto; }
.max360-entity-desc-md code { background: var(--surface-2, #f6f8fa); color: var(--ink, #1f2937); padding: 0 0.2rem; border-radius: 3px; }

/* Entity-profile knowledge-graph filter bar (mirrors EntityGraph.razor's inline
   .entgraph-knob rules so the reused knob renders styled on /entity/{id}). */
.entprofile-graph-filters {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 8px;
}
.entgraph-knob { display: inline-flex; align-items: center; gap: 4px; font-size: 0.8em; color: var(--ink-dim); white-space: nowrap; }
.entgraph-knob select,
.entgraph-knob input {
    border: 1px solid var(--rule);
    background: var(--surface);
    color: var(--ink);
    border-radius: 6px;
    padding: 0.25rem 0.4rem;
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   CALENDAR EVENT SURFACES — the cal-* rules shared by the event detail DRAWER and the event
   detail PAGE (/calendar/event/{CalendarEventId:int}).

   RELOCATED HERE, NOT COPIED. These rules lived in a single plain <style> block inside
   EventDetailDrawer.razor. A plain <style> block is markup: it reaches the DOM only while that
   component renders. Once the shared section components under Components/Pages/Calendar/Sections/
   gained a second host, every one of them rendered unstyled on the page — the drawer's stylesheet
   was simply not there. Duplicating the block into the page would have created two sources of
   truth for one set of class names and guaranteed drift, so the block MOVED.

   No specificity changed: an unscoped <style> block and this file are both plain global rules, and
   nothing else in the repo defines any of these names (measured — a rule search across every
   .razor and .css file under src/Max360.Web found no competing definition for any of the 56).

   Reachability is pinned by CalendarSectionStyleReachabilityTests, which also fails if these rules
   move back into a host component. A comment is not a guard; that test is.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */
.cal-drawer-overlay { display: none; }
.cal-drawer-open .cal-drawer-overlay { display: block; position: fixed; inset: 0; z-index: 200; background: rgba(0,0,0,0.15); }
.cal-drawer-panel { position: fixed; top: 0; right: -440px; width: 440px; max-width: 100vw; height: 100vh; background: var(--max360-surface); border-left: 1px solid var(--max360-border); z-index: 201; display: flex; flex-direction: column; transition: right 0.22s ease; overflow: hidden; }
.cal-drawer-open .cal-drawer-panel { right: 0; }
@media (max-width: 520px) { .cal-drawer-panel { width: 100vw; right: -100vw; } }
/* the phone bar sits above the page, so the drawer, which must cover it, says so */
@media (max-width: 700px) {
    .cal-drawer-open .cal-drawer-overlay { z-index: 1034; }
    .cal-drawer-panel { z-index: 1035; }
}
/* The PINNED header block (2026-08-07 UX pass): eyebrow, title, when/where, and the two
   always-reachable controls (the page link and the scope chip). The body scrolls beneath it, so a
   glance never loses "which meeting is this" to a scroll. */
.cal-drawer-header { padding: 14px 16px 12px; border-bottom: 1px solid var(--max360-border); flex: 0 0 auto; }
.cal-drawer-header-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 4px; }
.cal-drawer-eyebrow { display: flex; align-items: center; gap: 10px; min-width: 0; flex-wrap: wrap; }
.cal-drawer-header-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
/* The lifecycle word — where this meeting sits in its own life. The eyebrow device of the Today /
   Desk surfaces, scoped to the event surfaces; "live" gets a pulse dot, canceled goes danger. */
.cal-lifecycle { font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.18em; color: var(--accent); white-space: nowrap; }
.cal-lifecycle-live { color: var(--max360-primary); }
.cal-lifecycle-live::before { content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: currentColor; margin-right: 6px; vertical-align: 1px; animation: cal-live-pulse 2s ease-in-out infinite; }
@keyframes cal-live-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { .cal-lifecycle-live::before { animation: none; } }
.cal-lifecycle-cancelled { color: var(--max360-danger); }
.cal-drawer-body { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 4px 16px 16px; }
/* the header already draws a rule under itself; the first section must not draw a second one. */
.cal-drawer-body > .cal-drawer-section:first-child { margin-top: 8px; padding-top: 0; border-top: 0; }
.cal-drawer-body > .cal-drawer-section:first-child > .cal-drawer-ingest:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.cal-drawer-loading { padding: 2rem; text-align: center; color: var(--max360-text-muted); }
.cal-drawer-title { font-size: 1.3rem; line-height: 1.15; font-weight: 600; margin: 2px 0 8px; overflow-wrap: anywhere; }
.cal-drawer-meta { display: flex; gap: 6px; align-items: center; font-size: 0.85rem; color: var(--max360-text-muted); margin-bottom: 4px; min-width: 0; overflow-wrap: anywhere; }
.cal-drawer-section { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--max360-border); }
/* Meeting prep brief. The clamp is PRESENTATION ONLY -- the full text is always in the DOM, so
   nothing is dropped; the unclamped read is the event page (spec §2.B). Sources render OUTSIDE the
   clamped block on purpose; see the note at the markup. */
.cal-prep-brief-text { font-size: 0.9rem; line-height: 1.45; white-space: pre-wrap; }
.cal-prep-brief-clamped { display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
/* "Show more" is an ANCHOR to the event page now, not an expand button. The rule keeps the button
   reset (harmless on an <a>) and adds the two properties an anchor needs to look identical to the
   control it replaced: its own line, and no default underline until hover. */
.cal-prep-brief-toggle { display: inline-block; background: none; border: 0; padding: 2px 0 0; font-size: 0.82rem; color: var(--max360-primary, #0d6efd); cursor: pointer; text-decoration: none; }
/* The visible hedge for an inferred sentence — existing tokens only (button-style guard). */
.cal-prep-inferred { font-style: italic; border-bottom: 1px dotted var(--max360-text-muted); }
.cal-prep-brief-toggle:hover { text-decoration: underline; }
/* Provenance as a quiet line, not a row of badges (2026-08-07 UX pass): the receipts must stay
   visible without expanding — that property is pinned — but they are supporting metadata, and
   chip-styling them made them compete with the brief they attribute. Middot separators come from
   CSS so the markup stays a plain list of spans. */
/* Full density only: one sentence per line, each with the sources it rests on directly beneath.
   The drawer keeps the inline clamped run — see MeetingPrepBriefSection's density branch. */
/* Bullets under a heading, with the sources moved to a numbered list at the end. The per-sentence
   source line that used to live here put gray text between every pair of bullets; the numbers keep
   the mapping and take the labels out of the reading line. */
.cal-prep-group + .cal-prep-group { margin-top: 18px; }
.cal-prep-group-title { font-size: 0.78rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--max360-text-muted); margin-bottom: 7px; }
.cal-prep-bullets { margin: 0; padding-left: 18px; list-style: disc; }
.cal-prep-bullet { font-size: 0.9rem; line-height: 1.5; overflow-wrap: anywhere; margin-top: 7px; }
.cal-prep-bullet:first-child { margin-top: 0; }
.cal-prep-bullet::marker { color: var(--max360-text-muted); }
/* the drawer's glance: each point held to two lines so three of them never fill the panel. */
.cal-prep-glance .cal-prep-bullet { margin-top: 5px; }
.cal-prep-glance .cal-prep-bullet > span { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* a finished meeting's brief, folded under one line in the drawer; the section inside drops its
   own rule because the fold already is the section. */
.cal-prep-fold > .cal-prep-fold-summary { cursor: pointer; list-style: none; display: flex; gap: 6px; align-items: center; font-size: 0.85rem; font-weight: 600; color: var(--max360-text); }
.cal-prep-fold > .cal-prep-fold-summary::-webkit-details-marker { display: none; }
.cal-prep-fold > .cal-prep-fold-summary .bi { color: var(--max360-text-muted); font-size: 0.8rem; }
.cal-prep-fold > .cal-prep-fold-summary::after { content: "\F282"; font-family: "bootstrap-icons"; font-size: 0.7rem; color: var(--max360-text-muted); margin-left: auto; transition: transform 0.15s ease; }
.cal-prep-fold[open] > .cal-prep-fold-summary::after { transform: rotate(180deg); }
.cal-prep-fold > .cal-prep-fold-summary:focus-visible { outline: 2px solid var(--max360-primary); outline-offset: 3px; }
.cal-prep-fold > .cal-drawer-section { margin-top: 8px; padding-top: 0; border-top: 0; }
/* The annotation. Small, raised, and it must not stretch the line it sits on. */
.cal-prep-cite { font-size: 0.68rem; line-height: 0; vertical-align: super; margin-left: 2px; }
.cal-prep-cite a { color: var(--max360-text-muted); text-decoration: none; }
.cal-prep-cite a:hover { color: var(--max360-primary); text-decoration: underline; }
.cal-prep-citations { margin-top: 16px; padding-top: 10px; border-top: 1px solid var(--max360-border); }
.cal-prep-citations-title { font-size: 0.72rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--max360-text-muted); margin-bottom: 5px; }
.cal-prep-citation-list { margin: 0; padding-left: 20px; font-size: 0.75rem; color: var(--max360-text-muted); }
.cal-prep-citation { margin-top: 2px; overflow-wrap: anywhere; }
.cal-prep-citation::marker { color: var(--max360-text-muted); }
/* "Not related", on the cited source. Quiet and not danger-coloured: removing a wrong source is
   housekeeping, and it undoes in one click from the set-aside line below. No flex here: the "Why"
   beside it is inline in a non-flex <li>, so opening it reflows the line downward. */
.cal-prep-citation-veto { margin-left: 8px; vertical-align: baseline; }
/* Already set aside, where some surviving sentence still cites it. A STATUS, so not a button and
   not actionable -- the undo lives once, on the set-aside line below. */
.cal-prep-citation-vetoed { margin-left: 8px; vertical-align: baseline; opacity: 0.7; }
/* "Why this source is here", beside the veto. */
.cal-prep-citation-why { display: inline-block; margin-left: 8px; vertical-align: baseline; }
.cal-prep-citation-why > summary { display: inline-block; font-size: 0.72rem; color: var(--max360-text-muted); cursor: pointer; list-style: none; text-decoration: underline dotted; }
.cal-prep-citation-why > summary::-webkit-details-marker { display: none; }
.cal-prep-citation-why > summary:hover { color: var(--max360-text); }
.cal-prep-citation-why > span { display: block; margin: 3px 0 0; font-size: 0.74rem; color: var(--max360-text-muted); line-height: 1.45; }
/* "N you set aside" — the quiet undo, and the only way back from the veto above. Collapsed by
   default and separated from what precedes it, because on most meetings it is absent entirely and
   it must not read as another part of the brief. */
.cal-prep-setaside { margin-top: 12px; padding-top: 8px; border-top: 1px dashed var(--max360-border); }
.cal-prep-setaside > summary { display: inline-block; font-size: 0.74rem; color: var(--max360-text-muted); cursor: pointer; list-style: none; text-decoration: underline dotted; }
.cal-prep-setaside > summary::-webkit-details-marker { display: none; }
.cal-prep-setaside > summary:hover { color: var(--max360-text); }
.cal-prep-setaside-row { padding: 4px 0; font-size: 0.8rem; }
.cal-prep-setaside-row a { color: var(--max360-primary, #2563eb); text-decoration: none; }
.cal-prep-setaside-row a:hover { text-decoration: underline; }
/* Still rendered by the Summary branch and by a legacy unitless row, so these rules stay. */
.cal-prep-unit { margin-top: 16px; padding-left: 14px; position: relative; }
.cal-prep-unit:first-child { margin-top: 0; }
.cal-prep-unit::before { content: ""; position: absolute; left: 0; top: 0.55em; width: 5px; height: 5px; border-radius: 50%; background: var(--max360-text-muted); opacity: 0.55; }
.cal-prep-unit-text { margin: 0; font-size: 0.9rem; line-height: 1.5; overflow-wrap: anywhere; }
.cal-prep-unit-sources { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 2px; font-size: 0.75rem; }
/* The separator dot is on cal-prep-receipt + cal-prep-receipt below, which is what the pooled line
   needs. Here the gap does the separating, so the dot is suppressed. */
.cal-prep-unit-sources .cal-prep-receipt + .cal-prep-receipt::before { content: none; }
a.cal-prep-receipt { color: var(--max360-text-muted); text-decoration: none; border-bottom: 1px dotted var(--max360-border); }
a.cal-prep-receipt:hover { color: var(--max360-primary); border-bottom-color: var(--max360-primary); }
.cal-prep-brief-receipts { margin-top: 6px; font-size: 0.75rem; color: var(--max360-text-muted); overflow-wrap: anywhere; }
.cal-prep-receipt { font-weight: 400; color: var(--max360-text-muted); max-width: 100%; overflow-wrap: anywhere; }
.cal-prep-receipt + .cal-prep-receipt::before { content: " \00B7  "; }
.cal-prep-receipt-unresolved { font-style: italic; }
/* Sentence case since the 2026-08-07 UX pass: the uppercase device belongs to the eyebrow and the
   page's group titles, one per region — five shouting section headings in a 440px panel was the
   "excessive uppercase" the pass removed. */
.cal-drawer-section-title { font-size: 0.85rem; font-weight: 600; color: var(--max360-text); margin-bottom: 8px; display: flex; gap: 6px; align-items: center; }
.cal-drawer-section-title .bi { color: var(--max360-text-muted); font-size: 0.8rem; }

/* ── What Max may discuss in this meeting (MeetingWideningSection) ──────────────────────────
   Here rather than in a <style> block inside the component: a style block is markup, so its
   rules reach the DOM only while that component renders, and a host that is not the drawer would
   render the section completely unstyled. CalendarSectionStyleReachabilityTests fails if any
   cal-* class the Sections/ components render loses its rule or moves back into a component. */
.cal-widening-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.cal-widening-item { border-left: 3px solid var(--max360-brand-accent); padding: 4px 0 4px 10px; }
.cal-widening-what { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.cal-widening-scopes { font-weight: 600; color: var(--max360-text); }
/* The count-only rendering a non-member sees. Muted and italic so it reads as a withheld
   detail rather than as the name of something called "2 things". */
.cal-widening-hidden { font-weight: 500; font-style: italic; color: var(--max360-text-muted); }
.cal-widening-state { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--max360-text-muted); }
.cal-widening-statement { font-size: 0.85rem; color: var(--max360-text); margin-top: 2px; }
.cal-widening-who { font-size: 0.8rem; color: var(--max360-text-muted); margin-top: 2px; }
.cal-widening-when { margin-left: 6px; }
.cal-widening-sustainers { font-size: 0.8rem; color: var(--max360-text-muted); margin-top: 2px; }
.cal-widening-remove { margin-top: 6px; }
.cal-widening-feedback { margin-top: 10px; font-size: 0.85rem; color: var(--max360-text); }
.cal-widening-feedback-error { color: var(--max360-danger, #b3261e); }
.cal-widening-add { margin-top: 10px; }
.cal-widening-form { margin-top: 10px; border-top: 1px solid var(--max360-border, #e0e0e0); padding-top: 10px; display: flex; flex-direction: column; gap: 10px; }
.cal-widening-form-lead { font-size: 0.85rem; color: var(--max360-text-muted); margin: 0; }
.cal-widening-scope-picker, .cal-widening-sustainer-picker { border: 0; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 4px; }
.cal-widening-scope-picker legend, .cal-widening-sustainer-picker legend { font-size: 0.8rem; font-weight: 600; color: var(--max360-text); float: none; width: auto; margin-bottom: 2px; }
.cal-widening-choice { font-size: 0.85rem; display: flex; gap: 6px; align-items: center; }
/* the all-groups selector sits above the named boxes and ticks them; the rule it needs is a
   separator, so a reader can see the list below belongs to it. */
.cal-widening-everything { padding-bottom: 6px; margin-bottom: 2px; border-bottom: 1px solid var(--max360-border); }
.cal-widening-everything-box, .cal-widening-scope-box, .cal-widening-sustainer-box { flex: 0 0 auto; margin: 0; }
.cal-widening-statement-label { font-size: 0.8rem; color: var(--max360-text-muted); display: flex; flex-direction: column; gap: 4px; }
.cal-widening-form-actions { display: flex; gap: 8px; align-items: center; }
.cal-widening-save, .cal-widening-cancel { margin: 0; }
.cal-widening-until { font-size: 0.8rem; color: var(--max360-text-muted); margin-top: 2px; }
.cal-widening-expiry-label { font-size: 0.8rem; color: var(--max360-text-muted); display: flex; flex-direction: column; gap: 4px; max-width: 220px; }
.cal-drawer-body-text { font-size: 0.88rem; white-space: pre-wrap; overflow-wrap: anywhere; }
/* The invite body at drawer density: context, not the lead. Presentation only — the full text is
   in the DOM and renders whole on the page. */
.cal-drawer-body-clamp { display: -webkit-box; -webkit-line-clamp: 4; line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
.cal-drawer-attendee { display: flex; gap: 6px; align-items: center; padding: 3px 0; font-size: 0.88rem; flex-wrap: wrap; }
/* The Summary-density rollup — counts and a few names, one glanceable block. */
/* the drawer's header line for who is coming: names, then the tally under them in smaller type.
   aligned to the top so the icon sits beside the names when they wrap. */
.cal-attendee-rollup { align-items: flex-start; line-height: 1.4; }
.cal-attendee-rollup > .bi { margin-top: 2px; }
.cal-attendee-rollup-body { display: flex; flex-direction: column; min-width: 0; }
.cal-attendee-rollup-names { overflow-wrap: anywhere; }
.cal-attendee-more { align-self: flex-start; }
.cal-attendee-rollup-line { font-size: 0.75rem; }
/* Full density: every name on one wrapped, comma-separated line. One row per person with a badge
   each was three lines of chrome for three facts; the counts line above carries the totals and only
   the replies a reader ACTS on ride beside a name. */
.cal-attendee-names { margin-top: 4px; font-size: 0.88rem; line-height: 1.6; overflow-wrap: anywhere; }
.cal-attendee-name { white-space: nowrap; }
.cal-attendee-flag { font-size: 0.72rem; color: var(--max360-text-muted); margin-left: 4px; }
.cal-attendee-optional { font-size: 0.72rem; color: var(--max360-text-muted); }
.cal-attendee-response { font-size: 0.72rem; padding: 1px 5px; border-radius: 4px; }
.cal-response-accepted { background: #dcfce7; color: #166534; }
.cal-response-declined { background: var(--max360-danger-soft); color: var(--max360-danger-ink, var(--max360-danger)); }
.cal-response-tentative { background: #fef9c3; color: #854d0e; }
.cal-drawer-entity { display: flex; gap: 6px; align-items: center; padding: 3px 0; font-size: 0.88rem; }
.cal-drawer-thread { display: grid; grid-template-columns: auto 1fr auto; gap: 6px; align-items: center; padding: 3px 0; font-size: 0.82rem; }
.cal-thread-provider { font-weight: 500; }
.cal-thread-handles { color: var(--max360-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Who's in this meeting — per-attendee prep. Existing tokens only, no new colors
   (the button-style guard suite checks for exactly that). */
.cal-drawer-attendee-prep { padding: 3px 0; font-size: 0.88rem; }
.cal-prep-line { display: flex; gap: 6px; align-items: center; }
.cal-prep-history { font-size: 0.78rem; }
.cal-prep-detail { margin: 2px 0 6px 14px; padding-left: 8px; border-left: 2px solid var(--max360-border); }
.cal-prep-basis { font-size: 0.75rem; }
.cal-prep-fact { padding: 2px 0; font-size: 0.82rem; }
.cal-prep-detail-empty { font-size: 0.8rem; font-style: italic; }
.cal-prep-unsettled { font-size: 0.72rem; margin-left: 6px; color: var(--max360-text-muted); text-decoration: underline; }
/* The hairline is a MIS-CLICK FIX, not decoration. Even with both controls pulled onto one line
   inside the row, the veto's 44px WCAG hit box still ends 10px above the NEXT row's title while
   its own title is 23.7px above it (measured live, both before and after that move) — so proximity
   alone still points the wrong way. A rule between rows settles ownership without depending on
   pixel distances at all, and it costs one pixel of height rather than the padding that would be
   needed to win on distance. :last-child keeps the section from ending on a rule. */
.cal-drawer-related-doc { padding: 3px 0 4px; font-size: 0.82rem; border-bottom: 1px solid var(--max360-border); }
.cal-related-group .cal-drawer-related-doc:last-child { border-bottom: 0; }
.cal-drawer-related-doc a { color: var(--max360-primary, #2563eb); text-decoration: none; }
.cal-drawer-related-doc a:hover { text-decoration: underline; }
.cal-drawer-related-doc-meta { display: inline; font-size: 0.75rem; color: var(--max360-text-muted); }
/* The two headed groups inside "Worth reading first" — prior meetings with these people, and
   documents on this subject. The group title sits BELOW the section title in the hierarchy, so it
   is smaller and muted rather than a second heading competing with it. */
.cal-related-group { margin-top: 10px; }
.cal-related-group:first-of-type { margin-top: 4px; }
.cal-related-group-title { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--max360-text-muted); margin-bottom: 4px; }
/* The two explanatory empty states: "no earlier meeting … yet", and the name-stripped title line.
   Same treatment as cal-prep-detail-empty — an answer rather than a row, so it must not read as
   one. */
.cal-related-note { padding: 4px 0; font-size: 0.8rem; font-style: italic; color: var(--max360-text-muted); }
/* "Max searched for uv360, identitymax · attendee names ignored for subject matches" — the query
   itself, printed once above both groups so the reader can see it rather than infer it. */
.cal-related-searchedfor { margin: 0 0 8px; font-size: 0.76rem; color: var(--max360-text-muted); line-height: 1.4; }
.cal-related-searchedfor-note { opacity: 0.85; }
/* "N you set aside" — the quiet undo. Collapsed by default and separated from the groups above,
   because on most meetings it is absent entirely and it must not read as a third group. */
.cal-related-setaside { margin-top: 12px; padding-top: 8px; border-top: 1px dashed var(--max360-border); }
.cal-related-setaside > summary { display: inline-block; font-size: 0.74rem; color: var(--max360-text-muted); cursor: pointer; list-style: none; text-decoration: underline dotted; }
.cal-related-setaside > summary::-webkit-details-marker { display: none; }
.cal-related-setaside > summary:hover { color: var(--max360-text); }
.cal-related-setaside-row { padding: 4px 0; font-size: 0.8rem; }
.cal-related-setaside-row a { color: var(--max360-primary, #2563eb); text-decoration: none; }
.cal-related-setaside-row a:hover { text-decoration: underline; }
/* The guest list as header metadata (2026-08-23). Sits with the date and the room rather than in a
   section, so it takes cal-drawer-meta's size and color and adds only the wrapping behavior a
   list of names needs that a single location string does not. */
.cal-attendee-meta { display: flex; align-items: flex-start; }
.cal-attendee-meta > .bi { margin-top: 3px; }
.cal-attendee-meta .cal-attendee-name { white-space: nowrap; }
.cal-attendee-chips { display: flex; flex-wrap: wrap; gap: 4px 6px; min-width: 0; }
.cal-attendee-chip { display: inline-flex; align-items: center; gap: 5px; max-width: 100%; padding: 1px 9px 1px 2px; border-radius: 999px; background: var(--surface-2); color: var(--max360-text); font-size: 0.8rem; line-height: 1.5; }
.cal-attendee-chip .cal-attendee-name { overflow: hidden; text-overflow: ellipsis; }
.cal-attendee-initials { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%; background: var(--max360-info-soft, var(--max360-surface)); color: var(--max360-info-ink, var(--max360-primary)); font-size: 0.62rem; font-weight: 700; letter-spacing: 0.02em; }
.cal-attendee-chip.is-external { background: var(--max360-warning-soft, var(--surface-2)); }
.cal-attendee-chip.is-external .cal-attendee-initials { background: var(--max360-surface); color: var(--max360-warning-ink, var(--max360-text)); }
.cal-attendee-chip .cal-attendee-flag { margin-left: 0; }
.cal-drawer-footer { margin-top: 20px; padding-top: 12px; border-top: 1px solid var(--max360-border); font-size: 0.78rem; color: var(--max360-text-muted); display: flex; gap: 6px; }
/* The link-through to /calendar/event/{id} (spec §2.B, §2.K). PINNED in the header since the
   2026-08-07 UX pass — everything the drawer stopped rendering is reachable only from here, so it
   must never be lost to a scroll, let alone read as a footnote. */
.cal-drawer-open-page { font-size: 0.85rem; white-space: nowrap; }
.cal-drawer-error { color: var(--max360-danger); font-size: 0.82rem; margin-top: 4px; }
.cal-source-badge-m365   { background: #e8f4fd; color: #004578; padding: 2px 8px; border-radius: 10px; font-size: 0.75rem; font-weight: 600; }
.cal-source-badge-native { background: color-mix(in srgb, var(--max360-primary, #2563eb) 12%, transparent); color: var(--max360-primary, #2563eb); padding: 2px 8px; border-radius: 10px; font-size: 0.75rem; font-weight: 600; }
.cal-source-badge-inferred { background: color-mix(in srgb, var(--max360-primary, #2563eb) 14%, transparent); color: var(--max360-primary, #2563eb); padding: 2px 8px; border-radius: 10px; font-size: 0.75rem; font-weight: 600; }
.cal-drawer-source-link { margin-top: 4px; font-size: 0.82rem; }
.cal-drawer-source-link a { color: var(--max360-primary, #2563eb); text-decoration: none; }
.cal-drawer-source-link a:hover { text-decoration: underline; }
.cal-drawer-source-hint { display: block; font-size: 0.75rem; color: var(--max360-text-muted); margin-top: 2px; }
/* STANDING EXPLANATION, as opposed to a label. Both are .cal-drawer-source-hint and both are small
   and muted, which is why the long ones read as content: at three or four lines, quiet prose in the
   flow is still prose in the flow. Vikas: helpful once you read it, but very long and easy to
   confuse with actual content until you pay attention.
   So this is a RANK change, not a wording one -- the sentences are unchanged, and the attendance
   one in particular is the best copy on the page. The rule and the inset make a paragraph
   skippable: the eye can see where it starts and ends without reading it, which is the whole ask.
   NOT applied to short hints -- a timestamp or a kind label under a row needs no apparatus, and
   putting a rule beside four words makes the page noisier rather than calmer. */
.cal-drawer-explainer {
    border-left: 2px solid var(--max360-border);
    padding-left: 0.625rem;
    margin-top: 0.5rem;
    line-height: 1.5;
}
.cal-drawer-actions { display: flex; gap: 6px; }
.cal-drawer-danger { border-top-color: #fecaca; }
.cal-drawer-confirm { display: flex; flex-direction: column; gap: 8px; font-size: 0.88rem; }
.cal-drawer-confirm-actions { display: flex; gap: 6px; }
.cal-drawer-transcript-row { display: flex; gap: 8px; align-items: center; justify-content: space-between; padding: 4px 0; font-size: 0.82rem; flex-wrap: wrap; }
.cal-drawer-transcript-row > span { min-width: 0; overflow-wrap: anywhere; }
.cal-transcript-run { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* the search box the pickers' result list hangs from; the rows themselves are .max360-choice */
.linked-meeting-search { position: relative; }

/* the document pickers: what you are picking, a list that scrolls rather than pushing Cancel off the page */
.meeting-doc-picker { margin-top: 4px; }
.meeting-doc-picker-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.meeting-doc-picker-title { font-size: 0.82rem; font-weight: 600; color: var(--max360-text); }
.meeting-doc-results { max-height: 22rem; overflow-y: auto; margin-top: 0.3rem; }
.meeting-doc-results > * { flex-shrink: 0; }
.meeting-doc-results-note { margin-top: 0.3rem; font-size: 0.72rem; color: var(--max360-text-muted); }
.meeting-doc-result-name { overflow-wrap: anywhere; }
.meeting-notes-modes { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
.meeting-notes-typing { display: flex; flex-direction: column; gap: 6px; }
.meeting-upload-file { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.meeting-upload-file input[type="file"] { max-width: 100%; }
.meeting-notes-typing textarea { resize: vertical; min-height: 8rem; }
.meeting-notes-typing-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; }
.meeting-notes-typing-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
.meeting-notes-typing-actions > .meeting-doc-results-note { order: 3; flex-basis: 100%; }
.cal-event-add > div:has(.meeting-doc-picker) { flex-basis: 100%; }
.linked-meeting-empty {
    margin-top: 0.35rem;
    font-size: 0.75rem;
    color: var(--max360-text-muted);
}
/* What Max took from the meeting. Body text, not a hint: this is the primary read of the Meeting
   record group, and the transcript link below it is the provenance. pre-wrap because the summarizer
   emits labeled paragraphs ("Decisions:", "Commitments:", "Open questions:") separated by newlines
   — the ONLY way to keep that structure without a MarkupString, which this section forbids. */
.cal-transcript-summary { margin-top: 6px; white-space: pre-wrap; overflow-wrap: anywhere; font-size: 0.82rem; line-height: 1.55; color: var(--max360-text); }
/* The parsed form: one block per heading the model wrote. The heading is quiet — it labels a list,
   it does not compete with the section title above it. No white-space override here: once the
   bullets are real <li>s the newlines have done their job and pre-wrap would double the gaps. */
.cal-transcript-summary-group { margin-top: 14px; }
/* The heading is a <summary>, so it needs its own marker: the default triangle sits outside the
   flex row and cannot be aligned with the count beside it. Sentence case at text color: these are
   the labels the eye scans down, so they must not read as a muted caption. */
.cal-transcript-summary-heading { display: flex; align-items: center; gap: 0.45rem; cursor: pointer; list-style: none; font-size: 0.9rem; font-weight: 600; color: var(--max360-text); }
.cal-transcript-summary-heading::-webkit-details-marker { display: none; }
.cal-transcript-summary-heading::before { content: "\F285"; font-family: "bootstrap-icons"; font-size: 0.7rem; letter-spacing: 0; transition: transform 0.15s ease; }
.cal-transcript-summary-group[open] > .cal-transcript-summary-heading::before { transform: rotate(90deg); }
.cal-transcript-summary-heading:hover { color: var(--max360-primary); }
.cal-transcript-summary-heading:focus-visible { outline: 2px solid var(--max360-primary); outline-offset: 3px; }
.cal-transcript-summary-count { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--max360-text); background: var(--surface-2); border-radius: 999px; padding: 0 0.4rem; line-height: 1.5; }
.cal-transcript-summary-list { margin: 6px 0 0; padding-left: 1.25rem; font-size: 0.93rem; line-height: 1.6; color: var(--max360-text); max-width: 75ch; }
.cal-transcript-summary-list > li { margin-top: 5px; overflow-wrap: anywhere; }
/* What came out of the meeting, and the lead of an ended meeting's page. The serif title echoes the
   page headline and the accent rule marks it as Max's write-up; everything else in the record group
   stays at the small sans rank, so this is the one block that reads as the answer. */
.cal-outcomes { overflow-wrap: anywhere; }
.cal-outcomes-title { font-family: var(--max360-font-heading, 'Fraunces', Georgia, serif); font-size: 1.35rem; font-weight: 500; line-height: 1.2; letter-spacing: -0.01em; color: var(--max360-text); margin: 0; }
.cal-outcomes .cal-transcript-summary { font-size: 0.93rem; line-height: 1.6; }
.cal-outcomes-source { margin: 1rem 0 0; font-size: 0.78rem; line-height: 1.5; color: var(--max360-text-muted); }
.cal-outcomes-no-summary { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; font-size: 0.82rem; color: var(--max360-text-muted); }
/* a long transcript title would push the other records' tabs off a phone screen */
.cal-outcome-tab { max-width: 14rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 700px) { .cal-outcome-tab { max-width: 9rem; } }
.cal-outcomes-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 16px; margin-bottom: 6px; }
.cal-outcomes-banner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 12px; margin: 4px 0 10px; padding: 6px 10px;
                       border-radius: 6px; font-size: 0.82rem; background: var(--max360-warning-soft, var(--surface-2)); color: var(--max360-warning-ink, var(--max360-text)); }
/* the write-up's own controls, and where it is kept, in one strip above the write-up they act on */
.cal-record-bar { margin: 0 0 12px; padding: 6px 12px 8px; border: 1px solid var(--max360-border); border-radius: 8px; background: var(--surface-2); }
.cal-record-bar .cal-outcomes-head { margin-bottom: 0; }
.cal-record-actions { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0 18px; }
.cal-record-actions > .max360-action + .max360-action { margin-left: 0; }
.cal-record-note { flex-basis: 100%; }
.cal-record-docs { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 14px; font-size: 0.8rem; color: var(--max360-text-muted); }
.cal-record-docs > a { color: var(--max360-primary-ink, var(--max360-primary)); text-decoration: underline; text-underline-offset: 2px; }
.cal-record-docs-label { font-weight: 600; }
.cal-record-explain > summary { cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: 5px; min-height: 32px; font-weight: 600; color: var(--max360-text); }
.cal-record-explain > summary::-webkit-details-marker { display: none; }
.cal-record-explain > summary::before { content: "\F285"; font-family: "bootstrap-icons"; font-size: 0.7rem; transition: transform 0.15s ease; }
.cal-record-explain[open] { flex-basis: 100%; }
.cal-record-explain[open] > summary::before { transform: rotate(90deg); }
.cal-record-explain > summary:hover { color: var(--max360-primary); }
.cal-record-explain > p { margin: 2px 0 4px; max-width: 72ch; font-size: 0.84rem; line-height: 1.55; color: var(--max360-text); }
/* a record of the meeting in the list of what went into it */
.cal-source-row { align-items: flex-start; flex-wrap: nowrap; padding: 8px 0; border-bottom: 1px solid var(--max360-border); }
.cal-source-row:last-of-type { border-bottom: 0; }
.cal-source-main { flex: 1 1 auto; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; min-width: 0; }
.cal-source-kind { flex-basis: 100%; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--max360-text-muted); }
/* move and remove sit in plain view on each record row */
.cal-source-actions .doc-meeting-controls { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0 16px; }
.cal-source-actions .max360-action + .max360-action { margin-left: 0; }
@media (max-width: 700px) {
    .cal-source-row { flex-wrap: wrap; }
    .cal-source-actions .doc-meeting-controls { justify-content: flex-start; }
}
.cal-event-add { display: flex; flex-wrap: wrap; gap: 4px 20px; }
.cal-outcomes-source a { color: var(--max360-primary, #2563eb); text-decoration: underline; text-underline-offset: 2px; }
.cal-link-out { font-size: 0.7em; opacity: 0.8; }
.cal-outcomes-source a:hover { text-decoration: underline; }
/* The record reads as one column with one left edge: headings, the purpose and every line of
   bullet text start at the same x, and the fold arrows and bullet dots hang in the card's padding. */
.cal-summary-heading { margin: 1.25rem 0 0; font-size: 0.95rem; font-weight: 650; line-height: 1.4; color: var(--max360-text); }
.cal-summary-purpose { margin: 0.3rem 0 0; font-size: 0.97rem; line-height: 1.6; color: var(--max360-text); overflow-wrap: anywhere; }
.cal-summary-takeaways, .cal-summary-next-steps { margin: 0; }
.cal-summary-label { font-weight: 650; }
.cal-outcomes .cal-transcript-summary-group { margin-top: 1.25rem; }
.cal-outcomes .cal-transcript-summary-heading { position: relative; font-size: 0.95rem; font-weight: 650; }
.cal-outcomes .cal-transcript-summary-heading::before { position: absolute; left: -1rem; top: 50%; transform: translateY(-50%); }
.cal-outcomes .cal-transcript-summary-group[open] > .cal-transcript-summary-heading::before { transform: translateY(-50%) rotate(90deg); }
.cal-outcomes .cal-transcript-summary-list { margin: 0.3rem 0 0; padding-left: 0; list-style-position: outside; font-size: 0.97rem; line-height: 1.6; max-width: none; }
.cal-commitment-owner { margin: 0.7rem 0 0; font-size: 0.82rem; font-weight: 650; color: var(--max360-primary); }
.cal-outcomes .cal-transcript-summary-list > li { margin-top: 0.45rem; }
.cal-outcomes .cal-transcript-summary-list > li::marker { color: var(--max360-text-muted); }
/* The upkeep controls of a saved meeting, folded under the sources. */
.cal-record-manage { margin-top: 2px; }
.cal-record-manage[open] > .cal-transcript-recheck-summary::before { transform: rotate(90deg); }
/* The documents the record came from. They are filed under the write-up, so their headings drop
   below the write-up's rank and the links carry the row. */
.cal-record-sources > .cal-drawer-section-title { font-size: 0.78rem; color: var(--max360-text-muted); }
/* Why Max offered no group: the answer to a question only some readers have, one click away. */
.cal-transcript-why { margin-top: 6px; }
.cal-transcript-why > .cal-drawer-explainer { margin-top: 0.4rem; }
/* The re-check disclosure: the probe workflow, collapsed, once a transcript is already saved. Quiet
   by construction — it is the exception path, not the headline. */
.cal-transcript-recheck { margin-top: 2px; }
.cal-transcript-recheck-summary { cursor: pointer; font-size: 0.78rem; color: var(--max360-text-muted); list-style: none; display: inline-flex; align-items: center; gap: 5px; }
.cal-transcript-recheck-summary::-webkit-details-marker { display: none; }
.cal-transcript-recheck-summary::before { content: "\F285"; font-family: "bootstrap-icons"; font-size: 0.7rem; transition: transform 0.15s ease; }
.cal-transcript-recheck[open] > .cal-transcript-recheck-summary::before { transform: rotate(90deg); }
.cal-transcript-recheck-summary:hover { color: var(--max360-primary); }
.cal-transcript-recheck-summary:focus-visible { outline: 2px solid var(--max360-primary); outline-offset: 3px; }
.cal-drawer-ingest { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--max360-border); }
/* who can read it, under the save controls: the one line of the old paragraph that changes per
   meeting, so it reads at body weight rather than as a hint. */
.cal-drawer-reach { font-size: 0.8rem; color: var(--max360-text); margin-top: 8px; }
/* what a save does and what a transcript holds: the same on every meeting, so one click away. */
.cal-drawer-whatsaved { margin-top: 4px; }
.cal-drawer-whatsaved > summary { cursor: pointer; font-size: 0.75rem; color: var(--max360-text-muted); list-style: none; display: inline-flex; align-items: center; gap: 5px; }
.cal-drawer-whatsaved > summary::-webkit-details-marker { display: none; }
.cal-drawer-whatsaved > summary::before { content: "\F431"; font-family: "bootstrap-icons"; font-size: 0.75rem; }
.cal-drawer-whatsaved > summary:hover { color: var(--max360-primary); }
.cal-drawer-whatsaved > summary:focus-visible { outline: 2px solid var(--max360-primary); outline-offset: 3px; }
.cal-drawer-whatsaved > .cal-drawer-source-hint { border-left: 2px solid var(--max360-border); padding-left: 0.625rem; margin-top: 0.4rem; line-height: 1.5; }
.cal-drawer-link-sep { color: var(--max360-text-muted); margin: 0 4px; }
/* the heading and the save button share a row; wraps rather than overflowing on the drawer, which
   is narrower than the page and is where a long label would push the heading off its line */
.cal-transcript-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.cal-transcript-head .cal-drawer-section-title { margin-bottom: 0; }
/* the save controls move as one group, so a narrow drawer wraps both under the title together
   instead of stranding the second one on a line of its own. */
.cal-transcript-actions { display: inline-flex; flex-wrap: wrap; gap: 4px 10px; align-items: center; }
/* the group's gap spaces the buttons; the global sibling margin would indent a wrapped one. */
.cal-transcript-actions > .max360-action + .max360-action { margin-left: 0; }
/* A save's receipt, marked as one so it does not read as part of the meeting's content. */
.cal-drawer-ingest-result { font-size: 0.82rem; margin-top: 6px; color: var(--max360-success-ink); }
.cal-drawer-ingest-result::before { content: "\F270"; font-family: "bootstrap-icons"; margin-right: 6px; }
/* The save-time sharing tick (register R12). Indented under the button it qualifies, and the names
   sit under the tick's label rather than beside it so a long room wraps as a list instead of
   pushing the checkbox off the row. */
.cal-drawer-share-tick { display: flex; align-items: flex-start; gap: 6px; margin-top: 8px; font-size: 0.8rem; cursor: pointer; }
.cal-drawer-share-tick input { margin-top: 2px; flex: 0 0 auto; }
.cal-drawer-share-names { margin-left: 22px; }
/* sharing a file someone put on a meeting with the people invited */
.meeting-upload-share { display: flex; flex-direction: column; margin-bottom: 4px; }
.meeting-upload-share .cal-drawer-share-tick { margin-top: 0; }
.meeting-file-share { flex-basis: 100%; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; margin-top: 4px; }
.meeting-file-share-confirm { display: flex; flex-direction: column; gap: 6px; max-width: 60ch; padding: 8px 10px; border-radius: 6px; background: var(--max360-bg); border: 1px solid var(--max360-border); font-size: 0.85rem; }
.meeting-file-share-buttons { display: flex; flex-wrap: wrap; gap: 6px; }
.cal-drawer-share-recap { display: flex; align-items: flex-start; gap: 6px; margin: 4px 0 0 22px; font-size: 0.8rem; cursor: pointer; }
.cal-drawer-share-recap input { margin-top: 2px; flex: 0 0 auto; }
/* Reads as a note, not a warning: the name IS about to be granted and the tick is still ticked by
   default, so alarm styling here would argue against the decision the screen has already made. */
.cal-drawer-share-unfamiliar { margin-left: 22px; color: var(--max360-warning-ink); }
.cal-drawer-transcript-badges { margin-top: 6px; }
.cal-drawer-badge-external { background: #fef3c7; color: #92400e; padding: 2px 8px; border-radius: 10px; font-size: 0.72rem; font-weight: 600; }
.cal-drawer-badge-partial { background: color-mix(in srgb, var(--max360-primary, #2563eb) 12%, transparent); color: var(--max360-primary, #2563eb); padding: 2px 8px; border-radius: 10px; font-size: 0.72rem; font-weight: 600; }
.cal-drawer-transcript-text { margin-top: 8px; max-height: 320px; overflow: auto; white-space: pre-wrap; word-break: break-word; font-size: 0.75rem; background: var(--surface-2); border: 1px solid var(--max360-border); border-radius: 4px; padding: 8px; }

/* ── THE MEETING SIGNAL ON A CALENDAR ROW ──────────────────────────────────────────
   Rendered by MeetingSignalChip into all four grid views, so the rules live here rather than in
   any one view's <style> block — four copies of one class set is the arrangement that drifts.

   min-width: 0 and the overflow rule on cal-signal-word are load-bearing on Week: a 15-minute
   block has room for nothing, and the design says the glyph must be allowed to DISAPPEAR rather
   than push the time out of the block. A chip that cannot shrink pushes.
   ───────────────────────────────────────────────────────────────────────────────────── */
.cal-signal {
    display: inline-flex; align-items: center; gap: 4px;
    min-width: 0; max-width: 100%;
    padding: 0 6px; border-radius: 9px;
    font-size: 0.7rem; font-weight: 600; line-height: 1.6;
    vertical-align: middle; white-space: nowrap; text-decoration: none;
    border: 1px solid transparent;
}
a.cal-signal:hover { text-decoration: underline; }
.cal-signal .bi { font-size: 0.78rem; flex: 0 0 auto; }
.cal-signal-word { overflow: hidden; text-overflow: ellipsis; }

/* Max read this meeting and wrote it up — the gold coin. Themed tokens, NOT literals: this
   stylesheet has no prefers-color-scheme anywhere, because the app picks its theme with a
   .theme-* class on the root and every one of the five themes defines this soft/ink pair. A
   first version hardcoded #eab308/#a16207 with a prefers-color-scheme override, and on the Light
   theme under a dark OS preference the chip computed to #fcd34d on near-white — measured in a
   browser, invisible, and unreachable by any test cell. */
.cal-signal--read {
    background: var(--max360-warning-soft);
    color: var(--max360-warning-ink);
    border-color: var(--max360-warning);
}
/* Saved to Knowledge, nothing made of it yet. One click and it will be. */
.cal-signal--saved {
    background: color-mix(in srgb, var(--max360-primary, #2563eb) 14%, transparent);
    color: var(--max360-primary, #2563eb);
    border-color: color-mix(in srgb, var(--max360-primary, #2563eb) 40%, transparent);
}
/* An action, never a verdict. Dashed, because Max has not looked yet. */
.cal-signal--look {
    background: transparent; color: var(--max360-text-muted);
    border: 1px dashed var(--max360-border);
    font-weight: 500;
}
/* A prep brief with something in it. */
.cal-signal--prep {
    background: var(--surface-2, #1A2540); color: var(--max360-text-muted);
    border-color: var(--max360-border); font-weight: 500;
}

/* The one line under a row's title: what came out of the meeting, or what to walk in knowing. */
.cal-signal-snippet {
    color: var(--max360-text-muted); font-size: 0.8rem; font-weight: 400;
    line-height: 1.4; margin-top: 2px;
    overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
}

/* ── The event detail PAGE (/calendar/event/{CalendarEventId:int}) ────────────────────────────
   The page reuses the drawer's cal-drawer-section / -section-title / -meta / -body-text rules for
   the sections it shares, so its own rules are the shell: the editorial header (eyebrow, serif
   headline, meta row), the main-column/rail split, the group headings, and the refusal block.

   The 2026-08-07 UX pass gave the page the product's lead-article idiom (the Today / Desk
   shape): one serif headline, eyebrow above, hairline-ruled groups below, and
   governance in a quiet right rail instead of the bottom of a long single column. */
.cal-event-page { max-width: 1280px; margin: 0 auto; padding: 1.25rem 1.5rem 3rem; container-type: inline-size; }
/* the page keeps its own padding inside the dock shell, so the shell's workarea adds none */
.cal-event-workarea.cdock-workarea { padding: 0; }
.cal-event-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem 2rem; flex-wrap: wrap; }
/* `flex: 1 1 0` RATHER THAN THE DEFAULT `0 1 auto`, AND IT IS WHAT KEEPS THE SCOPE CHIP OFF A ROW
   OF ITS OWN. With an auto basis this item is sized from its content, and its content includes the
   full attendee roster on one line — so on any meeting with a few guests it claimed the whole
   header width, the wrapping header pushed .cal-event-header-side onto a second row, and one small
   pill occupied a full-width band. Measured on a real meeting: header 222px tall, chip on its own
   row at BOTH layout widths. With a zero basis this item takes the space the chip does not, and the
   chip sits beside the headline: 148px wide / 172px narrow, and the band is gone.
   `min-width: 0` was already here and is still required — it is what lets this item shrink below
   its content's intrinsic width instead of overflowing. */
.cal-event-header-main { flex: 1 1 0; min-width: 0; }
/* The padding aligns the chip with the HEADLINE rather than with the eyebrow badges above it. It
   costs no header height: this item is ~58px tall including the padding, against a main column of
   148px or more. */
.cal-event-header-side { flex-shrink: 0; padding-top: 1.9rem; }
.cal-event-eyebrow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 0.5rem; }
/* "-headline", NOT "-title": AgendaView already owns .cal-event-title for its chip titles, and a
   global rule under that name inflates every agenda row (found live, 2026-08-07). */
.cal-event-headline { font-family: var(--max360-font-heading, 'Fraunces', Georgia, serif); font-size: clamp(1.7rem, 3.5vw, 2.3rem); line-height: 1.08; letter-spacing: -0.02em; font-weight: 500; margin: 0 0 0.6rem; overflow-wrap: anywhere; }
.cal-event-meta-row { display: flex; flex-wrap: wrap; gap: 0.25rem 1.25rem; }
.cal-event-meta-row .cal-drawer-meta { margin-bottom: 0; }
/* ── ONE RULE SPACES EVERY META ITEM'S ICON FROM ITS TEXT, IN BOTH DISPLAY MODES ──────────────
   The three items in this row were spaced three different ways, and one of them was not spaced at
   all. `.cal-drawer-meta` is a flex row, so its `gap: 6px` separates the icon from the text for the
   date and the room. The attendee item cannot be a flex row — the names have to wrap as ordinary
   inline text — so it sets `display: block`, and a block container ignores `gap` entirely. Measured
   live: the bi-people icon's right edge and the first attendee name's left edge were both at
   385.6px. Zero pixels.
   Spacing the ICON works whichever mode the item is in, so the gap moves there and the flex gap is
   switched off to keep one source of the spacing rather than two that can disagree. The literal
   space that used to sit after the room's icon in EventDetail.razor went with it, for the same
   reason — it was a third mechanism doing the same job for one item only.
   Scoped to this row so the drawer's own .cal-drawer-meta items are untouched. */
.cal-event-meta-row .cal-drawer-meta { gap: 0; }
.cal-event-meta-row .cal-drawer-meta > .bi { margin-right: 6px; }
/* Actions sit on their own row BELOW the metadata, never inside .cal-event-meta-row. The attendee
   item there has a zero flex basis and takes the width the other items leave, so a sibling action
   wraps to wherever the names happen to end — which put Join meeting hard against the last guest's
   name. Keeping the two kinds of thing on separate rows is what stops that. */
.cal-event-action-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; margin-top: 0.85rem; }
/* The counts strip: what the write-up found, each a jump to its section. Buttons, not links, because
   they open a folded section as well as scrolling to it. */
.cal-event-counts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 0.75rem; }
.cal-prep-collapsed { margin: 0; font-size: 0.88rem; color: var(--max360-text-muted); }
/* On a phone the scope chip beside the title left the title, date, attendees and counts a 192px
   column; it goes on its own line under them instead. */
@media (max-width: 700px) {
    .cal-event-header-main { flex-basis: 100%; }
    .cal-event-header-side { padding-top: 0; }
}
.cal-drawer-join { white-space: nowrap; }
.cal-drawer-joinbar { margin: 8px 0 4px; text-align: center; }
.cal-drawer-join-hint { font-size: 0.8rem; color: var(--max360-text-muted, #6b7280); white-space: nowrap; }
/* The workspace split: the meeting in the main column, governance in the rail; one column when
   narrow, with the rail stacking after the main content (also the DOM reading order). A CONTAINER
   query, not a viewport one: the sidebar and the chat dock both eat width the viewport cannot see,
   and a 1280px window with both open leaves a main column too narrow to split (measured: 478px). */
.cal-event-layout { display: block; }
.cal-event-main { min-width: 0; }
.cal-event-rail { min-width: 0; margin-top: 1.75rem; }
@container (min-width: 980px) {
    .cal-event-layout { display: grid; grid-template-columns: minmax(0, 1fr) 300px; column-gap: 2.75rem; align-items: start; }
    .cal-event-rail { border-left: 1px solid var(--max360-border); padding-left: 1.75rem; }
}
.cal-event-group { margin-top: 1.75rem; padding-top: 1rem; border-top: 2px solid var(--max360-border); }
/* The page's one uppercase device (the drawer gave its version up for sentence case): a group
   heading in the eyebrow voice. */
.cal-event-group-title { font-size: 0.78rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.18em; color: var(--accent); margin: 0 0 0.5rem; }

/* The ruled-sections treatment above was the original design and it does not hold on the default
   theme, where --max360-bg, --max360-surface and --max360-border resolve so close together that a
   2px rule on white is invisible and the whole page reads as one sheet. Same defect and same fix as
   /my/sources (see .max360-stacked-sections in this file): the main column's groups become objects
   with a tinted title band. Three signals because no one of them survives every theme -- the band
   shows where a section starts, the darkened edge holds where --surface-2 is close to the surface,
   and the shadow is what forced colors leaves behind when both tints go. */
.cal-event-main .cal-event-group {
    margin-top: 0;
    margin-bottom: 1.75rem;
    padding: 1.25rem;
    border: 1px solid color-mix(in srgb, var(--max360-border) 80%, var(--max360-text) 20%);
    border-radius: 10px;
    background: var(--max360-surface);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05), 0 2px 6px rgba(15, 23, 42, 0.05);
}
/* A group heading that carries a control. The band already spans the group's full width, so the
   action sits at its far end rather than in a wrapper around the h2 -- wrapping breaks the
   direct-child selectors below that MAKE it a band. The button resets the heading's own casing and
   tracking, which it would otherwise inherit and render as a tiny spaced-out word. */
.cal-event-group-title-with-action {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}
.cal-event-group-title-with-action > button {
    text-transform: none;
    letter-spacing: normal;
    flex: 0 0 auto;
}
.cal-event-main .cal-event-group > .cal-event-group-title {
    margin: -1.25rem -1.25rem 1.125rem;
    padding: 0.6875rem 1.25rem;
    background: var(--surface-2);
    border-bottom: 1px solid color-mix(in srgb, var(--max360-border) 80%, var(--max360-text) 20%);
}
/* The band is the group's boundary, so the first block under it must not draw a second one. */
.cal-event-main .cal-event-group > .cal-event-group-title + .cal-drawer-section {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}
/* Inside a group the blocks ran together for the same reason the groups did: --max360-border on
   --max360-surface. Scoped to the page, so the drawer's own hairlines are untouched. */
.cal-event-main .cal-event-group .cal-drawer-section {
    border-top-color: color-mix(in srgb, var(--max360-border) 70%, var(--max360-text) 30%);
}

/* Rail groups keep the band and skip the card: the rail already has its own left border at
   container widths, and a second box inside it reads as a box in a box. */
.cal-event-rail .cal-event-group { border-top: 0; padding-top: 0; }
.cal-event-rail .cal-event-group-title { color: var(--max360-text-muted); }
.cal-event-rail .cal-event-group > .cal-event-group-title {
    padding: 0.4375rem 0.625rem;
    background: var(--surface-2);
    border-radius: 6px;
    margin-bottom: 0.75rem;
}
.cal-event-rail .cal-drawer-footer { margin-top: 1.5rem; }
/* The scope trace renders nothing for a reader it is hidden from, so its separator is drawn only
   when it has content. */
.cal-event-trace:has(> *) { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--max360-border); }
/* The band is the rail group's boundary, so whatever comes first under it draws no second one. */
.cal-event-rail .cal-event-group > .cal-event-group-title + .cal-drawer-section,
.cal-event-rail .cal-event-group > .cal-event-group-title + .cal-event-trace { margin-top: 0; padding-top: 0; border-top: 0; }
/* Centered and quiet on purpose: a refusal is an answer, not an error banner, and it must look the
   same whether the event is missing or merely out of reach (decision G). */
.cal-event-refusal { padding: 3rem 1rem; text-align: center; color: var(--max360-text-muted); }
.cal-event-refusal a { color: var(--max360-primary, #2563eb); text-decoration: none; }
.cal-event-refusal a:hover { text-decoration: underline; }

/* ── Report a problem with Agent Max ──────────────────────────────────────────
   Stacks above .contextual-help-btn (48px at bottom 54 / right 24): 12px of air, and the extra
   four on the right center the smaller circle over the larger one. */
.product-feedback-btn {
    position: fixed;
    bottom: 114px;
    right: 28px;
    z-index: 1041;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 1px solid var(--max360-border);
    background-color: var(--max360-surface);
    color: var(--max360-text-muted);
    font-size: 0.95rem;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10);
    transition: transform 0.2s ease, box-shadow 0.2s ease, color 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;
}

.product-feedback-btn:hover {
    transform: scale(1.1);
    color: var(--max360-text);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.16);
}

.feedback-panel {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 26rem;
    max-width: 100vw;
    overflow: hidden;
    z-index: 1042;
    background-color: var(--max360-surface);
    border-left: 1px solid var(--max360-border);
    box-shadow: -4px 0 16px rgba(0, 0, 0, 0.1);
    /* only the CLOSED state carries a transition, so the panel opens instantly: an environment whose
       animation timeline does not advance would otherwise hold it off-screen with no way to reach Send */
    transform: translateX(100%);
    visibility: hidden;
    transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s linear 0.25s;
}

.feedback-panel.panel-open {
    transform: none;
    visibility: visible;
    transition: none;
}

.feedback-panel-content {
    display: flex;
    flex-direction: column;
    height: 100%;
    width: 26rem;
    max-width: 100vw;
}

.feedback-panel-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.85rem 1rem 0.35rem;
    flex-shrink: 0;
}

.feedback-panel-title {
    flex: 1 1 auto;
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--max360-text);
}

.feedback-panel-close {
    flex: 0 0 auto;
    background: none;
    border: none;
    color: var(--max360-text-muted);
    padding: 0.15rem 0.35rem;
    border-radius: 4px;
    line-height: 1;
    cursor: pointer;
}
.feedback-panel-close:hover { color: var(--max360-text); background-color: var(--max360-bg); }

.feedback-panel-ctx {
    padding: 0 1rem 0.7rem;
    font-size: 0.78rem;
    color: var(--max360-text-muted);
    letter-spacing: 0.02em;
    flex-shrink: 0;
}

.feedback-panel-body { padding: 0 1rem 1rem; overflow-y: auto; flex: 1 1 auto; }

.feedback-box {
    width: 100%;
    min-height: 5rem;
    resize: vertical;
    border: 1px solid var(--max360-border);
    border-radius: 4px;
    background-color: var(--max360-bg);
    color: var(--max360-text);
    padding: 0.6rem 0.7rem;
    font-size: 0.9rem;
    line-height: 1.5;
    font-family: inherit;
}
.feedback-box::placeholder { font-style: italic; color: var(--max360-text-muted); }

.feedback-drafthead {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 1.05rem 0 0.55rem;
    font-size: 0.69rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--max360-primary);
}
.feedback-drafthead-line { flex: 1 1 auto; height: 1px; background-color: var(--max360-border); }

.feedback-undo {
    background: none;
    border: none;
    padding: 0;
    color: var(--max360-text-muted);
    text-decoration: underline;
    cursor: pointer;
    font-size: 0.69rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
.feedback-undo:hover { color: var(--max360-text); }

.feedback-fld { margin: 0.65rem 0 0; }
.feedback-fld label {
    display: block;
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--max360-text);
    margin-bottom: 0.25rem;
}

.feedback-val {
    width: 100%;
    border: 1px solid var(--max360-border);
    border-radius: 4px;
    background-color: var(--max360-surface);
    color: var(--max360-text);
    padding: 0.45rem 0.6rem;
    font-size: 0.87rem;
    line-height: 1.48;
    font-family: inherit;
    resize: vertical;
}
.feedback-val::placeholder { font-style: italic; color: var(--max360-text-muted); }

.feedback-panel-foot {
    border-top: 1px solid var(--max360-border);
    padding: 0.8rem 1rem 0.9rem;
    display: flex;
    align-items: flex-end;
    gap: 1rem;
    flex-shrink: 0;
}

.feedback-note {
    flex: 1 1 auto;
    margin: 0;
    font-size: 0.76rem;
    color: var(--max360-text-muted);
    line-height: 1.45;
}

.feedback-send {
    flex: none;
    font-size: 0.72rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    font-weight: 600;
    padding: 0.55rem 0.9rem;
    border: none;
    border-radius: 4px;
    background-color: var(--max360-primary);
    color: var(--max360-on-primary);
    white-space: nowrap;
    cursor: pointer;
}
.feedback-send:disabled {
    background-color: transparent;
    color: var(--max360-text-muted);
    border: 1px solid var(--max360-border);
    cursor: default;
}

.feedback-error {
    margin: 0;
    padding: 0 1rem 0.9rem;
    font-size: 0.8rem;
    color: var(--max360-danger);
}

.feedback-sent { padding: 1.6rem 1rem; text-align: center; }
.feedback-sent-big { font-size: 1.05rem; font-weight: 600; margin: 0 0 0.3rem; color: var(--max360-text); }
.feedback-sent-small { font-size: 0.84rem; color: var(--max360-text-muted); margin: 0; }

/* A per-session notice above a chat's message stream (MaxTalkCallBanner). GLOBAL, not inside
   AIAssistantPanel's own <style> block, which is where it used to live: the banner is a shared
   Library component and /ask renders it without that panel, so a rule kept in one consumer left
   the other one unstyled. Its own name rather than reusing .max360-lock-banner, which is named for
   its one use. */
.max360-session-notice {
    flex-shrink: 0;
    margin: 0 1rem 0.5rem;
}
/* The uncited and unresolved remainder, inside the Citations block rather than as a rival list. */
.cal-prep-citation-remainder { margin-top: 6px; font-size: 0.75rem; color: var(--max360-text-muted); }
/* The prep heading is a row: title left, recompose control and its timestamp right. */
.cal-prep-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.cal-prep-head-title { display: inline-flex; align-items: center; gap: 6px; }
/* what the brief was written about, above it (subject-first spec 4.7) */
.cal-prep-about { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin: 4px 0 10px; padding: 7px 10px; font-size: 0.86rem; border: 1px solid var(--max360-border); border-radius: 8px; background: var(--max360-info-soft); }
.cal-prep-about-guess { border-color: var(--max360-link); }
.cal-prep-about-who { color: var(--max360-text-muted); font-style: italic; font-size: 0.8rem; }
.cal-prep-about-actions { display: inline-flex; gap: 12px; margin-left: auto; }
.cal-prep-about-shared { flex-basis: 100%; color: var(--max360-text-muted); font-size: 0.78rem; }
.cal-prep-about-failed { margin-bottom: 4px; }
.cal-prep-head-actions { display: inline-flex; align-items: center; margin-left: auto; }

/* One suggestion on one line: title, what it is, why, and the veto at the far end. The gap
   between Why and the veto is deliberate -- adjacency is what got the veto pressed by mistake. */
.cal-related-line { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 0.8rem; }
.cal-related-title { flex: 0 1 auto; min-width: 0; }
.cal-related-more { margin-top: 4px; }
.cal-related-more > summary { font-size: 0.74rem; color: var(--max360-text-muted); cursor: pointer; list-style: none; text-decoration: underline dotted; }
.cal-related-more > summary::-webkit-details-marker { display: none; }
.cal-related-more > summary:hover { color: var(--max360-text); }

/* =============================================================================
   FORM STEPS + ADVANCED DISCLOSURE — the new-brief / edit-brief form
   ============================================================================= */

/* kicker above a step's heading: "STEP 1" */
.max360-form-step {
    font-family: var(--max360-font-mono);
    font-size: 0.66rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--max360-text-muted);
    white-space: nowrap;
}

.max360-step-head {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-bottom: 0.75rem;
}

.max360-step-head h3 {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 600;
}

/* a step's supporting sentence, quieter than body copy */
.max360-step-note {
    color: var(--max360-text-muted);
    font-size: 0.85rem;
    line-height: 1.45;
    margin: 0;
}

/* collapsible "advanced" group; summary carries a live précis of what is inside */
.max360-disclosure {
    background: var(--max360-surface);
    border: 1px solid var(--max360-border);
    border-radius: 0.5rem;
    margin-bottom: 1rem;
}

.max360-disclosure > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 1rem 1.25rem;
    cursor: pointer;
    list-style: none;
    font-weight: 600;
}

.max360-disclosure > summary::-webkit-details-marker { display: none; }
.max360-disclosure > summary:hover { color: var(--max360-primary); }

.max360-disclosure > summary::after {
    content: "";
    flex: 0 0 auto;
    width: 0.5rem;
    height: 0.5rem;
    border-right: 2px solid var(--max360-text-muted);
    border-bottom: 2px solid var(--max360-text-muted);
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform 0.15s ease;
}

.max360-disclosure[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }

.max360-disclosure-precis {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: 400;
    font-size: 0.8rem;
    color: var(--max360-text-muted);
}

.max360-disclosure-body {
    padding: 1.25rem;
    border-top: 1px solid var(--max360-border);
}

/* a field the model is currently writing: shimmering placeholder in place of the input */
.max360-field-skeleton {
    border-radius: 0.375rem;
    background: linear-gradient(90deg,
        var(--max360-surface) 0%,
        var(--max360-border) 50%,
        var(--max360-surface) 100%);
    background-size: 200% 100%;
    animation: max360-field-shimmer 1.25s ease-in-out infinite;
}

@keyframes max360-field-shimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
    .max360-field-skeleton { animation: none; }
}

/* "Max is drafting — usually 10 to 20 seconds", beside the control that started it */
.max360-busy-note {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8rem;
    color: var(--max360-primary);
}

/* the drawer's glance: when, and after a meeting what came out of it */
.cal-drawer-when { font-size: 0.75rem; color: var(--max360-text-muted, #6b7280); letter-spacing: normal; }
.cal-intel-glance { display: block; }
.cal-intel-glance-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.cal-intel-gist { --gist-accent: var(--max360-warning-ink); margin: 4px 0 6px; font-size: 0.875rem; line-height: 1.5; }
.cal-intel-counts { font-size: 0.8rem; color: var(--max360-text-muted, #6b7280); }

/* A chart comes drawn twice, and a phone shows the narrow drawing, so it fits the screen without
   its text shrinking to half size. */
.chat-visual .chart-phone { display: none; }
@media (max-width: 700px) {
    .chat-visual .chart-wide { display: none; }
    .chat-visual .chart-phone { display: block; }
}

/* Native dropdown list. A select styled `background: transparent` inherits the page's light
   text while the browser paints the popup itself, so on a dark theme it is light text on white. */
select option,
select optgroup {
    background-color: var(--max360-surface);
    color: var(--max360-text);
}

/* Bootstrap's .badge is white text; these three backgrounds are too light for it in every theme. */
.badge.bg-warning,
.badge.bg-info,
.badge.bg-light {
    color: #1f2937;
}

/* A translucent badge fill leaves the page showing through, so white text on it fails; use theme ink. */
.badge[class*="bg-opacity-"] {
    color: var(--max360-text);
}

/* A page Max Live shows on its board (js/board-framed.js): the page around it holds the menus, help and feedback,
   the banners and the conversation with Max, so the frame shows only the page itself. */
html.max360-board-framed .max360-nav,
html.max360-board-framed .max360-phone-backdrop,
html.max360-board-framed .max360-backbar,
html.max360-board-framed .max360-impersonation-bar,
html.max360-board-framed .max360-acting-as-banner,
html.max360-board-framed .max360-schema-skew,
html.max360-board-framed .day-one-banner,
html.max360-board-framed .crm-banner,
html.max360-board-framed .contextual-help-btn,
html.max360-board-framed .product-feedback-btn,
html.max360-board-framed .chat-dock {
    display: none !important;
}

/* a picture written into a board item's text; one the reader may not open says so instead of showing a broken image */
.bim-embed { margin: 12px 0; min-width: 0; }
.bim-embed img { display: block; max-width: 100%; height: auto; margin: 0 auto; border-radius: 6px; border: 1px solid var(--max360-border); }
.bim-embed-cap { margin-top: 4px; color: var(--max360-text-muted); font-size: 0.875rem; text-align: center; }
.bim-embed-gone-line { display: none; color: var(--max360-text-muted); font-size: 0.875rem; }
.bim-embed.bim-embed-gone img { display: none; }
.bim-embed.bim-embed-gone .bim-embed-gone-line { display: block; }
.bim-embed-half-left { float: left; width: 48%; margin: 4px 16px 12px 0; }
.bim-embed-half-right { float: right; width: 48%; margin: 4px 0 12px 16px; }
@media (max-width: 700px) {
    .bim-embed-half-left, .bim-embed-half-right { float: none; width: auto; margin: 12px 0; }
}
.max360-viewer-markdown:has(.bim-embed-half-left, .bim-embed-half-right)::after { content: ""; display: table; clear: both; }
.ows-embed-missing { display: block; margin: 12px 0; color: var(--max360-text-muted); font-size: 0.875rem; }
