/* =============================================================================
   Amby Teams stylesheet manifest
   -----------------------------------------------------------------------------
   Feature styles are kept in cascade order below. Do not reorder these imports:
   later modules intentionally override rules from earlier modules.
   ============================================================================= */

/* =============================================================================
   Amby Teams — teams.css
   Styles for the Teams tab (#panel-teams) and its modals.
   Loaded alongside main-chat.css; ALL selectors are namespaced under the
   top-level containers .teams-panel (in-panel UI) or .teams-modal-overlay
   (body-appended modals). No generic/global class names — the `teams-` /`tm-`
   prefixes prevent cross-stylesheet conflicts (CLAUDE.md CSS rule).
   Created: 2026-07-13
   ============================================================================= */

/* ── Design tokens (scoped to the Teams containers) ───────────────────────────
 * .teams-switcher and .teams-new-convo-fab live inside .sidebar (not .teams-panel),
 * so they MUST also receive the tokens or var(--tm-accent) resolves to nothing and
 * the buttons render invisibly (light-on-light). */
/* `.teams-emoji` is a PORTABLE component: the picker mounts on whichever
   surface opened it, and in a body-appended overlay (the Spaces post
   discussion, the Spaces composer) it has no `.teams-panel` ancestor at all.
   Without its own token root every `var(--tm-*)` inside it resolves to nothing
   and it renders as an unstyled list of glyphs down the page — reported from
   production 2026-08-13. Its RULES were de-scoped for the same reason; this is
   the other half of that fix. */
.teams-panel,
.docs-panel,
#docs-sidebar,
.docs-preview,
.docs-folder-menu,
.space-team-docs,
.teams-modal-overlay,
.teams-emoji,
.teams-switcher,
.teams-new-convo-fab,
/* The video-message / screen-recording recorder is appended to document.body
   so its scrim covers the app header too (inside `.teams-panel` it was trapped
   under the header's stacking context). */
.teams-clip-rec,
/* The Teams chat-folder surfaces. The filter bar lives in `.sidebar` and the
   two dialogs are appended to `document.body`, so none of them has a
   `.teams-panel` ancestor to inherit these tokens from — same reason
   `.space-media-viewer` is listed in the dark block below. Without this they
   silently fall back to their literal light defaults and stay white in dark
   mode. */
.session-folder-filter-bar,
.sessions-list .session-folder-group-header,
.sessions-list .session-item.session-folder-group-member,
.session-folder-dialog-overlay,
.session-folder-name-dialog-overlay,
/* The text-entry dialog (resolution note) is appended to document.body too. */
.teams-prompt-overlay,
/* So is the action-item "Full comment" / "Details" popover. */
.teams-sysnote-popover,
.session-item.pinned,
.session-item {
    --tm-bg: #ece9e2;
    --tm-bg-alt: #f0ede6;
    --tm-surface: #f8f5f0;
    --tm-white: #f6f5f3;
    --tm-border: #d8d3c8;
    --tm-border-strong: #b0ab9f;
    --tm-real-white: #fff;

    --tm-text-1: #6f6e6d;
    --tm-text-2: #5c5750;
    --tm-text-3: #9a9488;
    --tm-msg-text: #1f1e1d;

    --tm-accent: #2d5f84;
    --tm-accent-hover: #245070;
    --tm-accent-subtle: rgba(45, 95, 132, 0.09);
    --tm-avatar-placeholder: #dbddda;
    --tm-ai-msg-bg: #dfd9c6d4;

    --tm-agent: #0f79e4;
    --tm-agent-bg: transparent;
    --tm-agent-border: rgba(107, 79, 160, 0.28);
    /* Opaque on purpose: a sent bubble must remain readable over a personal
       Teams background. Do not reuse --tm-accent-subtle; it also tints links,
       mentions and sidebar affordances. */
    --tm-self-message-bg: #dddddd;
    --tm-audio-player-bg: rgba(255, 255, 255, 0.78);
    --tm-audio-player-control: #2d5f84;
    --tm-audio-player-icon: #fff;

    --tm-danger: #c0392b;
    --tm-danger-bg: #fdecea;
    --tm-success: #2e7d32;
    --tm-pinned-bg: #efede4;

    --tm-note-bg: #fef9e7;
    --tm-space-href: #6269d2;
    --tm-space-post-comments: #f8f7f6;

    --tm-r: 8px;
    --tm-r-lg: 12px;
    --tm-shadow-sm:
        0 1px 3px rgba(28, 25, 20, 0.08), 0 1px 2px rgba(28, 25, 20, 0.05);
    --tm-shadow-md:
        0 8px 28px rgba(28, 25, 20, 0.16), 0 2px 6px rgba(28, 25, 20, 0.08);
    --tm-t: 0.18s ease;

    /* The colour-emoji tail is REQUIRED on any stack that renders user text.
     * Teams is a chat product: its messages, its reactions and its emoji picker
     * are mostly emoji, and a stack that names no emoji font hands the decision
     * to the OS's fallback ordering — which on some machines lands on a
     * MONOCHROME symbol font and renders every emoji black-and-white. Reported
     * from production 2026-08-13 by a few users while everyone else saw colour.
     *
     * Last in the stack, so it only catches codepoints the text font lacks.
     * Never "Segoe UI Symbol": it HAS the glyphs and draws them monochrome. */
    --tm-font-emoji: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji",
        "Twemoji Mozilla", "Android Emoji";
    --tm-font-ui: "Figtree", system-ui, sans-serif, "Apple Color Emoji",
        "Segoe UI Emoji", "Noto Color Emoji", "Twemoji Mozilla", "Android Emoji";
    --tm-font-display: "Syne", system-ui, sans-serif, "Apple Color Emoji",
        "Segoe UI Emoji", "Noto Color Emoji", "Twemoji Mozilla", "Android Emoji";
}

body.dark-theme .teams-panel,
body.dark-theme .docs-panel,
body.dark-theme #docs-sidebar,
body.dark-theme .docs-preview,
body.dark-theme .docs-folder-menu,
body.dark-theme .space-team-docs,
body.dark-theme .teams-modal-overlay,
body.dark-theme .teams-emoji,
body.dark-theme .teams-switcher,
body.dark-theme .teams-new-convo-fab,
body.dark-theme .teams-clip-rec,
/* The Spaces gallery is appended to document.body and is the one Space surface
   that carries neither `.teams-modal-overlay` nor a `.teams-panel` ancestor, so
   without this it reads the LIGHT tokens while the rest of the app is dark. */
body.dark-theme .space-media-viewer,
body.dark-theme .session-folder-filter-bar,
body.dark-theme .sessions-list .session-folder-group-header,
body.dark-theme .sessions-list .session-item.session-folder-group-member,
body.dark-theme .session-folder-dialog-overlay,
body.dark-theme .session-folder-name-dialog-overlay,
body.dark-theme .teams-prompt-overlay,
body.dark-theme .teams-sysnote-popover,
body.dark-theme .session-item.pinned,
body.dark-theme .session-item {
    --tm-bg: #1a1a1a;
    --tm-bg-alt: #1e1e1e;
    --tm-surface: #242424;
    --tm-white: #2a2a2a;
    --tm-real-white: #363f4a;
    --tm-border: #3a3a3a;
    --tm-border-strong: #555;
    --tm-text-1: #f0f0f0;
    --tm-text-2: #fff;
    --tm-text-3: #707070;
    --tm-msg-text: #f0f0f0;
    --tm-accent: #71a4df;
    --tm-accent-hover: #5a90cc;
    --tm-accent-subtle: rgba(113, 164, 223, 0.12);
    --tm-avatar-placeholder: #252b33;
    --tm-agent: #66c3ff;
    --tm-agent-bg: #2c2540;
    --tm-agent-border: rgba(183, 155, 230, 0.35);
    --tm-self-message-bg: #2a4261;
    --tm-audio-player-bg: rgba(14, 17, 21, 0.62);
    --tm-audio-player-control: #9bc6ee;
    --tm-audio-player-icon: #172431;
    --tm-danger: #e57373;
    --tm-danger-bg: #3a2422;
    --tm-success: #81c784;
    --tm-note-bg: #877c29;
    --tm-pinned-bg: #413e3e;
    --tm-space-href: #c7caf9;
    --tm-space-post-comments: #353d46;
    --tm-ai-msg-bg: #322101e3;
}

/* ── Panel shell ──────────────────────────────────────────────────────────── */
/* Match the sizing of #panel-chat/#panel-tasks (flex child of .chat-area) so the
 * fixed-height chat header is never squeezed when switching to Teams. */
#panel-teams {
    flex: 1;
    display: flex;
    min-height: 0;
    overflow: hidden;
}

.teams-panel {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    font-family: var(--tm-font-ui);
    color: var(--tm-text-2);
    background: var(--tm-bg);
    overflow: hidden;
}

/* ── Loading / spinner / states (shared across panel, modal, and switcher) ──── */
.teams-panel .teams-loading,
.teams-modal-overlay .teams-loading,
.teams-switcher .teams-loading {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 32px;
    color: var(--tm-text-2);
    font-size: 14px;
    justify-content: center;
}

.teams-panel .teams-spinner,
.teams-modal-overlay .teams-spinner,
.teams-switcher .teams-spinner {
    width: 16px;
    height: 16px;
    border: 2px solid var(--tm-border);
    border-top-color: var(--tm-accent);
    border-radius: 50%;
    animation: teams-spin 0.7s linear infinite;
    flex-shrink: 0;
}
@keyframes teams-spin {
    to {
        transform: rotate(360deg);
    }
}

/* ── Skeleton loaders (message history) ───────────────────────────────────────
 * Shaped like the bubbles they stand in for, rather than a spinner, for two
 * loads: the initial history fetch (a few rows filling the transcript) and
 * "load older" on scroll-up (one small row pinned above today's oldest
 * message — teams-conversation-messages.js `_setOlderLoadingIndicator` /
 * `_renderSkeletonHistory`). Same shimmer language as the sidebar's
 * `.skeleton-session-item` (main-chat.css), re-expressed on the Teams `--tm-*`
 * tokens so it themes correctly here regardless of what page main-chat.css's
 * own skeleton variables resolve to. */
.teams-panel .teams-skeleton-msg {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 6px 4px;
}
.teams-panel .teams-skeleton-msg__avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    flex-shrink: 0;
}
.teams-panel .teams-skeleton-msg__lines {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding-top: 4px;
}
.teams-panel .teams-skeleton-msg__line {
    height: 12px;
    border-radius: 6px;
}
.teams-panel .teams-skeleton-msg__line:first-child {
    width: 35%;
    height: 10px;
    opacity: 0.7;
}
.teams-panel .teams-skeleton-msg__avatar,
.teams-panel .teams-skeleton-msg__line {
    background: linear-gradient(90deg, var(--tm-bg-alt) 0%, var(--tm-surface) 50%, var(--tm-bg-alt) 100%);
    background-size: 200% 100%;
    animation: teams-skeleton-shimmer 1.5s ease-in-out infinite;
}
@keyframes teams-skeleton-shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}
.teams-panel .teams-skeleton-messages {
    display: flex;
    flex-direction: column;
    padding: 12px 8px;
}
/* A little width variety so the block doesn't read as a repeated tile. */
.teams-panel .teams-skeleton-messages .teams-skeleton-msg:nth-child(3n+1) .teams-skeleton-msg__line:last-child { width: 62%; }
.teams-panel .teams-skeleton-messages .teams-skeleton-msg:nth-child(3n+2) .teams-skeleton-msg__line:last-child { width: 84%; }
.teams-panel .teams-skeleton-messages .teams-skeleton-msg:nth-child(3n+3) .teams-skeleton-msg__line:last-child { width: 45%; }

/* "Load older" — pinned above the oldest message while a scroll-up page
 * fetches. One compact row (no avatar-column padding change) so it doesn't
 * shove the transcript below it around by much; unlike the initial-load
 * skeleton it never blanks the transcript, so a fast page shows as a brief
 * flicker, not a layout jump. */
.teams-panel .teams-loading-older {
    padding: 4px 4px 2px;
}
.teams-panel .teams-loading-older .teams-skeleton-msg__line:last-child {
    width: 55%;
}

.teams-panel .teams-error,
.teams-modal-overlay .teams-error,
.teams-switcher .teams-error {
    padding: 28px;
    text-align: center;
    color: var(--tm-text-2);
}
.teams-panel .teams-error p,
.teams-switcher .teams-error p {
    margin: 0 0 12px;
}

.teams-panel .teams-empty,
.teams-modal-overlay .teams-empty,
.teams-switcher .teams-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 48px 24px;
    color: var(--tm-text-2);
    gap: 6px;
}
.teams-panel .teams-empty__icon,
.teams-switcher .teams-empty__icon {
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
    font-size: 22px;
    margin-bottom: 8px;
}
.teams-panel .teams-empty h3,
.teams-switcher .teams-empty h3 {
    margin: 0;
    font-size: 16px;
    color: var(--tm-text-2);
}
.teams-panel .teams-empty p,
.teams-switcher .teams-empty p {
    margin: 0;
    font-size: 13px;
    max-width: 320px;
}
/* Retry for a feed whose module failed to load (see teams-panel.js). An empty
   state offering an action needs it to look like one — the surrounding block is
   deliberately low-contrast, so an unstyled button reads as page furniture. */
.teams-panel .teams-empty__retry {
    margin-top: 14px;
    padding: 8px 20px;
    border: 1px solid var(--tm-accent, #2d5f84);
    border-radius: 18px;
    background: transparent;
    color: var(--tm-accent, #2d5f84);
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.teams-panel .teams-empty__retry:hover {
    background: var(--tm-accent-subtle);
}
.teams-panel .teams-empty--sidebar,
.teams-switcher .teams-empty--sidebar {
    padding: 28px 8px;
}
.teams-panel .teams-empty-inline,
.teams-modal-overlay .teams-empty-inline,
.teams-switcher .teams-empty-inline {
    padding: 16px;
    text-align: center;
    color: var(--tm-text-3);
    font-size: 13px;
}
/* Second line of an empty result: WHY the company-team half is unavailable
   (not a supervisor / no roster / missing permission). Sits under the "no
   matches" line in every member picker, including the new-conversation
   modal's people list, so all three explain themselves the same way. */
.teams-panel .teams-empty-inline__why,
.teams-modal-overlay .teams-empty-inline__why,
.teams-switcher .teams-empty-inline__why {
    display: block;
    margin-top: 6px;
    font-size: 12px;
    line-height: 1.45;
    color: var(--tm-text-3);
    opacity: 0.85;
    max-width: 320px;
    margin-left: auto;
    margin-right: auto;
}

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.teams-panel .teams-btn,
.teams-modal-overlay .teams-btn,
.teams-switcher .teams-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 1px solid var(--tm-border);
    background: var(--tm-white);
    color: var(--tm-text-1);
    font-family: var(--tm-font-ui);
    font-size: 13px;
    font-weight: 500;
    padding: 8px 14px;
    border-radius: var(--tm-r);
    cursor: pointer;
    transition: all var(--tm-t);
    justify-content: center;
}
/* `display: inline-flex` above outranks the UA `[hidden] { display: none }`
   (two classes vs one attribute), so a button toggled with the `hidden`
   property stays on screen. Restore it — the participants modal's removal
   Cancel is hidden until a removal is actually pending. */
.teams-panel .teams-btn[hidden],
.teams-modal-overlay .teams-btn[hidden],
.teams-switcher .teams-btn[hidden] {
    display: none;
}
.teams-panel .teams-btn:hover,
.teams-modal-overlay .teams-btn:hover,
.teams-switcher .teams-btn:hover {
    border-color: var(--tm-accent);
    color: var(--tm-accent);
}
.teams-panel .teams-btn:disabled,
.teams-modal-overlay .teams-btn:disabled,
.teams-switcher .teams-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
.teams-panel .teams-btn--sm,
.teams-modal-overlay .teams-btn--sm,
.teams-switcher .teams-btn--sm {
    padding: 5px 10px;
    font-size: 12px;
}
.teams-panel .teams-btn--primary,
.teams-modal-overlay .teams-btn--primary,
.teams-switcher .teams-btn--primary {
    background: var(--tm-accent);
    border-color: var(--tm-accent);
    color: #fff;
}
/* :not(:disabled) — a disabled primary button (e.g. "Save changes" with nothing
   to save) is dimmed by the :disabled rule above, but an unguarded hover still
   brightened it on pointer-over and read as clickable. */
.teams-panel .teams-btn--primary:hover:not(:disabled),
.teams-modal-overlay .teams-btn--primary:hover:not(:disabled),
.teams-switcher .teams-btn--primary:hover:not(:disabled) {
    background: var(--tm-accent-hover);
    border-color: var(--tm-accent-hover);
    color: #fff;
}
.teams-panel .teams-btn--danger,
.teams-modal-overlay .teams-btn--danger {
    color: var(--tm-danger);
}
.teams-panel .teams-btn--danger:hover,
.teams-modal-overlay .teams-btn--danger:hover {
    border-color: var(--tm-danger);
    background: var(--tm-danger-bg);
    color: var(--tm-danger);
}
.teams-panel .teams-btn--ghost,
.teams-modal-overlay .teams-btn--ghost,
.teams-switcher .teams-btn--ghost {
    background: var(--tm-real-white);
}

/* ── Avatars ──────────────────────────────────────────────────────────────── */
.teams-panel .teams-avatar,
.teams-modal-overlay .teams-avatar {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--tm-avatar-placeholder);
    color: var(--tm-accent);
    font-weight: 600;
    font-size: 13px;
    margin-right: 8px;
}

.teams-panel .teams-avatar--team {
    border-radius: var(--tm-r);
}
.teams-panel .teams-avatar--agent {
    background: var(--tm-agent-bg);
    color: var(--tm-agent);
}


/* ── Real panel: the panel holds ONE full-width child (conversation | config |
 *    empty). The Teams list/conversations live in the sidebar (.teams-sidebar). */
.teams-panel--real {
    flex-direction: column;
}
.teams-panel--real > * {
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    display: flex;
}
.teams-panel--real > .teams-empty {
    flex-direction: column;
}

/* ── Teams mode sidebar swap ──────────────────────────────────────────────────
 * Teams reuses the existing two-part sidebar (widgets slot + real Recent Sessions
 * + the real #sidebarSeparator divider). In teams mode we swap the widgets slot
 * for the Teams switcher and hide the Projects group — the Recent Sessions list
 * and divider are the platform's own, not a reconstruction. */
.sidebar[data-mode="teams"] #workflowsList > .workflow-item,
.sidebar[data-mode="teams"] #workflowsList > .workflows-skeleton-loader {
    display: none !important;
}
.sidebar[data-mode="teams"] #projectsSidebarContainer {
    display: none !important;
}
.sidebar:not([data-mode="teams"]) .teams-switcher {
    display: none !important;
}

.teams-sidebar-mobile-tabs {
    display: none;
}

/* The Teams rail has an independently persisted width.  It is intentionally
 * scoped to this tab: resizing Teams must not resize the ordinary Chat sidebar. */
.sidebar[data-mode="teams"]:not(.collapsed) {
    width: var(--teams-sidebar-width, 260px);
    flex: 0 0 var(--teams-sidebar-width, 260px);
}
.teams-sidebar-width-resizer {
    display: none;
    position: absolute;
    top: 0;
    right: -4px;
    z-index: 20;
    width: 12px;
    height: 100%;
    cursor: ew-resize;
    touch-action: none;
}
.sidebar[data-mode="teams"] .teams-sidebar-width-resizer {
    display: block;
}
.teams-sidebar-width-resizer__handle {
    position: absolute;
    top: 50%;
    left: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 42px;
    transform: translate(-50%, -50%);
    border: 1px solid var(--tm-border);
    border-radius: 9px;
    background: var(--tm-white);
    box-shadow: var(--tm-shadow-sm);
    color: var(--tm-text-3);
    font-size: 10px;
    opacity: 0.8;
    transition:
        opacity var(--tm-t),
        color var(--tm-t),
        border-color var(--tm-t);
}
.teams-sidebar-width-resizer:hover .teams-sidebar-width-resizer__handle,
body.teams-sidebar-resizing .teams-sidebar-width-resizer__handle {
    border-color: var(--tm-accent);
    color: var(--tm-accent);
    opacity: 1;
}
body.teams-sidebar-resizing,
body.teams-sidebar-resizing * {
    cursor: ew-resize !important;
    user-select: none;
}
body.teams-sidebar-resizing .sidebar {
    transition: none;
}

/* Hide the header "New Chat" action while the Teams tab is active — Teams has its
 * own "New conversation" button (body.teams-tab-active set by header-tabs.js). */
body.teams-tab-active #newSessionContainer,
body.docs-tab-active #newSessionContainer {
    display: none !important;
}

body.teams-tab-active .sessions-list .session-item {
    border-left: 5px solid transparent;
}

body.teams-tab-active .sidebar.collapsed .sessions-list .session-item {
    border-left: 0;
}

body.teams-tab-active .sessions-list .session-item.has-unread-assistant {
    background: #96ddf626 !important;
}

body.teams-tab-active .sessions-list .session-item.has-unread-assistant .session-content {
    font-weight: 600;
}

body.teams-tab-active .sessions-list .session-item.pinned.active {
    background: var(--active-workflow-bg);
}

body.teams-tab-active .sessions-list .session-item.pinned {
    border-left: 5px solid var(--primary-color, #3498db);
    background: var(--tm-pinned-bg);
    box-shadow:
        0 2px 4px rgba(0, 0, 0, 0.05),
        0 4px 8px -4px rgba(0, 0, 0, 0.18);
}

/* This stylesheet's `!important` unread rule above would replace the pinned
 * colour with a `background` shorthand; LAYER the tint over it instead. */
body.teams-tab-active .sessions-list .session-item.pinned.has-unread-assistant {
    background: var(--tm-pinned-bg) !important;
    background-image: linear-gradient(#96ddf626, #96ddf626) !important;
}

/* Collapsed sidebar: show icons/avatars only (mirrors widgets/tasks collapse). */
.sidebar.collapsed .teams-switcher__list {
    padding: 4px 0;
    overflow: visible;
}
.sidebar.collapsed .teams-switcher .teams-sb-team__meta,
.sidebar.collapsed .teams-switcher .teams-sb-team__actions,
.sidebar.collapsed .teams-switcher .teams-sb-team__gear,
.sidebar.collapsed .teams-switcher .teams-empty h3,
.sidebar.collapsed .teams-switcher .teams-empty p {
    display: none !important;
}
.sidebar.collapsed .teams-switcher .teams-sb-team {
    gap: 0;
}
.sidebar.collapsed .teams-switcher .teams-sb-team__main {
    justify-content: center;
    padding: 6px 0;
}
.sidebar.collapsed .teams-switcher .teams-empty {
    padding: 16px 0;
}
.sidebar.collapsed .teams-switcher .teams-empty__icon {
    margin-bottom: 0;
}
/* Don't stretch the switcher in collapsed mode, so the create button sits right
 * under the team icons instead of dropping to the bottom (behind the FAB). */
.sidebar.collapsed .teams-switcher {
    height: auto;
    min-height: 0;
}
.sidebar.collapsed .teams-switcher__list {
    flex: 0 1 auto;
}
.sidebar.collapsed .teams-switcher__create {
    font-size: 0; /* hide label, keep the icon */
    margin: 8px 6px;
    padding: 9px 0;
    gap: 0;
}
.sidebar.collapsed .teams-switcher__create i {
    font-size: 13px;
}

/* Unlike Chat, collapsed Teams keeps its recent conversations reachable.  The
 * list becomes a compact vertical icon rail while the standard Chat collapse
 * rule continues to hide its Recent Sessions section. */
.sidebar[data-mode="teams"].collapsed .sessions-list-container {
    display: block !important;
    height: auto !important;
    min-height: 0;
    overflow: visible;
    padding: 2px 0 58px;
    border-top: 1px solid var(--tm-border);
}
.sidebar[data-mode="teams"].collapsed {
    overflow-x: hidden;
    overflow-y: auto;
}
.sidebar[data-mode="teams"].collapsed .sessions-list-container .sessions-header,
.sidebar[data-mode="teams"].collapsed
    .sessions-list-container
    .sessions-search-container,
.sidebar[data-mode="teams"].collapsed .sessions-list-container .session-content,
.sidebar[data-mode="teams"].collapsed
    .sessions-list-container
    .session-menu-btn {
    display: none !important;
}
.sidebar[data-mode="teams"].collapsed .sessions-list-container .sessions-list {
    overflow: visible;
    max-height: none;
    padding: 0;
}
.sidebar[data-mode="teams"].collapsed .sessions-list-container .session-item {
    justify-content: center;
    min-height: 42px;
    margin: 2px 6px;
    padding: 7px 0;
}
.sidebar[data-mode="teams"].collapsed .sessions-list-container .session-icon {
    width: 30px;
    height: 30px;
    margin: 0;
    border-radius: var(--tm-r);
    background: transparent;
    color: inherit;
}

/* A phone drawer has enough room for a full row even if this user's desktop
 * rail is intentionally collapsed.  This is presentation-only: do not remove
 * `.collapsed`, because it is the persisted desktop preference. */
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .teams-switcher__list {
    padding: 6px 0;
    overflow: auto;
}
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .teams-switcher .teams-sb-team__meta {
    display: flex !important;
}
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .teams-switcher .teams-sb-team__actions {
    display: grid !important;
}
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .teams-switcher .teams-sb-team {
    gap: 2px;
}
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .teams-switcher .teams-sb-team__main {
    justify-content: flex-start;
    padding: 8px 10px;
}
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .teams-switcher {
    height: auto;
    min-height: 0;
}
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .teams-switcher__create {
    font-size: inherit;
    margin: 8px 6px 10px;
    padding: 8px 10px;
    gap: 6px;
}
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .sessions-list-container .sessions-header,
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .sessions-list-container .sessions-search-container,
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .sessions-list-container .session-content,
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .sessions-list-container .session-menu-btn {
    display: block !important;
}
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .sessions-list-container .sessions-header {
    display: flex !important;
}
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .sessions-list-container .session-menu-btn {
    display: inline-block !important;
}
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .sessions-list-container .session-content {
    display: block !important;
}
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .sessions-list-container .session-item {
    justify-content: flex-start;
    min-height: 42px;
    margin: 0 0 5px;
    padding: 8px 10px;
}
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .sessions-list-container .sessions-list {
    overflow: auto;
    max-height: initial;
    padding: initial;
}
.sidebar[data-mode="teams"] .sessions-list-container .session-icon--team-chat {
    position: relative;   /* anchors the muted badge */
    overflow: visible;
    width: 38px;
    margin-right: 8px;
}
/* A muted chat: a crossed bell at the top-right of its picture. Always present in
   the row's markup, shown from `data-is-muted` (set by the list render, the row
   menu and the conversation header's bell) so the two controls cannot disagree. */
.sidebar[data-mode="teams"] .sessions-list-container .session-muted-badge {
    display: none;
    position: absolute;
    top: -9px;
    right: -7px;
    z-index: 3;
    width: 25px;
    height: 25px;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 50%;
    background: var(--tm-surface, #fff);
    font-size: 11px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
    color: var(--tm-text-1, #d8d3c8);
}
.sidebar[data-mode="teams"] .sessions-list-container .session-item[data-is-muted="true"] .session-muted-badge {
    display: inline-flex;
}

.sidebar[data-mode="teams"] .sessions-list-container .session-avatar-stack {
    position: relative;
    display: inline-flex;
    width: 30px;
    height: 32px;
    flex: 0 0 30px;
    transition: opacity 0.15s ease;
}
.sidebar[data-mode="teams"] .sessions-list-container .session-avatar {
    position: absolute;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    top: 2px;
    width: 27px;
    height: 27px;
    border-radius: 50%;
    border: 2px solid var(--sidebar-bg);
    background: #5387aa;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.02em;
}
.sidebar[data-mode="teams"] .sessions-list-container .session-avatar--1 {
    left: 0;
    z-index: 2;
}
.sidebar[data-mode="teams"] .sessions-list-container .session-avatar--more {
    top: -4px;
    left: 17px;
    z-index: 3;
    width: 17px;
    height: 17px;
    border-width: 1px;
    background: #5387aa;
    font-size: 8px;
    display: none;
}
.sidebar[data-mode="teams"]
    .sessions-list-container
    .session-avatar-stack--group {
    /* Keep the primary avatar centred on the same column as 1:1 chats;
     * the count badge intentionally overflows to the right. */
    width: 30px;
    flex-basis: 30px;
}
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-avatar {
    border-color: var(--sidebar-bg);
}

/* Recent Sessions has two distinct states in dark Teams: the selected chat is
 * blue, while a different chat has unread activity. Blue tints for both made
 * those states merge visually, especially in a dense list. Use a restrained
 * amber wash for unread rows, text and the existing dot/count indicator.
 *
 * An active row deliberately does not match: selection remains blue even for
 * the brief live-unread state that an open Teams conversation can expose. */
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-assistant:not(.active),
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-mention:not(.active) {
    background: rgba(245, 158, 11, 0.15);
}
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-assistant:not(.active):hover,
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-mention:not(.active):hover {
    background: rgba(245, 158, 11, 0.22);
}
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-assistant:not(.active) .session-title,
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-assistant:not(.active) .session-time,
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-mention:not(.active) .session-title,
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-mention:not(.active) .session-time {
    color: #fbbf24;
    opacity: 1;
}
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-assistant:not(.active) .session-unread-indicator,
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-assistant:not(.active) .session-unread-count-badge {
    background: #f59e0b;
}
/* A mention keeps its own red "@" (session-stream-indicators.css); the amber
 * wash above is the row, the badge is the reason. A mentioned row carries
 * `has-unread-assistant` (the server-driven path) and/or `has-unread-mention`
 * (the legacy one), so both are matched or the amber rule above would win. */
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-assistant:not(.active) .session-unread-indicator--mentioned,
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-assistant:not(.active) .session-unread-count-badge--mentioned,
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-mention:not(.active) .session-unread-indicator--mentioned,
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.has-unread-mention:not(.active) .session-unread-count-badge--mentioned {
    background: #f87171;
}

/* Pinned unread rows keep the amber wash layered over the sidebar colour. */
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.pinned.has-unread-assistant:not(.active),
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.pinned.has-unread-mention:not(.active) {
    background-color: var(--sidebar-bg);
    background-image: linear-gradient(rgba(245, 158, 11, 0.15), rgba(245, 158, 11, 0.15));
}
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.pinned.has-unread-assistant:not(.active):hover,
body.dark-theme
    .sidebar[data-mode="teams"]
    .sessions-list-container
    .session-item.pinned.has-unread-mention:not(.active):hover {
    background-color: var(--sidebar-bg);
    background-image: linear-gradient(rgba(245, 158, 11, 0.22), rgba(245, 158, 11, 0.22));
}
.sidebar[data-mode="teams"].collapsed
    .sessions-list-container
    .session-icon--team-chat {
    width: 38px;
    margin: 0;
}
.sidebar[data-mode="teams"].collapsed
    .sessions-list-container
    .session-avatar-stack--group {
    width: 30px;
    flex-basis: 30px;
}
.sidebar[data-mode="teams"].collapsed
    .sessions-list-container
    .session-avatar--more {
    left: 22px;
}
.sidebar[data-mode="teams"].collapsed
    .sessions-list-container
    .session-pin-toggle-icon {
    display: none !important;
}
.sidebar[data-mode="teams"].collapsed
    .sessions-list-container
    .session-item.pinned {
    border-left: 0;
    padding-left: 0;
}

/* Reveal the pin only over the session image, not the rest of the row.
 * Disable its invisible hit target so the image still opens the chat on touch. */
.sidebar[data-mode="teams"] .sessions-list-container .session-item .session-pin-toggle-icon {
    opacity: 0;
    pointer-events: none;
}
@media (hover: hover) {
    .sidebar[data-mode="teams"]:not(.collapsed)
        .sessions-list-container
        .session-icon:hover
        .session-avatar-stack {
        opacity: 0;
    }
    .sidebar[data-mode="teams"]:not(.collapsed)
        .sessions-list-container
        .session-icon:hover
        .session-pin-toggle-icon {
        opacity: 1;
        pointer-events: auto;
    }
}

/* Promo path (no teams.can_manage_and_use): expose no Team data in the sidebar. */
.sidebar.teams-locked #workflowsList,
.sidebar.teams-locked #sidebarSeparator,
.sidebar.teams-locked #sessionsListContainer,
.sidebar.teams-locked .teams-new-convo-fab {
    display: none !important;
}

.sidebar[data-mode="teams"] .sessions-list-container .session-avatar {
    width: 32px;
    height: 32px;
}

.sidebar[data-mode="teams"] .sessions-list .session-item {
    padding: 8px 5px;
}

/* Teams switcher (injected as a child of #workflowsList, shown only in teams mode) */
.teams-switcher {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
    /* Belt to the drawer's braces: a flex item's automatic minimum size is its
       max-content width, so ANY row-direction host would otherwise let one long
       Team name decide how wide the switcher is. Nothing here may be sized by
       its own text — the labels ellipsize instead. */
    min-width: 0;
    font-family: var(--tm-font-ui);
    color: var(--tm-text-1);
}
.teams-switcher .teams-switcher__list {
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: hidden;
    padding-top: 6px;
    min-width: 0;
}

.teams-switcher .teams-switcher__create:hover {
    opacity: 1;
}

.teams-switcher .teams-switcher__create {
    flex-shrink: 0;
    justify-content: center;
    margin: 8px 6px 10px;
    padding-top: 8px;
    padding-bottom: 8px;
    opacity: 0.4;
}

/* A phone sidebar is a drawer, not a dashboard. Let one list own its full
 * height at a time; the controls live where the old "Teams" title did. */
@media (max-width: 768px) {
    .sidebar[data-mode="teams"] .sessions-search-container {
        display: flex;
        align-items: center;
        gap: 4px;
    }
    .sidebar[data-mode="teams"] .sessions-search-input {
        min-width: 0;
        flex: 1 1 auto;
    }
    .sidebar[data-mode="teams"] .teams-catch-up-trigger--sidebar {
        position: relative;
        flex: 0 0 auto;
        width: 38px;
        height: 38px;
        padding: 7px;
    }
    .sidebar[data-mode="teams"] .teams-catch-up-trigger--sidebar .teams-catch-up-trigger__label { display: none; }
    .sidebar[data-mode="teams"] .teams-catch-up-trigger--sidebar .teams-catch-up-trigger__badge {
        position: absolute;
        top: -3px;
        right: -5px;
        z-index: 1;
    }
    .sidebar[data-mode="teams"] .sidebar-header > h2 {
        display: none;
    }
    /* A segmented control, not two loose buttons: one recessed track, two equal
       halves, and a single raised thumb that SLIDES between them. The thumb is
       its own element so the movement is animatable — swapping a background
       between two buttons can only cut. Its position is driven by the sidebar's
       `data-teams-sidebar-view`, which is the same attribute that decides which
       list is shown, so the indicator can never disagree with the content. */
    .sidebar[data-mode="teams"] .teams-sidebar-mobile-tabs {
        position: relative;
        display: flex;
        flex: 1;
        align-items: stretch;
        gap: 0;
        min-width: 0;
        padding: 3px;
        border-radius: 11px;
        background: var(--tm-bg-alt, rgba(0, 0, 0, .05));
        box-shadow: inset 0 1px 2px rgba(0, 0, 0, .07);
    }
    .teams-sidebar-mobile-tabs__thumb {
        position: absolute;
        top: 3px;
        bottom: 3px;
        left: 3px;
        width: calc(50% - 3px);
        border-radius: 8px;
        background: var(--tm-real-white, #fff);
        box-shadow: 0 1px 3px rgba(0, 0, 0, .16);
        transition: transform .22s cubic-bezier(.32, .72, 0, 1);
    }
    .sidebar[data-teams-sidebar-view="teams"] .teams-sidebar-mobile-tabs__thumb {
        transform: translateX(100%);
    }
    .teams-sidebar-mobile-tabs button {
        position: relative;   /* above the thumb */
        z-index: 1;
        flex: 1 1 0;
        min-width: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
        border: 0;
        border-radius: 8px;
        padding: 7px 6px;
        background: transparent;
        color: var(--tm-text-1, var(--secondary-text));
        font: inherit;
        font-size: 13px;
        font-weight: 600;
        cursor: pointer;
        transition: color .18s;
        -webkit-tap-highlight-color: transparent;
    }
    .teams-sidebar-mobile-tabs button i {
        font-size: 12px;
        opacity: .75;
    }
    .teams-sidebar-mobile-tabs button.is-active {
        color: var(--tm-accent, var(--primary-color));
    }
    .teams-sidebar-mobile-tabs button.is-active i {
        opacity: 1;
    }
    /* Only meaningful on the Teams half: a team is selected, so the Chats half
       is showing a FILTERED list. Hidden unless the filter is actually on. */
    .teams-sidebar-mobile-tabs__filter-dot {
        display: none;
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background: var(--tm-accent, var(--primary-color));
    }
    .sidebar[data-teams-filter-active] .teams-sidebar-mobile-tabs__filter-dot {
        display: block;
    }
    body.dark-theme .teams-sidebar-mobile-tabs__thumb {
        background: rgba(255, 255, 255, .14);
        box-shadow: 0 1px 3px rgba(0, 0, 0, .35);
    }
    @media (prefers-reduced-motion: reduce) {
        .teams-sidebar-mobile-tabs__thumb { transition: none; }
    }
    .sidebar[data-mode="teams"][data-teams-sidebar-view="chats"] #workflowsList,
    .sidebar[data-mode="teams"][data-teams-sidebar-view="chats"] #sidebarSeparator {
        display: none !important;
    }
    .sidebar[data-mode="teams"][data-teams-sidebar-view="chats"] #sessionsListContainer {
        flex: 1 1 auto !important;
        height: auto !important;
    }
    .sidebar[data-mode="teams"][data-teams-sidebar-view="teams"] #sessionsListContainer,
    .sidebar[data-mode="teams"][data-teams-sidebar-view="teams"] #sidebarSeparator {
        display: none !important;
    }
    /* `max-height: 40%` + a drop shadow are the CHAT sidebar's widget slot,
       where the shadow separates the widgets from Recent Sessions below. In the
       Teams view that list is the drawer's only occupant, so the cap stranded it
       at 40% of the height and the shadow rendered as a horizontal rule across
       empty space. Both belong to the two-list layout, not to this one. */
    .sidebar[data-mode="teams"][data-teams-sidebar-view="teams"] #workflowsList {
        display: flex !important;
        /* COLUMN, explicitly. `display: flex` defaults to row, which made the
           switcher a row item sized to its max-content: a long Team name grew
           the list past the drawer, `overflow-x: hidden` clipped it mid-word,
           and the name never reached its own ellipsis while the gear was pushed
           out of view entirely. The list is a vertical stack on every viewport. */
        flex-direction: column;
        flex: 1 1 auto;
        height: auto !important;
        max-height: none !important;
        box-shadow: none;
    }
}

@media (min-width: 769px) {
    .teams-catch-up-trigger--sidebar { display: none; }
}

.teams-switcher .teams-sb-team {
    display: flex;
    align-items: stretch;
    gap: 2px;
    border-radius: var(--tm-r);
    margin: 0 5px;
}
.teams-switcher .teams-sb-team--active {
    background: var(--tm-real-white);
    box-shadow: 0 0 5px var(--tm-accent);
}

.teams-switcher .teams-sb-team--channel .teams-sb-team__label i {
    margin-right: 4px;
    color: var(--tm-accent);
}

/* Support Desk marker: same weight as the channel's broadcast glyph. */
.teams-switcher .teams-sb-team__label .teams-sb-team__desk {
    margin-right: 5px;
    font-size: 11px;
    color: var(--tm-accent);
}

/* An archived channel is visible to its owner only, so it reads as retired. */
.teams-switcher .teams-sb-team--archived {
    opacity: 0.6;
}

/* Group headings inside the expanded Spaces & channels list. */
.teams-switcher .teams-sb-group {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 8px 5px 2px;
    padding: 2px 10px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--tm-text-3);
}
.teams-switcher .teams-sb-group i {
    font-size: 10px;
}
.teams-switcher .teams-sb-group__count {
    margin-left: auto;
    font-weight: 400;
}

.teams-switcher .teams-sb-team__main {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
    background: transparent;
    border: none;
    cursor: pointer;
    text-align: left;
    min-width: 0;
    border-radius: var(--tm-r);
}
.teams-switcher .teams-sb-team:hover {
    background: var(--tm-white);
}

.teams-switcher .teams-sb-team__meta {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
    flex: 1;
}

/* The right edge is shared deliberately: the unread total is visible at rest;
   the settings control replaces it on hover, rather than pushing the Team name
   or its member count into a third line. */
.teams-switcher .teams-sb-team__actions {
    position: relative;
    flex: 0 0 30px;
    align-self: stretch;
    display: grid;
    place-items: center;
}

.teams-switcher .teams-sb-team__label {
    font-weight: 600;
    font-size: 14px;
    color: var(--tm-msg-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.teams-switcher .teams-sb-team__sub {
    font-size: 12px;
    color: var(--tm-text-3);
}
.teams-switcher .teams-sb-team__gear {
    position: absolute;
    inset: 0;
    width: 30px;
    border: none;
    background: transparent;
    color: var(--tm-text-3);
    cursor: pointer;
    border-radius: var(--tm-r);
    opacity: 0;
    transition:
        opacity var(--tm-t),
        color var(--tm-t);
}
.teams-switcher .teams-sb-team:hover .teams-sb-team__gear,
.teams-switcher .teams-sb-team--active .teams-sb-team__gear {
    opacity: 1;
}
.teams-switcher .teams-sb-team:hover .teams-sb-team__space-unread,
.teams-switcher .teams-sb-team--active .teams-sb-team__space-unread {
    opacity: 0;
}
.teams-switcher .teams-sb-team__gear:hover {
    color: var(--tm-accent);
}
.teams-switcher .teams-avatar {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    border-radius: var(--tm-r);
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
    font-weight: 600;
    font-size: 13px;
}

.teams-switcher .teams-avatar--channel {
    border-radius: 999px;
    background: var(--tm-accent);
    color: var(--tm-real-white);
    font-size: 12px;
}

.teams-switcher .teams-sb-team__space-unread {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 999px;
    background: var(--tm-accent, #2d5f84);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
    transition: opacity var(--tm-t);
    /* The badge is a READOUT, never a target — and without this it stole the
       gear's hover. `opacity` below 1 paints an element in the same layer as a
       positioned element with z-index 0, so the faded-out badge landed ABOVE
       the absolutely-positioned gear it was supposed to be revealing (it comes
       later in DOM order). The cursor only turned into a pointer once it left
       the invisible 18px badge box, which read as the gear being un-clickable
       in its own centre. */
    pointer-events: none;
}

/* Floating "New conversation" button pinned to the sidebar bottom (teams mode) */
.sidebar[data-mode="teams"] {
    position: relative;
}

/* .sidebar[data-mode="teams"] #sessionsListContainer { padding-bottom: 58px; } */

.sidebar[data-mode="teams"] .teams-new-convo-fab:hover {
    background: var(--tm-accent-hover);
    opacity: 1;
}

.sidebar[data-mode="teams"] .teams-new-convo-fab {
    position: absolute;
    bottom: 14px;
    z-index: 5;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 15px;
    border: none;
    border-radius: 30px;
    background: var(--tm-accent);
    color: #fff;
    font-family: var(--tm-font-ui);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: var(--tm-shadow-md);
    transition: background var(--tm-t);
    opacity: 0.4;
    /* Centred with left/transform, NOT `align-self: anchor-center`: that
       property does not exist in Safari (including iOS), where it computes to
       `auto` and an absolutely-positioned box with no `left`/`right` falls back
       to its static position — the bottom-LEFT corner, sitting on top of the
       session rows. This produces the identical centring in every engine. */
    left: 50%;
    transform: translateX(-50%);
}

/* Touch devices have no hover to raise the resting 0.4 opacity, so the button
   stays permanently faded and reads as being *behind* the session list it
   overlaps. Give it its full weight there. */
@media (hover: none) {
    .sidebar[data-mode="teams"] .teams-new-convo-fab {
        opacity: 1;
    }
}
.sidebar:not([data-mode="teams"]) .teams-new-convo-fab {
    display: none !important;
}
.sidebar[data-mode="teams"] .teams-new-convo-fab:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ── Desktop: collapsible spaces list above Recent Sessions ───────────────────
 * The chevron on the Home row opens and closes it. Collapsed (the default)
 * leaves just Home and gives the rest of the sidebar to the chat list. Expanded
 * changes nothing — the existing divider and its saved heights apply. Phones
 * (≤768px) never see any of this: the drawer keeps its own Chats/Teams switch. */
.teams-switcher .teams-sb-spaces-toggle {
    display: none;
}
@media (min-width: 769px) {
    .sidebar[data-mode="teams"] .teams-switcher .teams-sb-spaces-toggle {
        display: flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 32px;
        border: 0;
        border-radius: var(--tm-r);
        background: transparent;
        color: inherit;
        font-size: 12px;
        opacity: 0.65;
        cursor: pointer;
    }
    .sidebar[data-mode="teams"] .teams-switcher .teams-sb-spaces-toggle:hover {
        opacity: 1;
        background: var(--tm-accent-subtle);
    }
    .sidebar[data-mode="teams"] .teams-switcher .teams-sb-spaces-toggle i {
        transition: transform 0.15s ease;
    }
    .sidebar[data-mode="teams"][data-teams-spaces="collapsed"] .teams-switcher .teams-sb-spaces-toggle i {
        transform: rotate(-90deg);
    }

    /* Home is a destination, not a selection: it carries no highlight. Spaces
       and channels keep theirs. */
    .sidebar[data-mode="teams"] .teams-switcher .teams-sb-team--all.teams-sb-team--active {
        background: transparent;
        box-shadow: none;
        border-color: transparent;
    }

    .sidebar[data-mode="teams"][data-teams-spaces="collapsed"]:not(.collapsed) #workflowsList {
        flex: 0 0 auto !important;
        height: auto !important;
        min-height: 0 !important;
        overflow: visible;
        padding: 0 10px;
    }

    .sidebar[data-mode="teams"] #workflowsList {
        padding: 0 10px;
    }

    .sidebar[data-mode="teams"][data-teams-spaces="collapsed"]:not(.collapsed) #sidebarSeparator,
    .sidebar[data-mode="teams"][data-teams-spaces="collapsed"]:not(.collapsed) #sessionsListContainer .sessions-header,
    .sidebar[data-mode="teams"][data-teams-spaces="collapsed"]:not(.collapsed) .teams-switcher .teams-sb-group,
    .sidebar[data-mode="teams"][data-teams-spaces="collapsed"]:not(.collapsed) .teams-switcher .teams-sb-team:not(.teams-sb-team--all) {
        display: none;
    }
    .sidebar[data-mode="teams"][data-teams-spaces="collapsed"]:not(.collapsed) #sessionsListContainer {
        flex: 1 1 auto !important;
        height: auto !important;
        min-height: 0;
    }
}

/* Shared Teams session layout for desktop and mobile. */

.sessions-list .session-item .session-preview {
    display: none;
}

.sidebar[data-mode="teams"] .sessions-list .session-item .session-content {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
        "title time"
        "preview indicator";
    column-gap: 10px;
    row-gap: 1px;
    align-items: center;
    min-width: 0;
}

.sidebar[data-mode="teams"] .sessions-list .session-item .session-title-row {
    grid-area: title;
    padding-right: 0; /* Actions share the trailing metadata column. */
}

.sidebar[data-mode="teams"] .sessions-list .session-item .session-time {
    display: contents;
    margin-top: 0;
    white-space: nowrap;
}

.sidebar[data-mode="teams"] .sessions-list .session-item .session-preview {
    display: block;
    grid-area: preview;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.7rem;
    line-height: 1.3;
    color: var(--text-secondary, #666);
}

.sidebar[data-mode="teams"] .sessions-list .session-item .session-preview:empty {
    display: none;
}

.sidebar[data-mode="teams"] .sessions-list .session-item .session-preview i {
    margin-right: 3px;
    font-size: 0.85em;
}

/* The row's ⋯ menu button is invisible (opacity 0) until hover, and a phone has no
   hover — but it still sat at the end of every title and took the tap, so a
   short tap near the end of a name opened the DESKTOP popover instead of the
   chat. On a phone the long press (spotlight + action sheet) is the way in, so the
   button must not receive touches at all. With pointer-events off the tap lands
   on the row, and a long press that starts there is no longer refused for
   beginning on a button. */
body.mobile-standalone .sessions-list .session-item .session-menu-btn {
    pointer-events: none;
}

.sidebar[data-mode="teams"] .sessions-list .session-item .session-time-label {
    grid-area: time;
    justify-self: end;
    white-space: nowrap;
}
.sidebar[data-mode="teams"] .sessions-list .session-item .session-state-indicators {
    grid-area: indicator;
    justify-self: end;
    margin: 0;
}
.sidebar[data-mode="teams"] .sessions-list .session-item .session-preview {
    grid-column: 1 / -1;
    grid-row: 2;
}
.sidebar[data-mode="teams"] .sessions-list .session-item:has(.session-state-indicators > *) .session-preview {
    padding-right: 28px;
}
.sidebar[data-mode="teams"] .sessions-list .session-item .session-threads {
    grid-column: 1 / -1;
    min-width: 0;
}
.sidebar[data-mode="teams"] .sessions-list .session-item .session-threads__toggle {
    width: 100%;
}
.sidebar[data-mode="teams"] .sessions-list .session-item .session-threads__toggle .session-thread__new {
    margin-left: auto;
}
.sidebar[data-mode="teams"] .sessions-list .session-item .session-menu-btn {
    top: 1rem;
    right: 0;
    width: 28px;
    height: 28px;
    padding: 0;
    font-size: 1.1rem;
    z-index: 1;
}
@media (hover: hover) and (pointer: fine) {
    body:not(.mobile-standalone) .sidebar[data-mode="teams"] .session-item:hover .session-time-label,
    body:not(.mobile-standalone) .sidebar[data-mode="teams"] .session-item:hover .session-state-indicators {
        visibility: hidden;
    }
}
body:not(.mobile-standalone) .sidebar[data-mode="teams"] .session-item:has(.session-menu-btn:focus-visible) .session-time-label,
body:not(.mobile-standalone) .sidebar[data-mode="teams"] .session-item:has(.session-menu-btn:focus-visible) .session-state-indicators,
body:not(.mobile-standalone) .sidebar[data-mode="teams"] .session-item:has(.session-menu-btn[aria-expanded="true"]) .session-time-label,
body:not(.mobile-standalone) .sidebar[data-mode="teams"] .session-item:has(.session-menu-btn[aria-expanded="true"]) .session-state-indicators {
    visibility: hidden;
}
.sidebar[data-mode="teams"] .sessions-list .session-item .session-menu-btn:focus-visible {
    opacity: 1;
}

/* The mobile drawer can retain the desktop collapsed class. */
body.mobile-standalone .sidebar[data-mode="teams"].collapsed.mobile-drawer-open .sessions-list-container .session-content {
    display: grid !important;
}
body.mobile-standalone .sidebar[data-mode="teams"].mobile-drawer-open .session-item .session-threads {
    display: block;
}

/* Mentions lead the preview; ordinary unread/priority markers stay at the end. */
.sidebar[data-mode="teams"] .session-item .session-state-indicators:has([class*="--mentioned"]) {
    grid-column: 1;
    grid-row: 2;
    justify-self: start;
    align-self: center;
    visibility: visible;
    z-index: 1;
}
.sidebar[data-mode="teams"] .session-item:has(.session-state-indicators [class*="--mentioned"]) :is(.session-preview, .session-typing) {
    padding-left: 20px;
    padding-right: 0;
}
.sidebar[data-mode="teams"] .session-item .session-state-indicators [class*="--mentioned"] {
    visibility: visible;
    width: 14px;
    height: 14px;
    min-width: 14px;
    flex-basis: 14px;
    padding: 0;
    font-size: 0;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.sidebar[data-mode="teams"] .session-item .session-state-indicators [class*="--mentioned"]::before {
    font-size: 10px;
    margin: 0;
}
.sidebar[data-mode="teams"] .session-item.has-session-typing .session-preview {
    display: none;
}
.sidebar[data-mode="teams"] .session-item .session-typing {
    grid-column: 1 / -1;
    grid-row: 2;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.785rem;
    line-height: 1.3;
    color: var(--primary-color, #3498db);
    font-style: italic;
    padding-right: 28px;
    font-weight: normal;
}

/* Leave a clear gap between the text ellipsis and the larger action dots.
 * Keep the same space while keyboard-focused or while the menu is open. */
@media (hover: hover) and (pointer: fine) {
    body:not(.mobile-standalone) .sidebar[data-mode="teams"] .sessions-list .session-item:hover :is(.session-preview, .session-typing) {
        margin-right: 40px;
        padding-right: 0;
    }
}
body:not(.mobile-standalone) .sidebar[data-mode="teams"] .sessions-list .session-item:has(.session-menu-btn:is(:focus-visible, [aria-expanded="true"])) :is(.session-preview, .session-typing) {
    margin-right: 40px;
    padding-right: 0;
}

/* ── Private Teams chat folders ───────────────────────────────────────────────
 * Folders are an Amby Teams sidebar feature, so they live here rather than in
 * main-chat.css: that file has no `--tm-*` tokens, and the folder UI was
 * therefore hard-wired to light literals (#fff / #222 / #555) and stayed white
 * while the rest of the app went dark.
 *
 * Every colour below is a `--tm-*` token. `.session-folder-filter-bar` and the
 * two `…-overlay` elements are registered as token HOSTS in teams-foundation.css
 * — the bar lives in `.sidebar` and the dialogs are appended to `document.body`,
 * so neither has a `.teams-panel` ancestor to inherit from. Adding a new folder
 * surface that needs tokens means adding it to those two lists as well.
 *
 * Selectors are scoped to `.session-folder-*` / `.session-row-spotlight-*`
 * prefixes so nothing here can reach another module's `.chip` or `.dialog`. */

/* Two folder-local colours the shared tokens get wrong in dark mode:
 *   --sf-muted     secondary text and icons. Dark `--tm-text-3` is #707070 on
 *                  a #2a2a2a dialog (~3:1): labels and icons were barely there.
 *   --sf-on-accent text/icons ON an accent fill. Dark `--tm-real-white` is the
 *                  slate #363f4a, so a selected segment read dark-on-light-blue
 *                  and a disabled `+` drew its icon in the button's own colour.
 * Defined on the folder token hosts, so `var(--tm-*)` resolves right there. */
.session-folder-filter-bar,
.sessions-list .session-folder-group-header,
.session-folder-dialog-overlay,
.session-folder-name-dialog-overlay {
    --sf-muted: var(--tm-text-3);
    --sf-on-accent: var(--tm-real-white);
}
body.dark-theme .session-folder-filter-bar,
body.dark-theme .sessions-list .session-folder-group-header,
body.dark-theme .session-folder-dialog-overlay,
body.dark-theme .session-folder-name-dialog-overlay {
    --sf-muted: #a3a3a3;
    --sf-on-accent: #0f1b29;
}

.session-folder-filter-bar {
    display: flex;
    align-items: center;
    gap: 7px;
    min-height: 39px;
    padding: 9px 11px 7px;
    overflow: hidden;
    border-bottom: 1px solid var(--tm-border);
    background: var(--sidebar-bg, transparent);
}
.session-folder-filter-scroll {
    display: flex;
    align-items: center;
    gap: 5px;
    flex: 1 1 auto;
    min-width: 0;
    /* Headroom for a count badge that sits above a chip's corner (the scroller would clip it). */
    padding: 8px 8px 0 0;
    margin: -8px 0 0;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
}
.session-folder-filter-scroll::-webkit-scrollbar {
    display: none;
}

.session-folder-filter-chip,
.session-folder-filter-add {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    gap: 6px;
    padding: 5px 10px;
    border: 1px solid var(--tm-border);
    border-radius: 999px;
    background: var(--tm-white);
    color: var(--tm-text-2);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.76rem;
    font-weight: 500;
    box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);
    white-space: nowrap;
    transition:
        background var(--tm-t),
        border-color var(--tm-t),
        color var(--tm-t);
}
.session-folder-filter-chip i {
    font-size: 0.7rem;
}
/* A long folder name must not push every other chip off the rail. The full
   name is on the chip's `title`, and the create dialog caps new ones at 24. */
.session-folder-filter-chip > span {
    overflow: hidden;
    max-width: 11ch;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.session-folder-filter-chip:hover,
.session-folder-filter-add:hover {
    border-color: var(--tm-border-strong);
    background: var(--tm-surface);
    color: var(--tm-text-2);
}
.session-folder-filter-chip.is-active,
.session-folder-filter-chip.is-active:hover {
    border-color: var(--tm-accent);
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}
.session-folder-filter-add {
    width: 29px;
    padding: 7px 10px;
    color: var(--tm-accent);
}

/* How many chats are filed here. `em` only for a tag the reset does not style;
   the slant is cancelled below. */
.session-folder-filter-chip { position: relative; }

/* Unread chip: the server's unread-chat count floats above the chip's corner and takes
   no width from it (a folder's own count stays inline, inside its chip). */
.session-folder-filter-chip .session-folder-filter-chip__count--unread {
    position: absolute;
    top: -7px;
    right: -5px;
    z-index: 1;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    box-shadow: 0 0 0 2px var(--sidebar-bg, var(--tm-bg, #fff));
    font-size: 10px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
}

.session-folder-filter-chip__count {
    padding: 0 5px;
    border-radius: 999px;
    background: var(--tm-accent-subtle);
    color: var(--sf-muted);
    font-size: 0.68rem;
    font-style: normal;
    font-weight: 600;
    line-height: 1.5;
}
.session-folder-filter-chip .session-folder-filter-chip__count--unread,
.session-folder-filter-chip.is-active .session-folder-filter-chip__count--unread {
    background: var(--tm-danger, #c0392b);
    color: #fff;
}

.session-folder-filter-chip.is-active .session-folder-filter-chip__count {
    background: var(--tm-accent);
    color: var(--sf-on-accent);
}

.session-folder-filter-chip:focus-visible,
.session-folder-filter-add:focus-visible {
    outline: 2px solid var(--tm-accent);
    outline-offset: 2px;
}

.sessions-list .session-item.session-folder-filtered-out {
    display: none !important;
}
.sessions-list .session-item.session-folder-collapsed-out {
    display: none !important;
}

/* ── Folder groups inside the list (placement 'list' / 'both') ───────────────
 * A header is a sibling of the rows, not their container — see
 * session-folder-groups.js for why. It is a token host (teams-foundation.css)
 * because #sessionsList has no `.teams-panel` ancestor. */
.sessions-list .session-folder-group-header {
    display: flex;
    align-items: center;
    gap: 7px;
    width: 100%;
    box-sizing: border-box;
    margin: 6px 0 2px;
    padding: 6px 10px;
    border: 0;
    border-radius: var(--tm-r);
    background: transparent;
    color: var(--tm-text-2);
    cursor: pointer;
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-align: left;
    text-transform: uppercase;
    transition: background var(--tm-t);
}
.sessions-list .session-folder-group-header:hover {
    background: var(--tm-accent-subtle);
}
.sessions-list .session-folder-group-header:focus-visible {
    outline: 2px solid var(--tm-accent);
    outline-offset: -2px;
}
/* A shut folder that holds the open chat takes over the open-chat highlight,
   so "where is my conversation?" still has a visible answer. */
.sessions-list .session-folder-group-header.is-collapsed.has-active {
    background: var(--tm-accent-subtle);
    box-shadow: inset 3px 0 0 var(--tm-accent);
    color: var(--tm-accent);
}
.sessions-list .session-folder-group-header.is-collapsed.has-active .session-folder-group-header__chevron,
.sessions-list .session-folder-group-header.is-collapsed.has-active .session-folder-group-header__count {
    color: var(--tm-accent);
}
.sessions-list .session-folder-group-header__chevron {
    flex: 0 0 auto;
    width: 10px;
    color: var(--sf-muted);
    font-size: 0.7rem;
    transition: transform var(--tm-t);
}
.sessions-list .session-folder-group-header.is-collapsed .session-folder-group-header__chevron {
    transform: rotate(-90deg);
}
.sessions-list .session-folder-group-header__name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sessions-list .session-folder-group-header__count {
    flex: 0 0 auto;
    color: var(--sf-muted);
    font-style: normal;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

/* The expanded-folder "sleeve": one tinted block from the header down to the
   folder's last chat, so it is plain which chats are inside the folder and
   where the recent list resumes. The rows are siblings, not children, so the
   block is assembled per row: the header rounds the top, the last member
   rounds the bottom, and the 5px gap between rows is closed so the tint never
   breaks.

   Hover and the open chat replace the tint with their own colour across the
   FULL row, with square corners. Rounded "cards" inside the sleeve would leave
   notches of list background at their corners, and filling those with a ring
   doubles the translucent tint into a visible halo.

   Member rows are `--tm-*` token hosts (teams-foundation.css) because a
   session row has no `.teams-panel` ancestor. */
.sessions-list .session-folder-group-header.has-sleeve {
    margin-bottom: 0;
    border-radius: var(--tm-r-lg) var(--tm-r-lg) 0 0;
    background: var(--tm-accent-subtle);
}
.sessions-list .session-item.session-folder-group-member {
    margin-bottom: 0;
    border-radius: 0;
}
.sessions-list .session-item.session-folder-group-member:not(.active):not(:hover) {
    background: var(--tm-accent-subtle);
}
.sessions-list .session-item.session-folder-group-member--last {
    margin-bottom: 8px;
    border-radius: 0 0 var(--tm-r-lg) var(--tm-r-lg);
}

.session-folder-filter-empty {
    padding: 22px 14px;
    color: var(--tm-text-3);
    text-align: center;
    font-size: 0.82rem;
}

/* ── Move-to-folder + new-folder dialogs ─────────────────────────────────── */

.session-folder-dialog-overlay,
.session-folder-name-dialog-overlay {
    position: fixed;
    inset: 0;
    display: grid;
    place-items: center;
    padding: 16px;
    background: rgba(0, 0, 0, 0.38);
}
.session-folder-dialog-overlay {
    z-index: 10002;
}
/* Above the move dialog: the name prompt is opened FROM it and both are on
   screen together. */
.session-folder-name-dialog-overlay {
    z-index: 10003;
    background: rgba(0, 0, 0, 0.48);
}

.session-folder-dialog,
.session-folder-name-dialog {
    width: min(360px, 100%);
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r-lg);
    background: var(--tm-white);
    color: var(--tm-text-2);
    box-shadow: var(--tm-shadow-md);
    font-family: var(--tm-font-ui);
}
.session-folder-dialog {
    max-height: min(540px, calc(100vh - 32px));
    overflow: auto;
    padding: 18px;
}
.session-folder-dialog h3,
.session-folder-name-dialog h3 {
    margin: 0 0 12px;
    color: var(--tm-msg-text);
    font-family: var(--tm-font-display);
    font-size: 1rem;
}
.session-folder-dialog__choices {
    display: grid;
    gap: 3px;
}
.session-folder-dialog__choices button,
.session-folder-dialog__new,
.session-folder-dialog__cancel {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px;
    border: 0;
    border-radius: var(--tm-r);
    background: transparent;
    color: inherit;
    cursor: pointer;
    text-align: left;
    font: inherit;
    transition: background var(--tm-t);
}
.session-folder-dialog__choices button i,
.session-folder-dialog__new i {
    width: 16px;
    color: var(--sf-muted);
    text-align: center;
}
.session-folder-dialog__choices button:hover,
.session-folder-dialog__new:hover,
.session-folder-dialog__cancel:hover {
    background: var(--tm-accent-subtle);
}
.session-folder-dialog__choices button:focus-visible,
.session-folder-dialog__new:focus-visible,
.session-folder-dialog__cancel:focus-visible {
    outline: 2px solid var(--tm-accent);
    outline-offset: -2px;
}
/* The chat's current folder — the row the user is already in. */
.session-folder-dialog__choices button.is-current {
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
    font-weight: 600;
}
.session-folder-dialog__choices button.is-current i {
    color: var(--tm-accent);
}
.session-folder-dialog__choices button.is-current::after {
    content: "\f00c"; /* fa-check */
    margin-left: auto;
    font-family: "Font Awesome 6 Free", "Font Awesome 5 Free";
    font-weight: 900;
    font-size: 0.72rem;
}
.session-folder-dialog__choices button.is-destructive,
.session-folder-dialog__choices button.is-destructive i {
    color: var(--tm-danger);
}
.session-folder-dialog__choices button.is-destructive:hover {
    background: var(--tm-danger-bg);
}
/* ── Folder manager (the `+` in the filter bar) ──────────────────────────── */

.session-folder-manage__rows {
    display: grid;
    gap: 6px;
}
.session-folder-manage__row {
    padding: 4px 4px 8px 10px;
    border-radius: var(--tm-r);
}
.session-folder-manage__row + .session-folder-manage__row {
    padding-top: 8px;
    border-top: 1px solid var(--tm-border);
    border-radius: 0;
}
.session-folder-manage__head {
    display: flex;
    align-items: center;
    gap: 2px;
}
.session-folder-manage__options {
    display: grid;
    gap: 6px;
    margin-top: 4px;
}
.session-folder-manage__option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
.session-folder-manage__option-label {
    color: var(--sf-muted);
    font-size: 0.76rem;
}
.session-folder-manage__segmented {
    display: inline-flex;
    flex: 0 0 auto;
    padding: 2px;
    border: 1px solid var(--tm-border);
    border-radius: 999px;
    background: var(--tm-bg-alt);
}
.session-folder-manage__segmented button {
    min-height: 26px;
    padding: 3px 11px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--tm-text-2);
    cursor: pointer;
    font: inherit;
    font-size: 0.76rem;
    transition:
        background var(--tm-t),
        color var(--tm-t);
}
.session-folder-manage__segmented button:hover:not(.is-selected) {
    background: var(--tm-surface);
}
.session-folder-manage__segmented button.is-selected {
    background: var(--tm-accent);
    color: var(--sf-on-accent);
    font-weight: 600;
}
.session-folder-manage__segmented button:focus-visible {
    outline: 2px solid var(--tm-accent);
    outline-offset: 1px;
}
.session-folder-manage__name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    color: var(--tm-msg-text);
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.9rem;
}
.session-folder-manage__action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--sf-muted);
    cursor: pointer;
    font-size: 0.8rem;
    transition:
        background var(--tm-t),
        color var(--tm-t);
}
.session-folder-manage__action:hover {
    background: var(--tm-surface);
    color: var(--tm-accent);
}
.session-folder-manage__action.is-destructive:hover {
    background: var(--tm-danger-bg);
    color: var(--tm-danger);
}
.session-folder-manage__action:disabled {
    opacity: 0.35;
    cursor: default;
}
.session-folder-manage__action:disabled:hover {
    background: transparent;
    color: var(--sf-muted);
}
.session-folder-manage__action:focus-visible {
    outline: 2px solid var(--tm-accent);
    outline-offset: 1px;
}
/* Create-in-place: the field IS the primary action of the `+` button. */
.session-folder-manage__create {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--tm-border);
}
.session-folder-manage__create input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 9px 11px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-bg-alt);
    color: var(--tm-msg-text);
    font: inherit;
    font-size: 0.88rem;
}
.session-folder-manage__create input:focus {
    outline: 2px solid var(--tm-accent);
    outline-offset: 1px;
}
.session-folder-manage__create input[aria-invalid="true"] {
    border-color: var(--tm-danger);
}
.session-folder-manage__create-submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border: 0;
    border-radius: 999px;
    background: var(--tm-accent);
    color: var(--sf-on-accent);
    cursor: pointer;
    font-size: 0.85rem;
    transition:
        background var(--tm-t),
        opacity var(--tm-t);
}
.session-folder-manage__create-submit:hover:not(:disabled) {
    background: var(--tm-accent-hover);
}
.session-folder-manage__create-submit:focus-visible {
    outline: 2px solid var(--tm-accent);
    outline-offset: 2px;
}
.session-folder-manage__create-submit:disabled {
    /* Inert, but still legible as "the add button": a neutral chip with a
       muted glyph, not an accent button faded to near-invisibility. */
    box-shadow: inset 0 0 0 1px var(--tm-border);
    background: var(--tm-surface);
    color: var(--sf-muted);
    cursor: default;
}
.session-folder-manage__counter {
    margin: 6px 0 0;
    min-height: 1em;
    color: var(--sf-muted);
    text-align: right;
    font-size: 0.72rem;
    font-variant-numeric: tabular-nums;
}
.session-folder-manage__counter.is-full {
    color: var(--tm-danger);
}
.session-folder-manage__error {
    margin: 4px 0 0;
    color: var(--tm-danger);
    font-size: 0.78rem;
}

.session-folder-manage__empty {
    margin: 4px 0 0;
    padding: 14px 10px;
    color: var(--sf-muted);
    text-align: center;
    font-size: 0.82rem;
}

.session-folder-dialog__new {
    margin-top: 9px;
    color: var(--tm-accent);
}
/* Cancel (Move-to-folder) is a quiet outlined button. It used to be a
   `border-top` on a rounded button, which drew a curved sliver of outline
   rather than a separator — the "clipped pill" above Done. */
.session-folder-dialog__cancel {
    justify-content: center;
    margin-top: 12px;
    border: 1px solid var(--tm-border);
    color: var(--tm-text-2);
    font-weight: 500;
}
.session-folder-dialog__cancel:hover {
    border-color: var(--tm-border-strong);
}
/* Done is the one way out of the Folders manager — every change there is
   already saved — so it is the dialog's primary button. */
.session-folder-manage .session-folder-dialog__cancel {
    margin-top: 14px;
    border-color: var(--tm-accent);
    background: var(--tm-accent);
    color: var(--sf-on-accent);
    font-weight: 600;
}
.session-folder-manage .session-folder-dialog__cancel:hover {
    border-color: var(--tm-accent-hover);
    background: var(--tm-accent-hover);
}
.session-folder-manage .session-folder-dialog__cancel:focus-visible {
    outline-offset: 2px;
}

.session-folder-name-dialog {
    padding: 20px;
}
.session-folder-name-dialog h3 {
    margin-bottom: 15px;
    font-size: 1.05rem;
}
.session-folder-name-dialog label {
    display: grid;
    gap: 7px;
    color: var(--tm-text-1);
    font-size: 0.84rem;
}
.session-folder-name-dialog input {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 11px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-bg-alt);
    color: var(--tm-msg-text);
    font: inherit;
}
.session-folder-name-dialog input:focus {
    outline: 2px solid var(--tm-accent);
    outline-offset: 1px;
}
.session-folder-name-dialog input[aria-invalid="true"] {
    border-color: var(--tm-danger);
}
.session-folder-name-dialog__counter {
    margin: 6px 0 0;
    color: var(--sf-muted);
    text-align: right;
    font-size: 0.72rem;
    font-variant-numeric: tabular-nums;
}
.session-folder-name-dialog__counter.is-full {
    color: var(--tm-danger);
}
.session-folder-name-dialog .session-folder-name-dialog__settings {
    display: grid;
    gap: 8px;
    margin: 4px 0 8px;
}
.session-folder-name-dialog .session-folder-name-dialog__settings[hidden] {
    display: none;
}
.session-folder-name-dialog__error {
    margin: 8px 0 0;
    color: var(--tm-danger);
    font-size: 0.78rem;
}
.session-folder-name-dialog__actions {
    display: flex;
    justify-content: end;
    gap: 8px;
    margin-top: 18px;
}
.session-folder-name-dialog__actions button {
    padding: 8px 13px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: transparent;
    color: var(--tm-text-2);
    cursor: pointer;
    font: inherit;
    transition:
        background var(--tm-t),
        border-color var(--tm-t);
}
.session-folder-name-dialog__actions [data-action="cancel"]:hover {
    border-color: var(--tm-border-strong);
    background: var(--tm-surface);
}
.session-folder-name-dialog__actions [data-action="create"] {
    border-color: var(--tm-accent);
    background: var(--tm-accent);
    color: var(--sf-on-accent);
}
.session-folder-name-dialog__actions [data-action="create"]:hover {
    border-color: var(--tm-accent-hover);
    background: var(--tm-accent-hover);
}
.session-folder-name-dialog__actions button:focus-visible {
    outline: 2px solid var(--tm-accent);
    outline-offset: 2px;
}
.session-folder-name-dialog__actions button:disabled {
    opacity: 0.65;
    cursor: wait;
}

/* ── Long-press spotlight ─────────────────────────────────────────────────────
 * Four scrim panes deliberately leave the held session visible, matching the
 * Teams message spotlight without moving the row out of its scrolling list. */

.session-row-spotlight-backdrop {
    position: fixed;
    inset: 0;
    z-index: 9998;
    pointer-events: none;
}
/* Throwaway scroll runway so a row near the END of the list can still be
   scrolled clear of the bottom-pinned action sheet. Removed on close. */
.session-row-spotlight-spacer {
    flex: 0 0 auto;
    pointer-events: none;
}
.session-row-spotlight-scrim,
.session-row-spotlight-shield {
    position: fixed;
    display: block;
    margin: 0;
    padding: 0;
    border: 0;
    pointer-events: auto;
}
.session-row-spotlight-scrim {
    background: rgba(0, 0, 0, 0.48);
    backdrop-filter: blur(1px);
}
.session-row-spotlight-shield {
    background: transparent;
}
/* `--accent-color`, not `--tm-accent`: a session row is a platform element and
   is not one of the Teams token hosts. */
.session-item--spotlighted {
    position: relative;
    z-index: 9999;
    border-radius: 8px;
    box-shadow: 0 0 0 2px var(--accent-color, #268bd2);
}

@media (max-width: 768px) {
    .session-folder-filter-bar {
        min-height: 45px;
        padding: 10px 12px 8px;
        gap: 8px;
    }
    .session-folder-filter-chip,
    .session-folder-filter-add {
        min-height: 32px;
        font-size: 0.82rem;
    }
    .session-folder-filter-add {
        width: 32px;
    }
    .sessions-list .session-folder-group-header {
        min-height: 36px;
        font-size: 0.8rem;
    }
    .session-folder-manage__segmented button {
        min-height: 32px;
        padding: 5px 13px;
        font-size: 0.82rem;
    }
    .session-folder-dialog-overlay {
        align-items: end;
        padding: 0;
    }
    .session-folder-dialog {
        width: 100%;
        max-height: 74vh;
        padding: 20px 18px calc(20px + env(safe-area-inset-bottom));
        border-radius: 18px 18px 0 0;
    }
    .session-row-menu {
        min-width: 212px;
    }
    .session-row-menu .session-row-menu-item {
        min-height: 42px;
        font-size: 0.92rem;
    }
    .session-row-menu--spotlight {
        top: auto !important;
        right: 12px;
        bottom: max(6px, env(safe-area-inset-bottom));
        left: 12px !important;
        min-width: 0;
        padding: 9px;
        border-radius: 16px;
    }
    .session-row-menu--spotlight .session-row-menu-item {
        min-height: 48px;
        padding: 11px 13px;
        font-size: 1rem;
    }
    /* Suppress the iOS/Android text-selection callout that competes with the
       long press. The desktop synthetic `contextmenu` is handled in JS
       (`suppressNextContextMenu` in session-folders.js) — CSS cannot reach it. */
    .session-item {
        -webkit-touch-callout: none;
        -webkit-user-select: none;
        user-select: none;
    }
}

/* =============================================================================
   Teams sidebar — the COLLAPSED desktop rail (60px)
   -----------------------------------------------------------------------------
   Everything in the expanded sidebar that carries text was being squeezed into
   the rail and cut to one or two letters: the "Teams" / "Open channels" group
   headings ("TE", "OP CH"), the folder headings ("> I. 3"), the All / Unread /
   Favourite chip bar and the Home row's spaces chevron. In the rail each of them
   becomes either an icon or a hairline divider; nothing is clipped.

   Loaded after teams-session-folders.css so the folder-heading rules win.
   Every rule is scoped to `.sidebar[data-mode="teams"].collapsed` on desktop;
   a phone drawer never collapses to a rail (see teams-sidebar.css).
   ============================================================================= */

@media (min-width: 769px) {
    /* The spaces list is part of the rail; the splitter's saved height and the
       expanded-list padding do not apply to a column of icons. */
    .sidebar[data-mode="teams"].collapsed #workflowsList {
        flex: 0 0 auto !important;
        height: auto !important;
        min-height: 0 !important;
        padding: 0;
        overflow: visible;
    }
    .sidebar[data-mode="teams"].collapsed .teams-switcher__list {
        overflow: visible;
    }

    /* Home row: the house alone. The chevron only opens the spaces list, and the
       rail always shows it. */
    .sidebar[data-mode="teams"].collapsed .teams-switcher .teams-sb-spaces-toggle {
        display: none;
    }

    /* "Teams" / "Open channels" headings: a hairline between the groups. */
    .sidebar[data-mode="teams"].collapsed .teams-switcher .teams-sb-group {
        display: block;
        height: 0;
        margin: 6px 12px;
        padding: 0;
        overflow: hidden;
        border-top: 1px solid var(--tm-border);
        font-size: 0;
    }

    /* Folder chips: a filter for a list the rail cannot show as text. */
    .sidebar[data-mode="teams"].collapsed .session-folder-filter-bar {
        display: none !important;
    }

    /* Folder headings: a folder icon with its chat count, still clickable to
       open or close the folder. The name is in the button's title. */
    .sidebar[data-mode="teams"].collapsed .sessions-list .session-folder-group-header {
        position: relative;
        justify-content: center;
        /* A <button> with width:auto shrinks to its content, which left the icon
           at the rail's left edge with the count stacked above it. */
        width: calc(100% - 12px);
        min-height: 36px;
        margin: 4px 6px;
        padding: 6px 0;
        gap: 0;
    }
    .sidebar[data-mode="teams"].collapsed .sessions-list .session-folder-group-header.has-sleeve {
        margin-bottom: 0;
    }
    .sidebar[data-mode="teams"].collapsed .sessions-list .session-folder-group-header__chevron,
    .sidebar[data-mode="teams"].collapsed .sessions-list .session-folder-group-header__name {
        display: none;
    }
    .sidebar[data-mode="teams"].collapsed .sessions-list .session-folder-group-header::before {
        content: "\f07c"; /* folder-open */
        font-family: "Font Awesome 6 Free";
        font-weight: 900;
        font-size: 15px;
        line-height: 1;
        color: var(--tm-text-2);
    }
    .sidebar[data-mode="teams"].collapsed .sessions-list .session-folder-group-header.is-collapsed::before {
        content: "\f07b"; /* folder */
    }
    .sidebar[data-mode="teams"].collapsed .sessions-list .session-folder-group-header__count {
        position: absolute;
        top: 2px;
        right: 6px;
        font-size: 10px;
        line-height: 1;
    }
    .sidebar[data-mode="teams"].collapsed .sessions-list .session-folder-group-header .session-unread-indicator {
        position: absolute;
        top: 3px;
        left: 7px;
        margin: 0;
    }

    /* New-conversation button: a rail-sized circle at full strength. Faded to
       0.4 it read as a ghost lying on the avatar beneath it. */
    .sidebar[data-mode="teams"].collapsed .teams-new-convo-fab {
        width: 40px;
        height: 40px;
        padding: 0;
        opacity: 1;
    }
}

/* ── Full-panel Team config ─────────────────────────────────────────────────── */
.teams-panel .teams-config {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
    width: 100%;
    background: var(--tm-bg);
}
.teams-panel .teams-config__header {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px 24px;
    border-bottom: 1px solid var(--tm-border);
    background: var(--tm-surface);
    flex-shrink: 0;
}
.teams-panel .teams-config__back {
    border: 1px solid var(--tm-border);
    background: var(--tm-white);
    color: var(--tm-text-2);
    border-radius: var(--tm-r);
    padding: 6px 11px;
    font-size: 13px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.teams-panel .teams-config__back:hover {
    border-color: var(--tm-accent);
    color: var(--tm-accent);
}
.teams-panel .teams-config__title {
    margin: 0;
    font-size: 19px;
    font-family: var(--tm-font-display);
    color: var(--tm-text-1);
    flex: 1;
}
.teams-panel .teams-config__readonly {
    font-size: 12px;
    color: var(--tm-text-3);
    border: 1px solid var(--tm-border);
    padding: 3px 9px;
    border-radius: 999px;
}
.teams-panel .teams-config__scroll {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 24px;
    max-width: 1200px;
    width: 100%;
    margin: 0 auto;
    overflow-x: hidden;
}

/* Read-only notice for a member who is not an admin of this team. Sits at the
 * TOP of the scroll area, above Details, so the reason every field below is
 * disabled is read before the disabled fields are. Matches the .teams-member-note
 * treatment used elsewhere in Teams rather than inventing a second note style. */
.teams-panel .teams-config__notice {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 24px;
    padding: 13px 15px;
    background: var(--tm-note-bg);
    border-radius: var(--tm-r);
    color: var(--tm-msg-text);
    font-size: 13px;
    line-height: 1.5;
}
.teams-panel .teams-config__notice-icon {
    margin-top: 2px;
    flex-shrink: 0;
}
.teams-panel .teams-config__notice-body {
    display: flex;
    flex-direction: column;
    gap: 3px;
}
.teams-panel .teams-config__notice-title {
    font-weight: 600;
}
.teams-panel .teams-config__notice-link {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: inherit;
    text-decoration: underline;
    cursor: pointer;
}
.teams-panel .teams-config__notice-link:hover {
    color: var(--tm-accent);
}

.teams-panel .teams-config__section {
    margin-bottom: 32px;
    padding: 20px;
    background: var(--tm-real-white);
    border-radius: 8px;
}

/* Transient highlight after "See who to ask" scrolls the Members section into
 * view — a smooth scroll alone doesn't say which block it landed on. */
.teams-panel .teams-config__section--flash {
    animation: teams-config-flash 1.6s ease-out;
}
@keyframes teams-config-flash {
    0%,
    40% {
        box-shadow: 0 0 0 2px var(--tm-accent);
    }
    100% {
        box-shadow: 0 0 0 2px transparent;
    }
}

.teams-panel .teams-config__section-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--tm-text-1);
    margin: 0 0 14px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--tm-border);
}
.teams-panel .teams-config__actions {
    margin-top: 6px;
}
.teams-panel .teams-config__section--danger .teams-config__section-title {
    color: var(--tm-danger);
    border-color: var(--tm-danger-bg);
}
.teams-panel .teams-config__danger-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}
.teams-panel .teams-config__danger-title {
    font-weight: 600;
    font-size: 14px;
}
.teams-panel .teams-config__danger-body {
    font-size: 13px;
    color: var(--tm-text-2);
    margin-top: 2px;
    max-width: 440px;
}
.teams-panel .teams-config .teams-members-list {
    display: flex;
    flex-direction: column;
}

/* ── Form fields (config + create modal) ────────────────────────────────────── */
.teams-panel .teams-field,
.teams-modal-overlay .teams-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 18px;
    padding: 10px;
    background: var(--tm-bg);
    border-radius: 8px;
}

.teams-panel .teams-field__label,
.teams-modal-overlay .teams-field__label {
    font-size: 13px;
    font-weight: 600;
    color: var(--tm-text-1);
}
.teams-panel .teams-field__req,
.teams-modal-overlay .teams-field__req {
    color: var(--tm-danger);
}
.teams-panel .teams-field__hint,
.teams-modal-overlay .teams-field__hint {
    font-size: 12px;
    color: var(--tm-text-3);
}
.teams-panel .teams-field__hint strong,
.teams-modal-overlay .teams-field__hint strong {
    color: var(--tm-agent);
}
.teams-panel .teams-field__input,
.teams-modal-overlay .teams-field__input {
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-white);
    font-family: var(--tm-font-ui);
    font-size: 14px;
    color: var(--tm-text-1);
    outline: none;
    transition:
        border-color var(--tm-t),
        box-shadow var(--tm-t);
}
.teams-panel .teams-field__input:focus,
.teams-modal-overlay .teams-field__input:focus {
    border-color: var(--tm-accent);
    box-shadow: 0 0 0 3px var(--tm-accent-subtle);
    background: var(--tm-real-white);
}

.teams-panel .teams-field__textarea,
.teams-modal-overlay .teams-field__textarea {
    resize: vertical;
    min-height: 74px;
    line-height: 1.45;
}
.teams-panel .teams-field__input:disabled,
.teams-modal-overlay .teams-field__input:disabled {
    background: var(--tm-bg-alt);
    color: var(--tm-text-2);
    cursor: not-allowed;
}

/* Member chips (create modal) */
.teams-modal-overlay .teams-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.teams-modal-overlay .teams-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 6px 3px 10px;
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
    border-radius: 999px;
    font-size: 12px;
    font-weight: 500;
}
.teams-modal-overlay .teams-chip button {
    border: none;
    background: transparent;
    color: var(--tm-accent);
    cursor: pointer;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    font-size: 10px;
}
.teams-modal-overlay .teams-chip button:hover {
    background: var(--tm-accent);
    color: #fff;
}

/* Create-modal form chrome */
.teams-modal-overlay .teams-modal--form {
    max-width: 560px;
}
.teams-modal-overlay .teams-form {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}
.teams-modal-overlay .teams-modal__footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: 14px 20px;
    border-top: 1px solid var(--tm-border);
    background: var(--tm-surface);
}

.teams-config__channel-note {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--tm-text-1, #6f6e6d);
}

/* ── Open Channel followers (open-channel-followers.js) ───────────────────────
   Owner/admin-only, read-only. Styled as a plain list, never as a roster. */
.teams-config--channel .oc-followers__list {
    margin: 10px 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-height: 320px;
    overflow-y: auto;
}

.teams-config--channel .oc-followers__row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 10px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-surface);
}

.teams-config--channel .oc-followers__who {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--tm-text-1);
}

.teams-config--channel .oc-followers__level,
.teams-config--channel .oc-followers__since {
    flex: 0 0 auto;
    font-size: 12px;
    color: var(--tm-text-3);
}

.teams-config--channel .oc-followers__empty {
    padding: 7px 2px;
    color: var(--tm-text-3);
    font-size: 12.5px;
}

/* ── Open Channel roles (open-channel-roles.js) ───────────────────────────────
   The channel ROLE table — who may publish or moderate. Deliberately not
   styled like a Team member roster: a channel has no visible membership, and
   followers never appear here at all. */
.teams-config--channel .oc-roles__list {
    margin: 8px 0 12px;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.teams-config--channel .oc-roles__row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-surface);
}

.teams-config--channel .oc-roles__who {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--tm-text-1);
}

.teams-config--channel .oc-roles__role {
    flex: 0 0 auto;
    padding: 2px 9px;
    border-radius: 999px;
    background: var(--tm-accent-subtle);
    color: var(--tm-text-2);
    font: 600 11px/1.6 var(--tm-font-ui);
}

.teams-config--channel .oc-roles__remove {
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: 999px;
    background: transparent;
    color: var(--tm-text-3);
    cursor: pointer;
}

.teams-config--channel .oc-roles__remove:hover:not(:disabled) {
    border-color: var(--tm-border);
    color: var(--tm-danger, #b3261e);
}

.teams-config--channel .oc-roles__empty {
    padding: 7px 2px;
    color: var(--tm-text-3);
    font-size: 12.5px;
}

.teams-config--channel .oc-roles__add {
    display: flex;
    gap: 8px;
    align-items: center;
}

.teams-config--channel .oc-roles__add [data-role-search] { flex: 1 1 auto; min-width: 0; }
.teams-config--channel .oc-roles__add [data-role-kind] { flex: 0 0 auto; width: auto; }

.teams-config--channel .oc-roles__results {
    margin: 6px 0 0;
    padding: 0;
    list-style: none;
    max-height: 200px;
    overflow-y: auto;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
}

.teams-config--channel .oc-roles__result {
    display: block;
    width: 100%;
    padding: 8px 10px;
    border: none;
    background: none;
    text-align: left;
    color: var(--tm-text-1);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}

.teams-config--channel .oc-roles__result:hover { background: var(--tm-bg-alt); }

/* ── Two columns where the form is wide enough ───────────────────────────────
   Two equal columns (Name | Image, Description | Prompt) while the page has room;
   one column when it does not. The scroll area is the container, so a narrow chat
   window and a narrow screen behave the same. */
.teams-panel .teams-config__scroll { container: teams-config / inline-size; }
.teams-panel .teams-config__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px 24px;
    align-items: stretch;
    margin-bottom: 18px;
}
.teams-panel .teams-config__grid > .teams-field,
.teams-panel .teams-config__grid > [data-avatar-host] > .teams-field { margin-bottom: 0; }
.teams-panel .teams-config__grid > [data-avatar-host] { display: flex; min-width: 0; }
.teams-panel .teams-config__grid > [data-avatar-host] > .teams-avatar-picker { flex: 1 1 auto; }
.teams-panel .teams-config .teams-visibility__public {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px 24px;
    align-items: start;
}
.teams-panel .teams-config .teams-visibility__public[hidden] { display: none; }
.teams-panel .teams-config .teams-visibility__public > .teams-visibility__warning { grid-column: 1 / -1; }
@container teams-config (max-width: 760px) {
    .teams-panel .teams-config__grid,
    .teams-panel .teams-config .teams-visibility__public { grid-template-columns: minmax(0, 1fr); }
}

/* ── Conversation view ────────────────────────────────────────────────────── */
.teams-panel .teams-conversation-view {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.teams-panel .teams-conversation__context {
    flex-shrink: 0;
    position: relative;
    z-index: 2;
    box-shadow: 0 15px 15px rgba(31, 38, 44, 0.26);
}

/* The chat column and the Support Desk case panel side by side. A plain row
   that collapses to just the chat when the panel slot is empty, which is the
   state of every conversation without a desk — so the layout costs nothing
   where the feature is not in use. */
.teams-panel .teams-conversation__body {
    flex: 1 1 auto;
    display: flex;
    flex-direction: row;
    align-items: stretch;
    min-height: 0;
    overflow: hidden;
    /* Containing block for the absolutely positioned aside (the Support Desk
       case panel and the observers card). Without it the aside is positioned
       against the viewport and has no height to bound its cards. */
    position: relative;
}

/* Only the conversation view — and, when the user opts in, the Spaces feed —
 * receives a personal image. The Teams panel itself and the sidebar never match
 * these selectors. The tint is intentional: it preserves message readability
 * without changing composer geometry, audio controls, or Safari's isolated
 * transcript scroll container.
 *
 * The image sits on the VIEW rather than on `__body` so the conversation header
 * sits over the same picture and can be made translucent (below) instead of
 * capping it with an opaque bar. */
.teams-panel--real.teams-panel--has-chat-background .teams-conversation-view,
.teams-panel--real.teams-panel--has-chat-background.teams-panel--background-spaces .spaces-panel {
    background-color: var(--tm-bg);
    /* ONE image layer, at `cover`. An earlier draft stacked a `contain` layer
       over a `cover` one so a portrait photo stayed whole; on a landscape image
       the cover layer remained visible in the side gutters and read as the
       picture repeating itself. The per-form-factor images replace that trick —
       the user uploads the crop that fits each shape. */
    background-image: linear-gradient(rgba(20, 24, 28, .28), rgba(20, 24, 28, .28)), var(--teams-chat-background-image);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

/* The chrome above the transcript stops being an opaque lid once there is a
   picture behind it. Scoped to the two hosts that actually paint one, so a
   Spaces header with the opt-in OFF keeps its solid background. */
.teams-panel--real.teams-panel--has-chat-background .teams-conversation-view .teams-conversation__header,
.teams-panel--real.teams-panel--has-chat-background.teams-panel--background-spaces .spaces-panel .teams-conversation__header {
    background: color-mix(in srgb, var(--tm-bg) 30%, transparent);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
}

.teams-panel--real.teams-panel--has-chat-background .teams-conversation-view .teams-conversation__pinned,
.teams-panel--real.teams-panel--has-chat-background.teams-panel--background-spaces .spaces-panel .teams-conversation__pinned {
    background: color-mix(in srgb, var(--tm-bg-alt) 62%, transparent);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
}

.teams-panel .teams-conversation__aside:empty {
    display: none;
}

.teams-panel .teams-conversation {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
    /* The conversation owns the full available width so its native scrollbar
       sits at the browser-side edge. The readable 60rem cap belongs to the
       transcript/composer CONTENT below, not to this scrolling viewport. */
    width: 100%;
    position: relative; /* containing block for the scroll-to-latest arrow */
    padding-bottom: 5px;
}

/* Keep the transcript at its familiar reading width while the parent scroller
   remains full-width. This mirrors the Space feed's full-width scroller plus
   constrained content, without changing message rendering or scroll logic. */
.teams-panel .teams-conversation__scroll-content,
.teams-panel .teams-conversation__typing,
.teams-panel .teams-status-notes,
.teams-panel .teams-conversation__composer-slot {
    width: 100%;
    max-width: 60rem;
    margin-inline: auto;
    box-sizing: border-box;
}

.teams-conversation__scroll-content .message-container-bot .bot-message {
    padding: 10px 20px;
    background: #8080802e;
    background: var(--tm-ai-msg-bg);
}

/* Stacking above the input, top to bottom:
 *     typing indicator  — the most transient, so the least anchored
 *     status notes      — context for what you are about to write
 *     attachments       — part of the message itself, so nearest the field
 *     the input
 * Attachments live INSIDE the composer slot, which is what keeps them closest
 * to the field without a rule here. */
.teams-panel .teams-status-notes {
    overflow-anchor: none;
}

/* ── Scroll-to-latest arrow (appears when scrolled up) ─────────────────────── */
.teams-panel .teams-conversation__scroll-btn {
    position: absolute;
    /* The shared composer can grow (and, on mobile, lift above the keyboard).
       ConversationView measures its live clearance into this variable, so this
       control never lands on top of text being composed. */
    bottom: calc(var(--teams-composer-clearance, 96px) + 12px);
    left: 50%;
    transform: translateX(-50%);
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: 1px solid var(--tm-border);
    background: var(--tm-white);
    color: var(--tm-text-2);
    box-shadow: var(--tm-shadow-md);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 5;
}
.teams-panel .teams-conversation__scroll-btn:hover {
    color: var(--tm-accent);
}
/* Higher specificity than the display:flex above so [hidden] actually hides it
   (scoped display rules otherwise beat the bare [hidden] attribute). */
.teams-panel .teams-conversation__scroll-btn[hidden] {
    display: none;
}

/* ── "N new messages" ───────────────────────────────────────────────────────
   Messages that arrived while the reader was scrolled up. The same offer, and
   the same visual language, as the Spaces feed's "N new posts" pill
   (spaces-foundation.css) — a floating, dismissable invitation rather than an
   alert, because the whole point is that the transcript did NOT move.

   Occupies the same slot as the scroll-to-latest arrow above and replaces it
   while up (teams-conversation-messages.js hides the arrow), so the corner
   never holds two floating controls that do nearly the same thing. */
.teams-panel .teams-conversation__new-msgs {
    position: absolute;
    bottom: calc(var(--teams-composer-clearance, 96px) + 12px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 6;

    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 16px;
    border: none;
    border-radius: 999px;
    background: var(--tm-accent);
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    box-shadow: var(--tm-shadow-md);
}
.teams-panel .teams-conversation__new-msgs:hover {
    filter: brightness(1.08);
}
/* Same specificity reason as the arrow above: the scoped `display: inline-flex`
   would otherwise beat the bare [hidden] attribute. */
.teams-panel .teams-conversation__new-msgs[hidden] {
    display: none;
}

.teams-panel .teams-conversation__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 56px;
    background: var(--tm-bg);
    flex-shrink: 0;
    position: relative;
}
.teams-panel .teams-conversation__heading {
    min-width: 0;
}

.teams-panel .teams-conversation__title {
    display: flex;
    align-items: center;
    gap: 6px;
    font-weight: 600;
    font-size: 15px;
    color: var(--tm-msg-text);
}
.teams-panel .teams-conversation__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 46ch;
    font-size: 1.2rem;
}

/* 1:1 chats: the people pill sits beside the title and the roster line under
   it is hidden (the roster's own `display: flex` would otherwise beat [hidden]). */
.teams-panel .teams-conversation__title-people {
    display: inline-flex;
    flex-shrink: 0;
    font-weight: 400;
}
.teams-panel .teams-conversation__title-people[hidden],
.teams-panel .teams-conversation__participants[hidden] {
    display: none;
}

/* Pencil: hidden until the title is hovered. */
.teams-panel .teams-conversation__rename {
    border: none;
    background: none;
    cursor: pointer;
    padding: 3px;
    color: var(--tm-text-3);
    border-radius: 5px;
    line-height: 1;
    opacity: 0;
    transition:
        opacity 0.12s ease,
        background 0.12s ease;
    font-size: 12px;
}
.teams-panel .teams-conversation__title:hover .teams-conversation__rename {
    opacity: 1;
}

.teams-panel .teams-conversation__rename:hover {
    background: var(--tm-accent-subtle);
    color: var(--tm-msg-text);
}

/* Header actions cluster (schedule + video), pinned to the far right. */
.teams-panel .teams-conversation__header-actions {
    flex-shrink: 0;
    margin-left: 12px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    position: relative;
}

/* The ⋯ trigger; it and the overflow popover are styled in
   teams-header-menu.css. */
.teams-panel .teams-conversation__more-actions {
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border: 1px solid var(--tm-border);
    border-radius: 8px;
    background: var(--tm-surface);
    color: var(--tm-text-2);
    cursor: pointer;
    font-size: 16px;
    line-height: 1;
}
/* Audio call: the other primary header action, and the ONLY one on a phone —
   video moves into the overflow menu there. Shares the video button's shape so
   the pair reads as one control group; fully rounded because, unlike video, it
   has no select chevron welded to its right edge. */
.teams-panel .teams-conversation__audio {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    border: 1px solid var(--tm-border);
    background: var(--tm-surface);
    color: var(--tm-text-2);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    transition:
        background 0.12s ease,
        color 0.12s ease,
        border-color 0.12s ease;
}
.teams-panel .teams-conversation__audio:hover {
    background: var(--tm-accent);
    color: #fff;
    border-color: var(--tm-accent);
}
.teams-panel .teams-conversation__audio.is-loading,
.teams-panel .teams-conversation__audio.is-loading:hover {
    cursor: wait;
    opacity: 0.72;
}
.teams-panel .teams-conversation__audio:disabled,
.teams-panel .teams-conversation__audio:disabled:hover {
    cursor: not-allowed;
    opacity: 0.55;
    background: #ffffff9e;
    color: var(--tm-text-3);
    border-color: var(--tm-border);
}

/* Video call: a primary header action. */
.teams-panel .teams-conversation__video {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    border: 1px solid var(--tm-border);
    background: #ffffff9e;
    color: var(--tm-text-2);
    cursor: pointer;
    font-size: 14px;
    background: var(--tm-surface);
    line-height: 1;
    transition:
        background 0.12s ease,
        color 0.12s ease,
        border-color 0.12s ease;
}
.teams-panel .teams-conversation__video:hover {
    background: var(--tm-accent);
    color: #fff;
    border-color: var(--tm-accent);
}
.teams-panel .teams-conversation__video.is-loading,
.teams-panel .teams-conversation__video.is-loading:hover {
    cursor: wait;
    opacity: 0.72;
}
.teams-panel .teams-conversation__video:disabled,
.teams-panel .teams-conversation__video:disabled:hover {
    cursor: not-allowed;
    opacity: 0.55;
    background: #ffffff9e;
    color: var(--tm-text-3);
    border-color: var(--tm-border);
}
/* "Call selected people" is a ⋯ menu row at every width
   (teams-header-menu.css); it keeps only the menu's row styling. */
.teams-panel .teams-conversation__video-select {
    display: inline-flex;
    align-items: center;
    height: 34px;
    color: var(--tm-text-2);
    cursor: pointer;
    font-size: 14px;
}
.teams-call-picker-overlay .teams-modal {
    max-width: 430px;
}
.teams-call-picker {
    height: 60vh;
    display: flex;
    flex-direction: column;
}
.teams-call-picker .teams-modal__body {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}
.teams-call-picker__hint {
    margin: 4px 4px 12px;
    color: var(--tm-text-2);
    font-size: 13px;
}
.teams-call-picker__search-wrap {
    margin: 0 0 10px;
}
.teams-call-picker__list {
    display: grid;
    flex: 1 1 auto;
    min-height: 0;
    align-content: start;
    gap: 4px;
    max-height: none;
    overflow-y: auto;
    padding-right: 2px;
}

.teams-call-picker__list .teams-call-picker__row .teams-avatar {
    margin-top: 0;
    margin-right: 0;
}
.teams-call-picker__row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px;
    border-radius: 7px;
    cursor: pointer;
}
/* The row's flex rule is more specific than the browser's generic [hidden]
   rule in some embedded WebViews, so state the filter's display contract here. */
.teams-call-picker__row[hidden] {
    display: none !important;
}
.teams-call-picker__row:hover {
    background: var(--tm-bg-alt);
}
.teams-call-picker__row input {
    margin: 0;
}
.teams-call-picker__avatar {
    width: 28px;
    height: 28px;
    font-size: 10px;
}
.teams-call-picker__meta {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.teams-call-picker__name {
    min-width: 0;
    color: var(--tm-text-1);
}
/* Team · Office — same line the Participants modal shows under a name. */
.teams-call-picker__org {
    font-size: 12px;
    color: var(--tm-text-3);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-call-picker__name small {
    margin-left: 5px;
    color: var(--tm-text-3);
    font-weight: 600;
}
.teams-call-picker__direct {
    width: 30px;
    height: 30px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--tm-accent);
    cursor: pointer;
}
.teams-call-picker__direct:hover:not(:disabled) {
    background: var(--tm-accent-subtle);
}
.teams-call-picker__direct:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}
.teams-call-picker__no-results {
    margin: 8px 0 0;
}
.teams-call-picker .teams-modal__footer {
    flex: 0 0 auto;
    margin-top: auto;
}
.teams-panel .teams-member-role-select {
    min-width: 112px;
    padding: 6px 30px 6px 10px;
    border: 1px solid var(--tm-border);
    border-radius: 999px;
    background: var(--tm-bg-alt);
    color: var(--tm-text-1);
    font-size: 12px;
    font-weight: 650;
    line-height: 1.2;
    cursor: pointer;
    transition:
        border-color 0.15s ease,
        box-shadow 0.15s ease,
        background 0.15s ease;
}
.teams-panel .teams-member-role-select:hover {
    border-color: var(--tm-accent);
    background: var(--tm-accent-subtle);
}
.teams-panel .teams-member-role-select:focus {
    outline: none;
    border-color: var(--tm-accent);
    box-shadow: 0 0 0 3px var(--tm-accent-subtle);
}
.teams-panel .teams-conversation__call-banner {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    /* There is no global border-box reset in this stylesheet, so width:100%
       plus horizontal padding made the banner 112px wider than its parent
       (40px at the mobile breakpoint) and pushed Join off the right edge. */
    box-sizing: border-box;
    margin: 0;
    padding: 7px 56px;
    background: var(--tm-bg-alt);
    border-bottom: 1px solid var(--tm-border);
    color: var(--tm-text-2);
    font-size: 12.5px;
    flex-shrink: 0;
    border-radius: 0;
}
.teams-panel .teams-conversation__call-banner[hidden] {
    display: none;
}
.teams-panel .teams-conversation__call-banner > i {
    color: var(--tm-accent);
}
.teams-panel .teams-conversation__call-banner .teams-conversation__call-banner-text {
    flex: 1;
    /* A flex item's default min-width is its content, so on a narrow screen the
       label refuses to shrink and squeezes the button out instead. */
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-panel .teams-conversation__call-banner button {
    /* Never the item that gives way: joining is the whole point of the banner. */
    flex-shrink: 0;
    border: 1px solid var(--tm-accent);
    border-radius: 6px;
    padding: 4px 12px;
    background: var(--tm-accent);
    color: #fff;
    cursor: pointer;
    font-size: 12px;
    font-weight: 600;
}
.teams-panel .teams-conversation__call-banner button:hover {
    filter: brightness(1.08);
}
.teams-panel .teams-conversation__call-banner button[hidden] {
    display: none;
}
/* Live call clock + faces of who is on the call (teams-call-banner.js). */
.teams-panel .teams-conversation__call-banner .teams-conversation__call-duration {
    flex-shrink: 0;
    font-variant-numeric: tabular-nums;
    color: var(--tm-text-2);
}
.teams-panel .teams-conversation__call-banner .teams-conversation__call-people {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
}
.teams-panel .teams-conversation__call-banner [hidden] {
    display: none;
}
.teams-panel .teams-conversation__call-banner .teams-conversation__call-pill {
    width: 24px;
    height: 24px;
    margin: 0 0 0 -6px;
    border: 2px solid var(--tm-bg-alt);
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Not overflow:hidden — that clipped the presence badge, which overhangs
       the circle by design. The photo rounds itself (rule below). */
    position: relative;
    background: var(--tm-avatar-placeholder);
    color: var(--tm-accent);
    font-size: 10.5px;
    font-weight: 600;
    box-sizing: border-box;
}
.teams-panel .teams-conversation__call-banner .teams-conversation__call-pill:first-child {
    margin-left: 0;
}
.teams-panel .teams-conversation__call-banner .teams-conversation__call-pill img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
}
/* Ring the badge in the banner colour so it reads against overlapping faces. */
.teams-panel .teams-conversation__call-banner .teams-conversation__call-pill .teams-presence-badge {
    box-shadow: 0 0 0 1.5px var(--tm-bg-alt);
}
.teams-panel .teams-conversation__call-banner .teams-conversation__call-pill-more {
    margin-left: 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--tm-text-2);
}
/* Compact "👥 22" head count — the phone layout's stand-in for the faces
   (shown by teams-responsive.css). */
.teams-panel .teams-conversation__call-banner .teams-conversation__call-count {
    display: none;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    font-weight: 600;
    color: var(--tm-text-2);
}

/* ── Pinned messages bar (teams-pins.js) ─────────────────────────────────────
 * Sits under the header: a collapsed summary row (count + latest peek) that
 * expands to the full pinned list. A row click scrolls to + flashes the original
 * message; the X unpins. */
.teams-panel .teams-conversation__pinned {
    position: relative;
    z-index: 1;
    flex-shrink: 0;
    background: var(--tm-bg-alt);
    border-bottom: 1px solid var(--tm-border);
}
.teams-panel .teams-conversation__pinned[hidden] {
    display: none;
}
.teams-panel .teams-pinbar__summary {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 7px 56px;
    border: none;
    background: none;
    cursor: pointer;
    color: var(--tm-text-2);
    font-size: 12.5px;
    text-align: left;
}
.teams-panel .teams-pinbar__summary:hover {
    background: var(--tm-accent-subtle);
}
.teams-panel .teams-pinbar__summary > .fa-thumbtack {
    color: var(--tm-accent);
    transform: rotate(35deg);
}
.teams-panel .teams-pinbar__count {
    font-weight: 600;
    flex-shrink: 0;
}
.teams-panel .teams-pinbar__peek {
    flex: 1;
    min-width: 0;
    color: var(--tm-text-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.teams-panel .teams-pinbar__chev {
    margin-left: auto;
    font-size: 11px;
    color: var(--tm-text-3);
}
.teams-panel .teams-pinbar__list {
    max-height: 200px;
    overflow-y: auto;
    padding: 2px 43px 8px;
    border-top: 1px solid var(--tm-border);
}
.teams-panel .teams-pinbar__row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border-radius: 8px;
    cursor: pointer;
}
.teams-panel .teams-pinbar__row:hover {
    background: var(--tm-accent-subtle);
}
.teams-panel .teams-pinbar__row-icon {
    flex-shrink: 0;
    color: var(--tm-accent);
    width: 16px;
    text-align: center;
}
.teams-panel .teams-pinbar__row-icon .fa-thumbtack {
    transform: rotate(35deg);
}
.teams-panel .teams-pinbar__row-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.teams-panel .teams-pinbar__row-sender {
    font-size: 12px;
    font-weight: 600;
    color: var(--tm-text-2);
}
.teams-panel .teams-pinbar__row-preview {
    font-size: 12.5px;
    color: var(--tm-text-1);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.teams-panel .teams-pinbar__row-remove {
    flex-shrink: 0;
    border: none;
    background: none;
    cursor: pointer;
    color: var(--tm-text-3);
    padding: 4px;
    border-radius: 50%;
    line-height: 1;
}
.teams-panel .teams-pinbar__row-remove:hover {
    background: var(--tm-border);
    color: var(--tm-text-1);
}

/* Per-message pin popover (appended to <body>, so it carries its own tokens via
 * the shared .teams-modal-overlay token set — reference concrete fallbacks to be
 * safe on the admin/widget pages that don't ship the panel scope). */
.teams-pin-menu {
    position: fixed;
    z-index: 100001;
    min-width: 180px;
    padding: 5px;
    border-radius: 10px;
    background: var(--tm-bg, #fff);
    border: 1px solid var(--tm-border, rgba(0, 0, 0, 0.12));
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.22);
}
.teams-pin-menu__item {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 8px 10px;
    border: none;
    background: none;
    cursor: pointer;
    border-radius: 7px;
    font-size: 13px;
    text-align: left;
    color: var(--tm-text-1, #1c1c1c);
}
.teams-pin-menu__item:hover {
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.09));
}
.teams-pin-menu__item .fa-thumbtack {
    transform: rotate(35deg);
    color: var(--tm-accent, #2d5f84);
}
.teams-pin-menu__item .fa-bookmark {
    color: var(--tm-accent, #2d5f84);
}

/* Lines a row's avatar up with the bubble under the name row. An offset, not a margin:
   a margin would keep every row, however short, at least name-row plus avatar tall.
   The row's own avatar only: cards inside a bubble carry avatars of their own. */
.teams-panel .teams-conversation-view .teams-conversation__messages .teams-msg > .teams-avatar {
    position: relative;
    top: 18px;
}
/* Schedule a video meeting: opens the Calendar dialog linked to this chat. */
.teams-panel .teams-conversation__schedule {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    border: 1px solid var(--tm-border);
    color: var(--tm-text-2);
    cursor: pointer;
    font-size: 14px;
    background: var(--tm-surface);
    line-height: 1;
    transition:
        background 0.12s ease,
        color 0.12s ease,
        border-color 0.12s ease;
}
.teams-panel .teams-conversation__schedule:hover {
    background: var(--tm-accent);
    color: #fff;
    border-color: var(--tm-accent);
}

/* ── Header swap + Space actions ─────────────────────────────────────────────
   The Space feed renders the SAME header a chat does, so its buttons are
   styled HERE, beside the chat's own, rather than in spaces.css. Styling them
   over there produced a header whose icons visibly did not match the same
   header one click away — which is the one thing sharing the markup was meant
   to prevent.

   `__swap` is the icon that moves between the two surfaces: 📰 in a chat,
   💬 in a feed. `__notify` is the per-space mute bell. Both match
   `__video` / `__ask-ai` exactly. */

.teams-panel .teams-conversation__swap,
.teams-panel .teams-conversation__notify {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    border: 1px solid var(--tm-border);
    background: var(--tm-surface);
    color: var(--tm-text-2);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    transition:
        background var(--tm-t),
        color var(--tm-t),
        border-color var(--tm-t);
}

/* No dark-theme override: `--tm-surface` is itself theme-aware (see
   teams-foundation.css), so these controls now follow the theme with every
   other header action instead of carrying their own dark-mode rule. */

.teams-panel .teams-conversation__swap:hover,
.teams-panel .teams-conversation__notify:hover {
    background: var(--tm-accent);
    color: #fff;
    border-color: var(--tm-accent);
}

/* Muted is a STATE, not a hover: it has to read at a glance from across the
   header, because the whole point is knowing you turned this space down. */
.teams-panel .teams-conversation__notify.is-muted {
    color: var(--tm-danger);
    border-color: var(--tm-danger);
}

.teams-panel .teams-conversation__notify.is-muted:hover {
    background: var(--tm-danger);
    color: #fff;
}

/* "New post" is the one LABELLED action in the row — a feed's primary verb,
   and an unlabelled ＋ beside three icons is a guess. Uses the same accent as
   every other primary button in Teams. */
.teams-panel .space-new-post {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 34px;
    padding: 0 14px;
    border: 1px solid var(--tm-accent);
    border-radius: 8px;
    background: var(--tm-accent);
    color: #fff;
    font-family: var(--tm-font-ui);
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition:
        background var(--tm-t),
        border-color var(--tm-t);
}

.teams-panel .space-new-post:hover {
    background: var(--tm-accent-hover);
    border-color: var(--tm-accent-hover);
}

/* Narrow panes drop the label and keep the icon — the action stays reachable
   without pushing the participant summary off the row. */
@media (max-width: 900px) {
    .teams-panel .space-new-post {
        padding: 0;
        width: 34px;
        justify-content: center;
    }
    .teams-panel .space-new-post span { display: none; }
}

/* ── Video call overlay ─────────────────────────────────────────────────────── */
.teams-video-overlay {
    position: fixed;
    inset: 0;
    z-index: 4000;
    background: rgba(0, 0, 0, 0.62);
    display: flex;
    align-items: center;
    justify-content: center;
}
body.teams-video-window .app-container,
body.teams-video-window .snowflake-area {
    display: none !important;
}
body.teams-video-window {
    background: #0b0d11;
}
body.teams-video-window .teams-video-overlay {
    background: #0b0d11;
}
body.teams-video-window .teams-video-overlay .teams-video-modal {
    width: 100vw;
    height: 100vh;
    max-width: none;
    border: 0;
    border-radius: 0;
}
body.teams-video-window [data-minimize],
body.teams-video-window [data-restore],
body.teams-video-window [data-popout] {
    display: none !important;
}
.teams-video-overlay .teams-video-modal {
    width: min(1280px, 96vw);
    height: min(880px, 92vh);
    display: flex;
    flex-direction: column;
    background: var(--tm-surface-1, #1a1d24);
    color: var(--tm-msg-text, #e6e9ef);
    border: 1px solid var(--tm-border, #2a2f3a);
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
.teams-video-overlay .teams-video-header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    border-bottom: 1px solid #2a2f3a;
    flex-shrink: 0;
}
.teams-video-overlay .teams-video-title {
    font-weight: 600;
    font-size: 14px;
}
.teams-video-overlay .teams-video-duration {
    color: #cbd2dc;
    font: 600 12px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
    white-space: nowrap;
}
.teams-video-overlay .teams-video-status {
    font-size: 12px;
    color: #9aa3b2;
    margin-left: auto;
}
.teams-video-overlay .teams-video-chattoggle {
    border: 1px solid #2a2f3a;
    background: transparent;
    color: #e6e9ef;
    width: 32px;
    height: 32px;
    border-radius: 8px;
    cursor: pointer;
    font-size: 14px;
}
.teams-video-overlay .teams-video-chattoggle:hover {
    background: rgba(255, 255, 255, 0.08);
}
.teams-video-overlay .teams-video-min,
.teams-video-overlay .teams-video-restore,
.teams-video-overlay .teams-video-fullscreen,
.teams-video-overlay .teams-video-popout,
.teams-video-overlay .teams-video-return {
    border: 1px solid #2a2f3a;
    background: transparent;
    color: #e6e9ef;
    width: 32px;
    height: 32px;
    border-radius: 8px;
    cursor: pointer;
    font-size: 13px;
}
.teams-video-overlay .teams-video-min:hover,
.teams-video-overlay .teams-video-restore:hover,
.teams-video-overlay .teams-video-fullscreen:hover,
.teams-video-overlay .teams-video-popout:hover,
.teams-video-overlay .teams-video-return:hover {
    background: rgba(255, 255, 255, 0.08);
}
.teams-video-overlay .teams-video-min[hidden],
.teams-video-overlay .teams-video-restore[hidden] {
    display: none;
}

/* Body: video stage (left) + optional collapsible chat panel (right). */
.teams-video-overlay .teams-video-main {
    flex: 1;
    display: flex;
    min-height: 0;
}
.teams-video-overlay .teams-video-participants { width: 280px; border-left: 1px solid #2a2f3a; background: #1d222c; display: flex; flex-direction: column; }
.teams-video-overlay .teams-video-participants[hidden] { display: none; }
/* Every People-panel rule is scoped to the overlay (CLAUDE.md rule 2): the call
   modal is appended to <body>, on third-party widget pages as well as ours, so
   an unscoped `.teams-video-participant` would be loose in the host document. */
.teams-video-overlay .teams-video-participants__head { display:flex; justify-content:space-between; align-items:center; padding:12px 14px; font-size:14px; font-weight:700; border-bottom:1px solid #2a2f3a; }
.teams-video-overlay .teams-video-participants__head > span { display:inline-flex; align-items:center; gap:7px; }
.teams-video-overlay .teams-video-participants__head button { border:0; background:transparent; color:#cbd2dc; font-size:18px; cursor:pointer; }
.teams-video-overlay .teams-video-participants__invite { position:relative; z-index:3; padding:10px; border-bottom:1px solid #2a2f3a; }
.teams-video-overlay .teams-video-participants__invite input { width:100%; box-sizing:border-box; border:1px solid #3a4352; border-radius:6px; background:#272f3c; color:#fff; padding:8px; font-size:13px; }
.teams-video-overlay .teams-video-participants__invite [data-participant-results] { position:absolute; z-index:5; top:calc(100% - 6px); left:10px; right:10px; max-height:190px; overflow:auto; background:#222936; border:1px solid #3a4352; border-radius:6px; box-shadow:0 8px 18px rgba(0,0,0,.35); }
.teams-video-overlay .teams-video-participants__invite [data-participant-results]:empty { display:none; }
.teams-video-overlay .teams-video-participant-result { display:grid; grid-template-columns:30px minmax(0,1fr) auto; align-items:center; gap:8px; width:100%; min-height:40px; border:0; border-bottom:1px solid #303947; background:#222936; color:#e6e9ef; padding:5px 7px; font-size:13px; text-align:left; cursor:pointer; }
.teams-video-overlay .teams-video-participant-result:hover,
.teams-video-overlay .teams-video-participant-result:focus-visible { background:#303a4b; outline:0; }
.teams-video-overlay .teams-video-participant-result:last-child { border-bottom:0; }
.teams-video-overlay .teams-video-participant-result small { color:#9aa3b2; font-size:11px; }
.teams-video-overlay .teams-video-participants__list { overflow:auto; padding:6px; }
/* Roster rows carry a smaller avatar than the invite picker, so the first grid
   column tracks the 20px size instead of leaving a 10px gap beside it. */
.teams-video-overlay .teams-video-participant {
    position:relative;
    display:grid;
    grid-template-columns:20px minmax(0, 1fr) 16px;
    align-items:center;
    column-gap:8px;
    min-height:38px;
    padding:4px 6px;
    font-size:13px;
    color:#e6e9ef;
    cursor: pointer;
}

.teams-video-overlay .teams-video-participant:hover {
    background:#303a4b;
}

.teams-video-overlay .teams-video-participant__avatar {
    width:30px;
    height:30px;
    border-radius:50%;
    display:grid;
    place-items:center;
    background:#356a95 center/cover no-repeat;
    color:#fff;
    font-size:11px;
    font-weight:700;
}
.teams-video-overlay .teams-video-participant .teams-video-participant__avatar {
    width:20px;
    height:20px;
    font-size:9px;
}
/* Presence badge ring in the panel's own dark colour, not the light default. */
.teams-video-overlay .teams-video-participant__avatar .teams-presence-badge {
    box-shadow: 0 0 0 1.5px #1d222c;
}
.teams-video-overlay .teams-video-participant > i {
    grid-column:3;
    grid-row:1 / span 2;
    align-self:center;
    font-size:12px;
    color:#cbd2dc;
    text-align:center;
}

.teams-video-overlay .teams-video-participant__mic-button { border:0; border-radius:5px; background:transparent; color:#cbd2dc; padding:4px; cursor:pointer; }
.teams-video-overlay .teams-video-participant__mic-button:hover,
.teams-video-overlay .teams-video-participant__mic-button:focus-visible { background:#394150; color:#fff; outline:0; }
.teams-video-overlay .teams-video-participant--self { background:rgba(79, 140, 255, .10); border-radius:6px; font-weight:600; color:#d7e6ff; }
.teams-video-overlay .teams-video-mute-popover { position:absolute; z-index:8; top:calc(100% + 3px); right:4px; display:grid; grid-template-columns:1fr auto auto; align-items:center; gap:7px; min-width:230px; padding:8px; border:1px solid #465166; border-radius:7px; background:#293241; box-shadow:0 7px 16px rgba(0,0,0,.4); color:#e6e9ef; font-size:12px; }
.teams-video-overlay .teams-video-mute-popover button { border:0; border-radius:5px; padding:5px 7px; background:#9fc1ff; color:#10254c; font-weight:700; cursor:pointer; }
.teams-video-overlay .teams-video-mute-popover button:last-child { background:transparent; color:#cbd2dc; }
.teams-video-overlay .teams-video-participant small { grid-column:2 / 4; margin-top:-4px; color:#9aa3b2; font-size:11px; }
.teams-video-overlay .teams-video-participant__pending { color:#9aa3b2; }
.teams-video-overlay .teams-video-participant > span:nth-child(2) { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.teams-video-overlay .teams-video-participant__request-join { grid-column:3; grid-row:1 / span 2; justify-self:end; align-self:center; border:1px solid #59677d; border-radius:4px; background:#303a4b; color:#e6e9ef; padding:3px 7px; font-size:11px; cursor:pointer; opacity:0; pointer-events:none; white-space:nowrap; }
.teams-video-overlay .teams-video-participant--requestable:hover .teams-video-participant__request-join,
.teams-video-overlay .teams-video-participant--requestable:focus-within .teams-video-participant__request-join { opacity:1; pointer-events:auto; }
.teams-video-overlay .teams-video-participant__request-join:hover,
.teams-video-overlay .teams-video-participant__request-join:focus-visible { border-color:#9fc1ff; background:#394a62; outline:0; }
.teams-video-overlay .teams-video-participant__request-join:disabled { cursor:wait; opacity:.72; }

.teams-video-overlay .teams-video-stage {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.teams-video-overlay .teams-video-grid {
    flex: 1;
    overflow: auto;
    padding: 16px;
    display: grid;
    gap: 14px;
    position: relative; /* anchors the self-view PiP overlay (.has-remotes .local) */
    /* auto-fit collapses empty tracks so 1 participant fills the row (large);
       2 → two columns, 3+ → wrap. Large min keeps tiles big for small calls. */
    grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
    grid-auto-rows: 1fr;
    align-content: center;
    background: #0b0d11;
}
.teams-video-overlay .teams-video-notices {
    position: absolute;
    z-index: 10;
    top: 14px;
    left: 50%;
    transform: translateX(-50%);
    display: grid;
    gap: 8px;
}
.teams-video-overlay .teams-video-notice {
    display: flex;
    align-items: center;
    gap: 8px;
    border: 1px solid #d6a22c;
    border-radius: 8px;
    background: #312711;
    color: #fff1bd;
    padding: 8px 10px;
    font-size: 13px;
    box-shadow: 0 5px 16px rgba(0, 0, 0, .35);
}
.teams-video-overlay .teams-video-notice button {
    margin-left: 4px;
    border: 0;
    background: transparent;
    color: inherit;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
}
.teams-video-overlay .teams-video-mute-request {
    position: absolute;
    z-index: 11;
    top: 14px;
    left: 50%;
    transform: translateX(-50%);
    width: min(420px, calc(100% - 28px));
    display: flex;
    align-items: center;
    gap: 11px;
    box-sizing: border-box;
    border: 1px solid #d6a22c;
    border-radius: 10px;
    background: #312711;
    color: #fff1bd;
    padding: 11px 12px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .45);
}
.teams-video-overlay .teams-video-mute-request[hidden] { display: none; }
.teams-video-overlay .teams-video-mute-request div { display: grid; gap: 2px; margin-right: auto; }
.teams-video-overlay .teams-video-mute-request span { font-size: 12px; color: #f7ddb0; }
.teams-video-overlay .teams-video-mute-request [data-mute-request-accept] { border: 0; border-radius: 7px; background: #f0bd45; color: #231a05; padding: 7px 10px; font-weight: 700; white-space: nowrap; cursor: pointer; }
.teams-video-overlay .teams-video-mute-request [data-mute-request-dismiss] { border: 0; background: transparent; color: inherit; font-size: 20px; line-height: 1; cursor: pointer; }
.teams-video-overlay .teams-video-tile {
    position: relative;
    background: #000;
    border: 2px solid #fff;
    border-radius: 20px;
    overflow: hidden;
    aspect-ratio: 16 / 9;
    min-height: 220px;
    align-self: anchor-center;
    /* Own stacking context: the speaking frame (z-index 7) must stay inside its
       tile and never paint over the floating self-view (z-index 5). Inline-size
       containment lets the camera-off avatar scale with the tile (cqw). */
    z-index: 0;
    container-type: inline-size;
}
.teams-video-overlay .teams-video-tile.local {
    border-color: #4f8cff;
}
/* One tile owns the stage (1:1 call, or alone). At full stage WIDTH a 16:9
   card is taller than the stage in a wide window, so the grid scrolled and the
   bottom of the person was cut off. Size it by the stage HEIGHT instead and let
   the width follow (capped at the stage width). */
.teams-video-overlay .teams-video-grid.has-single-tile:not(.has-spotlight) .teams-video-tile:not(.local),
.teams-video-overlay .teams-video-grid.has-single-tile:not(.has-remotes):not(.has-spotlight) .teams-video-tile.local {
    height: 100%;
    width: auto;
    max-width: 100%;
    min-height: 0;
    justify-self: center;
}
/* Self-view picture-in-picture: once a REMOTE participant is on the call, the
   local tile floats as a small overlay in the bottom-right and the remote
   participants fill the stage (MS-Teams style). Overrides both the grid and the
   spotlight (flex) layouts because it is absolutely positioned. When alone
   (no `.has-remotes`) the local tile stays a normal full-size grid tile. */
.teams-video-overlay .teams-video-grid.has-remotes .teams-video-tile.local {
    position: absolute;
    right: 16px;
    bottom: 16px;
    width: clamp(150px, 18vw, 240px);
    min-height: 0;
    aspect-ratio: 16 / 9;
    z-index: 5;
    flex: none; /* opt out of the spotlight flex sizing */
    box-shadow: 0 6px 22px rgba(0, 0, 0, 0.55);
    cursor: move; /* draggable — user can park it anywhere on the stage */
    touch-action: none; /* let touch-drag move the PiP instead of scrolling */
}
.teams-video-overlay
    .teams-video-grid.has-remotes
    .teams-video-tile.local.is-dragging {
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.65);
    cursor: grabbing;
    user-select: none;
}
.teams-video-overlay .teams-video-tile video {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* Mirror the LOCAL self-view only (like a real mirror / Zoom / Meet / Teams):
   raising your left hand shows on your left. Display-only — the outgoing stream
   is NOT flipped, so others still see you the right way round.

   REMOTE TILES ARE DELIBERATELY NOT MIRRORED. Only your own camera is a mirror;
   everyone else is a window. Flipping remote video reverses whatever they hold
   up to it — a badge, a document, a screen behind them — and puts their raised
   right hand on the wrong side. (The apparent left/right disagreement between
   the local PiP and the same camera seen as a remote tile is an artifact of
   testing with two accounts, not something a real participant ever sees.)

   A local SCREEN share is excluded (:not(.screen-share)) — shared text must not
   reverse. */
.teams-video-overlay .teams-video-tile.local:not(.screen-share) video {
    transform: scaleX(-1) !important;
    -webkit-transform: scaleX(-1) !important;
}
/* Camera-off placeholder: an initials avatar centered on the tile. Hidden until
   the tile is flagged .teams-video-tile--cam-off (local toggle or remote mute). */
.teams-video-overlay .teams-video-avatar {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: clamp(32px, 26cqw, 180px);
    aspect-ratio: 1;
    border-radius: 50%;
    display: none;
    align-items: center;
    justify-content: center;
    background: #2d5f84;
    /* Profile photos are set dynamically with `backgroundImage`; set the
       remaining background properties here so they are centred and cropped as
       an avatar instead of rendering at their intrinsic size in the corner. */
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    color: #fff;
    font-size: clamp(12px, 9cqw, 64px);
    font-weight: 600;
    letter-spacing: 0.5px;
    user-select: none;
    z-index: 1;
}
.teams-video-overlay .teams-video-tile--cam-off video {
    opacity: 0;
}
.teams-video-overlay .teams-video-tile--cam-off .teams-video-avatar {
    display: flex;
}
.teams-video-overlay .teams-video-tile.screen-share video {
    object-fit: contain;
    background: #050608;
}
.teams-video-overlay .teams-video-annotation-canvas {
    position: absolute;
    inset: 0;
    z-index: 3;
    width: 100%;
    height: 100%;
    pointer-events: none;
}
.teams-video-overlay .teams-video-annotation-canvas.is-drawing {
    pointer-events: auto;
    cursor: crosshair;
}
.teams-video-overlay .teams-video-screen-badge {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 6;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 8px;
    border-radius: 6px;
    background: rgba(0, 0, 0, 0.68);
    color: #dce8ff;
    font-size: 11px;
    font-weight: 600;
}

.teams-video-overlay .teams-video-label {
    position: absolute;
    left: 8px;
    bottom: 8px;
    background: rgba(0, 0, 0, 0.6);
    color: #fff;
    font-size: 12px;
    padding: 3px 8px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
/* Mic-state badge inside the name label. An UNMUTED mic is hidden until the
   tile is hovered (keeps the grid clean + is the future host-mute hotspot); a
   MUTED mic is always shown, tinted red. JS swaps the <i> between
   fa-microphone / fa-microphone-slash and toggles .teams-video-tile--muted. */
.teams-video-overlay .teams-video-mic {
    display: none;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    line-height: 1;
    border: 0;
    padding: 0;
    color: inherit;
    background: transparent;
    cursor: pointer;
}
.teams-video-overlay .teams-video-tile:hover .teams-video-mic,
.teams-video-overlay .teams-video-tile--muted .teams-video-mic {
    display: inline-flex;
}
.teams-video-overlay .teams-video-tile--muted .teams-video-mic {
    color: #f0a5a5;
}

/* LiveKit's active-speaker signal is transient and can include several
   participants at once. Keep this frame distinct from the yellow hand state. */
.teams-video-overlay .teams-video-tile--speaking::before {
    content: "";
    position: absolute;
    inset: 0;
    border: 3px solid #4f8cff;
    border-radius: inherit;
    pointer-events: none;
    z-index: 7;
    animation: teams-video-speaking-pulse 0.9s ease-in-out infinite alternate;
}

@keyframes teams-video-speaking-pulse {
    from {
        box-shadow: inset 0 0 0 rgba(79, 140, 255, 0.15);
    }
    to {
        box-shadow: inset 0 0 24px rgba(79, 140, 255, 0.38);
    }
}

.teams-video-overlay .teams-video-reactions {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.teams-video-overlay .teams-video-reaction-picker {
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%);
    display: grid;
    /* Fill downward so 19 quick reactions + the library trigger form four full
       columns and a fifth four-control column. */
    grid-template-columns: repeat(5, 34px);
    grid-template-rows: repeat(4, 34px);
    grid-auto-flow: column;
    gap: 4px;
    padding: 7px;
    border: 1px solid #3a4250;
    border-radius: 10px;
    background: #171b23;
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.42);
    z-index: 20;
}
.teams-video-overlay .teams-video-reaction-picker[hidden] {
    display: none;
}
.teams-video-overlay .teams-video-reaction-picker button {
    width: 34px;
    height: 34px;
    border: 0;
    border-radius: 7px;
    background: transparent;
    font-size: 20px;
    cursor: pointer;
}
.teams-video-overlay .teams-video-reaction-picker button:hover {
    background: #2a3140;
}
.teams-video-overlay .teams-video-reaction-picker__library-icon {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    opacity: 0.55;
    color: white;
}
.teams-video-overlay .teams-video-reaction-picker__library-icon .fa-face-smile {
    font-size: 20px;
}
.teams-video-overlay .teams-video-reaction-picker__library-icon .fa-plus {
    position: absolute;
    right: -3px;
    bottom: -2px;
    font-size: 10px;
    color: #cdd5e1;
    text-shadow: 0 1px 2px #171b23;
}
.teams-video-overlay .teams-emoji {
    position: absolute;
    bottom: calc(100% + 10px);
    right: 0;
    z-index: 40;
    width: 320px;
    max-width: min(320px, calc(100vw - 32px));
    background: #171b23;
    color: #e6e9ef;
    border: 1px solid #3a4250;
    border-radius: 12px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.28);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.teams-video-overlay .teams-emoji__tabs {
    display: flex;
    gap: 4px;
    padding: 8px 10px 0;
}
.teams-video-overlay .teams-emoji__tab {
    font-size: 12px;
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 8px;
    color: #9aa3b2;
    cursor: default;
}
.teams-video-overlay .teams-emoji__tab--active {
    background: rgba(79, 140, 255, 0.14);
    color: #84b1ff;
}
.teams-video-overlay .teams-emoji__search {
    margin: 8px 10px;
    padding: 7px 10px;
    border-radius: 8px;
    border: 1px solid #2a2f3a;
    background: #11141a;
    color: inherit;
    font-size: 13px;
    outline: none;
}
.teams-video-overlay .teams-emoji__search:focus {
    border-color: #4f8cff;
}
.teams-video-overlay .teams-emoji__cats {
    display: flex;
    gap: 2px;
    padding: 0 8px 6px;
    border-bottom: 1px solid #2a2f3a;
    overflow-x: auto;
}
.teams-video-overlay .teams-emoji__cat {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 17px;
    padding: 3px 5px;
    border-radius: 6px;
    line-height: 1;
}
.teams-video-overlay .teams-emoji__cat:hover {
    background: rgba(79, 140, 255, 0.12);
}
.teams-video-overlay .teams-emoji__grid {
    padding: 6px 8px 10px;
    overflow-y: auto;
    max-height: 240px;
    display: flex;
    flex-direction: column;
}
.teams-video-overlay .teams-emoji__cat-label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #9aa3b2;
    padding: 8px 4px 4px;
    position: sticky;
    top: 0;
    background: #171b23;
}
.teams-video-overlay .teams-emoji__cat-grid {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    gap: 2px;
}
.teams-video-overlay .teams-emoji__item {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 20px;
    line-height: 1;
    padding: 4px 0;
    border-radius: 8px;
    aspect-ratio: 1;
    text-align: center;
    width: auto;
    height: auto;
}
.teams-video-overlay .teams-emoji__item:hover {
    background: rgba(79, 140, 255, 0.12);
}
.teams-video-overlay .teams-emoji__empty {
    grid-column: 1 / -1;
    text-align: center;
    color: #9aa3b2;
    font-size: 13px;
    padding: 20px 0;
}
.teams-video-overlay .teams-video-reaction-pop {
    position: absolute;
    left: 50%;
    bottom: 28%;
    z-index: 10;
    font-size: clamp(28px, 4vw, 52px);
    pointer-events: none;
    animation: teams-video-reaction-float 4s ease-out forwards;
}
@keyframes teams-video-reaction-float {
    0% {
        opacity: 0;
        transform: translate(-50%, 18px) scale(0.7);
    }
    18% {
        opacity: 1;
        transform: translate(-50%, 0) scale(1);
    }
    100% {
        opacity: 0;
        transform: translate(-50%, -95px) scale(1.1);
    }
}

/* Raise-hand: a golden badge (top-left) with the queue number, plus a matching
   tile highlight so raised hands are obvious. Driven by _refreshHands(). */
.teams-video-overlay .teams-video-hand {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 6;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 8px;
    border-radius: 999px;
    background: #f5b301;
    color: #1a1d24;
    font-size: 12px;
    font-weight: 700;
    line-height: 1;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}
.teams-video-overlay .teams-video-hand[hidden] {
    display: none;
}
.teams-video-overlay .teams-video-hand__n::before {
    content: "#";
    opacity: 0.7;
}
/* Yellow frame around a raised-hand tile. Drawn as a ::after overlay (not
   outline/inset-shadow) so it paints reliably ON TOP of the <video> and follows
   the tile's rounded corners. */
.teams-video-overlay .teams-video-tile--hand::after {
    content: "";
    position: absolute;
    inset: 0;
    border: 3px solid #f5b301;
    border-radius: inherit;
    pointer-events: none;
    z-index: 7;
}
/* Active state on a control button while our hand is up (or screen sharing):
   yellow icon + text + border only (no filled background). */
.teams-video-overlay .teams-video-ctrl.is-on {
    background: transparent;
    border-color: #f5b301;
    color: #f5b301;
}
.teams-video-overlay .teams-video-ctrl.is-on:hover {
    background: rgba(245, 179, 1, 0.12);
}

/* AI toggle "connected" state — green icon + text, on its OWN class (.is-ai-on)
   so it never bleeds into the yellow hand/screen-share active state (both share
   .teams-video-ctrl). */
.teams-video-overlay .teams-video-ctrl.is-ai-on {
    color: #7ee6a2;
}
.teams-video-overlay .teams-video-ctrl.is-ai-on i {
    color: #7ee6a2;
}
.teams-video-overlay .teams-video-ctrl[data-cam] {
    position: relative;
}
/* This dot is intentionally independent of the dismissible recording notice:
   it tells every caller that a watchable call recording is still active. */
.teams-video-overlay .teams-video-ctrl[data-cam].is-video-recording::after {
    content: '';
    position: absolute;
    top: 7px;
    right: 7px;
    width: 8px;
    height: 8px;
    border: 1px solid #fff;
    border-radius: 50%;
    background: #ef4444;
    box-shadow: 0 0 0 1px rgba(80, 0, 0, 0.45);
}
.teams-video-overlay .teams-video-recording-dot {
    color: #ff5b5b;
}

/* Spotlight: click a tile to enlarge one participant so adaptiveStream pulls
   its full 720p layer (small grid tiles otherwise receive only ~360p). The
   spotlit tile takes a full row on top; the rest wrap into a thumbnail strip
   below. Click the spotlit tile (or any thumbnail) to switch/exit. No DOM or
   track changes — purely element sizing that adaptiveStream reacts to. */
.teams-video-overlay .teams-video-tile {
    cursor: pointer;
}
.teams-video-overlay .teams-video-grid.has-spotlight {
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
}
.teams-video-overlay .teams-video-grid.has-spotlight .teams-video-tile {
    flex: 0 0 clamp(120px, 15vw, 200px);
    width: clamp(120px, 15vw, 200px);
    height: auto;
    min-height: 0;
}
.teams-video-overlay
    .teams-video-grid.has-spotlight
    .teams-video-tile.is-spotlight {
    flex: 1 1 100%;
    width: 100%;
    order: -1;
    aspect-ratio: auto;
    height: min(70vh, calc(100% - 130px));
    min-height: 240px;
    cursor: zoom-out;
    border-color: #4f8cff;
}
.teams-video-overlay
    .teams-video-grid.has-spotlight
    .teams-video-tile.screen-share.is-spotlight {
    position: relative;
}

/* Connecting overlay — shown over the (black) stage until media arrives. */
.teams-video-overlay .teams-video-loading {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    color: #cdd3dc;
    font-size: 14px;
    background: #0b0d11;
}
.teams-video-overlay .teams-video-loading[hidden] {
    display: none;
}
.teams-video-overlay .teams-video-spinner {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 3px solid rgba(255, 255, 255, 0.18);
    border-top-color: #4f8cff;
    animation: teams-spin 0.8s linear infinite;
}
/* The stage is the positioning context for the loading overlay. */
.teams-video-overlay .teams-video-stage {
    position: relative;
}

/* Icon controls: icon on top, label underneath. */
.teams-video-overlay .teams-video-controls {
    display: flex;
    gap: 12px;
    justify-content: center;
    padding: 14px;
    border-top: 1px solid #2a2f3a;
    flex-shrink: 0;
}
.teams-video-overlay .teams-video-ctrl {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    min-width: 50px;
    padding: 8px 10px;
    cursor: pointer;
    border: 1px solid #2a2f3a;
    border-radius: 10px;
    background: #252a34;
    color: #e6e9ef;
    font-size: 9px;
    font-weight: 600;
    line-height: 1;
}
.teams-video-overlay .teams-video-ctrl i {
    font-size: 12px;
}
.teams-video-overlay .teams-video-ctrl:hover {
    background: rgba(255, 255, 255, 0.08);
}
.teams-video-overlay .teams-video-ctrl.is-off {
    background: #3a2422;
    border-color: #e5484d;
    color: #f0a5a5;
}
.teams-video-overlay .teams-video-ctrl--danger {
    background: #e5484d;
    border-color: #e5484d;
    color: #fff;
}
.teams-video-overlay .teams-video-ctrl--danger:hover {
    background: #d33f43;
}

/* Desktop: the "More" overflow toggle is not needed (every control fits inline),
   and the tray is a transparent wrapper so its children (Share / React / Connect
   AI) lay out inline exactly as before. The mobile media query overrides both. */
.teams-video-overlay .teams-video-more-toggle {
    display: none;
}
.teams-video-overlay .teams-video-more-tray {
    display: contents;
}

/* Camera stays a familiar primary action; its adjacent chevron exposes optional
   effects without making a first-use camera toggle ambiguous. */
.teams-video-overlay .teams-video-camera-control {
    position: relative;
    display: flex;
}
.teams-video-overlay .teams-video-share-control {
    position: relative;
    display: flex;
}
.teams-video-overlay .teams-video-share-control .teams-video-ctrl {
    border-radius: 10px 0 0 10px;
}
.teams-video-overlay .teams-video-share-menu-toggle {
    width: 20px;
    border: 0;
    border-left: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 0 10px 10px 0;
    background: #252a34;
    color: #e6e9ef;
    cursor: pointer;
}
.teams-video-overlay .teams-video-share-menu-toggle:hover {
    background: #323846;
}
.teams-video-overlay .teams-video-share-menu {
    position: absolute;
    z-index: 12;
    bottom: calc(100% + 9px);
    left: 0;
    width: 245px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
    border: 1px solid #394150;
    border-radius: 10px;
    background: #1d222c;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
    color: #9aa3b2;
    font-size: 12px;
    line-height: 1.35;
}
.teams-video-overlay .teams-video-share-menu[hidden] {
    display: none;
}
.teams-video-overlay .teams-video-share-menu button {
    border: 1px solid #465166;
    border-radius: 7px;
    background: #293241;
    color: #e6e9ef;
    padding: 7px 8px;
    text-align: left;
    cursor: pointer;
}
.teams-video-overlay .teams-video-screen-share-tip { color: #cbd2dc; }
.teams-video-overlay .teams-video-timer { position: relative; display: inline-flex; }
.teams-video-overlay .teams-video-timer-menu {
    position: absolute;
    z-index: 12;
    bottom: calc(100% + 9px);
    left: 50%;
    transform: translateX(-50%);
    width: 250px;
    display: flex;
    flex-direction: column;
    gap: 9px;
    padding: 12px;
    border: 1px solid #394150;
    border-radius: 10px;
    background: #1d222c;
    box-shadow: 0 10px 28px rgba(0, 0, 0, .45);
    color: #9aa3b2;
    font-size: 12px;
}
.teams-video-overlay .teams-video-timer-menu[hidden] { display: none; }
.teams-video-overlay [data-timer-display] { color: #fff; font: 700 28px/1 ui-monospace, SFMono-Regular, Menlo, monospace; text-align: center; }
.teams-video-overlay .teams-video-timer-inputs,
.teams-video-overlay .teams-video-timer-actions { display: flex; gap: 8px; }
.teams-video-overlay .teams-video-timer-inputs label { display: grid; flex: 1; gap: 4px; }
.teams-video-overlay .teams-video-timer-inputs input { min-width: 0; border: 1px solid #465166; border-radius: 6px; background: #151922; color: #fff; padding: 7px; }
.teams-video-overlay .teams-video-timer-actions button { flex: 1; border: 0; border-radius: 7px; background: #9fc1ff; color: #10254c; padding: 7px; font-weight: 700; cursor: pointer; }
.teams-video-overlay .teams-video-timer-actions button[data-timer-stop] { background: #394150; color: #fff; }
.teams-video-overlay .teams-video-camera-control .teams-video-ctrl {
    border-radius: 10px 0 0 10px;
}
.teams-video-overlay .teams-video-camera-menu-toggle {
    width: 25px;
    border: 0;
    border-left: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 0 10px 10px 0;
    background: #252a34;
    color: #e6e9ef;
    cursor: pointer;
}
.teams-video-overlay .teams-video-camera-menu-toggle:hover {
    background: #323846;
}
.teams-video-overlay .teams-video-camera-menu {
    position: absolute;
    z-index: 12;
    bottom: calc(100% + 9px);
    left: 0;
    width: 270px;
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 12px;
    border: 1px solid #394150;
    border-radius: 10px;
    background: #1d222c;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
    color: #e6e9ef;
    font-size: 12px;
}
.teams-video-overlay .teams-video-camera-menu[hidden] {
    display: none;
}
.teams-video-overlay .teams-video-camera-menu button {
    display: flex;
    align-items: center;
    gap: 8px;
    border: 0;
    border-radius: 7px;
    padding: 9px;
    background: #29303c;
    color: #e6e9ef;
    text-align: left;
    cursor: pointer;
}
.teams-video-overlay .teams-video-camera-menu button:hover,
.teams-video-overlay .teams-video-camera-menu button.is-active {
    background: #2d5f84;
}
.teams-video-overlay .teams-video-camera-menu button.is-loading {
    opacity: 0.65;
    pointer-events: none;
}
.teams-video-overlay .teams-video-camera-menu__strength {
    display: flex;
    flex-direction: column;
    gap: 5px;
    color: #d9dee7;
}
.teams-video-overlay .teams-video-camera-menu__strength > span {
    display: flex;
    justify-content: space-between;
}
.teams-video-overlay .teams-video-camera-menu__strength output {
    color: #82b6ff;
    font-variant-numeric: tabular-nums;
}
.teams-video-overlay .teams-video-camera-menu__strength input {
    width: 100%;
    accent-color: #4f8cff;
    cursor: pointer;
}
.teams-video-overlay .teams-video-camera-menu__hint {
    color: #9aa3b2;
    line-height: 1.35;
}
.teams-video-overlay .teams-video-camera-menu__backgrounds {
    display: flex;
    flex-direction: column;
    gap: 7px;
    color: #d9dee7;
}
.teams-video-overlay [data-custom-background-list] {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 7px;
}
.teams-video-overlay .teams-video-camera-menu__background {
    aspect-ratio: 16 / 9;
    overflow: hidden;
    padding: 0;
}
.teams-video-overlay .teams-video-camera-menu__background-item {
    position: relative;
}
/* "None" — back to the plain camera. Same 16:9 card as the images. */
.teams-video-overlay .teams-video-camera-menu__background--none {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    width: 100%;
    background: rgba(255, 255, 255, 0.06);
    color: #d9dee7;
    font-size: 11px;
}
.teams-video-overlay .teams-video-camera-menu__background img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.teams-video-overlay .teams-video-camera-menu__background-remove {
    position: absolute;
    top: 3px;
    right: 3px;
    display: grid;
    width: 23px;
    height: 23px;
    padding: 0;
    place-items: center;
    border: 1px solid rgba(255, 255, 255, 0.28);
    border-radius: 6px;
    background: rgba(20, 24, 31, 0.88);
    color: #fff;
    opacity: 0;
}
.teams-video-overlay .teams-video-camera-menu__background-item:hover .teams-video-camera-menu__background-remove,
.teams-video-overlay .teams-video-camera-menu__background-item:focus-within .teams-video-camera-menu__background-remove {
    opacity: 1;
}
.teams-video-overlay .teams-video-camera-menu__background-remove:hover {
    background: #a52c35;
}
.teams-video-overlay .teams-video-camera-background-preview {
    position: absolute;
    z-index: 13;
    left: calc(100% + 10px);
    bottom: 0;
    width: 320px;
    overflow: hidden;
    border: 1px solid #4b566b;
    border-radius: 10px;
    background: #1d222c;
    box-shadow: 0 12px 30px rgba(0, 0, 0, 0.55);
}
.teams-video-overlay .teams-video-camera-background-preview[hidden] {
    display: none;
}
.teams-video-overlay .teams-video-camera-background-preview img {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
}
.teams-video-overlay .teams-video-camera-background-preview span {
    display: block;
    padding: 8px 10px;
    overflow: hidden;
    color: #e6e9ef;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-video-overlay .teams-video-camera-menu__upload,
.teams-video-overlay .teams-video-screen-audio {
    display: flex;
    align-items: center;
    gap: 7px;
    cursor: pointer;
}
.teams-video-overlay .teams-video-camera-menu__upload {
    padding: 8px;
    border-radius: 7px;
    background: #29303c;
}
.teams-video-overlay .teams-video-screen-audio {
    padding: 4px 8px;
    color: #d9dee7;
    font-size: 12px;
}

/* The screen sharer alone gets this compact presentation toolbox; annotation
   data is rendered as a canvas overlay on every participant's screen tile. */
.teams-video-overlay .teams-video-annotations {
    position: relative;
}
.teams-video-overlay .teams-video-annotation-menu {
    position: absolute;
    z-index: 12;
    bottom: calc(100% + 9px);
    left: 0;
    width: 218px;
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 12px;
    border: 1px solid #394150;
    border-radius: 10px;
    background: #1d222c;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
    color: #e6e9ef;
    font-size: 12px;
}
.teams-video-overlay .teams-video-annotation-menu[hidden] {
    display: none;
}
.teams-video-overlay .teams-video-annotation-menu button {
    display: flex;
    align-items: center;
    gap: 8px;
    border: 0;
    border-radius: 7px;
    padding: 9px;
    background: #29303c;
    color: #e6e9ef;
    text-align: left;
    cursor: pointer;
}
.teams-video-overlay .teams-video-annotation-menu button:hover,
.teams-video-overlay .teams-video-annotation-menu button.is-active {
    background: #2d5f84;
}
.teams-video-overlay .teams-video-annotation-menu [data-annotation-stop] {
    color: #ffb1b1;
}
.teams-video-overlay .teams-video-annotation-menu > span {
    color: #9aa3b2;
    line-height: 1.35;
}

/* Native Fullscreen API keeps browser chrome out of the way while preserving
   the existing call layout and controls. */
.teams-video-modal:fullscreen {
    width: 100vw;
    height: 100vh;
    max-width: none;
    border: 0;
    border-radius: 0;
}
.teams-video-modal:-webkit-full-screen {
    width: 100vw;
    height: 100vh;
    max-width: none;
    border: 0;
    border-radius: 0;
}

/* In-call side chat. */
.teams-video-overlay .teams-video-chat {
    position: relative;
    width: 330px;
    min-width: 260px;
    max-width: 620px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    border-left: 1px solid #2a2f3a;
    background: #14171d;
}
/* The [hidden] attribute must win over display:flex, or the panel can never be
   closed (default-closed + the toggle/× buttons rely on this). */
.teams-video-overlay .teams-video-chat[hidden] {
    display: none;
}
.teams-video-overlay .teams-video-chat__resize {
    position: absolute;
    z-index: 4;
    top: 0;
    bottom: 0;
    left: -5px;
    width: 10px;
    cursor: col-resize;
    touch-action: none;
}
.teams-video-chat-resizing,
.teams-video-chat-resizing * {
    cursor: col-resize !important;
    user-select: none !important;
}
.teams-video-overlay .teams-video-chat__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 11px 14px;
    border-bottom: 1px solid #2a2f3a;
    font-weight: 600;
    font-size: 13px;
    flex-shrink: 0;
}
.teams-video-overlay .teams-video-chat__close {
    border: none;
    background: none;
    color: #9aa3b2;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}
.teams-video-overlay .teams-video-chat__list {
    flex: 1;
    overflow-y: auto;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 9px;
    padding-bottom: 40px;
}
.teams-video-overlay .teams-video-chat__msg {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-width: 92%;
    align-self: flex-start;
}
.teams-video-overlay .teams-video-chat__msg.me {
    align-self: flex-end;
    text-align: right;
}
.teams-video-overlay .teams-video-chat__meta {
    display: flex;
    align-items: baseline;
    gap: 6px;
}
.teams-video-overlay .teams-video-chat__msg.me .teams-video-chat__meta {
    justify-content: flex-end;
}
.teams-video-overlay .teams-video-chat__who {
    font-size: 10.5px;
    color: #9aa3b2;
}
.teams-video-overlay .teams-video-chat__time {
    font-size: 10px;
    color: #778191;
}
.teams-video-overlay .teams-video-chat__msg.agent .teams-video-chat__who {
    color: #b79be6;
}
.teams-video-overlay .teams-video-chat__text {
    background: #252a34;
    color: #e6e9ef;
    padding: 6px 10px;
    border-radius: 10px;
    font-size: 13px;
    word-break: break-word;
    display: inline-block;
    line-height: 1.38;
}
.teams-video-overlay .teams-video-chat__msg.me .teams-video-chat__text {
    background: #2d5f84;
    color: #fff;
}
/* Retracted message inside the in-call chat — same tombstone treatment as the
   main transcript (muted, italic, dashed), so a deleted message never just
   vanishes mid-call. */
.teams-video-overlay .teams-video-chat__msg.deleted .teams-video-chat__text {
    background: transparent;
    border: 1px dashed #4a5260;
    color: #9aa3b2;
    font-style: italic;
}
.teams-video-overlay .teams-video-chat__text p {
    margin: 0 0 7px;
}
.teams-video-overlay .teams-video-chat__text p:last-child {
    margin-bottom: 0;
}
.teams-video-overlay .teams-video-chat__text a {
    color: #9dd3ff;
    text-decoration: underline;
}
.teams-video-overlay .teams-video-chat__text table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    border-collapse: collapse;
    font-size: 11px;
}
.teams-video-overlay .teams-video-chat__text th,
.teams-video-overlay .teams-video-chat__text td {
    border: 1px solid #4a5260;
    padding: 4px 6px;
    text-align: left;
}

.teams-video-overlay .teams-video-chat__actions {
    position: absolute;
    z-index: 3;
    bottom: calc(100% + -15px);
    left: 20px;
    display: none;
    gap: 2px;
    padding: 2px 4px;
    background: #252a34;
    border: 1px solid #3a4250;
    border-radius: 8px;
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.28);
    white-space: nowrap;
}
.teams-video-overlay
    .teams-video-chat__msg.has-reactions
    .teams-video-chat__actions {
    bottom: calc(100% + 30px);
}
.teams-video-overlay .teams-video-chat__msg.me .teams-video-chat__actions {
    right: 0;
    left: auto;
}
.teams-video-overlay .teams-video-chat__msg:hover .teams-video-chat__actions,
.teams-video-overlay
    .teams-video-chat__msg:focus-within
    .teams-video-chat__actions {
    display: flex;
}
.teams-video-overlay .teams-video-chat__actions button {
    padding: 2px 3px;
    border: 0;
    background: transparent;
    color: inherit;
    font-size: 13px;
}

.teams-video-overlay .teams-video-chat__actions button:hover {
    color: #9dd3ff;
    background: #313946;
    border-radius: 4px;
    cursor: pointer;
}

.teams-video-overlay .teams-video-chat__reactions {
    position: absolute;
    z-index: 2;
    bottom: calc(100% + 4px);
    left: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}
.teams-video-overlay .teams-video-chat__msg.me .teams-video-chat__reactions {
    right: 0;
    left: auto;
    justify-content: flex-end;
}
.teams-video-overlay .teams-video-chat__reaction {
    padding: 2px 6px;
    border: 1px solid #46505f;
    border-radius: 999px;
    background: #252a34;
    color: #e6e9ef;
    font-size: 11px;
}
.teams-video-overlay .teams-video-chat__reaction.is-mine {
    border-color: #4f8cff;
    background: #1c3956;
}
.teams-video-overlay .teams-video-chat__composer {
    position: relative;
    display: flex;
    gap: 8px;
    padding: 10px;
    border-top: 1px solid #2a2f3a;
    flex-shrink: 0;
    flex-wrap: wrap;
}
.teams-video-overlay .teams-video-chat__composer.is-file-drop {
    outline: 2px dashed #4f8cff;
    outline-offset: -5px;
    background: rgba(79, 140, 255, 0.1);
}
.teams-video-overlay .teams-video-chat__input-wrap {
    position: relative;
    display: flex;
    flex: 1 1 100%;
    min-width: 0;
}
.teams-video-overlay .teams-video-chat__composer textarea {
    width: 100%;
    min-width: 0;
    background: #11141a;
    border: 1px solid #2a2f3a;
    color: #e6e9ef;
    border-radius: 8px;
    padding: 8px 42px 8px 44px;
    font: inherit;
    font-size: 13px;
    line-height: 1.35;
    resize: none;
    max-height: 90px;
    min-height: 36px;
}
.teams-video-overlay .teams-video-chat__input-wrap .mention-input-shell {
    position: relative;
    display: grid;
    flex: 1;
    min-width: 0;
    background: #11141a;
    border-radius: 8px;
}
.teams-video-overlay
    .teams-video-chat__composer
    .mention-input-shell
    > textarea,
.teams-video-overlay
    .teams-video-chat__composer
    .mention-input-shell
    > .mention-input-highlight {
    grid-area: 1 / 1;
    min-width: 0;
}
.teams-video-overlay
    .teams-video-chat__composer
    .mention-input-shell
    > textarea {
    position: relative;
    z-index: 1;
    background: transparent;
    color: #e6e9ef;
    -webkit-text-fill-color: currentColor;
    caret-color: #e6e9ef;
}
.teams-video-overlay .teams-video-chat__composer .mention-input-highlight {
    z-index: 2;
    pointer-events: none;
    overflow: hidden;
    color: transparent;
    white-space: pre-wrap;
    word-break: break-word;
    padding: 8px 42px 8px 44px;
    border: 1px solid transparent;
    line-height: 1.35;
    box-sizing: border-box;
}
.teams-video-overlay
    .teams-video-chat__composer
    .mention-input-highlight__mention {
    color: #6caeff;
}
.teams-video-overlay .teams-video-chat__composer button {
    border: none;
    background: #2d5f84;
    color: #fff;
    border-radius: 8px;
    cursor: pointer;
}
.teams-video-overlay .teams-video-chat__input-wrap > button {
    position: absolute;
    z-index: 2;
    top: 50%;
    width: 30px;
    height: 30px;
    padding: 0;
    transform: translateY(-50%);
}
.teams-video-overlay .teams-video-chat__input-wrap > [data-chat-emoji] {
    left: 4px;
    background: transparent;
    color: #aeb7c4;
}
.teams-video-overlay .teams-video-chat__input-wrap > button[type="submit"] {
    right: 4px;
}
.teams-video-overlay .teams-video-chat__input-wrap > [data-chat-emoji]:hover,
.teams-video-overlay
    .teams-video-chat__input-wrap
    > [data-chat-emoji].teams-emoji-btn--active {
    background: #252a34;
    color: #fff;
}
.teams-video-overlay .teams-video-chat__attachments {
    display: flex;
    flex: 0 0 100%;
    flex-wrap: wrap;
    gap: 5px;
}
.teams-video-overlay .teams-video-chat__attachment {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 100%;
    padding: 4px 6px;
    border-radius: 6px;
    background: #252a34;
    color: #dce1e9;
    font-size: 11px;
}
.teams-video-overlay .teams-video-chat__attachment--error {
    color: #ffb1b1;
}
.teams-video-overlay .teams-video-chat__attachment button {
    padding: 0 3px;
    background: transparent;
    color: inherit;
    font-size: 15px;
}
.teams-video-overlay .teams-video-chat__files {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin-top: 2px;
}
.teams-video-overlay .teams-video-chat__files a {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 190px;
    overflow: hidden;
    color: #cfe8ff;
    font-size: 12px;
    text-decoration: none;
    word-break: break-word;
}
.teams-video-overlay .teams-video-chat__files img {
    display: block;
    max-width: 150px;
    max-height: 110px;
    border-radius: 7px;
}

.teams-video-overlay .teams-video-chat__reply {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    flex: 0 0 100%;
    padding: 5px 7px;
    border-left: 2px solid #4f8cff;
    background: #202631;
    color: #cbd2dc;
    font-size: 11px;
    max-width: 100%;
}
.teams-video-overlay .teams-video-chat__reply span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-video-overlay .teams-video-chat__reply button {
    padding: 0 4px;
    background: transparent;
    color: #cbd2dc;
    font-size: 17px;
    line-height: 1;
}

/* The in-call composer reuses the Teams picker, but lives outside .teams-panel. */
.teams-video-overlay .teams-video-chat__input-wrap .teams-emoji {
    position: absolute;
    left: 0;
    bottom: calc(100% + 8px);
    z-index: 40;
    width: 320px;
    max-width: calc(100vw - 32px);
    background: #202631;
    color: #e6e9ef;
    border: 1px solid #3a4250;
    border-radius: 12px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.teams-video-overlay .teams-video-chat__input-wrap .teams-emoji__tabs {
    display: flex;
    gap: 4px;
    padding: 8px 10px 0;
}
.teams-video-overlay .teams-video-chat__input-wrap .teams-emoji__tab {
    padding: 4px 10px;
    background: transparent;
    color: #aeb7c4;
    font-size: 12px;
    font-weight: 600;
}
.teams-video-overlay .teams-video-chat__input-wrap .teams-emoji__tab--active {
    background: #293b4d;
    color: #9dd3ff;
}
.teams-video-overlay .teams-video-chat__input-wrap .teams-emoji__search {
    margin: 8px 10px;
    padding: 7px 10px;
    border: 1px solid #3a4250;
    border-radius: 8px;
    background: #14171d;
    color: inherit;
    font-size: 13px;
    outline: none;
}
.teams-video-overlay .teams-video-chat__input-wrap .teams-emoji__cats {
    display: flex;
    gap: 2px;
    padding: 0 8px 6px;
    border-bottom: 1px solid #3a4250;
    overflow-x: auto;
}
.teams-video-overlay .teams-video-chat__input-wrap .teams-emoji__cat {
    padding: 3px 5px;
    background: transparent;
    color: inherit;
    font-size: 17px;
    line-height: 1;
}
.teams-video-overlay .teams-video-chat__input-wrap .teams-emoji__grid {
    max-height: 240px;
    padding: 6px 8px 10px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
}
.teams-video-overlay .teams-video-chat__input-wrap .teams-emoji__cat-label {
    padding: 8px 4px 4px;
    background: #202631;
    color: #9aa3b2;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.teams-video-overlay .teams-video-chat__input-wrap .teams-emoji__cat-grid {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    gap: 2px;
}
.teams-video-overlay .teams-video-chat__input-wrap .teams-emoji__item {
    width: auto;
    height: auto;
    padding: 4px 0;
    background: transparent;
    color: inherit;
    font-size: 20px;
    line-height: 1;
}
.teams-video-overlay .teams-video-chat__input-wrap .teams-emoji__item:hover,
.teams-video-overlay .teams-video-chat__input-wrap .teams-emoji__cat:hover {
    background: #293b4d;
}
.teams-video-overlay .teams-video-chat__input-wrap .mention-dropdown {
    display: none;
    position: absolute;
    right: 0;
    bottom: 100%;
    left: 0;
    z-index: 1000;
    max-height: 220px;
    margin-bottom: 8px;
    padding: 4px 0;
    overflow-y: auto;
    background: #202631;
    color: #e6e9ef;
    border: 1px solid #3a4250;
    border-radius: 10px;
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.4);
}
.teams-video-overlay .teams-video-chat__input-wrap .mention-dropdown__item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    cursor: pointer;
    font-size: 13px;
    line-height: 1.4;
}
.teams-video-overlay
    .teams-video-chat__input-wrap
    .mention-dropdown__item:hover,
.teams-video-overlay
    .teams-video-chat__input-wrap
    .mention-dropdown__item--active {
    background: #293b4d;
}
.teams-video-overlay .teams-video-chat__input-wrap .mention-dropdown__name {
    display: flex;
    align-items: center;
    gap: 6px;
    color: #e6e9ef;
    font-weight: 600;
    white-space: nowrap;
}
.teams-video-overlay .teams-video-chat__input-wrap .mention-dropdown__handle {
    color: #9aa3b2;
    font-size: 11px;
}
.teams-video-overlay .teams-video-chat__input-wrap .mention-dropdown__badge {
    padding: 1px 6px;
    border-radius: 4px;
    background: #344152;
    color: #cbd2dc;
    font-size: 11px;
}

/* ── Minimized call: the whole overlay collapses to a small floating, draggable
      thumbnail so the user can work elsewhere while staying on the call. The
      LiveKit room keeps running (JS only toggles this class). The backdrop goes
      click-through so the page behind stays interactive; only the thumbnail
      itself captures pointer events. ─────────────────────────────────────────── */
.teams-video-overlay--minimized {
    background: transparent;
    pointer-events: none;
    display: block; /* opt out of the centering flex so fixed positioning wins */
}
.teams-video-overlay--minimized .teams-video-modal {
    pointer-events: auto;
    position: fixed;
    left: auto;
    top: auto;
    right: 20px;
    bottom: 20px;
    width: 300px;
    height: auto;
    min-height: 0;
    border-radius: 12px;
    box-shadow: 0 14px 40px rgba(0, 0, 0, 0.55);
    cursor: grab;
    touch-action: none; /* let touch-drag move the window instead of scrolling */
}
.teams-video-overlay--minimized .teams-video-modal.is-dragging {
    cursor: grabbing;
    user-select: none;
}
/* Buttons inside the thumbnail stay clickable (drag ignores them). */
.teams-video-overlay--minimized .teams-video-modal button {
    cursor: pointer;
}
/* Header stays (drag handle + restore/close); trim the non-essentials. */
.teams-video-overlay--minimized .teams-video-header {
    padding: 8px 10px;
    cursor: grab;
}
.teams-video-overlay--minimized .teams-video-status,
.teams-video-overlay--minimized .teams-video-chattoggle,
.teams-video-overlay--minimized .teams-video-controls,
.teams-video-overlay--minimized .teams-video-chat,
.teams-video-overlay--minimized .teams-video-ai-banner {
    display: none;
}
.teams-video-overlay--minimized .teams-video-title {
    margin-right: auto;
    font-size: 12.5px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-video-overlay--minimized .teams-video-duration { display: none; }
/* Shrink the stage to a compact 16:9 preview; the grid still shows live video. */
.teams-video-overlay--minimized .teams-video-main {
    min-height: 0;
}
.teams-video-overlay--minimized .teams-video-stage {
    height: 169px;
}
.teams-video-overlay--minimized .teams-video-grid {
    padding: 4px;
    gap: 4px;
    overflow: hidden; /* no scrollbar: the preview must not pan sideways */
    /* The desktop 360px column minimum is wider than this 300px window and pushed
       the tile off-centre; one column that can shrink keeps it centred. */
    grid-template-columns: minmax(0, 1fr);
}
.teams-video-overlay--minimized .teams-video-tile {
    min-height: 0;
}
/* Only "Expand to normal size" in the thumbnail; full screen lives in the
   header of the normal-size window. */
.teams-video-overlay--minimized .teams-video-fullscreen {
    display: none;
}
.teams-video-overlay--minimized .teams-video-label {
    font-size: 10px;
    padding: 2px 5px;
}
/* Keep the self-view PiP from covering the whole tiny window. */
.teams-video-overlay--minimized
    .teams-video-grid.has-remotes
    .teams-video-tile.local {
    width: 34%;
    right: 8px;
    bottom: 8px;
}

/* Header roster: participant chips (dot + name) + an always-visible people pill. */
.teams-panel .teams-conversation__participants {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 5px 10px;
    font-size: 12px;
    color: var(--tm-text-3);
    min-width: 0;
}
/* Desktop: transparent wrapper — the name chips + "+N more" behave as direct
   children of the wrapping row, exactly as before. Mobile overrides this to a real
   truncating box (see the media query) so the people pill stays on one line. */
.teams-panel .teams-conversation__pnames {
    display: contents;
}
.teams-panel .teams-participant-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: var(--tm-text-2);
    white-space: nowrap;
}
.teams-panel .teams-people-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    cursor: pointer;
    border: 1px solid var(--tm-border);
    background: var(--tm-white);
    color: var(--tm-text-2);
    border-radius: 999px;
    padding: 2px 9px;
    font-size: 12px;
    font-weight: 600;
    font-family: inherit;
    line-height: 1.6;
    transition: all var(--tm-t);
}
.teams-panel .teams-people-pill:hover {
    border-color: var(--tm-accent);
    color: var(--tm-accent);
}
.teams-panel .teams-people-pill i {
    font-size: 11px;
}

/* Presence dot — shared by the header roster, the participants modal, and (as
 * .teams-presence-badge below) every avatar in the product.
 *
 * COLOUR IS NOT ENOUGH. Once people can CHOOSE a status, several states share a
 * colour — busy and do-not-disturb are both red, away and be-right-back both
 * amber — and telling them apart matters, because one of them means "do not
 * ring me". So each state also draws a SHAPE, in pure CSS: no icon font is
 * involved, both because a webfont glyph is illegible at 8px and because the
 * dot must never depend on Font Awesome having loaded.
 *
 * The state names are the shared vocabulary from teams-presence-states.js and
 * its Python counterpart; adding a class here without adding it there produces
 * a dot nothing ever paints. */
.teams-presence-dot {
    position: relative;
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #b0ab9f;
    flex-shrink: 0;
}
/* The glyph layer. `content` is deliberately absent here and switched on ONLY
   by the states that draw a shape — a bare `content: ""` with `inset: 0` and no
   size stretches to fill the dot, which painted every badge in the product as a
   solid white square. */
.teams-presence-dot::after {
    position: absolute;
    inset: 0;
    margin: auto;
    background: #fff;
}
.teams-presence-dot--available {
    background: #37b24d;
} /* green  — active <15m, or chosen */
.teams-presence-dot--away {
    background: #f59f00;
} /* amber  — active 15m–24h ago, or "appear away" */
.teams-presence-dot--offline {
    background: #b0ab9f;
} /* grey   — inactive >24h, or "appear offline" */
.teams-presence-dot--busy,
.teams-presence-dot--on_call,
.teams-presence-dot--presenting {
    background: #e5484d;
} /* red    — chosen Busy, in a call, or presenting (the tooltip tells them apart) */
.teams-presence-dot--do_not_disturb {
    background: #c2181f;
} /* deeper red — a stronger promise than Busy, and it mutes call rings */
.teams-presence-dot--be_right_back {
    background: #f59f00;
} /* amber  — chosen, auto-clears once they are active again */

/* A BAR MEANS "DELIBERATELY UNAVAILABLE". Solid = observed or simple; a bar =
   the person chose this. That gives a consistent two-dimensional read at 8px:
   colour says how interruptible they are, shape says whether they decided it.
     busy           solid red     — chosen, but interruptible
     do_not_disturb bar, deep red — chosen, and it actually mutes call rings
     away           solid amber   — merely aged out of the active window
     be_right_back  bar, amber    — chosen, and it clears itself on return
   An earlier cut drew be-right-back as a clock hand, which at this size read as
   an exclamation mark — an alarm, which is the opposite of what it means. */
.teams-presence-dot--do_not_disturb::after,
.teams-presence-dot--be_right_back::after {
    content: "";
    width: 62%;
    height: 1.5px;
    border-radius: 1px;
}
/* Offline — hollow, so "we do not know / they are gone" never looks asserted. */
.teams-presence-dot--offline::after {
    content: "";
    width: 50%;
    height: 50%;
    border-radius: 50%;
}

/* Presence badge — the same dot, positioned ON an avatar.
 *
 * Used wherever a person's picture appears (session list, conversation header,
 * message authors, participants modal). It reuses the .teams-presence-dot
 * colour classes above so the palette is defined exactly once; this rule only
 * adds placement and the ring that keeps a coloured dot legible against a
 * photo of any brightness.
 *
 * The host avatar must be a positioned box — see [data-presence-host] below —
 * otherwise the badge escapes to the nearest positioned ancestor and lands in
 * the wrong corner of the row. */
.teams-avatar .teams-presence-badge,
[data-presence-host] .teams-presence-badge {
    position: absolute;
    right: -1px;
    bottom: -1px;
    width: 8px;
    height: 8px;
    /* Ring drawn with box-shadow rather than border so the dot's own size stays
       constant; a border would shrink the coloured area and make the states
       read as different sizes. */
    box-shadow: 0 0 0 1px var(--teams-surface, #ffffff);
    /* Colour changes should ease rather than snap, so a green->amber ageing
       transition is not mistaken for a flicker. */
    transition: background-color 180ms ease;
    pointer-events: none;
}

/* Any avatar that can carry a badge must establish a containing block. */
[data-presence-host] {
    position: relative;
}

/* ...and must not clip it away.
 *
 * `.avatar--has-image` (added by paintAvatar once a photo loads) sets
 * `overflow: hidden` to keep a square photo inside a round frame. The badge
 * deliberately overhangs the circle by a pixel, so that clip erased it
 * completely on every avatar that had a picture — which is most of them. The
 * dot was in the DOM, correctly coloured, and invisible.
 *
 * Relaxing the clip is safe HERE because the photo does not depend on it:
 * `.avatar-image` already carries `border-radius: inherit`, so it rounds itself
 * against the host's own radius. The overflow was belt-and-braces, and only
 * hosts that actually carry a badge opt out of it. */
[data-presence-host].avatar--has-image {
    overflow: visible;
}

/* Keep the dot above the photo it overlaps. */
[data-presence-host] .teams-presence-badge {
    z-index: 2;
}

/* Small avatars (sidebar rows, inline message authors) get a proportionally
   smaller dot — a 10px badge on a 24px avatar covers the face. */
[data-presence-host].teams-avatar--sm .teams-presence-badge {
    width: 8px;
    height: 8px;
    box-shadow: 0 0 0 1.5px var(--teams-surface, #ffffff);
}

@media (prefers-reduced-motion: reduce) {
    .teams-avatar .teams-presence-badge,
    [data-presence-host] .teams-presence-badge {
        transition: none;
    }
}

/* Participants modal (opened from the people pill). Reuses the shared
   .teams-modal chrome; only the row layout is bespoke. */

.teams-participants-modal.teams-modal-overlay .teams-modal__header {
    padding: 20px;
}

.teams-modal__header h3 {
    margin: 0;
}

.teams-participants-modal .teams-modal {
    width: min(420px, 92vw);
    min-height: 500px;
    max-height: 85vh;
    display: flex;
    flex-direction: column;
}
/* Body grows so the footer stays pinned to the bottom and the (short) list is
   allowed to leave whitespace beneath it rather than looking crowded. */
.teams-participants-modal .teams-modal__body {
    flex: 1 1 auto;
}
/* Non-clickable "+N more" hint in the header roster (the exact count also lives
   in the people pill; this just signals the inline list is truncated). */
.teams-panel .teams-participant-more {
    color: var(--tm-text-3);
    font-size: 12px;
    white-space: nowrap;
}
.teams-participants-modal .teams-people-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 4px;
    border-bottom: 1px solid var(--tm-border);
}
.teams-participants-modal .teams-people-row:last-child {
    border-bottom: none;
}
.teams-participants-modal .teams-people-row__meta {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.teams-participants-modal .teams-people-row__name {
    font-size: 14px;
    color: var(--tm-text-1);
}
.teams-participants-modal .teams-people-row__org {
    font-size: 12px;
    color: var(--tm-text-3);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.teams-participants-modal .teams-people-row__you {
    color: var(--tm-text-3);
    font-size: 12px;
}
.teams-participants-modal .teams-people-row__status {
    font-size: 11.5px;
    color: var(--tm-text-3);
}
.teams-participants-modal .teams-people-row__status--online {
    color: #2f9e44;
}
.teams-participants-modal .teams-people-row__status--away {
    color: #b8860b;
}
.teams-participants-modal .teams-people-row__status--on_call,
.teams-participants-modal .teams-people-row__status--presenting {
    color: #c0392b;
}

.teams-panel .teams-conversation__scroll {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 16px 20px 100px 20px;
    min-height: 0;
    scrollbar-width: thin;
    scrollbar-color: rgba(0, 0, 0, 0.1) transparent;
    overflow-x: hidden;
}

.teams-panel .teams-conversation__load-older {
    text-align: center;
    margin-bottom: 12px;
}

/* ── Messages ─────────────────────────────────────────────────────────────── */
.teams-panel .teams-conversation {
    /* iOS may re-run its automatic text inflation after an inline video exits
       landscape full-screen. Lock the whole transcript to the authored page
       scale so only accessibility settings—not the prior orientation—change
       message text. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

.teams-panel .teams-msg {
    display: flex;
    gap: 10px;
    margin-bottom: 14px;
    align-items: flex-start;
    position: relative; /* anchors the hover Reply action */
}

/* ⚠️ `[hidden]` MUST WIN OVER THE `display: flex` ABOVE.
 *
 * The UA stylesheet's `[hidden] { display: none }` is an element-level rule, so
 * ANY class selector beats it — and `.teams-panel .teams-msg` is two classes.
 * Setting `el.hidden = true` therefore did nothing visible: the attribute was
 * on the element and the message stayed on screen.
 *
 * This is what made selecting a Support Desk case appear to do nothing. The
 * filter was computing the right answer and applying it to the right elements;
 * the layout rule simply outranked it. */
.teams-panel .teams-msg[hidden] {
    display: none;
}

/* The same override for every OTHER message kind in a transcript. Each has its
 * own `display` rule in its own stylesheet (`teams-modals.css`,
 * `teams-ai-drawer.css`, below), and each would otherwise outrank `[hidden]`
 * exactly as the bubble rule did. One extra attribute selector puts these at
 * 0,3,0, so they win on specificity rather than on file load order — which is
 * not something this page can rely on. */
.teams-conversation .teams-sysnote[hidden],
.teams-conversation .teams-shared-ai[hidden],
.teams-conversation .teams-space-share[hidden] {
    display: none;
}
.teams-panel .teams-msg__body {
    min-width: 0;
    flex: 1;
}
.teams-panel .teams-msg__meta {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 3px;
    flex-wrap: wrap;
}
.teams-panel .teams-msg__sender {
    font-size: 13px;
    color: var(--tm-text-2);
}

/* "(inactive)" — the sender's account was disabled (they left). */
.teams-panel .teams-msg__sender .teams-inactive-suffix {
    font-style: italic;
    color: var(--tm-text-3);
}

.teams-panel .teams-msg__agent {
    font-weight: 600;
    font-size: 13px;
    color: var(--tm-agent);
}
.teams-panel .teams-msg__time {
    font-size: 11px;
    color: var(--tm-text-3);
}
.teams-panel .teams-msg__asked {
    font-size: 11px;
    color: var(--tm-agent);
    background: var(--tm-agent-bg);
    padding: 1px 7px;
    border-radius: 999px;
}
.teams-panel .teams-msg__bubble {
    display: inline-block;
    /* SHRINK-TO-FIT, STATED EXPLICITLY. `inline-block` already implies it, and
       in Blink the two compute identically (measured: same px, and long
       paragraphs still wrap against `max-width`) — so this is a no-op there.
       It is here for WebKit, where the legacy inline-block shrink-to-fit
       under-measures a bubble whose content is a nested BLOCK carrying its own
       indent: the same one-item list message rendered ~30px narrower in the
       Safari PWA than in Chrome and wrapped mid-word, which is roughly the
       list's own indentation going uncounted. `fit-content` is the modern
       spelling of the same intrinsic sizing and is computed on the current
       path in both engines. See also the single-source list indent in
       teams-rich-editor.css. */
    width: fit-content;
    padding: 9px 13px;
    background: var(--tm-white);
    border: 1px solid var(--tm-border);
    border-radius: 4px 12px 12px 12px;
    font-size: 1em;
    line-height: 1.5;
    color: var(--tm-msg-text);
    word-break: break-word;
    max-width: 100%;
}
/* Only the message TEXT preserves author whitespace/newlines. The bubble is now
 * a container (quote + text), so pre-wrap must NOT live on it — otherwise the
 * indentation between the child elements in the template renders as blank lines
 * and inflates the bubble height. */
.teams-panel .teams-msg__text {
    white-space: pre-wrap;
    word-break: break-word;
}
/* Autolinked URLs inside a message bubble. Inherit the mine/other bubble colour
   context but stay underlined + clickable; break long URLs so they never
   overflow the bubble. */
.teams-panel .teams-msg__text .teams-msg__link {
    color: var(--tm-accent);
    text-decoration: underline;
    word-break: break-all;
}
.teams-panel .teams-msg--mine .teams-msg__text .teams-msg__link {
    color: #006fff;
}
/* Small breathing room around each emoji so consecutive emojis (and emoji↔text
   boundaries) don't collide in the bubble. inline-block lets the horizontal
   margin apply reliably across emoji fonts. */
.teams-panel .teams-msg__text .teams-msg__emoji {
    display: inline-block;
    margin: 0 1.5px;
}

/* An image placed inline by the sender, sitting between the runs of text it was
   dropped between. `pre-wrap` on the parent preserves the author's newlines, so
   this block carries its own spacing instead of relying on blank lines. */
.teams-panel .teams-msg__inline-img {
    display: block;
    margin: 6px 0;
    white-space: normal;
}
.teams-panel .teams-msg__inline-img:first-child {
    margin-top: 0;
}
.teams-panel .teams-msg__inline-img:last-child {
    margin-bottom: 0;
}
/* An inline image is part of the message the sender wrote, not a file hanging
   off it, so it gets room to be readable — the 320px card width that suits the
   trailing attachment gallery makes a screenshot unreadable AND squeezes the
   whole bubble to that width (the bubble is inline-block, so it shrink-wraps to
   its widest child). Capped at the column width so narrow viewports still fit. */
/* .teams-panel .teams-msg__inline-img .teams-att {
    max-width: min(560px, 100%);
} */
.teams-panel .teams-msg__inline-img .teams-att--image img {
    max-height: 420px;
    width: auto;
}

/* ── Message attachments (drag-drop / paste / picker; task #1) ────────────────
   Images and video render inline; PDFs/presentations/other files render as a
   download card. Scoped under .teams-panel so nothing leaks to the main chat. */
.teams-panel .teams-msg__attachments {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 6px;
}
/* A native <audio> element has no useful intrinsic width. Message bubbles are
   shrink-to-fit, so without a width on this wrapper browsers can collapse the
   player into the thin, unusable vertical sliver seen in sent messages. */
.teams-panel .teams-msg__attachments--audio {
    width: min(360px, calc(100vw - 72px));
    max-width: 100%;
}
.teams-panel .teams-att {
    display: block;
    max-width: 320px;
}
.teams-panel .teams-att--image img {
    max-width: 100%;
    max-height: 260px;
    border-radius: 10px;
    display: block;
    border: 1px solid var(--tm-border);
}
/* An image whose real pixel size travelled with it (see `_imageSizeAttrs`).
   The `width`/`height` attributes are presentational hints, so without
   `height: auto` the attribute height wins and `max-width` squashes the picture
   out of shape. With it, the browser derives the aspect ratio from the
   attributes and reserves the EXACT box before a single byte of the image has
   arrived — which is what stops a lazily-loaded picture from growing out of
   nothing and shoving the rest of the transcript down while someone is reading
   it. Images sent before the server measured them have no attributes, do not
   match this rule, and are held steady by teams-scroll-anchor.js instead. */
.teams-panel .teams-att--image img[width][height] {
    height: auto;
    width: auto;
}

/* Native scroll anchoring wherever it exists (Chrome/Firefox — Safari has
   none, which is why teams-scroll-anchor.js carries the load). Stated
   explicitly so nothing downstream quietly opts the transcript out of it.
   The typing indicator and the floating "latest" button are excluded: they
   appear and disappear constantly and must never be chosen as the anchor. */
.teams-panel .teams-conversation__scroll {
    overflow-anchor: auto;
}
.teams-panel .teams-conversation__typing,
.teams-panel .teams-conversation__scroll-btn {
    overflow-anchor: none;
}

/* The message a search result sent the reader to. A brief wash of the accent
   colour rather than a persistent highlight: it has to catch the eye on
   arrival and then get out of the way of reading. */
.teams-panel .teams-msg--search-hit,
.teams-panel .message-container.teams-msg--search-hit {
    animation: teams-search-hit-flash 2.4s ease-out 1;
    border-radius: 10px;
}
@keyframes teams-search-hit-flash {
    0%, 55% {
        background-color: color-mix(in srgb, var(--tm-accent) 22%, transparent);
        box-shadow: 0 0 0 4px color-mix(in srgb, var(--tm-accent) 16%, transparent);
    }
    100% {
        background-color: transparent;
        box-shadow: 0 0 0 4px transparent;
    }
}
@media (prefers-reduced-motion: reduce) {
    /* No flash, but the reader still has to be able to SEE which message they
       were sent to — so the cue becomes a static outline rather than nothing. */
    .teams-panel .teams-msg--search-hit,
    .teams-panel .message-container.teams-msg--search-hit {
        animation: none;
        outline: 2px solid var(--tm-accent);
        outline-offset: 2px;
    }
}
.teams-panel .teams-att--video {
    /* A reserved 16:9 box, not the video's own size: Safari does not load
       metadata until play, so an unsized video collapsed the whole bubble to
       the 300x150 default. fitVideoToContent() (teams-attachment-render.js)
       replaces the ratio with the real one once metadata is known. */
    width: min(100%, 533px);
    aspect-ratio: 16 / 9;
    max-width: 100%;
    max-height: 300px;
    border-radius: 10px;
    background: #000;
}
.teams-panel .teams-att--video[data-orientation="portrait"] {
    width: auto;
    height: min(420px, 60vh);
    max-height: none;
}
.teams-panel .teams-att--audio {
    width: 100%;
    max-width: 100%;
}
.teams-panel .teams-audio-player {
    width: 100%;
    min-height: 48px;
    box-sizing: border-box;
    display: grid;
    /* play · track · speed · download · wave — one column per visible child,
       or the last one wraps onto a second row and breaks the pill. */
    grid-template-columns: auto minmax(0, 1fr) auto auto auto;
    gap: 9px;
    align-items: center;
    padding: 7px 10px;
    border: 1px solid color-mix(in srgb, var(--tm-border) 82%, transparent);
    border-radius: 999px;
    background: var(--tm-audio-player-bg);
    color: var(--tm-msg-text);
}
.teams-panel .teams-audio-player__native { display: none; }
.teams-panel .teams-audio-player__play {
    width: 31px;
    height: 31px;
    border: 0;
    border-radius: 50%;
    background: var(--tm-audio-player-control);
    color: var(--tm-audio-player-icon);
    cursor: pointer;
    display: grid;
    place-items: center;
    flex: 0 0 auto;
}
.teams-panel .teams-audio-player__play:hover { filter: brightness(1.1); }
.teams-panel .teams-audio-player__speed {
    min-width: 34px;
    height: 24px;
    padding: 0 6px;
    border: 0;
    border-radius: 12px;
    background: transparent;
    color: var(--tm-audio-player-control);
    font: 600 12px/1 inherit;
    cursor: pointer;
    flex: 0 0 auto;
    transition: background var(--tm-t);
}
.teams-panel .teams-audio-player__speed:hover,
.teams-panel .teams-audio-player__speed:focus-visible {
    background: rgba(127, 127, 127, 0.18);
}
.teams-panel .teams-audio-player__download {
    width: 28px;
    height: 28px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    color: var(--tm-audio-player-control);
    text-decoration: none;
    transition: background var(--tm-t), color var(--tm-t);
}
.teams-panel .teams-audio-player__download:hover,
.teams-panel .teams-audio-player__download:focus-visible {
    background: color-mix(in srgb, var(--tm-audio-player-control) 14%, transparent);
    color: var(--tm-audio-player-icon);
    outline: none;
}

/* A clip this browser cannot decode. Muted rather than alarming: nothing is
   broken for the reader to fix, and the message beside it already says so. */
.teams-panel .teams-audio-player.is-unplayable {
    border-style: dashed;
    opacity: 0.75;
}
.teams-panel .teams-audio-player.is-unplayable .teams-audio-player__play,
.teams-panel .teams-audio-player.is-unplayable .teams-audio-player__play:hover {
    background: color-mix(in srgb, var(--tm-audio-player-control) 35%, transparent);
    cursor: not-allowed;
    filter: none;
}
.teams-panel .teams-audio-player.is-unplayable .teams-audio-player__seek {
    cursor: not-allowed;
}
.teams-panel .teams-audio-player__track {
    min-width: 0;
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 7px;
}
.teams-panel .teams-audio-player__seek {
    width: 100%;
    min-width: 64px;
    accent-color: var(--tm-audio-player-control);
    cursor: pointer;
}
.teams-panel .teams-audio-player__time {
    color: var(--tm-text-1);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.teams-panel .teams-audio-player__wave {
    display: flex;
    align-items: center;
    gap: 2px;
    height: 20px;
}
.teams-panel .teams-audio-player__wave i {
    width: 2px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--tm-audio-player-control) 55%, transparent);
}
.teams-panel .teams-audio-player__wave i:nth-child(1),
.teams-panel .teams-audio-player__wave i:nth-child(5) { height: 7px; }
.teams-panel .teams-audio-player__wave i:nth-child(2),
.teams-panel .teams-audio-player__wave i:nth-child(4) { height: 15px; }
.teams-panel .teams-audio-player__wave i:nth-child(3) { height: 20px; }
/* Narrow phones: the waveform is decoration, the controls are not. */
@media (max-width: 400px) {
    .teams-panel .teams-audio-player { grid-template-columns: auto minmax(0, 1fr) auto auto; gap: 6px; }
    .teams-panel .teams-audio-player__wave { display: none; }
}
/* ── Call video recording card (teams-recording-card.js) ──────────────────
   Same card language as the calendar event intro: a quiet header naming the
   thing and its facts, the content edge to edge, a muted footer. */
.teams-panel .teams-recording-card {
    width: min(560px, 100%);
    margin: 12px auto;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r-lg, 12px);
    background: var(--tm-surface, var(--tm-white));
    overflow: hidden;
}
/* ONE compact row on desktop: icon, title, then the facts pushed to the right.
   The header only labels the player below it, so it stays a single line. */
.teams-panel .teams-recording-card__head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 12px;
    border-bottom: 1px solid var(--tm-border);
}
.teams-panel .teams-recording-card__icon {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    color: var(--tm-accent);
    background: color-mix(in srgb, var(--tm-accent) 13%, transparent);
    font-size: 10px;
}
.teams-panel .teams-recording-card__heading {
    display: flex;
    flex: 1;
    flex-wrap: wrap;
    align-items: center;
    gap: 2px 14px;
    min-width: 0;
}
.teams-panel .teams-recording-card__title {
    font-family: var(--tm-font-display);
    font-size: 13.5px;
    font-weight: 650;
    line-height: 1.3;
    color: var(--tm-msg-text);
}
.teams-panel .teams-recording-card__facts {
    display: flex;
    flex-wrap: wrap;
    gap: 2px 12px;
    margin-left: auto;
    font-size: 11.5px;
    font-variant-numeric: tabular-nums;
    color: var(--tm-text-2);
}
/* Mobile keeps the two-line layout (title above facts); only the sizes shrink. */
@media (max-width: 768px) {
    .teams-panel .teams-recording-card__heading {
        flex-direction: column;
        align-items: flex-start;
        gap: 1px;
    }
    .teams-panel .teams-recording-card__facts {
        margin-left: 0;
    }
}
.teams-panel .teams-recording-card__fact {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}
.teams-panel .teams-recording-card__fact i {
    color: var(--tm-text-3);
}
.teams-panel .teams-recording-card__video {
    display: block;
    width: 100%;
    max-width: 100%;
    max-height: none;
    aspect-ratio: 16 / 9;
    border-radius: 0;
    object-fit: contain;
}
.teams-panel .teams-recording-card__note {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    font-size: 12px;
    color: var(--tm-text-3);
}
.teams-panel .teams-att--file {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 9px 12px;
    border: 1px solid var(--tm-border);
    border-radius: 10px;
    background: var(--tm-white);
    color: var(--tm-text-1);
    text-decoration: none;
    transition:
        border-color var(--tm-t),
        background var(--tm-t);
}
.teams-panel .teams-att--file:hover {
    border-color: var(--tm-accent);
    background: var(--tm-bg-alt);
}
.teams-panel .teams-att__thumb {
    width: 100%;
    max-height: 160px;
    object-fit: cover;
    border-radius: 8px;
    border: 1px solid var(--tm-border);
    margin-bottom: 2px;
}
.teams-panel .teams-att__file-main {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    flex: 1;
}
.teams-panel .teams-att__file-main i {
    color: var(--tm-accent);
    font-size: 18px;
    flex-shrink: 0;
}
.teams-panel .teams-att__name {
    font-size: 13px;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-panel .teams-att__open {
    font-size: 12px;
    font-weight: 600;
    color: var(--tm-accent);
    flex-shrink: 0;
}

/* ── Pending-attachment tray (above the composer while files are staged) ─────── */

/* CLIPPED, NOT `display: none`. These inputs are never touched directly — the
   paperclip (or the mobile source sheet) calls `.click()` on one of them. A
   `display: none` file input is the pattern WebKit is least dependable about
   for a programmatic activation, and the failure mode is silent: the tap is
   accepted, no picker appears, nothing errors. Kept in the layout at zero
   effective size instead, which every engine activates. Out of the tab order
   and out of the accessibility tree, since the paperclip is the real control. */
.teams-panel .teams-attach__picker {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    opacity: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}
.teams-panel .teams-attach__tray {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 6px 20px 0;
}
.teams-panel .teams-attach__tray[hidden] {
    display: none;
}
.teams-panel .teams-attach__chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 6px 4px 10px;
    border-radius: 14px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--tm-accent);
    max-width: 220px;
    background: var(--tm-avatar-placeholder);
}
.teams-panel .teams-attach__chip--error {
    background: var(--tm-danger-subtle, #fbe9e7);
    color: var(--tm-danger, #c0392b);
}
/* Image/GIF attachments preview as a live thumbnail (the GIF animates) so the
   sender sees exactly what will be sent and can add text around it before send. */
.teams-panel .teams-attach__chip--thumb {
    padding: 4px 6px 4px 4px;
    max-width: 260px;
}
.teams-panel .teams-attach__chip--audio {
    max-width: min(360px, 100%);
    padding-left: 8px;
}
.teams-panel .teams-attach__chip-audio {
    width: min(280px, 54vw);
    height: 34px;
}
.teams-panel .teams-attach__chip-thumb {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    object-fit: cover;
    flex-shrink: 0;
    display: block;
    background: var(--tm-surface-2, rgba(0, 0, 0, 0.04));
}
/* Wraps the thumbnail so it opens the full-size preview (the same viewer a
 * sent message's images already use) — reset the default link chrome so it
 * reads as "click the picture", not as a piece of text. */
.teams-panel .teams-attach__chip-thumb-link {
    display: block;
    flex-shrink: 0;
    line-height: 0;
    border-radius: 10px;
}
.teams-panel .teams-attach__chip-thumb-link:hover .teams-attach__chip-thumb {
    filter: brightness(0.92);
}
.teams-panel .teams-attach__chip-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-panel .teams-attach__chip-x {
    border: none;
    background: none;
    color: inherit;
    cursor: pointer;
    font-size: 15px;
    line-height: 1;
    padding: 0 2px;
}
/* ── Emoji quick-picker (button next to the paperclip + popover) ────────────── */
/* The composer's paperclip is ABSOLUTELY positioned on the left, inside the
   input pill. The emoji button must be absolute too (a static flex item would
   consume row space and shove the textarea/paperclip out of the pill), sitting
   just to the RIGHT of the paperclip. Positioning is scoped to the adopted Teams
   composer so it only applies while Teams owns the input. */
.teams-emoji-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
    border-radius: 50%;
    color: var(--tm-text-muted, #6b7280);
    font-size: 16px;
    transition:
        background 0.15s ease,
        color 0.15s ease;
}
.teams-emoji-btn:hover,
.teams-emoji-btn--active {
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}
/* Absolute placement next to the paperclip + widen the textarea's left padding
   so typed text clears both icons. Matched to the composer's own 50px/54px
   padding scheme (see the #userInput rule below). */
.teams-panel
    .teams-conversation__composer-slot
    #inputContainer
    .teams-emoji-btn,
#inputContainer.teams-input-adopted .teams-emoji-btn {
    position: absolute;
    left: 30px;
    top: 50%;
    transform: translateY(-50%);
    width: 30px;
    height: 30px;
    z-index: 5;
    background: transparent;
    border: none;
}

.teams-panel .input-row {
    position: relative;
}
.teams-emoji {
    position: absolute;
    bottom: calc(100% + 8px);
    left: 8px;
    z-index: 40;
    width: 320px;
    max-width: calc(100vw - 32px);
    background: var(--tm-surface, #fff);
    color: var(--tm-text, #1f2937);
    border: 1px solid var(--tm-border, rgba(0, 0, 0, 0.12));
    border-radius: 12px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
/* Message-reaction picker: a viewport-fixed overlay positioned next to the "+"
   trigger button in JS (teams-emoji-picker._positionFloating). Overrides the
   composer's above-the-input-row placement so it lands beside the message being
   reacted to instead of at the top of a tall/off-screen message container. */
/* `position: fixed` is viewport-relative, so this is safe to mount on any
   surface root — see `openPopover`, which prefers `.teams-panel`, then the
   `.teams-modal-overlay` that opened it.

   The z-index has to clear a Teams modal (10000) for the one case that is left:
   a picker with neither ancestor, which falls back to `document.body`. At the
   old 60 it rendered perfectly and invisibly BEHIND the dialog that opened it,
   so "more reactions" in a post discussion looked like a dead button. Below the
   Spaces media viewer (12000), which is the one surface that should cover a
   picker rather than the other way round. */
.teams-emoji.teams-emoji--floating {
    position: fixed;
    bottom: auto;
    right: auto;
    z-index: 10050;
}
.teams-emoji__tabs {
    display: flex;
    gap: 4px;
    padding: 8px 10px 0;
}
.teams-emoji__tab {
    font-size: 12px;
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 8px;
    color: var(--tm-text-muted, #6b7280);
    cursor: default;
}
.teams-emoji__tab--active {
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}
.teams-emoji__search {
    margin: 8px 10px;
    padding: 7px 10px;
    border-radius: 8px;
    border: 1px solid var(--tm-border, rgba(0, 0, 0, 0.14));
    background: var(--tm-surface-2, rgba(0, 0, 0, 0.03));
    color: inherit;
    font-size: 13px;
    outline: none;
}
.teams-emoji__search:focus {
    border-color: var(--tm-accent);
}
.teams-emoji .teams-emoji__cats {
    display: flex;
    gap: 2px;
    padding: 0 8px 6px;
    border-bottom: 1px solid var(--tm-border, rgba(0, 0, 0, 0.08));
    overflow-x: auto;
}
.teams-emoji .teams-emoji__cat {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 17px;
    padding: 3px 5px;
    border-radius: 6px;
    line-height: 1;
}
.teams-emoji .teams-emoji__cat:hover {
    background: var(--tm-accent-subtle);
}
.teams-emoji .teams-emoji__grid {
    padding: 6px 8px 10px;
    overflow-y: auto;
    max-height: 240px;
    display: flex;
    flex-direction: column;
}
.teams-emoji .teams-emoji__cat-label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--tm-text-muted, #9ca3af);
    padding: 8px 4px 4px;
    position: sticky;
    top: 0;
    background: var(--tm-surface, #fff);
}
.teams-emoji__cat-grid {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    gap: 2px;
}
/* The picker grid and the emoji inside a bubble are the two surfaces made
   ENTIRELY of emoji, so they name the colour fonts explicitly rather than
   relying on inheriting a stack that happens to carry them. Both are also
   reachable from a body-appended overlay (the floating picker, the Spaces
   composer), where a `--tm-*` token defined on `.teams-panel` does not resolve
   — hence the literal fallback inside var(). */
.teams-emoji__item,
.teams-emoji--floating .teams-emoji__item,
.teams-panel .teams-msg__text .teams-msg__emoji {
    font-family: var(--tm-font-emoji, "Apple Color Emoji"), "Segoe UI Emoji",
        "Noto Color Emoji", "Twemoji Mozilla", "Android Emoji", sans-serif;
}

.teams-emoji .teams-emoji__item {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 20px;
    line-height: 1;
    padding: 4px 0;
    border-radius: 8px;
    aspect-ratio: 1;
    text-align: center;
    width: auto;
    height: auto;
}
.teams-emoji .teams-emoji__item:hover {
    background: var(--tm-accent-subtle);
}
.teams-emoji__empty {
    grid-column: 1 / -1;
    text-align: center;
    color: var(--tm-text-muted, #9ca3af);
    font-size: 13px;
    padding: 20px 0;
}

/* Drop affordance: a centered overlay shown only while files are dragged over
   the conversation (pointer-events:none so the drop still lands underneath). */
.teams-panel .teams-conversation {
    position: relative;
}
.teams-panel .teams-attach__dropzone {
    position: absolute;
    inset: 8px;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    border: 2px dashed var(--tm-accent);
    border-radius: var(--tm-r-lg);
    background: var(--tm-accent-subtle);
}
.teams-panel .teams-attach__dropzone[hidden] {
    display: none;
}
.teams-panel .teams-attach__dropzone-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    color: var(--tm-accent);
    font-weight: 600;
    font-size: 15px;
}
.teams-panel .teams-attach__dropzone-inner i {
    font-size: 28px;
}

.teams-conversation__scroll .message-container-bot {
    padding: 0;
}

.teams-panel .teams-msg__bubble--assistant {
    background: var(--tm-agent-bg);
    border-color: var(--tm-agent-border);
    background: transparent;
    border-color: transparent;
    border: none;
}
.teams-panel .teams-msg--mine .teams-msg__bubble {
    background: var(--tm-self-message-bg);
    border-color: var(--tm-self-message-bg);
}
.teams-panel .teams-msg--ai_request .teams-msg__bubble {
    border-style: dashed;
    border-color: var(--tm-agent-border);
}
.teams-panel .teams-msg--failed {
    opacity: 0.7;
}
.teams-panel .teams-msg--failed .teams-msg__bubble {
    border-color: var(--tm-danger);
}
.teams-panel .teams-msg__retry {
    margin-top: 6px;
}

/* ── Inline reply / quote ──────────────────────────────────────────────────────
 * Flat single-level quote (Slack / MS-Teams style). Two pieces here: the hover
 * ACTIONS TOOLBAR (a small rounded pill that overlaps the top of the message and
 * has room to grow into reactions) and the QUOTED-PARENT PREVIEW rendered inside
 * the message bubble, above the reply text. Composer chip is defined below. All
 * scoped to .teams-panel and token-driven (no global selectors). */

/* Content column: anchors the floating actions toolbar to the bubble. */
.teams-panel .teams-msg__content {
    position: relative;
    display: inline-flex;
    flex-direction: column;
    max-width: 100%;
}

/* Hover actions toolbar — overlaps the top-right of the message (MS-Teams-like),
 * appears on hover of the bubble, and is a pill so more actions/reactions can
 * be added later without shifting layout. */
.teams-panel .teams-msg__actions {
    position: absolute;
    top: -30px;
    /* Incoming messages: anchor the pill to the bubble's RIGHT and let it hang
       slightly PAST that edge, so a short bubble's toolbar sits over the open
       message area rather than over the text it belongs to. Own messages keep
       the same edge without the overhang (see the --mine override below), and
       phones flip the anchor entirely (see teams-responsive.css) because the
       overhang has nowhere to go at that width. */
    left: auto;
    right: -30px;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 2px;
    border: 1px solid var(--tm-border);
    border-radius: 999px;
    background: var(--tm-white);
    box-shadow: var(--tm-shadow-md);
    opacity: 0;
    transform: translateY(4px);
    pointer-events: none;
    transition:
        opacity var(--tm-t),
        transform var(--tm-t);
    /* The pill must never be clipped by the narrow bubble it overlays. */
    max-width: none;
    white-space: nowrap;
    /* NOT SELECTABLE, and therefore not COPYABLE. The pill is absolutely
       positioned but still a child of the message, so a drag-selection across
       the bubble puts its quick-reaction buttons inside the range — and
       pasting the message then carried "👍❤️😂😮" on their own lines after the
       text. Chrome, Firefox and Safari all omit a `user-select: none` subtree
       from the copied string, so this is the fix rather than a copy handler
       that would have to re-serialise the selection by hand. */
    -webkit-user-select: none;
    user-select: none;
}
/* Own (right-aligned) messages: anchor RIGHT so the pill grows LEFTWARD into the
   open area on that side. */
.teams-panel .teams-msg--mine .teams-msg__actions {
    left: auto;
    right: 8px;
}
/* `.teams-msg` is a full-width flex row, so using `.teams-msg:hover` here made
 * the toolbar appear while the pointer was anywhere across that row. The bubble
 * row is the actual, shrink-wrapped message target. Keep the toolbar itself as
 * a trigger too, so a pointer can move from a bubble into an already-visible
 * toolbar without closing it before a button can be clicked. */
.teams-panel .teams-msg__bubble-row:hover + .teams-msg__actions,
.teams-panel .teams-msg__actions:hover,
.teams-panel .teams-msg-repliable:hover .teams-msg__actions {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
    /* Hold ~0.5s before the reply toolbar fades in on hover so it doesn't flicker
       while the pointer merely passes over messages. Hover-out (the base rule,
       delay 0) still hides it immediately. */
    transition-delay: 0.5s;
}
/* An open "Additional actions" menu pins the pill visible: the pointer has to
   travel down into the menu, which would otherwise leave the message and fade
   the whole thing away mid-click. */
.teams-panel .teams-msg__actions--menu-open {
    opacity: 1 !important;
    transform: translateY(0) !important;
    pointer-events: auto !important;
    transition-delay: 0s !important;
}
/* Keyboard focus surfaces the toolbar immediately — no hover-intent delay. */
.teams-panel .teams-msg__actions:focus-within {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
    transition-delay: 0s;
}

/* A touch tap must not latch the desktop hover toolbar. The long-press
   spotlight owns the only mobile action surface. */
@media (hover: none), (pointer: coarse) {
    .teams-panel .teams-msg__actions,
    .teams-panel .teams-msg__actions--menu-open {
        opacity: 0 !important;
        pointer-events: none !important;
    }
    /* A long press on a message IS the spotlight. The platform's own long press
       (iOS magnifier, link/image callout, Android selection) would start
       half-way through the hold and compete with it, so it is switched off
       on touch devices. Copy stays one tap away in the spotlight's menu.
       CSS, never a cancelled touchstart: that would stop the transcript
       scrolling. An inline edit box is still a text field. */
    .teams-panel .teams-msg {
        -webkit-touch-callout: none;
        -webkit-user-select: none;
        user-select: none;
    }
    .teams-panel .teams-msg :is(input, textarea, [contenteditable="true"]) {
        -webkit-touch-callout: default;
        -webkit-user-select: text;
        user-select: text;
    }
}
.teams-panel .teams-msg__action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--tm-text-2);
    font-size: 13px;
    cursor: pointer;
    transition:
        background var(--tm-t),
        color var(--tm-t);
}
.teams-panel .teams-msg__action:hover {
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}
/* Delete is the one destructive action in the pill — it reads neutral until
   hover, then turns danger-red so it can't be mistaken for its neighbours. */
.teams-panel .teams-msg__action--delete:hover {
    background: var(--tm-danger-subtle, rgba(220, 53, 69, 0.12));
    color: var(--tm-danger);
}
/* Edit past its window: still SHOWN (a pencil that vanishes reads as a missing
   feature), but muted and inert, with a tooltip stating the limit. */
.teams-panel .teams-msg__action[disabled] {
    opacity: 0.35;
    cursor: not-allowed;
}
.teams-panel .teams-msg__action[disabled]:hover {
    background: transparent;
    color: var(--tm-text-2);
}

/* ── "Additional actions" menu (the "⋯" popup) ───────────────────────────────
   Everything except the quick emojis lives here, so the default pill stays
   narrow (MS-Teams parity). Anchored under the "⋯" trigger inside the pill. */
.teams-panel .teams-msg__menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    left: auto;
    z-index: 12;
    min-width: 208px;
    padding: 6px;
    border: 1px solid var(--tm-border);
    border-radius: 10px;
    background: var(--tm-white);
    box-shadow: var(--tm-shadow-md);
    display: flex;
    flex-direction: column;
    gap: 1px;
    white-space: nowrap;
    text-align: left;
}
/* No room below (the last messages in the transcript, where the composer and
   the viewport edge sit): the menu opens UPWARD from the pill instead. Applied
   by flipDropdown (js/shared/dropdown-flip.js) at open time, after measuring —
   the same anchor, the other side. */
.teams-panel .teams-msg__menu--up {
    top: auto;
    bottom: calc(100% + 6px);
}
/* Incoming messages anchor their pill LEFT, so the menu opens leftward too and
   never runs off the panel edge. */
.teams-panel .teams-msg:not(.teams-msg--mine) .teams-msg__menu {
    right: auto;
    left: 0;
}
.teams-panel .teams-msg__menu[hidden] {
    display: none;
}
.teams-panel .teams-msg__menu-title {
    padding: 4px 10px 6px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--tm-text-3);
}
/* A menu row is icon + name on one line — the round icon-button sizing of the
   pill does not apply inside the menu. */
.teams-panel .teams-msg__menu-item {
    width: 100%;
    height: auto;
    justify-content: flex-start;
    gap: 10px;
    padding: 7px 10px;
    border-radius: 6px;
    font-size: 13px;
    color: var(--tm-text-1);
}
.teams-panel .teams-msg__menu-item i {
    width: 16px;
    flex: 0 0 16px;
    text-align: center;
    color: var(--tm-text-2);
    font-size: 13px;
}
.teams-panel .teams-msg__menu-item:hover:not([disabled]) {
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}
.teams-panel .teams-msg__menu-item:hover:not([disabled]) i {
    color: var(--tm-accent);
}
/* Delete stays the one destructive row. */
.teams-panel
    .teams-msg__menu-item.teams-msg__action--delete:hover:not([disabled]),
.teams-panel
    .teams-msg__menu-item.teams-msg__action--delete:hover:not([disabled])
    i {
    background: var(--tm-danger-subtle, rgba(220, 53, 69, 0.12));
    color: var(--tm-danger);
}

/* While a message is being edited it is a form, not a bubble: the hover pill and
   the reaction chips must get out of the way (the pill otherwise floats over the
   editor's own Save/Cancel controls). */
.teams-panel .teams-msg--editing .teams-msg__actions,
.teams-panel .teams-msg--editing .teams-msg__reactions {
    display: none !important;
}

/* ── Edited marker + deleted tombstone ──────────────────────────────────────── */
/* The pencil sits next to the timestamp on every edited message. It is not
   optional and not the editor's choice — an edit is always disclosed. */
.teams-panel .teams-msg__edited {
    font-size: 10px;
    color: var(--tm-text-3);
    display: inline-flex;
    align-items: center;
    gap: 3px;
    cursor: default;
}

/* Reminder-set badge — a Calendar event is linked to this message. Rendered
   hidden until teams-message-reminder.js's batched lookup confirms the
   VIEWER (not just anyone) may see it, then unhidden in place.
 *
 * LIVES OUTSIDE THE BUBBLE, MIRRORING .teams-msg__receipt — not in
 * .teams-msg__meta (the sender/time row): that row sits directly under
 * .teams-msg__actions' hover-toolbar anchor point (top: -25px overlaps it),
 * so a badge there was permanently covered by "reply/react/more" on hover.
 * Anchored to the SIDE OPPOSITE the toolbar (toolbar is left for an incoming
 * message, right for --mine — see .teams-msg__actions above) so hovering
 * the toolbar never covers it either. Own messages also dodge
 * .teams-msg__receipt (right: -20px) by sitting on the left instead.
 *
 * The `[hidden]` variant is declared SEPARATELY, at higher specificity than
 * the plain rule below (one extra attribute selector) — declaring `display`
 * only on the bare class would beat the UA's `[hidden]{display:none}` and
 * the badge would show for every message regardless of the actual lookup. */
.teams-panel .teams-msg__reminder-badge {
    position: absolute;
    top: 50%;
    right: -20px;
    transform: translateY(-50%);
    font-size: 11px;
    color: var(--tm-text-3);
    background: none;
    border: none;
    padding: 0;
    display: inline-flex;
    align-items: center;
    cursor: pointer;
}
.teams-panel .teams-msg__reminder-badge[hidden] {
    display: none;
}
.teams-panel .teams-msg--mine .teams-msg__reminder-badge {
    right: auto;
    left: -20px;
}
.teams-panel .teams-msg__reminder-badge:hover,
.teams-panel .teams-msg__reminder-badge:focus-visible {
    color: var(--tm-accent, var(--tm-text-1));
}

/* A message its author retracted. Keeps the sender + time so the timeline still
   reads correctly; the bubble itself is muted, italic and non-interactive. */
.teams-panel .teams-msg--deleted .teams-msg__bubble--deleted {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    background: transparent;
    border: 1px dashed var(--tm-border);
    color: var(--tm-text-3);
    font-style: italic;
    font-size: 0.92em;
}
.teams-panel .teams-msg--deleted .teams-msg__bubble--deleted i {
    font-size: 11px;
}
/* No hover affordances on a tombstone — nothing left to react to, reply to or
   pin. Hiding the toolbar in CSS is cosmetic; the server refuses these anyway. */
.teams-panel .teams-msg--deleted .teams-msg__actions {
    display: none;
}

/* ── Inline message editor (edit-in-place inside the bubble) ─────────────────── */
.teams-panel .teams-msg__editor {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: min(520px, 60vw);
    /* The editor is sized in JS to the width the message text already had (see
       _beginMessageEdit) so a long message doesn't collapse into a narrow
       column; this keeps that inline width inside the bubble on any viewport. */
    max-width: 100%;
}
.teams-panel .teams-msg__editor-input {
    width: 100%;
    resize: none;
    border: 1px solid var(--tm-accent);
    border-radius: 6px;
    padding: 6px 8px;
    font: inherit;
    line-height: 1.5;
    color: var(--tm-msg-text);
    background: var(--tm-white);
    max-height: 40vh;
    overflow-y: auto;
}
.teams-panel .teams-msg__editor-input:focus {
    outline: none;
}
.teams-panel .teams-msg__editor-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
}
/* Files in an edit: the composer's chips, minus the composer's 20px gutter. */
.teams-panel .teams-msg__editor-attachments {
    padding: 8px 0 0;
}
.teams-panel .teams-msg__editor-attach {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--tm-text-2);
    cursor: pointer;
}
.teams-panel .teams-msg__editor-attach:hover:not(:disabled) {
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}
.teams-panel .teams-msg__editor-attach:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}
.teams-panel .teams-msg__editor-hint {
    margin-right: auto;
    font-size: 11px;
    color: var(--tm-text-3);
}
.teams-panel .teams-msg__editor-btn {
    flex-shrink: 0;
    white-space: nowrap;
    border: 1px solid var(--tm-border);
    border-radius: 6px;
    background: transparent;
    color: var(--tm-text-2);
    font-size: 12px;
    padding: 3px 10px;
    cursor: pointer;
    transition:
        background var(--tm-t),
        color var(--tm-t);
}
.teams-panel .teams-msg__editor-btn--save {
    background: var(--tm-accent);
    border-color: var(--tm-accent);
    color: var(--tm-white);
}
.teams-panel .teams-msg__editor-btn:hover {
    filter: brightness(1.05);
}
/* A phone has no Enter-to-save or Esc: the hint named keys that do not exist
   and squeezed Cancel / Save into two-line stubs. Drop it, widen the floor
   (a short message pinned the editor to a sliver) and size the buttons for
   a thumb. */
@media (hover: none), (pointer: coarse) {
    .teams-panel .teams-msg__editor {
        min-width: min(320px, 75vw);
    }
    .teams-panel .teams-msg__editor-hint {
        display: none;
    }
    .teams-panel .teams-msg__editor-btn {
        min-height: 36px;
        padding: 6px 16px;
        font-size: 14px;
    }
}
/* In-flight save: block double submits without collapsing the editor. */
.teams-panel .teams-msg__editor--busy {
    opacity: 0.6;
    pointer-events: none;
}
/* Assistant answers render in a bot container; anchor + nudge their toolbar. */
.teams-panel .teams-msg-repliable {
    position: relative;
}
.teams-panel .teams-msg-repliable .teams-msg__actions {
    top: -12px;
    left: 4px;
    right: auto;
}

/* ── Quick-reaction emojis inside the hover pill ─────────────────────────────── */
.teams-panel .teams-msg__quickreacts {
    display: inline-flex;
    align-items: center;
    gap: 1px;
    padding-right: 2px;
    margin-right: 2px;
    border-right: 1px solid var(--tm-border);
}
.teams-panel .teams-msg__quickreact {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
    transition:
        background var(--tm-t),
        transform var(--tm-t);
}
.teams-panel .teams-msg__quickreact:hover {
    background: var(--tm-accent-subtle);
    transform: scale(1.25);
}
/* "+" more-emoji: an icon (not an emoji glyph) opening the full picker. Muted
 * until hover; a hair smaller than the glyph buttons and never zoom-scaled. */
.teams-panel .teams-msg__reactmore {
    font-size: 16px;
    color: var(--tm-text-3);
    margin-left: 1px;
}
.teams-panel .teams-msg__reactmore:hover {
    transform: none;
    color: var(--tm-accent);
}

/* ── Aggregated reaction chips under a bubble ────────────────────────────────── */
.teams-panel .teams-msg__reactions {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: -6px;
    z-index: 10;
    /* Controls, not message text — same reasoning as `.teams-msg__actions`.
       A selection dragged across several messages otherwise picked up each
       chip's emoji and its count ("😀1") between the bubbles it spanned. */
    -webkit-user-select: none;
    user-select: none;
}
.teams-panel .teams-msg--mine .teams-msg__reactions {
    justify-content: flex-end;
}
.teams-panel .teams-reaction-chip {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    height: 22px;
    padding: 0 7px;
    border: 1px solid var(--tm-border);
    border-radius: 999px;
    background: var(--tm-white);
    color: var(--tm-text-2);
    font-size: 12px;
    line-height: 1;
    cursor: pointer;
    transition:
        background var(--tm-t),
        border-color var(--tm-t),
        transform var(--tm-t);
}
.teams-panel .teams-reaction-chip:hover {
    border-color: var(--tm-border-strong);
}
.teams-panel .teams-reaction-chip--mine {
    background: var(--tm-real-white);
    /* border-color: var(--tm-real-white); */
    color: var(--tm-accent);
    z-index: 10;
}
.teams-panel .teams-reaction-chip__emoji {
    font-size: 13px;
}
.teams-panel .teams-reaction-chip__count {
    font-weight: 600;
}
.teams-panel .teams-reaction-chip--pop {
    animation: teams-reaction-pop 0.28s ease;
}
@keyframes teams-reaction-pop {
    0% {
        transform: scale(0.6);
    }
    55% {
        transform: scale(1.3);
    }
    100% {
        transform: scale(1);
    }
}

/* ── 1:1 "seen" receipt on the sender's own bubble ───────────────────────────── */
/* Bubble + receipt share a row; the reactions row lives OUTSIDE it (below), so the
 * receipt stays anchored to the bubble and never shifts when a reaction is added.
 * `align-self` shrink-wraps the row to the bubble width so the overhanging receipt
 * is always positioned relative to the BUBBLE, not the (wider) reaction row. */
.teams-panel .teams-msg__bubble-row {
    position: relative;
    align-self: flex-start;
    max-width: 100%;
}
.teams-panel .teams-msg--mine .teams-msg__bubble-row {
    align-self: flex-end;
}
.teams-panel .teams-msg__receipt {
    position: absolute;
    top: 50%;
    right: -20px;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    color: var(--tm-text-3);
    font-size: 11px;
}
.teams-panel .teams-msg__receipt--seen {
    color: var(--tm-accent);
}
/* "Seen" only on the latest seen own message; every unseen one keeps its
 * "sent" check (teams-reactions.js _scheduleLatestSeenReceipt). */
.teams-panel .teams-msg__receipt--superseded {
    display: none;
}

/* ── "Read by" modal (group chats) ───────────────────────────────────────────── */
.teams-modal-overlay.teams-readby-overlay .teams-modal {
    max-width: 380px;
}
.teams-readby-overlay .teams-readby__section {
    margin-bottom: 14px;
}

.teams-readby-overlay .teams-readby__section:first-child {
    border-bottom: 1px solid var(--tm-border);
    padding-bottom: 10px;
    margin-bottom: 30px;
}

.teams-readby-overlay .teams-readby__heading {
    margin: 0 0 6px;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--tm-text-3);
}
.teams-readby-overlay .teams-readby__list {
    list-style: none;
    margin: 0;
    padding: 0;
}
/* One child (the name) since the timestamp was removed — see
 * _openReadByModal for why there is no per-message read time to show. Left
 * aligned rather than space-between, which only mattered with a trailing cell. */
.teams-readby-overlay .teams-readby__row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 6px 2px;
}
.teams-readby-overlay .teams-readby__name {
    color: var(--tm-text-2);
    font-size: 14px;
}
.teams-readby-overlay .teams-readby__empty {
    color: var(--tm-text-3);
    font-size: 13px;
    padding: 4px 2px;
}

/* Quoted-parent preview INSIDE the bubble, above the reply text. Neutral inset
 * overlay so it reads on both the white and the "mine" (accent) bubble and in
 * dark mode without a per-theme override. */
.teams-panel .teams-msg__reply-quote,
.teams-panel .teams-msg__reply-quote--missing {
    display: flex;
    flex-direction: column;
    gap: 1px;
    max-width: 340px; /* cap so a long snippet ellipsizes instead of widening the bubble */
    margin-bottom: 6px;
    padding: 4px 8px;
    text-align: left;
    border: none;
    border-left: 3px solid var(--tm-accent);
    border-radius: 3px;
    background: rgba(128, 128, 128, 0.15);
    font: inherit;
    cursor: pointer;
    transition: background var(--tm-t);
    position: relative;
    width: 90%;
}
.teams-panel .teams-msg__reply-quote:hover {
    background: rgba(128, 128, 128, 0.24);
}
.teams-panel .teams-msg__reply-quote-sender {
    font-size: 11px;
    font-weight: 600;
    color: var(--tm-accent);
}
.teams-panel .teams-msg__reply-quote-snippet {
    min-width: 0; /* allow the flex child to shrink so ellipsis engages */
    font-size: 12px;
    color: var(--tm-text-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.teams-panel .teams-msg__reply-quote-snippet--media,
.teams-panel .teams-composer-reply-chip__snippet--media {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.teams-panel .teams-msg__reply-quote-media i,
.teams-panel .teams-composer-reply-chip__snippet--media i {
    color: var(--tm-accent);
    font-size: 11px;
    padding-right: 6px;
}
.teams-panel .teams-msg__reply-thumb {
    width: 36px;
    height: 36px;
    flex: 0 0 auto;
    object-fit: cover;
    border-radius: 6px;
    background: var(--tm-border-strong);
}
.teams-panel .teams-msg__reply-quote--missing {
    border-left-color: var(--tm-border-strong);
    color: var(--tm-text-3);
    font-size: 12px;
    font-style: italic;
    cursor: default;
}

/* The FORWARDER's own note, above the quoted block. Ordinary message text —
   because that is what it is. It is the QUOTE below that is set apart, not
   this: the note is the sender speaking in their own chat, and it should read
   exactly like any other message they wrote. */
.teams-panel .teams-msg__forward-note {
    margin-bottom: 8px;
    white-space: pre-wrap;
    word-break: break-word;
}

/* THE FORWARDED MESSAGE ITSELF, as a QUOTE.
   An attribution line alone was too weak: with a note above it, the two voices
   ran together and the bubble read as one person saying all of it ("it looks
   very weird" — reported the first time a forward carried a comment). A left
   bar and an inset ground are the same device this app already uses for a
   reply quote and for the forward preview in the picker, so the shape already
   means "somebody else's words" everywhere else a reader has seen it. */
.teams-panel .teams-msg__forward-quote {
    padding: 6px 10px;
    border-left: 3px solid var(--tm-border);
    border-radius: 0 6px 6px 0;
    background: var(--tm-bg-alt);
}
/* On the sender's own (accent-filled) bubble the muted ground disappears —
   translucent white keeps the inset readable against either background without
   needing a second colour. */
.teams-panel .teams-msg--mine .teams-msg__forward-quote {
    border-left-color: rgba(0, 0, 0, 0.18);
    background: rgba(255, 255, 255, 0.45);
}
/* The quote owns the bottom of the bubble, so its padding replaces the
   bubble's own — otherwise the inset floats with a visible gap beneath it. */
.teams-panel .teams-msg__bubble > .teams-msg__forward-quote:last-child {
    margin-bottom: -1px;
}

/* "Forwarded from <sender> in <chat>" attribution — always shown at the TOP
 * of a forwarded bubble (never a silent copy), plain label rather than a
 * quote box: unlike a reply quote it names its own SOURCE conversation, not
 * a message inside THIS one, so there is nowhere sensible to scroll on click. */
.teams-panel .teams-msg__forwarded {
    display: flex;
    align-items: center;
    gap: 5px;
    margin-bottom: 3px;
    font-size: 11.5px;
    font-style: italic;
    color: var(--tm-text-3);
}
.teams-panel .teams-msg__forwarded i {
    font-size: 10px;
}

/* Composer chip: "Replying to <name>: <snippet>" above the adopted input. */
.teams-panel .teams-composer-reply-chip {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 20px;
    padding: 6px 10px;
    border: 1px solid var(--tm-border);
    border-left: 3px solid var(--tm-accent);
    border-radius: var(--tm-r);
    background: var(--tm-surface);
}
.teams-panel .teams-composer-reply-chip__icon {
    color: var(--tm-accent);
    font-size: 12px;
}
.teams-panel .teams-composer-reply-chip__text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
    flex: 1;
}
.teams-panel .teams-composer-reply-chip__label {
    font-size: 12px;
    font-weight: 600;
    color: var(--tm-text-1);
}
.teams-panel .teams-composer-reply-chip__snippet {
    font-size: 12px;
    color: var(--tm-text-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.teams-panel .teams-composer-reply-chip__cancel {
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: var(--tm-r);
    background: transparent;
    color: var(--tm-text-3);
    cursor: pointer;
    transition:
        background var(--tm-t),
        color var(--tm-t);
}
.teams-panel .teams-composer-reply-chip__cancel:hover {
    background: var(--tm-bg-alt);
    color: var(--tm-danger);
}

/* Flash the parent when a quote is clicked (scroll-to + highlight). */
.teams-panel .teams-msg--flash .teams-msg__bubble,
.teams-panel .teams-msg-repliable.teams-msg--flash {
    animation: teams-msg-flash 1.6s ease;
}
@keyframes teams-msg-flash {
    0%,
    100% {
        box-shadow: 0 0 0 0 transparent;
    }
    15% {
        box-shadow: 0 0 0 3px var(--tm-accent);
    }
    50% {
        box-shadow: 0 0 0 3px var(--tm-accent-subtle);
    }
}
@media (prefers-reduced-motion: reduce) {
    .teams-panel .teams-msg--flash .teams-msg__bubble,
    .teams-panel .teams-msg-repliable.teams-msg--flash {
        animation: none;
        outline: 2px solid var(--tm-accent);
    }
}

/* ── Composer slot — hosts the ADOPTED shared chat input (#inputContainer) ─────
 * Teams reuses the platform chat input rather than a separate composer (#6), so
 * this slot only provides the surrounding chrome (border, hint). The input keeps
 * its own styles from main-chat.css. */
.teams-panel .teams-conversation__composer-slot {
    flex-shrink: 0;
    /* border-top: 1px solid var(--tm-border);
    background: var(--tm-surface); */
}
.teams-panel .teams-conversation__composer-slot #inputContainer {
    /* The shared #inputContainer is normally laid out inside #panel-chat (which
     * is display:none while Teams is active) and may carry chat-panel-scoped
     * absolute positioning / hidden state. When ADOPTED into this slot, force it
     * back to a plain in-flow, visible block so the field always appears. Scoped
     * to the composer slot so the real chat input is never affected.
     *
     * `relative`, NOT `static`: #inputContainer's own .mic-button/.send-button
     * are `position: absolute`, and this is their nearest positioned ancestor for
     * PLACEMENT — `top/right` are computed against it. (Their PAINT ORDER is a
     * separate question, fixed at `.teams-conversation__composer-slot` below —
     * see that comment for why the icons showed through the AI observers
     * popover; it was not this.) `relative` with no offset stays visually
     * identical to `static` — still in normal flow — while giving the length
     * counter overlay (teams-rich-editor.css `.teams-len`) a sane containing
     * block too, instead of leaking out to the composer slot for that as well. */
    display: flex !important;
    position: relative !important;
    inset: auto !important;
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
    height: auto !important;
    opacity: 1 !important;
    visibility: visible !important;
    transform: none !important;
    pointer-events: auto !important;
    padding: 5px 20px;
    gap: 5px;
}

.teams-panel .teams-conversation__composer-slot #inputContainer .input-row {
    display: flex !important;
    width: 100%;
    position: relative;
    align-items: center;
}
.teams-panel .teams-conversation__composer-slot .input-row #userInput {
    display: block !important;
    visibility: visible !important;
    width: 100%;
    /* The shared textarea normally takes its foreground/background from the
       Chat tab. It is adopted into Teams, where the global focused background
       remains white in dark mode, so bind both sides of the contrast pair to
       the Teams theme instead. */
    background-color: var(--tm-real-white, #fff);
    border-color: var(--tm-border, #d8d3c8);
    color: var(--tm-msg-text, #1f1e1d);
    caret-color: var(--tm-msg-text, #1f1e1d);
    /* 80px clears BOTH left icons: the paperclip (~10px) and the emoji button
       (absolute at left:44px). Mirror below must match to keep @tokens aligned. */
    padding-left: 70px;
    padding-right: 54px;
}
/* Smaller placeholder so the single-line hint fits without wrapping. Applies to
 * the placeholder only — typed text keeps the input's normal size. */
.teams-panel .teams-conversation__composer-slot #userInput::placeholder {
    font-size: 0.95em;
    color: var(--tm-text-3, #9a9488);
}
/* The mention highlighter is a grid overlay. Keep its stacking context below
 * the sibling mic/send controls, while preserving the main chat's native
 * button visibility and speech-to-text behavior. */
.teams-panel .teams-conversation__composer-slot .mention-input-shell {
    z-index: 0;
}
/* The Teams composer widens #userInput's horizontal padding (50px/54px) to clear
 * the attach + mic/send icons. The mention-highlight mirror must match, or the
 * coloured @token drifts left of the typed text. #inputContainer is in the
 * selector so it out-specifies the base `#inputContainer .mention-input-highlight`
 * ID rule; vertical padding + line-height are inherited from that base. */
.teams-panel
    .teams-conversation__composer-slot
    #inputContainer
    .mention-input-highlight {
    padding-left: 80px;
    padding-right: 54px;
}

body:not(.mobile-standalone)
    .chat-area
    #inputContainer.teams-input-adopted
    .mention-input-highlight {
    padding-left: 70px;
    padding-right: 54px;
}

/* The main chat syncs the textarea + mirror font via `.chat-area #inputContainer
 * textarea` / `.mention-input-highlight`, but the adopted Teams composer is NOT
 * inside `.chat-area`, so those never apply and the textarea vs mirror end up on
 * DIFFERENT fonts → the coloured @token drifts across the line. `inherit` isn't
 * reliable here (a form control resolves it differently than the sibling div), so
 * pin BOTH to the SAME explicit stack — the Teams UI font (--tm-font-ui, Figtree)
 * so the composer matches the rest of the surface — with identical size, weight,
 * line-height and letter-spacing. Identical metrics on both = the overlay stays
 * aligned end-to-end. */
.teams-panel .teams-conversation__composer-slot #inputContainer #userInput,
.teams-panel
    .teams-conversation__composer-slot
    #inputContainer
    .mention-input-highlight {
    font-family: var(--tm-font-ui);
    font-size: 1rem;
    line-height: 26px;
    letter-spacing: normal;
    font-weight: 400;
}
.teams-panel .teams-conversation__composer-slot .mic-button,
.teams-panel .teams-conversation__composer-slot .send-button {
    z-index: 1;
}
.teams-panel .teams-audio-recorder {
    position: absolute;
    z-index: 4;
    left: 50%;
    bottom: calc(100% + 8px);
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 8px;
    /* Sized to its content so "Release to attach" stays on one line, but
       never wider than the screen minus a gutter. */
    width: max-content;
    min-width: 250px;
    max-width: calc(100vw - 24px);
    box-sizing: border-box;
    white-space: nowrap;
    padding: 10px 14px;
    border: 1px solid color-mix(in srgb, var(--tm-danger) 38%, var(--tm-border));
    border-radius: 999px;
    background: var(--tm-real-white, #fff);
    color: var(--tm-msg-text);
    box-shadow: var(--tm-shadow-md);
    font-size: 14px;
}
.teams-panel .teams-audio-recorder[hidden] { display: none; }
.teams-panel .teams-audio-recorder__dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--tm-danger);
    animation: teams-audio-dot 1s ease-in-out infinite;
}
.teams-panel .teams-audio-recorder__hint { color: var(--tm-text-3); margin-left: auto; }
.teams-panel .teams-conversation__composer-slot .mic-button.teams-audio-recording {
    color: var(--tm-danger);
    background: var(--tm-danger-bg);
}
.teams-panel .teams-conversation__composer-slot .mic-button.teams-audio-uploading {
    pointer-events: none;
    opacity: 0.6;
}
@keyframes teams-audio-dot {
    50% { transform: scale(1.45); opacity: 0.45; }
}
.teams-panel .teams-conversation--ai-streaming .teams-conversation__scroll-btn {
    display: none !important;
}
.teams-panel .teams-conversation__hint {
    padding-left: 40px;
    font-size: 12px;
    color: var(--tm-text-3);
}
.teams-panel .teams-conversation__hint strong {
    color: var(--tm-agent);
}

/* File upload isn't supported by the human-first send endpoint — hide the
 * paperclip + attachments while the input is adopted by Teams. */
/* .teams-panel .teams-conversation__composer-slot .file-upload-button,
.teams-panel .teams-conversation__composer-slot .file-attachments-container {
    display: none !important;
} */

/* ── "From a Space post" card ────────────────────────────────────────────────
   The post a "Continue in chat" conversation was started from.

   A CARD, not a bubble, and that distinction is the whole point: team chat
   bubbles are plain text (escape + mentions + bare-URL linkify), so the first
   version of this feature — which sent markdown — opened the chat with literal
   asterisks, a raw image URL and a link nobody could click. This card renders
   the snippet through the shared markdown renderer, shows the images as
   images, and makes "Open the post" a button.

   Scoped under .teams-conversation (CLAUDE.md rule 2). */

.teams-conversation .teams-space-share {
    margin: 12px 0;
    padding: 0 0 12px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r-lg);
    background: var(--tm-surface);
    overflow: hidden;
}

.teams-conversation .teams-space-share__header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 14px;
    border-bottom: 1px solid var(--tm-border);
    background: var(--tm-surface-2, transparent);
    color: var(--tm-text-2);
    font-size: 12px;
}

.teams-conversation .teams-space-share__label { font-weight: 600; }
.teams-conversation .teams-space-share__time { margin-left: auto; opacity: 0.8; }

.teams-conversation .teams-space-share__title {
    padding: 12px 14px 0;
    font-size: 15px;
    font-weight: 650;
    color: var(--tm-text);
}

.teams-conversation .teams-space-share__author {
    padding: 2px 14px 0;
    font-size: 12px;
    color: var(--tm-text-2);
}

.teams-conversation .teams-space-share__body {
    padding: 8px 14px 0;
    font-size: 14px;
    line-height: 1.55;
    color: var(--tm-text);
    /* The card is an invitation to open the post, not a second copy of it. */
    max-height: 180px;
    overflow: hidden;
}

.teams-conversation .teams-space-share__images {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 10px 14px 0;
}

.teams-conversation .teams-space-share__images img {
    width: 96px;
    height: 96px;
    object-fit: cover;
    border-radius: 8px;
    border: 1px solid var(--tm-border);
}

.teams-conversation .teams-space-share__footer {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 12px 14px 0;
}

.teams-conversation .teams-space-share__by {
    font-size: 12px;
    color: var(--tm-text-2);
}

.teams-conversation .teams-space-share__open {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

/* ── Calendar event chat context ───────────────────────────────────────── */

.teams-conversation .teams-calendar-intro {
    margin: 12px 0;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r-lg);
    background: var(--tm-surface);
    overflow: hidden;
}
.teams-conversation .teams-calendar-intro__header,
.teams-conversation .teams-calendar-intro__footer {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 14px;
    color: var(--tm-text-2);
    font-size: 12px;
}
.teams-conversation .teams-calendar-intro__header {
    border-bottom: 1px solid var(--tm-border);
    background: var(--tm-surface-2, transparent);
}
.teams-conversation .teams-calendar-intro__label { font-weight: 600; }
.teams-conversation .teams-calendar-intro__time { margin-left: auto; opacity: .8; }
.teams-conversation .teams-calendar-intro__title {
    padding: 12px 14px 4px;
    font-size: 15px;
    font-weight: 650;
    color: var(--tm-text);
}
.teams-conversation .teams-calendar-intro__cancelled {
    display: inline-block;
    margin-left: 8px;
    padding: 2px 6px;
    border-radius: 10px;
    color: var(--tm-danger, #c0392b);
    background: color-mix(in srgb, var(--tm-danger, #c0392b) 12%, transparent);
    font-size: 11px;
    font-weight: 600;
    vertical-align: middle;
}
.teams-conversation .teams-calendar-intro__facts {
    margin: 0;
    padding: 3px 14px 0;
    display: grid;
    gap: 6px;
    color: var(--tm-text-2);
    font-size: 13px;
}
.teams-conversation .teams-calendar-intro__facts div { display: grid; grid-template-columns: 105px minmax(0, 1fr); gap: 8px; }
.teams-conversation .teams-calendar-intro__facts dt,
.teams-conversation .teams-calendar-intro__facts dd { margin: 0; }
.teams-conversation .teams-calendar-intro__facts dt { font-weight: 600; }
.teams-conversation .teams-calendar-intro__facts dt i { width: 14px; }
.teams-conversation .teams-calendar-intro__facts dd { color: var(--tm-text); overflow-wrap: anywhere; }
.teams-conversation .teams-calendar-intro__footer { padding-top: 12px; flex-wrap: wrap; }
.teams-conversation .teams-calendar-intro__footer span { margin-left: 2px; }

/* ── An AI wrote it, a person sent it ──────────────────────────────────────
 *
 * An observer's `direct` post and a shared Ask-AI answer are both SENT by a
 * person — the support desk attributes and authorises on them, and that is
 * right. But the words are the agent's, and until this they rendered under a
 * human's name and photograph: the claim "I am a person", made on the model's
 * behalf and far more convincingly than the model could make it itself, in a
 * product whose observer protocol explicitly forbids exactly that.
 *
 * Deliberately the same visual language as a tagged @Amby reply — left-aligned,
 * agent avatar, agent name — because a reader should not have to learn a second
 * way of recognising an AI depending on which door it came through. */
.teams-panel .teams-msg--ai-authored .teams-avatar--ai {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--teams-accent-soft, #eef2ff);
    color: var(--teams-accent, #3f51b5);
    font-size: 13px;
}

.teams-panel .teams-msg__sender--ai {
    color: var(--teams-accent, #3f51b5);
}

/* Who is accountable for it reaching the chat, which is NOT who wrote it:
   "auto-reply" for an unattended observer, "sent by <name>" when a
   person read the draft and chose to send it. The second is not a footnote —
   that judgement is what makes it a human response to the desk. */
.teams-panel .teams-msg__ai-note {
    font-size: 11px;
    color: var(--teams-text-muted, #6b6b6b);
    font-style: italic;
}


/* ── "Copied" feedback on the Copy row of the message menu ───────────────────
   The menu closes on the click, so the confirmation has to be ON the control
   that was pressed rather than only in a toast. A short pop plus the accent
   colour; `prefers-reduced-motion` keeps the colour change and drops the
   movement, since the colour is what actually carries the message. */
.teams-panel .teams-msg__action--copied {
    color: var(--tm-accent);
    animation: teams-copied-pop 260ms ease-out;
}
.teams-panel .teams-msg__action--copied i {
    color: var(--tm-accent);
}
@keyframes teams-copied-pop {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.09); }
    100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
    .teams-panel .teams-msg__action--copied {
        animation: none;
    }
}
.teams-panel .teams-attach__chip-pct {
    font-variant-numeric: tabular-nums;
    opacity: 0.75;
    white-space: nowrap;
}

/* Legacy attachments have no dimensions. Keep their fallback box after load. */
.teams-panel .teams-att--image img:not([width][height]) {
    width: 320px;
    height: 220px;
    object-fit: contain;
    background: rgba(127,127,127,.1);
}
.teams-panel .teams-att--video[data-layout-fixed] {
    object-fit: contain;
    height: auto;
}

/* An agent's structured form for the person who asked (teams-structured-form.js).
   The card itself is the shared .structured-feedback-card from feedback-ui.css. */
.teams-conversation__messages .teams-feedback-note {
    align-self: center;
    width: min(560px, 100%);
    margin: 8px auto;
}

/* The docked structured form in a Teams chat: more compact than the main chat's. */
.teams-conversation__composer-slot .structured-feedback-modal--docked .structured-feedback-modal__dialog { max-height: min(46vh, 420px); }
.teams-conversation__composer-slot .structured-feedback-modal--docked .structured-feedback-modal__content { padding: 12px 16px; }
.teams-conversation__composer-slot .structured-feedback-modal--docked .structured-feedback-modal__header { margin-bottom: 8px; }
.teams-conversation__composer-slot .structured-feedback-modal--docked .structured-feedback-modal__header h3 { font-size: 1rem; }
.teams-conversation__composer-slot .structured-feedback-modal--docked .structured-feedback-modal__question { font-size: 0.92rem; margin-bottom: 8px; }
.teams-conversation__composer-slot .structured-feedback-modal--docked .structured-feedback-modal__options { gap: 6px; }
.teams-conversation__composer-slot .structured-feedback-modal--docked .structured-feedback-modal__option { padding: 7px 10px; border-radius: 10px; font-size: 0.9rem; }
.teams-conversation__composer-slot .structured-feedback-modal--docked .structured-feedback-modal__option--custom { margin-top: 6px; }

/* Touch-only hold-to-spotlight. JS adds this state after a deliberate hold;
   desktop retains the quieter hover toolbar above. The backdrop and raised
   message make the selected bubble read as the current action target. */
.teams-msg__spotlight-backdrop {
    position: fixed;
    z-index: 1900;
    inset: 0;
    pointer-events: none;
}
.teams-msg__spotlight-scrim {
    position: fixed;
    border: 0;
    padding: 0;
    background: rgba(18, 24, 32, .48);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    pointer-events: auto;
    touch-action: none;
}
.teams-msg__spotlight-shield {
    position: fixed;
    z-index: 1;
    background: transparent;
    touch-action: none;
    pointer-events: auto;
}
/* Transient scroll room for a spotlighted final message. It is appended only
   while the overlay is open, then removed with it. */
.teams-msg__spotlight-spacer {
    width: 100%;
    flex: 0 0 auto;
    pointer-events: none;
    overflow-anchor: none;
}
body > .teams-msg__spotlight-actions {
    position: fixed;
    z-index: 1902;
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: center;
    box-sizing: border-box;
    width: 360px;
    gap: 4px;
    padding: 8px;
    padding-bottom: max(8px, env(safe-area-inset-bottom, 0px));
    overflow-y: auto;
    overscroll-behavior: contain;
    touch-action: pan-y;
    border: 1px solid #d9d5cc;
    border-radius: 18px;
    background: #fff;
    box-shadow: 0 7px 20px rgba(26, 31, 37, .24);
    opacity: 1;
    pointer-events: auto;
}
body > .teams-msg__spotlight-actions > .teams-msg__action,
body > .teams-msg__spotlight-actions .teams-msg__quickreact {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: #5e5a53;
    font-size: 21px;
}
body > .teams-msg__spotlight-actions .teams-msg__quickreacts {
    display: inline-flex;
    align-items: center;
    justify-content: space-around;
    min-width: 0;
    gap: 0;
}
body > .teams-msg__spotlight-actions .teams-msg__menu {
    display: flex;
    flex-direction: column;
    gap: 1px;
    grid-column: 1 / -1;
    min-width: 0;
    padding: 6px 0 0;
    border: 0;
    border-top: 1px solid #d9d5cc;
    background: transparent;
    white-space: normal;
    text-align: left;
}
body > .teams-msg__spotlight-actions .teams-msg__menu-title {
    padding: 4px 10px 6px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: #8a8479;
}
body > .teams-msg__spotlight-actions .teams-msg__menu-item {
    display: inline-flex;
    align-items: center;
    width: 100%;
    gap: 10px;
    min-height: 44px;
    padding: 10px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: #302e2a;
    font-size: 15px;
    text-align: left;
}
body > .teams-msg__spotlight-actions .teams-msg__menu-item i {
    width: 16px;
    flex: 0 0 16px;
    text-align: center;
    color: #625e57;
}
body.dark-theme > .teams-msg__spotlight-actions {
    border-color: #485260;
    background: #252d38;
    box-shadow: 0 9px 24px rgba(0, 0, 0, .5);
}
body.dark-theme > .teams-msg__spotlight-actions .teams-msg__quickreacts { border-color: #485260; }
body.dark-theme > .teams-msg__spotlight-actions > .teams-msg__action,
body.dark-theme > .teams-msg__spotlight-actions .teams-msg__quickreact { color: #c8d1db; }
body.dark-theme > .teams-msg__spotlight-actions .teams-msg__menu {
    border-color: #485260;
    background: #252d38;
}
body.dark-theme > .teams-msg__spotlight-actions .teams-msg__menu-title { color: #aeb8c4; }
body.dark-theme > .teams-msg__spotlight-actions .teams-msg__menu-item { color: #edf1f5; }
body.dark-theme > .teams-msg__spotlight-actions .teams-msg__menu-item i { color: #bac5d1; }

body > .teams-msg__spotlight-actions > [data-more-actions],
body > .teams-msg__spotlight-actions .teams-msg__menu-title {
    display: none;
}
body > .teams-msg__spotlight-actions .teams-msg__quickreact {
    flex: 1;
    min-width: 0;
    font-size: 26px;
}
body > .teams-msg__spotlight-actions .teams-msg__action--delete {
    color: #cf4242;
}

/* Loaded with Teams itself; independent of the optional global toast library. */
body > .teams-msg__copied-toast {
    position: fixed;
    z-index: 10001;
    left: 50%;
    bottom: calc(80px + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    box-sizing: border-box;
    max-width: calc(100vw - 32px);
    padding: 12px 20px;
    border-radius: 12px;
    background: #252d38;
    color: #fff;
    box-shadow: 0 4px 18px rgba(0, 0, 0, .25);
    font-size: 15px;
    line-height: 1.4;
    text-align: center;
    pointer-events: none;
}
body.dark-theme > .teams-msg__copied-toast {
    background: #edf1f5;
    color: #252d38;
}

/* Swipe-to-reply (chat_page/js/teams-swipe-reply.js). Touch only: the classes
   below are only ever set by a touch gesture, so desktop never matches.
   The row's children move; the reply icon stays put in the space they leave. */
.teams-panel .teams-conversation__messages .teams-msg:is(.is-swiping, .is-swipe-settling) {
    overflow-x: clip;
}
.teams-panel .teams-conversation__messages .teams-msg:is(.is-swiping, .is-swipe-settling)
    > :not(.teams-msg__swipe-reply-icon) {
    transform: translate3d(var(--teams-swipe-x, 0px), 0, 0);
}
/* 220ms — SETTLE_MS in the JS removes the state when this finishes. */
.teams-panel .teams-conversation__messages .teams-msg.is-swipe-settling
    > :not(.teams-msg__swipe-reply-icon) {
    transition: transform 220ms cubic-bezier(.2, .8, .2, 1);
}
.teams-panel .teams-conversation__messages .teams-msg__swipe-reply-icon {
    position: absolute;
    /* Overridden inline with the bubble's centre; 50% is the fallback. */
    top: 50%;
    left: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    margin-top: -16px;
    border-radius: 50%;
    background: var(--tm-accent-subtle, rgba(0, 0, 0, .08));
    color: var(--tm-text-2);
    font-size: 14px;
    pointer-events: none;
    opacity: var(--teams-swipe-progress, 0);
    transform: scale(calc(.6 + .4 * var(--teams-swipe-progress, 0)));
    transition: background-color 120ms ease, color 120ms ease, transform 120ms ease;
}
.teams-panel .teams-conversation__messages .teams-msg.is-swipe-armed .teams-msg__swipe-reply-icon {
    background: var(--tm-accent);
    color: var(--tm-real-white, #fff);
    transform: scale(1.08);
}
@media (prefers-reduced-motion: reduce) {
    .teams-panel .teams-conversation__messages .teams-msg.is-swipe-settling
        > :not(.teams-msg__swipe-reply-icon) {
        transition: none;
    }
}

/* ── Formatting composer (Amby Teams) ─────────────────────────────────────────
 *
 * The rich-text composer and its toolbar, plus the formatted body inside a
 * message bubble. See frontend/chat_page/js/teams-rich-editor.js.
 *
 * SCOPING (CLAUDE.md rule 2). Everything here is scoped to `.teams-panel`, to
 * `:is(#inputContainer, .teams-thread-input).teams-rich-active`, or to `.space-post-modal`, because the
 * composer this attaches to is the CHAT TAB'S input element, borrowed while
 * Teams is open and handed back on teardown. An unscoped rule here would follow
 * that element back into the Chat tab and restyle a composer this feature does
 * not own.
 *
 * THREE SCOPES, ONE RULE SET. `.space-post-modal` is the Space post composer,
 * which mounts THE SAME editor in its inline mode. It is a third scope on the
 * existing selectors rather than a copied stylesheet: the toolbar, the swatch
 * menu and the editable surface are one component, and a second copy of ~250
 * lines is how the two surfaces drift into looking like different products.
 * The modal is appended to <body>, outside `.spaces-panel`, so it cannot be
 * reached through the Spaces scope and could not borrow its `--sp-*` tokens
 * either — the `--tm-*` tokens used throughout this file are on :root.
 */

/* The rich surface clears the same controls the textarea does. Kept in one
   place so the two can't drift apart mid-message. */


/* ── In-place expansion (composer) ───────────────────────────────────────────
 *
 * THE SHAPE THIS HAS TO KEEP. The composer is ONE field with one set of
 * controls. Turning formatting on EXPANDS that field — a toolbar row appears
 * above the text and the text surface becomes editable-rich — it does not add
 * a second input box above the first. Everything below is driven by a single
 * class on the existing :is(#inputContainer, .teams-thread-input), so the paperclip, emoji, mic and send
 * buttons never move and keep acting on the same message.
 */

/* The toolbar is always in the DOM (it is the composer's first row) and is
   revealed by the toggle. `display: none` by default, not `[hidden]`, because
   this element lives inside a container whose own rules use `!important`. */
:is(#inputContainer, .teams-thread-input) .teams-rich__bar {
    display: none;
}
/* The toolbar is the TOP HALF of the field, not a strip floating above it: the
   composer's pill is drawn by the textarea itself (border + 20px radius), so
   the expanded field is that pill reopened — rounded on top here, rounded on
   the bottom on the editor, and no border between them. */
:is(#inputContainer, .teams-thread-input).teams-rich-active .teams-rich__bar {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 5px 14px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-bottom: none;
    border-radius: 20px 20px 0 0;
    /* This input is temporarily moved out of .chat-area. Its former
       `--input-focus-bg` is always white, including in the app's dark theme;
       using the Teams surface token keeps the expanded field readable in both
       themes. */
    background-color: var(--tm-real-white, #fff);
    /* A narrow composer scrolls its toolbar rather than wrapping into a second
       row that pushes the text surface off-screen on a phone. */
    overflow-x: auto;
    scrollbar-width: thin;
}

/* The editable surface only exists while formatting is on; the textarea stands
   down for exactly as long. Swapping them (rather than showing both) is what
   makes this one field. */
:is(#inputContainer, .teams-thread-input) .teams-rich__editor {
    display: none;
}
:is(#inputContainer, .teams-thread-input).teams-rich-active .teams-rich__editor {
    display: block;
    flex: 1 1 auto;
    /* The pill's bottom half. Same border, background and metrics as the
       textarea it stands in for, minus the top edge and the top corners, so
       the toolbar above joins it into one continuous field. */
    border: 1px solid var(--tm-border, #d8d3c8);
    border-top: none;
    border-radius: 0 0 20px 20px;
    background-color: var(--tm-real-white, #fff);
    min-height: 50px;
    max-height: 30vh;
    overflow-y: auto;
    outline: none;
    word-break: break-word;
    /* Matches the textarea it stands in for (see teams-messages.css): clears
       the paperclip + emoji on the left and the format/mic/send cluster on the
       right, so the caret sits exactly where it did a moment ago. */
    padding: 12px 54px 12px 70px;
    font-family: var(--tm-font-ui);
    font-size: 1rem;
    line-height: 21px;
    color: var(--tm-msg-text, inherit);
}
:is(#inputContainer, .teams-thread-input).teams-rich-active :is(#userInput, .teams-thread-text-input),
:is(#inputContainer, .teams-thread-input).teams-rich-active .mention-input-highlight {
    display: none !important;
}

/* Inline (bubble edit) mode keeps its own shell — there is no composer row to
   expand there, so the editor IS the box. */
.space-post-modal .teams-rich--inline,
.teams-panel .teams-rich--inline {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--tm-accent, #2d5f84);
    border-radius: 10px;
    background: var(--tm-white, #f6f5f3);
    overflow: hidden;
}
.space-post-modal .teams-rich--inline[hidden],
.teams-panel .teams-rich--inline[hidden] {
    /* `[hidden]` must beat the `display: flex` above — a class selector
       outranks the UA's element-level `[hidden] { display: none }`, which is
       the trap documented at the top of teams-messages.css. */
    display: none;
}
.space-post-modal .teams-rich--inline .teams-rich__bar,
.teams-panel .teams-rich--inline .teams-rich__bar {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 5px 7px;
    border-bottom: 1px solid var(--tm-border, #d8d3c8);
    background: var(--tm-bg-alt, #f0ede6);
    overflow-x: auto;
    scrollbar-width: thin;
}
.space-post-modal .teams-rich--inline .teams-rich__editor,
.teams-panel .teams-rich--inline .teams-rich__editor {
    display: block;
    min-height: 48px;
    max-height: 40vh;
    overflow-y: auto;
    padding: 9px 12px;
    font: inherit;
    line-height: 1.5;
    color: var(--tm-msg-text, inherit);
    outline: none;
    word-break: break-word;
}

/* ── Toolbar buttons (both modes) ────────────────────────────────────────── */
.space-post-modal .teams-rich__btn,
.teams-panel .teams-rich__btn,
:is(#inputContainer, .teams-thread-input) .teams-rich__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border: none;
    border-radius: 5px;
    background: transparent;
    color: var(--tm-text-2, #5c5750);
    font-size: 13px;
    cursor: pointer;
    transition: background var(--tm-t, 0.15s), color var(--tm-t, 0.15s);
}
.space-post-modal .teams-rich__btn:hover,
.teams-panel .teams-rich__btn:hover,
:is(#inputContainer, .teams-thread-input) .teams-rich__btn:hover {
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.1));
    color: var(--tm-accent, #2d5f84);
}
.space-post-modal .teams-rich__btn--on,
.teams-panel .teams-rich__btn--on,
:is(#inputContainer, .teams-thread-input) .teams-rich__btn--on {
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.16));
    color: var(--tm-accent, #2d5f84);
}
.space-post-modal .teams-rich__sep,
.teams-panel .teams-rich__sep,
:is(#inputContainer, .teams-thread-input) .teams-rich__sep {
    flex: 0 0 auto;
    width: 1px;
    height: 18px;
    margin: 0 4px;
    background: var(--tm-border, #d8d3c8);
}
/* The keyboard hint rides at the end of the toolbar rather than on a line of
   its own: Enter no longer sends while this is open, and that has to be said
   somewhere the composer doesn't grow taller for. */
.space-post-modal .teams-rich__hint,
.teams-panel .teams-rich__hint,
:is(#inputContainer, .teams-thread-input) .teams-rich__hint {
    margin-left: auto;
    padding-left: 10px;
    flex: 0 0 auto;
    font-size: 11px;
    color: var(--tm-text-3, #8a8378);
    white-space: nowrap;
}

/* Placeholder for a contenteditable: driven by a class the editor maintains
   from the TEXT content, because a box left holding `<br>` after a select-all
   delete is empty to a reader but not to the DOM.

   OUT OF FLOW, and that is the whole point. A `::before` on a contenteditable
   is an inline box INSIDE the editable region: the caret sits after it, so
   clicking into an empty formatting composer put the cursor at the end of the
   placeholder text rather than at the start of the line, and the first
   character was typed into what looked like the middle of the hint. Absolute
   positioning takes it out of the line box entirely — it is painted over the
   empty editor, never measured as content. */
.space-post-modal .teams-rich__editor,
.teams-panel .teams-rich__editor,
:is(#inputContainer, .teams-thread-input).teams-rich-active .teams-rich__editor {
    position: relative;
}
.space-post-modal .teams-rich__editor--empty::before,
.teams-panel .teams-rich__editor--empty::before,
:is(#inputContainer, .teams-thread-input) .teams-rich__editor--empty::before {
    content: attr(data-placeholder);
    position: absolute;
    /* Inset to the editor's own text box, so the hint starts exactly where the
       caret is rather than a few pixels off it. */
    left: 70px;
    right: 54px;
    top: 12px;
    color: var(--tm-text-3, #8a8378);
    pointer-events: none;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
/* The inline (bubble) editor has its own, tighter padding — see below. */
.space-post-modal .teams-rich--inline .teams-rich__editor--empty::before,
.teams-panel .teams-rich--inline .teams-rich__editor--empty::before {
    left: 12px;
    right: 12px;
    top: 9px;
}

/* ── Authored formatting, in the editor AND in the bubble ────────────────────
   One block for both so a message can never look different once sent than it
   did while being written — the mismatch people notice immediately. */
.space-post-modal .teams-rich__editor ul,
.teams-panel .teams-rich__editor ul,
.teams-panel .teams-msg__text--rich ul,
.space-post-modal .teams-rich__editor ol,
.teams-panel .teams-rich__editor ol,
.teams-panel .teams-msg__text--rich ol {
    margin: 4px 0;
    padding-left: 37px;   /* was 22px here + 15px on each <li>; see the note below */
}
/* ONE source of horizontal indentation for a list, on the list itself. It used
   to be split across the list's `padding-left` and a second `margin-left` on
   every item, which totalled 37px of indent that a shrink-to-fit ancestor has
   to account for in TWO places — and WebKit visibly did not (see the bubble
   width note in teams-messages.css). Same visual indent, one box to measure. */
.space-post-modal .teams-rich__editor li,
.teams-panel .teams-rich__editor li,
.teams-panel .teams-msg__text--rich li {
    margin: 2px 0;
}
.space-post-modal .teams-rich__editor p,
.teams-panel .teams-rich__editor p,
.teams-panel .teams-msg__text--rich p {
    margin: 0 0 6px;
}
.space-post-modal .teams-rich__editor p:last-child,
.teams-panel .teams-rich__editor p:last-child,
.teams-panel .teams-msg__text--rich p:last-child {
    margin-bottom: 0;
}
.space-post-modal .teams-rich__editor blockquote,
.teams-panel .teams-rich__editor blockquote,
.teams-panel .teams-msg__text--rich blockquote {
    margin: 4px 0;
    padding: 2px 0 2px 10px;
    border-left: 3px solid var(--tm-border, #d8d3c8);
    color: var(--tm-text-2, #5c5750);
}
/* A pasted spreadsheet: a plain bordered grid that scrolls sideways instead of widening the bubble. */
.space-post-modal .teams-rich__editor table,
.teams-panel .teams-rich__editor table,
.teams-panel .teams-msg__text--rich table {
    display: block;
    max-width: 100%;
    margin: 4px 0;
    overflow-x: auto;
    border-collapse: collapse;
    font-size: 0.92em;
}
.space-post-modal .teams-rich__editor :is(td, th),
.teams-panel .teams-rich__editor :is(td, th),
.teams-panel .teams-msg__text--rich :is(td, th) {
    min-width: 2.5em;
    padding: 3px 8px;
    border: 1px solid var(--tm-border-strong, #bdb7ab);
    text-align: left;
    vertical-align: top;
    white-space: nowrap;
}
.space-post-modal .teams-rich__editor th,
.teams-panel .teams-rich__editor th,
.teams-panel .teams-msg__text--rich th {
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.1));
    font-weight: 600;
}
.space-post-modal .teams-rich__editor code,
.teams-panel .teams-rich__editor code,
.teams-panel .teams-msg__text--rich code {
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.1));
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.92em;
}
.space-post-modal .teams-rich__editor pre,
.teams-panel .teams-rich__editor pre,
.teams-panel .teams-msg__text--rich pre {
    margin: 4px 0;
    padding: 8px 10px;
    border-radius: 6px;
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.08));
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.92em;
    overflow-x: auto;
    white-space: pre;
}
.space-post-modal .teams-rich__editor a,
.teams-panel .teams-rich__editor a,
.teams-panel .teams-msg__text--rich a {
    color: var(--tm-accent, #2d5f84);
    text-decoration: underline;
    word-break: break-all;
}
.teams-panel .teams-msg--mine .teams-msg__text--rich a {
    color: #006fff;
}

/* A formatted bubble is MARKUP, not preformatted text: `pre-wrap` (correct for
   a plain message) would render the newline between every pair of the author's
   tags as a blank line, so the same message would grow gaps once formatted. */
.teams-panel .teams-msg__text--rich {
    white-space: normal;
}

/* ── Inline mode extras ──────────────────────────────────────────────────── */
.teams-panel .teams-msg__editor-rich {
    display: block;
}

/* ── Phones ──────────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
    :is(#inputContainer, .teams-thread-input).teams-rich-active .teams-rich__editor {
        max-height: 24vh;
    }
    .space-post-modal .teams-rich__hint,
    .teams-panel .teams-rich__hint,
    :is(#inputContainer, .teams-thread-input) .teams-rich__hint {
        display: none;   /* no room, and the toolbar already shows the mode */
    }

    .tm-al-center, .tm-al-right {
        margin: 0;
    }
}

/* ── @mention highlight, live in the composer ────────────────────────────────
   The plain textarea gets this from a mirror layer painted behind it; a
   contenteditable has no single text run to mirror, so the token is marked up
   in place instead (teams-rich-editor.js `_paintMentions`). Same colour as the
   mirror's, so switching between the two composers is not a visible change.
   The class is NOT a palette class, so it is stripped on send — the renderer
   re-derives mention styling from the message's own text. */
:is(#inputContainer, .teams-thread-input) .teams-rich__editor .tm-mn {
    color: var(--tm-accent, #2d5f84);
    font-weight: 600;
}

/* ── Colour ──────────────────────────────────────────────────────────────────
 *
 * A FIXED palette, carried as classes. Not inline styles: a literal colour
 * cannot adapt to the reader's theme, so a message written in light mode would
 * come out unreadable in dark mode — and a style attribute is an open door into
 * the app's own layout. The names here are the contract with the sanitizers on
 * both sides (teams-rich-html.js, app/utils/html_sanitize.py).
 *
 * Foreground values are darkened and background values lightened on purpose:
 * these are read as body text at 1rem, so they have to hold contrast rather
 * than be vivid. The values are theme-independent by construction — each holds
 * contrast on both grounds — which is why they need no dark-mode variant.
 *
 * UNSCOPED, like `tm-al-*` and `tm-sz-*` below, and for the same reason. This
 * markup is now rendered in FIVE places under four different roots: the chat
 * bubble, the chat composer, the post composer, the post card and the post
 * preview. While the rules were enumerated per root, every new surface silently
 * rendered colourless text — the post card did exactly that, and so did the
 * swatch menu inside the post dialog, which drew a row of empty circles because
 * `tm-sw-*` had been scoped to the two roots that existed when it was written.
 * A namespaced, single-purpose class that matches nothing without it is the safe
 * kind of global; a list of roots to remember is not.
 */
[class*="tm-bg-"] {
    /* Highlighted text sits tight against the next word without this. */
    padding: 0 2px;
    border-radius: 3px;
}
.tm-bg-red { background: #ffd9d9; color: #4a1010; }
.tm-bg-orange { background: #ffe4c4; color: #4a2a06; }
.tm-bg-yellow { background: #fff2a8; color: #453800; }
.tm-bg-green { background: #ccf0d8; color: #0e3d22; }
.tm-bg-blue { background: #d4e6ff; color: #10305c; }
.tm-bg-purple { background: #e8dcf7; color: #331b52; }
.tm-bg-grey { background: #e4e0d8; color: #35312a; }

/* AFTER the highlights, deliberately. A highlight sets a readable foreground of
   its own, and a run carrying both classes (which the sanitizers allow — one
   per family) would otherwise lose its chosen text colour to the highlight's
   default. Same specificity, so source order is the whole mechanism: an
   explicit colour wins, and the pale backgrounds above carry any of them. */
.tm-fg-red { color: #c02b2b; }
.tm-fg-orange { color: #b96208; }
.tm-fg-yellow { color: #8a6d00; }
.tm-fg-green { color: #1f7a44; }
.tm-fg-blue { color: #1d63b8; }
.tm-fg-purple { color: #6b3fa0; }
.tm-fg-grey { color: #6b6459; }

/* ── The swatch menu ─────────────────────────────────────────────────────── */
.space-post-modal .teams-rich__colours,
.teams-panel .teams-rich__colours,
:is(#inputContainer, .teams-thread-input) .teams-rich__colours {
    position: absolute;
    bottom: calc(100% + 4px);
    z-index: 45;
    display: flex;
    gap: 4px;
    padding: 6px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 8px;
    background: var(--tm-surface, #fff);
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.16);
}
.space-post-modal .teams-rich__colour,
.teams-panel .teams-rich__colour,
:is(#inputContainer, .teams-thread-input) .teams-rich__colour {
    width: 20px;
    height: 20px;
    padding: 0;
    border: 1px solid rgba(0, 0, 0, 0.15);
    border-radius: 50%;
    cursor: pointer;
}
/* "None" — a struck-through empty circle, so removing a colour is as obvious
   as applying one. */
.space-post-modal .teams-rich__colour--none,
.teams-panel .teams-rich__colour--none,
:is(#inputContainer, .teams-thread-input) .teams-rich__colour--none {
    background:
        linear-gradient(to top left,
            transparent calc(50% - 1px), #c02b2b calc(50% - 1px),
            #c02b2b calc(50% + 1px), transparent calc(50% + 1px)),
        var(--tm-white, #fff);
}
/* The chips in the swatch menu. Unscoped for the reason above — enumerated per
   root, they drew a row of EMPTY CIRCLES in the post dialog, which was the
   third surface and not on the list. `tm-sw-*` appears on nothing but these.

   THE CLASS IS DOUBLED TO RAISE ITS SPECIFICITY, and that is the whole point of
   this block. Unscoping fixed the post dialog and broke the CHAT composer,
   which drew the same row of empty circles in production: the swatch menu opens
   inside `:is(#inputContainer, .teams-thread-input)`, and main-chat.css carries

       .input-container button { background-color: var(--input-bg); }

   at (0,1,1) — a class plus a type — while a bare `.tm-sw-red` is only (0,1,0).
   Specificity is decided before source order, so it did not matter that this
   file loads later; the chips were painted the composer's own grey. The post
   dialog is not inside `.input-container`, so it was unaffected, which is
   exactly the "works in New post, broken in Chat" split that was reported.

   The tell was the "None" chip: it was the ONE circle that rendered, because
   its rule above is `:is(#inputContainer, .teams-thread-input) .teams-rich__colour--none` at (1,1,0).

   `.tm-sw-red.tm-sw-red` is (0,2,0), so it outranks any single class+type rule
   in any host, now and later. Preferred over the alternatives on purpose:
   `button.tm-sw-red` would merely TIE at (0,1,1) and lean on load order, which
   is the fragility this already fell into once; `!important` would win but take
   the property out of the cascade for every future surface too. This stays a
   plain, overridable rule that is simply specific enough. */
.tm-sw-red.tm-sw-red { background: #c02b2b; }
.tm-sw-orange.tm-sw-orange { background: #d97706; }
.tm-sw-yellow.tm-sw-yellow { background: #eab308; }
.tm-sw-green.tm-sw-green { background: #1f7a44; }
.tm-sw-blue.tm-sw-blue { background: #1d63b8; }
.tm-sw-purple.tm-sw-purple { background: #6b3fa0; }
.tm-sw-grey.tm-sw-grey { background: #6b6459; }

/* The COMPOSER anchors the swatch menu, not the toolbar: the toolbar is a
   horizontal scroll container, and it would clip its own popover. */
:is(#inputContainer, .teams-thread-input).teams-rich-active,
.space-post-modal .teams-rich--inline,
.teams-panel .teams-rich--inline {
    position: relative;
}

/* ── Message length counter ───────────────────────────────────────────────────
 *
 * The plain-text cap (MAX_MESSAGE_TEXT_LENGTH, mirroring the server's
 * MAX_CONTENT_LENGTH) made visible. Hidden until the last few hundred
 * characters — a counter hovering over every two-line message is noise, and the
 * number only becomes information when it is running out.
 *
 * Scoped to `.teams-panel` and to the ADOPTED `:is(#inputContainer, .teams-thread-input)`, like the rest
 * of this file: the composer belongs to the Chat tab and is handed back on
 * teardown, so an unscoped rule here would follow it home.
 */
/* Stated explicitly rather than left to the UA sheet: this element is
   positioned and lives among rules that set `display`, and `[hidden]` loses to
   any of them — a counter that stayed on screen reading "5000" over an empty
   composer would be worse than no counter. */
.teams-panel .teams-len[hidden],
:is(#inputContainer, .teams-thread-input) .teams-len[hidden] {
    display: none;
}
.teams-panel .teams-len,
:is(#inputContainer, .teams-thread-input) .teams-len {
    font-size: 11px;
    font-variant-numeric: tabular-nums;  /* the digits must not jitter as they change */
    color: var(--tm-text-3, #6b6459);
    line-height: 1;
    white-space: nowrap;
    pointer-events: none;
}
.teams-panel .teams-len--warn,
:is(#inputContainer, .teams-thread-input) .teams-len--warn {
    color: var(--tm-text-3, #6b6459);
}
.teams-panel .teams-len--error,
:is(#inputContainer, .teams-thread-input) .teams-len--error {
    color: var(--tm-danger, #c0392b);
    font-weight: 600;
}

/* In the COMPOSER the counter floats at the field's bottom-right corner, over
   the padding the pill already has — it must not take part in the input row's
   layout, or the send button would shift sideways the moment the counter
   appeared. */
:is(#inputContainer, .teams-thread-input) .teams-len {
    position: absolute;
    right: 16px;
    bottom: 2px;
    z-index: 2;
    padding: 0 4px;
    border-radius: 4px;
    background: var(--input-bg, #fff);
}

/* The composer needs a positioning context for the counter. It already gets one
   while formatting is on (the swatch menu anchors there); this covers the plain
   textarea state, where the counter is just as necessary. */
:is(#inputContainer, .teams-thread-input).teams-input-adopted {
    position: relative;
}

/* Over the limit: the field itself says so, not only the number. The send is
   blocked in JS — this is the part that explains why. */
:is(#inputContainer, .teams-thread-input).teams-len-over :is(#userInput, .teams-thread-text-input),
:is(#inputContainer, .teams-thread-input).teams-len-over .teams-rich__editor {
    border-color: var(--tm-danger, #c0392b) !important;
}
:is(#inputContainer, .teams-thread-input).teams-len-over.teams-rich-active .teams-rich__bar {
    border-color: var(--tm-danger, #c0392b);
}

/* In an inline message edit the counter sits in the actions row next to the
   hint, where there is already space for it and nothing to displace. */
.teams-panel .teams-msg__editor-actions .teams-len {
    margin-right: 4px;
}
.teams-panel .teams-msg__editor.teams-len-over .teams-msg__editor-input,
.teams-panel .teams-msg__editor.teams-len-over .teams-rich__editor {
    border-color: var(--tm-danger, #c0392b);
}

/* ── Alignment, headings and images (the Space post surface) ──────────────
 *
 * ALIGNMENT IS A CLASS, not `style="text-align"`. Both sanitizers drop every
 * `style` attribute, so an editor that emitted one would appear to work and
 * lose the alignment on send. These four names are on both allowlists, and the
 * stylesheet is what resolves them — which is also why they are declared HERE,
 * once, and used by the editor and by the rendered post alike.
 *
 * Unscoped on purpose, and the ONLY rules in this file that are: the same
 * markup is rendered inside the composer (`.teams-rich__editor`), inside a
 * Space post card (`.space-post__body`) and inside the post preview, which live
 * under three different roots. A single-purpose class name with no styling of
 * its own is the safe kind of global — it matches nothing that does not carry
 * the class. */
.tm-al-left { text-align: left; }
.tm-al-center { text-align: center; }
.tm-al-right { text-align: right; }
.tm-al-justify { text-align: justify; }

/* A centred list still needs its markers to travel with the text, or the
   bullets sit on the left edge pointing at nothing. */
.tm-al-center, .tm-al-right { list-style-position: inside; }

/* The subheading button, so two heading controls are told apart at a glance
   without inventing a second icon for the same idea. */
.space-post-modal .teams-rich__btn--small,
.teams-panel .teams-rich__btn--small,
:is(#inputContainer, .teams-thread-input) .teams-rich__btn--small {
    font-size: 10.5px;
}

/* Headings inside the composer read as headings while they are being written —
   an editor whose H2 looks like a paragraph is one where the button appears to
   do nothing. */
.space-post-modal .teams-rich__editor h1,
.space-post-modal .teams-rich__editor h2,
.space-post-modal .teams-rich__editor h3,
.space-post-modal .teams-rich__editor h4 {
    margin: 12px 0 6px;
    font-weight: 700;
    line-height: 1.3;
}
.space-post-modal .teams-rich__editor h1 { font-size: 1.4em; }
.space-post-modal .teams-rich__editor h2 { font-size: 1.25em; }
.space-post-modal .teams-rich__editor h3 { font-size: 1.1em; }
.space-post-modal .teams-rich__editor h4 { font-size: 1em; }
.space-post-modal .teams-rich__editor hr {
    margin: 12px 0;
    border: 0;
    border-top: 1px solid var(--tm-border, #d8d3c8);
}

/* An inline image in the composer is a placed object, not an attachment chip:
   it sits where the caret put it and is bounded so a 4000px screenshot does not
   push the toolbar off screen. */
.space-post-modal .teams-rich__editor img {
    max-width: 100%;
    height: auto;
    border-radius: 8px;
    vertical-align: middle;
}

/* ── Text size (the Space post surface) ──────────────────────────────────
 *
 * A LADDER, in `em` rather than `px`, so a resized run scales with whatever
 * surface it lands on: the composer at 14.5px, the post card at 14px, the
 * preview, a future digest. A pixel value here would freeze a paragraph at the
 * composer's own type size and make it wrong everywhere else.
 *
 * There is deliberately no `tm-sz-md`: normal size is the ABSENCE of a class,
 * so text nobody resized and text stepped back down to normal carry identical
 * markup. See SIZE_LADDER in teams-rich-editor.js.
 *
 * Unscoped, for the same reason the alignment classes are: one class name,
 * carrying its own meaning, rendered inside the composer, inside a post card
 * and inside the preview — three different roots. */
.tm-sz-xs { font-size: 0.8em; }
.tm-sz-sm { font-size: 0.9em; }
.tm-sz-lg { font-size: 1.25em; }
.tm-sz-xl { font-size: 1.55em; }

/* Line height has to travel with the size or a run of large text overlaps the
   line above it — the size classes are inline, so they inherit the block's
   leading unless they say otherwise. */
.tm-sz-lg, .tm-sz-xl { line-height: 1.35; }

/* ── Modal (member management — appended to body) ─────────────────────────── */
.teams-modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 10000;
    background: rgba(20, 18, 14, 0.42);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    font-family: var(--tm-font-ui);
}
/* The shared agent combobox (.at-agent-body-dropdown) is appended to <body> at
 * z-index 9999 — below the Teams modal (10000), so it rendered hidden behind it.
 * Raise it above the modal so the agent list is visible inside Create/Edit forms. */
.at-agent-body-dropdown {
    z-index: 10050 !important;
}
.teams-modal-overlay .teams-modal {
    width: 100%;
    max-width: 520px;
    max-height: 80vh;
    background: var(--tm-white);
    border-radius: var(--tm-r-lg);
    box-shadow: var(--tm-shadow-md);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    color: var(--tm-text-1);
}

/* The participant roster may be very long; actions remain available without
   scrolling past the final person. The destructive leave action stays visually
   separated from the ordinary invite/removal controls. */
.teams-participants-modal .teams-modal__footer {
    position: sticky;
    bottom: 0;
    z-index: 1;
    background: var(--tm-white);
    border-top: 1px solid var(--tm-border);
}
.teams-participants-modal__leave {
    margin-left: auto;
}

.teams-modal-overlay .teams-modal.teams-scheduled {
    min-height: 500px;
}

.teams-modal-overlay .teams-modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid var(--tm-border);
}
.teams-modal-overlay .teams-modal__title {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
}
.teams-modal-overlay .teams-modal__close {
    border: none;
    background: transparent;
    cursor: pointer;
    color: var(--tm-text-3);
    font-size: 16px;
    width: 32px;
    height: 32px;
    border-radius: var(--tm-r);
}
.teams-modal-overlay .teams-modal__close:hover {
    background: var(--tm-bg-alt);
    color: var(--tm-text-1);
}
.teams-modal-overlay .teams-modal__add {
    padding: 14px 20px;
    border-bottom: 1px solid var(--tm-border);
    position: relative;
}
.teams-modal-overlay .teams-modal__search-wrap {
    position: relative;
}
.teams-modal-overlay .teams-modal__search-wrap i {
    position: absolute;
    left: 11px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--tm-text-3);
    font-size: 12px;
    pointer-events: none;
}
.teams-modal-overlay .teams-modal__search {
    width: 100%;
    padding: 9px 12px 9px 32px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-surface);
    font-family: var(--tm-font-ui);
    font-size: 13px;
    color: var(--tm-text-1);
    outline: none;
}
.teams-modal-overlay .teams-modal__search:focus {
    border-color: var(--tm-accent);
    box-shadow: 0 0 0 3px var(--tm-accent-subtle);
}
.teams-modal-overlay .teams-modal__search-results {
    margin-top: 8px;
    max-height: 180px;
    overflow-y: auto;
}
.teams-modal-overlay .teams-modal__search-result {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    border: 1px solid transparent;
    border-radius: var(--tm-r);
    background: transparent;
    cursor: pointer;
    text-align: left;
    font-size: 13px;
    color: var(--tm-text-1);
}
.teams-modal-overlay .teams-modal__search-result:hover {
    background: var(--tm-bg-alt);
    border-color: var(--tm-border);
}
/* Person rows in the pickers carry a face (user photo, or the initial as
 * fallback). Slightly smaller than the default 30px avatar and without its
 * margin, because these rows already space their children with `gap`. */
.teams-modal-overlay .teams-modal__search-result .teams-avatar,
.teams-panel .teams-modal__search-result .teams-avatar,
.teams-participants-modal .teams-people-row .teams-avatar {
    width: 24px;
    height: 24px;
    font-size: 11px;
    margin-right: 0;
    margin-top: 0;
}
/* The search-result row is `space-between`, which would push a two-child row
 * apart; the name block must take the slack so the avatar stays beside it. */
.teams-modal-overlay
    .teams-modal__search-result
    .teams-modal__search-result-main,
.teams-panel .teams-modal__search-result .teams-modal__search-result-main {
    flex: 1;
    min-width: 0;
}
.teams-modal-overlay .teams-modal__body {
    padding: 8px 12px 16px;
    overflow-y: auto;
}
/* Form controls use the available field width including their border. A mobile
   reset once changed every element to `box-sizing: unset`; a 100%-wide input
   then added its own border outside the card and visibly crossed its edge. */
.teams-modal-overlay .teams-field__input,
.teams-modal-overlay .teams-field textarea,
.teams-modal-overlay .teams-field select {
    box-sizing: border-box;
    max-width: 100%;
}
/* Member rows are used by both the modal and the full-panel config, so scope
 * under both top-level containers. */
.teams-modal-overlay .teams-members-list,
.teams-panel .teams-members-list {
    display: flex;
    flex-direction: column;
}

.teams-modal-overlay .teams-member-row,
.teams-panel .teams-member-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 8px;
    border-bottom: 1px solid var(--tm-border);
}
.teams-modal-overlay .teams-member-row:last-child,
.teams-panel .teams-member-row:last-child {
    border-bottom: none;
}
.teams-modal-overlay .teams-member-name,
.teams-panel .teams-member-name {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
    font-size: 14px;
    font-weight: 500;
}
.teams-modal-overlay .teams-member-you,
.teams-panel .teams-member-you {
    font-weight: 400;
    color: var(--tm-text-3);
    font-size: 12px;
}
.teams-modal-overlay .teams-member-handle,
.teams-panel .teams-member-handle {
    font-size: 12px;
    color: var(--tm-text-3);
    font-weight: 400;
}
.teams-modal-overlay .teams-member-role,
.teams-panel .teams-member-role {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 2px 8px;
    border-radius: 999px;
}
.teams-modal-overlay .teams-member-role--admin,
.teams-panel .teams-member-role--admin {
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}
.teams-modal-overlay .teams-member-role--manager,
.teams-panel .teams-member-role--manager {
    background: #f0e9ff;
    color: #7150ad;
}
.teams-modal-overlay .teams-member-role--member,
.teams-panel .teams-member-role--member {
    background: var(--tm-bg-alt);
    color: var(--tm-text-3);
}
.teams-modal-overlay .teams-member-actions,
.teams-panel .teams-member-actions {
    display: flex;
    gap: 6px;
    flex-shrink: 0;
}

/* Add-member search box also appears inside the config page. */
.teams-panel .teams-modal__search-wrap {
    position: relative;
    margin-bottom: 8px;
}
.teams-panel .teams-modal__search-wrap i {
    position: absolute;
    left: 11px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--tm-text-3);
    font-size: 12px;
    pointer-events: none;
}
.teams-panel .teams-modal__search {
    width: 100%;
    padding: 9px 12px 9px 32px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-surface);
    font-family: var(--tm-font-ui);
    font-size: 13px;
    color: var(--tm-text-1);
    outline: none;
}
.teams-panel .teams-modal__search:focus {
    border-color: var(--tm-accent);
    box-shadow: 0 0 0 3px var(--tm-accent-subtle);
    background: var(--tm-real-white);
}

.teams-panel .teams-modal__search-results {
    margin-bottom: 10px;
}
.teams-panel .teams-modal__search-result {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    border: 1px solid transparent;
    border-radius: var(--tm-r);
    background: transparent;
    cursor: pointer;
    text-align: left;
    font-size: 13px;
    color: var(--tm-text-1);
}
.teams-panel .teams-modal__search-result:hover {
    background: var(--tm-bg-alt);
    border-color: var(--tm-border);
}

/* ── Participant-picker pop-over ───────────────────────────────────────────────
 * The Create-team modal and the Team-settings add box render their suggestions
 * as an absolutely-positioned pop-over anchored to the search input, so the
 * results overlay whatever sits below (chips, member list, footer) instead of
 * pushing it down as the user types. Scoped under both top-level containers. */
.teams-modal-overlay .teams-picker,
.teams-panel .teams-picker {
    position: relative;
}

.teams-modal-overlay .teams-picker .teams-modal__search-results,
.teams-panel .teams-picker .teams-modal__search-results {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 60;
    margin: 0;
    max-height: 240px;
    overflow-y: auto;
    padding: 6px;
    background: var(--tm-surface);
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
}
/* Collapse entirely when there are no suggestions so no empty box floats. */
.teams-modal-overlay .teams-picker .teams-modal__search-results:empty,
.teams-panel .teams-picker .teams-modal__search-results:empty {
    display: none;
}

/* The Create-team modal's "Add members" is the last field, hard against the
 * modal's clipped bottom edge — open its pop-over UPWARD so it stays fully
 * visible over the Team Prompt area instead of being cut off. */
.teams-modal-overlay
    .teams-modal--form
    .teams-picker
    .teams-modal__search-results {
    top: auto;
    bottom: calc(100% + 6px);
}

/* The create-modal search input reuses .teams-field__input (no icon padding),
 * so reserve space for the leading user-plus icon like the settings box does. */
.teams-modal-overlay .teams-member-search {
    padding-left: 32px;
}

/* "Add everyone from a company team" — a company team surfaces as an "Add
 * everyone" suggestion row INSIDE the user-search autocomplete (shared
 * teams-team-add.js), so it reuses .teams-modal__search-result. A leading
 * people glyph + accent line distinguishes it from an individual-person row. */
.teams-modal-overlay
    .teams-modal__search-result--team
    .teams-modal__search-result-team,
.teams-panel
    .teams-modal__search-result--team
    .teams-modal__search-result-team {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 600;
}
.teams-modal-overlay
    .teams-modal__search-result--team
    .teams-modal__search-result-team
    i,
.teams-panel
    .teams-modal__search-result--team
    .teams-modal__search-result-team
    i {
    color: var(--tm-agent, #6366f1);
    font-size: 12px;
}

/* 30-day activity disclaimer shown beside every member picker (shared
 * memberActivityNote). Muted, with a leading info glyph. */
.teams-modal-overlay .teams-member-note,
.teams-panel .teams-member-note {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 8px 0 0;
    font-size: 11.5px;
    line-height: 1.4;
    color: var(--tm-text-2, #6b7280);
    background: var(--tm-note-bg);
    padding: 10px;
    border-radius: 8px;
}
.teams-modal-overlay .teams-member-note i,
.teams-panel .teams-member-note i {
    margin-top: 1px;
    flex-shrink: 0;
}

/* Capacity line ("up to N people" / "no member limit"). Carries the base
   .teams-member-note styling and only adds weight — it is a rule the user has
   to plan around, not a caveat, and it is what steers a large group to a team. */
.teams-modal-overlay .teams-member-note--capacity,
.teams-panel .teams-member-note--capacity {
    font-weight: 500;
}

/* Stacked name + team·office in a picker result row. */
.teams-modal-overlay .teams-modal__search-result-main,
.teams-panel .teams-modal__search-result-main {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}
.teams-modal-overlay .teams-org-line,
.teams-panel .teams-org-line,
.teams-panel .teams-newchat__row-org,
.teams-modal-overlay .teams-newchat__row-org {
    font-size: 11px;
    color: var(--tm-text-3);
    font-weight: 400;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── New-conversation modal (teams-new-chat-modal.js) ─────────────────────── */
/* A FIXED height, not just a `max-height` ceiling. The base `.teams-modal`
 * only caps height — it otherwise shrinks to fit its content — which is fine
 * for a modal whose content doesn't change shape after opening, but this one
 * re-renders `.teams-newchat__scroll` on every keystroke in the search box
 * (a full list of teams + recent people vs. a single filtered row). Without a
 * fixed height the whole modal visibly grew and shrank as the reader typed;
 * `.teams-newchat__scroll`'s own `min-height` couldn't hold it because THIS
 * container has no height of its own for that flex child to be a fraction of.
 * min() keeps it from overflowing a short viewport exactly like max-height did. */
.teams-modal-overlay .teams-modal--newchat {
    width: 520px;
    max-width: 100%;
    display: flex;
    flex-direction: column;
    height: min(640px, 80vh);
}
/* The fixed height above only holds if `.teams-modal__body` actually FILLS
 * it: the shared `.teams-modal__body` rule is a plain block with no `flex`
 * of its own, so as a flex-item of the modal it defaults to content-sized
 * (`flex: 0 1 auto`) rather than stretching to the remaining space — the
 * fixed height would otherwise leave a gap or, on a tall result list, get
 * fought by the item's automatic (content-based) minimum size instead of
 * shrinking to fit. `min-height: 0` overrides that automatic minimum, which
 * is what actually lets `.teams-newchat__scroll` below take over the
 * scrolling instead of the fixed-size modal. Scoped to this modal only. */
.teams-modal-overlay .teams-modal--newchat .teams-modal__body {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}
/* The "Forward to…" picker (teams-forward-modal.js) — same fixed-height /
 * flex-body reasoning as .teams-modal--newchat above, just a touch shorter
 * (no group-image picker, no company-team suggester section to make room for). */
.teams-modal-overlay .teams-modal--forward {
    width: 460px;
    max-width: 100%;
    display: flex;
    flex-direction: column;
    height: min(560px, 80vh);
}
.teams-modal-overlay .teams-modal--forward .teams-modal__body {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}

/* Team member → chat roster follow-up. Uses the ordinary Teams modal shell so
   colours follow --tm-* light/dark tokens rather than a separate palette. */
.teams-modal-overlay .teams-member-chat-sync { width: min(680px, calc(100vw - 32px)); }
.teams-member-chat-sync__intro { margin: 4px 0 0; color: var(--tm-text-3); font-size: 13px; font-weight: 400; }
.teams-member-chat-sync__body { max-height: min(58vh, 560px); overflow: auto; }
.teams-member-chat-sync__person { margin: 0 0 12px; color: var(--tm-text-2); font-size: 13px; }
.teams-member-chat-sync__list { display: grid; gap: 8px; }
.teams-member-chat-sync__row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 10px; border: 1px solid var(--tm-border); border-radius: 8px; background: var(--tm-bg-alt); cursor: pointer; }
.teams-member-chat-sync__row > input { accent-color: var(--tm-accent); }
.teams-member-chat-sync__chat { min-width: 0; display: grid; gap: 2px; color: var(--tm-text-1); }
.teams-member-chat-sync__chat strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.teams-member-chat-sync__chat small { color: var(--tm-text-3); font-size: 11px; }
.teams-member-chat-sync__history { display: flex; align-items: end; gap: 7px; color: var(--tm-text-3); font-size: 11px; }
.teams-member-chat-sync__history label { display: grid; gap: 3px; }
.teams-member-chat-sync__history select, .teams-member-chat-sync__history input { box-sizing: border-box; height: 30px; border: 1px solid var(--tm-border); border-radius: 5px; background: var(--tm-real-white); color: var(--tm-text-1); font: inherit; padding: 3px 6px; }
.teams-member-chat-sync__history input { width: 52px; }
.teams-member-chat-sync__days { display: none !important; }
.teams-member-chat-sync__row.has-days .teams-member-chat-sync__days { display: grid !important; }
.teams-member-chat-sync__bulk { display: flex; align-items: end; justify-content: space-between; gap: 10px; margin: 0 0 12px; padding: 10px; border: 1px dashed var(--tm-border); border-radius: 8px; }
.teams-member-chat-sync__bulk-all { display: flex; align-items: center; gap: 8px; color: var(--tm-text-1); font-size: 13px; font-weight: 600; cursor: pointer; }
.teams-member-chat-sync__bulk-all input { accent-color: var(--tm-accent); }
.teams-member-chat-sync__bulk.has-days .teams-member-chat-sync__days { display: grid !important; }
.teams-member-chat-sync__footer { display: flex; justify-content: flex-end; gap: 8px; }
@media (max-width: 620px) { .teams-member-chat-sync__row { grid-template-columns: auto minmax(0, 1fr); } .teams-member-chat-sync__history { grid-column: 2; } }
/* The message being forwarded, named up front so picking a destination is
 * never a guess at what is about to be sent. Quoted-note styling (muted
 * background + left accent bar), matching the reply-quote box's own visual
 * language elsewhere in Teams rather than inventing a new one. */
.teams-modal-overlay .teams-forward__preview {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 10px;
    margin-bottom: 10px;
    border-left: 3px solid var(--tm-accent);
    border-radius: 6px;
    background: var(--tm-bg-alt);
}
.teams-modal-overlay .teams-forward__preview-label {
    font-size: 11.5px;
    color: var(--tm-text-3);
}
.teams-modal-overlay .teams-forward__preview-snippet {
    font-size: 13px;
    color: var(--tm-text-2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* The forwarder's optional note, between the message being forwarded and the
   destination list — the modal reads top-to-bottom as "this message, my note,
   who gets it". A plain field rather than the quoted styling above: this text
   is the forwarder's OWN, and it must not look like part of the thing being
   quoted. */
.teams-modal-overlay .teams-forward__comment-label {
    display: block;
    margin-bottom: 4px;
    font-size: 12px;
    font-weight: 600;
    color: var(--tm-text-2);
}
.teams-modal-overlay .teams-forward__optional {
    font-weight: 400;
    color: var(--tm-text-3);
}
.teams-modal-overlay .teams-forward__comment {
    width: 100%;
    box-sizing: border-box;
    padding: 8px 10px;
    margin-bottom: 10px;
    border: 1px solid var(--tm-border);
    border-radius: 6px;
    color: var(--tm-text);
    font: inherit;
    font-size: 13px;
    line-height: 1.45;
    resize: vertical;
    min-height: 44px;
}
.teams-modal-overlay .teams-forward__comment:focus {
    outline: none;
    border-color: var(--tm-accent);
}

.teams-modal-overlay .teams-newchat__search {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 12px;
    margin: 4px 0 10px;
    border: 1px solid var(--tm-border);
    border-radius: 8px;
    background: var(--tm-bg-alt);
    color: var(--tm-text-1);
    font-size: 14px;
}
.teams-modal-overlay .teams-newchat__search:focus {
    outline: none;
    border-color: var(--tm-accent);
    box-shadow: 0 0 0 3px var(--tm-accent-subtle);
    background: var(--tm-real-white);
}
.teams-modal-overlay .teams-newchat__selected {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 10px;
}
.teams-modal-overlay .teams-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 6px 3px 10px;
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
    border-radius: 14px;
    font-size: 12.5px;
    font-weight: 600;
}
.teams-modal-overlay .teams-chip__x {
    border: none;
    background: none;
    color: inherit;
    cursor: pointer;
    font-size: 15px;
    line-height: 1;
    padding: 0 2px;
}
.teams-modal-overlay .teams-newchat__scroll {
    overflow-y: auto;
    flex: 1;
    min-height: 180px;
    margin: 0 -4px;
    padding: 0 4px;
}
.teams-modal-overlay .teams-newchat__section-title {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--tm-text-3);
    font-weight: 700;
    padding: 10px 4px 4px;
}
.teams-modal-overlay .teams-newchat__hint {
    text-transform: none;
    letter-spacing: 0;
    font-weight: 400;
    color: var(--tm-text-3);
}
.teams-modal-overlay .teams-newchat__row {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 8px;
    border: none;
    background: none;
    border-radius: 8px;
    cursor: pointer;
    text-align: left;
    color: var(--tm-text-1);
}
.teams-modal-overlay .teams-newchat__row:hover {
    background: var(--tm-bg-alt);
}
.teams-modal-overlay .teams-newchat__row[disabled] {
    opacity: 0.45;
    cursor: not-allowed;
}
.teams-modal-overlay .teams-newchat__row--selected {
    background: var(--tm-accent-subtle);
}

/* "Add everyone from a company team" rows — shown above the people list as the
 * user types (teams-new-chat-modal.js _renderCompanyTeams). Squared avatar with
 * a people glyph marks it as a bulk-add, distinct from an individual person. */
.teams-modal-overlay .teams-newchat__company {
    display: flex;
    flex-direction: column;
}
.teams-modal-overlay .teams-newchat__company[hidden] {
    display: none;
}
.teams-modal-overlay .teams-newchat__row--company .teams-avatar--team {
    border-radius: var(--tm-r);
    background: var(--tm-agent-bg);
    color: var(--tm-agent);
}
.teams-modal-overlay .teams-newchat__row-meta {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}
.teams-modal-overlay .teams-newchat__row-label {
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.teams-modal-overlay .teams-newchat__row-label mark {
    background: rgba(45, 95, 132, 0.22);
    color: inherit;
    border-radius: 2px;
    padding: 0 1px;
}
.teams-modal-overlay .teams-newchat__row-sub {
    font-size: 12px;
    color: var(--tm-text-3);
}
.teams-modal-overlay .teams-newchat__check {
    color: var(--tm-accent);
    width: 18px;
    text-align: center;
}
.teams-modal-overlay .teams-newchat__more {
    padding: 8px 4px;
    font-size: 12px;
    color: var(--tm-text-3);
    text-align: center;
}
.teams-modal-overlay .teams-badge {
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 2px 7px;
    border-radius: 10px;
    white-space: nowrap;
}
.teams-modal-overlay .teams-badge--team {
    background: var(--tm-agent-bg);
    color: var(--tm-agent);
}
.teams-modal-overlay .teams-badge--native {
    background: rgba(45, 95, 132, 0.12);
    color: var(--tm-accent);
}
.teams-modal-overlay .teams-badge--widget {
    background: rgba(120, 120, 120, 0.15);
    color: var(--tm-text-2);
}
.teams-modal-overlay .teams-badge--sso {
    background: rgba(180, 120, 40, 0.16);
    color: #9a6a1a;
}
.teams-modal-overlay .teams-badge--self {
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}
.teams-modal-overlay .teams-newchat__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--tm-border);
}
.teams-modal-overlay .teams-newchat__count {
    font-size: 12.5px;
    color: var(--tm-text-3);
}
/* Over the ad-hoc group ceiling — the footer line explains the cap and the way
   round it (create a team), so the disabled Start button isn't a dead end. */
.teams-modal-overlay .teams-newchat__count--error {
    color: var(--tm-danger, #c0392b);
    font-weight: 600;
    max-width: 60ch;
}

/* ── "Continue existing chat?" prompt (shown when a member set already has a
      session — task #3). Replaces the picker body with a two-choice confirm. ── */
.teams-modal-overlay .teams-newchat__confirm {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 14px;
    padding: 22px 12px 8px;
}
.teams-modal-overlay .teams-newchat__confirm-icon {
    font-size: 30px;
    color: var(--tm-accent, #4f7cff);
    opacity: 0.9;
}
.teams-modal-overlay .teams-newchat__confirm-msg {
    margin: 0;
    font-size: 14px;
    line-height: 1.5;
    color: var(--tm-text-1);
    max-width: 340px;
}
.teams-modal-overlay .teams-newchat__confirm-actions {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    justify-content: center;
    margin-top: 4px;
}

/* ── Tab unread badges (count of chat SESSIONS with unread activity) ────────── */
/* One unified reconciler badges BOTH the Chat and Teams tabs from a single
   server source (unread-manager.js), so the shared .teams-tab-badge style
   applies to either tab. */
.header-tab[data-panel="teams"],
.header-tab[data-panel="chat"],
.header-tab[data-panel="feed"] {
    position: relative;
}
/* The count sits ABOVE the tab's top-right corner and takes no room in it: the tab
   keeps the width it has with no unread, so the pill never reflows when a number
   appears. */
.header-tab[data-panel="teams"] .teams-tab-badge,
.header-tab[data-panel="chat"] .teams-tab-badge,
.header-tab[data-panel="feed"] .teams-tab-badge {
    position: absolute;
    top: -6px;
    right: -3px;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    margin: 0;
    border-radius: 8px;
    background: #e5484d;
    box-shadow: 0 0 0 2px var(--tm-bg, #fff);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
    pointer-events: none;
}

/* ── Composer @mention anchor (shared agent-mention-dropdown renders here) ──── */
/* The shared dropdown is component-scoped in agent-mention-dropdown.css; this
   only provides the positioning context it anchors to (bottom: 100%).
 *
 * `z-index: 0` IS LOAD-BEARING — do not "clean up" this to a bare
 * `position: relative`. Without an explicit z-index, this element does not
 * establish its own stacking context, so it and everything inside it
 * (`#inputContainer`'s .mic-button z-index:2, .send-button, the paperclip,
 * the emoji button — main-chat.css gives several of them their own small
 * z-index once `.chat-area` is an ancestor, which it still is: #panel-teams
 * lives INSIDE .chat-area, adoption just moves #inputContainer to a
 * different child of it) all leak PAST this element, PAST
 * `.teams-conversation`, PAST `.teams-conversation__body` — none of which set
 * a z-index either — and get compared directly against
 * `.teams-conversation__context` (teams-conversation.css, z-index: 2), the
 * header row the AI observers popover is anchored under.
 *
 * `.mic-button`'s leaked z-index of 2 TIES that header row's z-index of 2.
 * A tie is broken by document order, and the composer comes AFTER the header
 * in the markup — so the mic/send icons (and, depending on layout, more of
 * the composer besides) painted ABOVE the observers popover. Sealing this
 * element's own stacking context with an explicit z-index — any value below
 * 2 — stops that leak: everything inside is compared only against siblings
 * inside this element from then on, and this element's own contribution (0)
 * loses cleanly to the header row's 2, no tie involved. Verified against a
 * static reproduction of the real DOM/CSS before landing this comment. */
.teams-panel .teams-conversation__composer-slot {
    position: relative;
    z-index: 0;
}

/* Lighter placeholder for the adopted chat input while in Teams (the shared
   #userInput inherits a darker main-chat placeholder colour otherwise). */
.teams-input-adopted #userInput::placeholder {
    color: var(--tm-text-3);
    opacity: 1;
}

/* ── Sent/received message enter animation (slide up from the composer) ────── */
@keyframes teams-msg-enter {
    from {
        opacity: 0;
        transform: translateY(16px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}
.teams-panel .teams-msg--enter {
    animation: teams-msg-enter 0.32s ease both;
}
@media (prefers-reduced-motion: reduce) {
    .teams-panel .teams-msg--enter {
        animation: none;
    }
}

/* Mirror the CodePen's list-level send animation: every visible bubble moves
 * up as the new one settles in from the left. The old implementation put an
 * animation class only on the new row, so it could not reproduce the defining
 * "the conversation moved" part of that example. */
@keyframes teams-msg-send-shift {
    from {
        transform: translateY(24px);
    }
    to {
        transform: none;
    }
}
@keyframes teams-msg-send-enter {
    from {
        /* These variables are measured from the visible composer to the new
         * bubble immediately after a send. The fallbacks preserve a sensible
         * motion for non-layout test environments. */
        transform: translate(
            var(--teams-msg-send-from-x, -300px),
            var(--teams-msg-send-from-y, 72px)
        );
    }
    to {
        transform: none;
    }
}
.teams-panel .teams-conversation__messages.teams-msgs--sending > .teams-msg {
    animation: teams-msg-send-shift 0.400s cubic-bezier(.4, 0, .2, 1) both;
}
.teams-panel .teams-conversation__messages.teams-msgs--sending > .teams-msg:last-child {
    animation-name: teams-msg-send-enter;
}
@media (prefers-reduced-motion: reduce) {
    .teams-panel .teams-conversation__messages.teams-msgs--sending > .teams-msg {
        animation: none;
    }
}

/* ── "All conversations" switcher row (clears the team filter) ─────────────── */
.teams-switcher .teams-sb-team--all {
    margin-bottom: 4px;
}
.teams-switcher .teams-avatar--all {
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}

/* ── Self messages on the right; others (incl. AI) on the left ─────────────── */
.teams-panel .teams-msg--mine {
    flex-direction: row-reverse;
}
.teams-panel .teams-msg--mine .teams-msg__body {
    align-items: flex-end;
    display: flex;
    flex-direction: column;
}
.teams-panel .teams-msg--mine .teams-msg__meta {
    flex-direction: row-reverse;
}
.teams-panel .teams-msg--mine .teams-msg__bubble {
    border-radius: 12px 4px 12px 12px;
}
.teams-panel .teams-msg--mine .teams-avatar {
    display: none;
} /* your own avatar is redundant */

/* ── @mention highlight inside message bubbles ────────────────────────────── */
.teams-panel .teams-mention {
    color: var(--tm-accent);
    font-weight: 600;
    background: var(--tm-accent-subtle);
    border-radius: 4px;
    padding: 0 3px;
}
.teams-panel .teams-mention--agent {
    color: var(--tm-agent);
    background: var(--tm-agent-bg);
    font-size: 0.95em;
}
/* A mention OF the current user stands out in red so they notice they were tagged. */
.teams-panel .teams-mention--self {
    color: #d92d20;
    background: rgba(217, 45, 32, 0.12);
}
/* @everyone reuses the accent treatment from the base .teams-mention rule. */
.teams-panel .teams-mention--everyone {
    color: var(--tm-accent);
}

/* ── Typing indicator (above the composer) ────────────────────────────────── */
.teams-panel .teams-conversation__typing {
    min-height: 18px;
    padding: 2px 20px 0;
    font-size: 12px;
    color: var(--tm-text-2);
    display: flex;
    align-items: center;
    gap: 6px;
}
.teams-panel .teams-conversation__typing:empty {
    display: none;
}
.teams-panel .teams-typing-dots {
    display: inline-flex;
    gap: 3px;
}
.teams-panel .teams-typing-dots span {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--tm-text-3);
    animation: teams-typing-bounce 1.2s infinite ease-in-out;
}
.teams-panel .teams-typing-dots span:nth-child(2) {
    animation-delay: 0.15s;
}
.teams-panel .teams-typing-dots span:nth-child(3) {
    animation-delay: 0.3s;
}
@keyframes teams-typing-bounce {
    0%,
    60%,
    100% {
        transform: translateY(0);
        opacity: 0.5;
    }
    30% {
        transform: translateY(-4px);
        opacity: 1;
    }
}

/* ── Team Prompt: label row + Expand affordance ───────────────────────────── */
.teams-panel .teams-field__label-row,
.teams-modal-overlay .teams-field__label-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
.teams-panel .teams-field__label-note,
.teams-modal-overlay .teams-field__label-note {
    font-weight: 400;
    color: var(--tm-text-3);
    font-size: 12px;
}
.teams-panel .teams-field__expand,
.teams-modal-overlay .teams-field__expand {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 9px;
    font-size: 12px;
    font-weight: 600;
    font-family: var(--tm-font-ui);
    color: var(--tm-accent);
    background: transparent;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    cursor: pointer;
    white-space: nowrap;
}
.teams-panel .teams-field__expand:hover,
.teams-modal-overlay .teams-field__expand:hover {
    border-color: var(--tm-accent);
    background: var(--tm-accent-subtle);
}
.teams-panel .teams-field__expand i,
.teams-modal-overlay .teams-field__expand i {
    font-size: 11px;
}

/* ── Team Prompt editor modal (EasyMDE) ───────────────────────────────────── */
.teams-prompt-editor-overlay .teams-prompt-editor {
    max-width: 760px;
    width: 100%;
    max-height: 86vh;
}
.teams-prompt-editor-overlay .teams-prompt-editor__body {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 16px 20px 18px;
    overflow-y: auto;
}
.teams-prompt-editor-overlay .teams-prompt-editor__guide {
    background: var(--tm-agent-bg);
    border: 1px solid var(--tm-agent-border);
    border-radius: var(--tm-r);
    padding: 12px 14px;
    font-size: 12.5px;
    color: var(--tm-text-2);
    line-height: 1.5;
}
.teams-prompt-editor-overlay .teams-prompt-editor__guide-title {
    font-weight: 700;
    color: var(--tm-agent);
    font-size: 13px;
    margin-bottom: 6px;
}
.teams-prompt-editor-overlay .teams-prompt-editor__guide-title i {
    margin-right: 5px;
}
.teams-prompt-editor-overlay .teams-prompt-editor__guide-lead {
    margin: 0 0 8px;
}
.teams-prompt-editor-overlay .teams-prompt-editor__guide-list {
    margin: 0 0 8px;
    padding-left: 18px;
    display: flex;
    flex-direction: column;
    gap: 3px;
}
.teams-prompt-editor-overlay .teams-prompt-editor__guide-warn {
    margin: 0;
    padding-top: 8px;
    border-top: 1px dashed var(--tm-agent-border);
    color: var(--tm-text-2);
}
.teams-prompt-editor-overlay .teams-prompt-editor__guide-warn i {
    color: var(--tm-danger);
    margin-right: 4px;
}

.teams-prompt-editor-overlay .teams-prompt-editor__counter {
    align-self: flex-end;
    font-size: 12px;
    color: var(--tm-text-3);
}
.teams-prompt-editor-overlay .teams-prompt-editor__counter--warn {
    color: #b7791f;
    font-weight: 600;
}
.teams-prompt-editor-overlay .teams-prompt-editor__counter--over {
    color: var(--tm-danger);
    font-weight: 600;
}

.teams-prompt-editor-overlay .teams-prompt-editor__area--fallback {
    width: 100%;
    min-height: 300px;
    resize: vertical;
    padding: 12px 14px;
    line-height: 1.5;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-surface);
    color: var(--tm-text-1);
    font-family: var(--tm-font-ui);
    font-size: 13.5px;
    outline: none;
}
.teams-prompt-editor-overlay .teams-prompt-editor__area--fallback:focus {
    border-color: var(--tm-accent);
    box-shadow: 0 0 0 3px var(--tm-accent-subtle);
}

/* EasyMDE chrome inside the modal — constrain height + match Teams theming. */
.teams-prompt-editor-overlay .EasyMDEContainer {
    display: flex;
    flex-direction: column;
}
.teams-prompt-editor-overlay .editor-toolbar {
    border-color: var(--tm-border);
    border-top-left-radius: var(--tm-r);
    border-top-right-radius: var(--tm-r);
    background: var(--tm-surface);
}
.teams-prompt-editor-overlay .editor-toolbar button {
    color: var(--tm-text-2) !important;
}
.teams-prompt-editor-overlay .editor-toolbar button:hover,
.teams-prompt-editor-overlay .editor-toolbar button.active {
    background: var(--tm-bg-alt);
    border-color: var(--tm-border);
}
.teams-prompt-editor-overlay .CodeMirror {
    border-color: var(--tm-border);
    border-bottom-left-radius: var(--tm-r);
    border-bottom-right-radius: var(--tm-r);
    background: var(--tm-white);
    color: var(--tm-text-1);
    min-height: 260px;
    max-height: 46vh;
    font-family: var(--tm-font-ui);
    font-size: 13.5px;
}
.teams-prompt-editor-overlay .CodeMirror-cursor {
    border-left-color: var(--tm-text-1);
}
.teams-prompt-editor-overlay .editor-preview,
.teams-prompt-editor-overlay .editor-preview-side {
    background: var(--tm-surface);
    color: var(--tm-text-1);
}

/* ═══════════════════════════════════════════════════════════════════════════
   Video call — AI participation (post-call summary) + system chat notes
   ═══════════════════════════════════════════════════════════════════════════ */

/* The video modal toggles elements via the HTML `hidden` attribute; any rule
   here that sets `display` silently overrides it (the UA [hidden] rule loses)
   — that was the "recording banner always visible" bug. Guard them all. */
.teams-video-overlay [hidden] {
    display: none !important;
}

/* Recording/AI banner across the top of the call stage (visible to ALL while
   AI is connected; dismissible — acknowledging once per call is enough). */
.teams-video-overlay .teams-video-ai-banner {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    font-size: 12.5px;
    color: #ffd9d9;
    background: rgba(190, 40, 40, 0.35);
    border-bottom: 1px solid rgba(255, 90, 90, 0.45);
}
.teams-video-overlay .teams-video-ai-banner i {
    color: #ff6b6b;
}
.teams-video-overlay .teams-video-ai-banner__close {
    margin-left: auto;
    width: 22px;
    height: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    border-radius: 4px;
    color: #ffd9d9;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    opacity: 0.75;
}
.teams-video-overlay .teams-video-ai-banner__close:hover {
    opacity: 1;
    background: rgba(255, 255, 255, 0.12);
}

/* In-call notices ("X declined the call"). Floated over the top of the stage
   rather than inserted into it: the video grid must not reflow — and jump every
   remote tile — because someone said no. `.teams-video-stage` is already
   position: relative, so this anchors to it. pointer-events stay off so a notice
   can never swallow a click meant for a tile or control. */
.teams-video-overlay .teams-video-notices {
    position: absolute;
    top: 12px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 12;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    max-width: min(92%, 420px);
    pointer-events: none;
}

.teams-video-overlay .teams-video-notice {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 9px 15px;
    border-radius: 999px;
    background: rgba(20, 24, 32, 0.92);
    border: 1px solid rgba(255, 255, 255, 0.14);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
    color: #e9edf5;
    font-size: 13px;
    line-height: 1.35;
    text-align: center;
    opacity: 1;
    transform: translateY(0);
    transition:
        opacity 0.35s ease,
        transform 0.35s ease;
    animation: teams-video-notice-in 0.28s ease-out;
}

.teams-video-overlay .teams-video-notice i {
    color: #ff9b9b;
    flex-shrink: 0;
}

.teams-video-overlay .teams-video-notice.is-leaving {
    opacity: 0;
    transform: translateY(-8px);
}

@keyframes teams-video-notice-in {
    from {
        opacity: 0;
        transform: translateY(-10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* The minimized call is a 169px preview — a stack of notices would cover the
   whole thing. The caller is not watching it closely at that size anyway. */
.teams-video-overlay--minimized .teams-video-notices {
    display: none;
}

@media (prefers-reduced-motion: reduce) {
    .teams-video-overlay .teams-video-notice {
        animation: none;
        transition: opacity 0.35s ease;
    }
    .teams-video-overlay .teams-video-notice.is-leaving {
        transform: none;
    }
}

/* Consent dialog overlaying the call modal (blocking, pre-recording). */
.teams-video-overlay .teams-video-consent {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(10, 12, 16, 0.72);
    z-index: 5;
}
.teams-video-overlay .teams-video-consent__dialog {
    max-width: 480px;
    margin: 16px;
    padding: 20px 22px;
    border-radius: 12px;
    background: #1d2230;
    color: #e6e9ef;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
    font-size: 13.5px;
    line-height: 1.5;
}
.teams-video-overlay .teams-video-consent__dialog ul {
    margin: 8px 0 8px 18px;
    padding: 0;
}
.teams-video-overlay .teams-video-consent__dialog li {
    margin: 4px 0;
}
.teams-video-overlay .teams-video-consent__actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 14px;
}
/* The shared .teams-btn styles are scoped to .teams-panel/.teams-modal-overlay
   and never reach the video overlay — style the consent buttons here (dark
   call-modal palette). */
.teams-video-overlay .teams-video-consent__actions button {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition:
        background 0.15s ease,
        border-color 0.15s ease;
}
.teams-video-overlay .teams-video-consent__actions .teams-btn--ghost {
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.35);
    color: #cfd6e2;
}
.teams-video-overlay .teams-video-consent__actions .teams-btn--ghost:hover {
    border-color: rgba(255, 255, 255, 0.65);
    color: #fff;
}
.teams-video-overlay .teams-video-consent__actions .teams-btn--primary {
    background: #b23b3b;
    border: 1px solid #c94f4f;
    color: #fff;
}
.teams-video-overlay .teams-video-consent__actions .teams-btn--primary:hover {
    background: #c74747;
}
.teams-video-overlay .teams-video-consent__actions button:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.teams-modal-overlay .teams-newchat__row .teams-avatar {
    margin-top: 0;
}

/* Centered system notes in the conversation (call ended / summary ready). */
.teams-conversation .teams-sysnote {
    display: flex;
    justify-content: center;
    margin: 10px 0;
}
.teams-conversation .teams-sysnote--video-call-ended {
    align-items: center;
    gap: 14px;
    margin: 12px auto;
    width: 80%;
}
.teams-conversation .teams-sysnote--video-call-ended::before,
.teams-conversation .teams-sysnote--video-call-ended::after {
    content: "";
    flex: 1 1 auto;
    border-top: 1px dotted var(--tm-border);
    opacity: 0.8;
}
.teams-conversation .teams-sysnote--video-call-ended .teams-sysnote__chip {
    flex: 0 1 auto;
}
.teams-conversation .teams-sysnote__chip {
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    /* NOWRAP, deliberately. With `wrap`, the icon and the timestamp are wrap
       items like any other, so a note that needed two lines of text put its
       icon alone on line 1 and its time alone on line 4 — a four-line pill for
       one sentence. They are fixed chrome: they hold the first line and the
       text wraps between them. */
    flex-wrap: nowrap;
    gap: 8px;
    max-width: 100%;
    padding: 5px 14px;
    border-radius: 999px;
    background: var(--tm-surface);
    border: 1px solid var(--tm-border);
    color: var(--tm-text-2);
    font-size: 12.5px;
    /* A FLOOR on the width, left-aligned: a run of notes then reads as a log
       with one left margin and one right margin, instead of a ragged stack of
       pills each sized to its own sentence. `min()` keeps the floor from
       overflowing a phone narrower than it (min-width beats max-width). */
    min-width: min(300px, 100%);
    text-align: left;
}
.teams-conversation .teams-sysnote__chip > i,
.teams-conversation .teams-sysnote__time {
    flex: 0 0 auto;
}
/* The note text ("Video call ended (1 participants) — 1 min.") is one inline
   span so the parenthesised participant link flows as normal text — no flex gap
   opens a space inside the brackets. It wraps naturally at word boundaries when
   the chip is narrow. */
.teams-conversation .teams-sysnote__msg {
    min-width: 0;
}
/* Keep the participant/summary link on one line so it never breaks mid-phrase. */
.teams-conversation .teams-sysnote__link {
    white-space: nowrap;
}
.teams-conversation .teams-sysnote__chip > i {
    color: var(--tm-text-3);
}
.teams-conversation .teams-sysnote__time {
    color: var(--tm-text-3);
    font-size: 11px;
    /* Pinned to the chip's right edge. The chip is a fixed-width flex row, so
       the free space between the text and the time is real space — an auto
       margin absorbs all of it and the times line up in a column down the
       transcript, whatever length the notes are. */
    margin-left: auto;
    /* It must not be pushed out of the chip by a long note. */
    padding-left: 8px;
}
.teams-conversation .teams-sysnote__link {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: var(--ai-list-blue);
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.teams-conversation .teams-sysnote__link:hover {
    filter: brightness(1.15);
}

/* A merged chip ("Nelly S, Diaz C +4 added") reads as text but opens the full
   list of names on tap — the count is the summary, the names are the detail. */
.teams-conversation .teams-sysnote__expand {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: inherit;
    cursor: pointer;
    text-decoration: underline dotted;
    text-underline-offset: 3px;
}
.teams-conversation .teams-sysnote__names {
    display: block;
    margin-top: 3px;
    color: var(--tm-text-3);
    font-size: 11.5px;
}
.teams-conversation .teams-sysnote__names[hidden] {
    display: none;
}

/* AI meeting summary modal (reuses .teams-modal chrome). */
.teams-meeting-summary-modal .teams-modal {
    max-width: 640px;
    width: min(640px, 92vw);
    padding: 10px;
}

.teams-meeting-summary-modal .teams-meeting-summary__body {
    max-height: 70vh;
    overflow-y: auto;
}
.teams-meeting-summary-modal .teams-meeting-summary__meta {
    color: var(--tm-text-3);
    font-size: 12px;
    margin-bottom: 10px;
}
.teams-meeting-summary-modal .teams-meeting-summary__content {
    color: var(--tm-text-1);
    font-size: 13.5px;
    line-height: 1.55;
}
.teams-meeting-summary-modal .teams-meeting-summary__pending {
    color: var(--tm-text-2);
    font-size: 13px;
    margin: 8px 0;
}
.teams-meeting-summary-modal .teams-meeting-summary__participants {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--tm-border);
}
.teams-meeting-summary-modal .teams-meeting-summary__participants-heading {
    margin: 0 0 6px;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--tm-text-3);
}
.teams-meeting-summary-modal .teams-meeting-summary__participants-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.teams-meeting-summary-modal .teams-meeting-summary__participants-list li {
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
    font-size: 12.5px;
    padding: 3px 10px;
    border-radius: 999px;
}
.teams-meeting-summary-modal .teams-meeting-summary__transcript {
    margin: 12px 0 0;
}
.teams-meeting-summary-modal .teams-meeting-summary__transcript a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--tm-accent);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
}
.teams-meeting-summary-modal .teams-meeting-summary__transcript a:hover {
    text-decoration: underline;
}
.teams-meeting-summary-modal .teams-meeting-summary__disclaimer {
    margin-top: 14px;
    padding-top: 10px;
    border-top: 1px solid var(--tm-border);
    color: var(--tm-text-3);
    font-size: 11.5px;
}

/* Participant duration modal uses the same Teams meeting-summary chrome. */
.teams-meeting-participants-modal .teams-modal {
    max-width: 820px;
    width: min(820px, 96vw);
    padding: 10px;
}
.teams-meeting-participants-modal .teams-meeting-participants__body {
    max-height: 70vh;
    overflow-y: auto;
}
.teams-meeting-participants__columns,
.teams-meeting-participants__list li {
    display: grid;
    /* Fixed time columns keep every row and its header on the same rhythm.
       Auto-sized columns varied with each name/timestamp and made Joined and
       Left appear to run together. */
    grid-template-columns: minmax(160px, 1fr) 185px 185px 120px;
    column-gap: 28px;
    align-items: center;
}
.teams-meeting-participants__columns {
    padding: 8px 10px;
    color: var(--tm-text-3);
    background: var(--tm-accent-subtle);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.teams-meeting-participants__columns > :last-child,
.teams-meeting-participants__list li > :last-child {
    text-align: right;
}
.teams-meeting-participants__toolbar {
    display: flex;
    justify-content: flex-end;
    margin: 0 0 10px;
}
.teams-meeting-participants__list {
    list-style: none;
    padding: 0;
    margin: 0;
}
.teams-meeting-participants__list li {
    padding: 11px 10px;
    border-bottom: 1px solid var(--tm-border);
    color: var(--tm-text-1);
    font-size: 13.5px;
}
.teams-meeting-participants__list li strong {
    color: var(--tm-text-2);
    font-variant-numeric: tabular-nums;
}
.teams-meeting-participants__list time {
    color: var(--tm-text-2);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
@media (max-width: 620px) {
    .teams-meeting-participants__columns,
    .teams-meeting-participants__list li {
        grid-template-columns: minmax(95px, 1fr) 96px 96px 72px;
        column-gap: 8px;
        font-size: 12px;
    }
}

/* ── Open Channel browser (open-channel-browser-modal.js) ─────────────────────
   A browse row has to answer "what is this channel for?", which a name and a
   follower count cannot. It carries the owner-written description (clamped to
   two lines so one verbose channel cannot push the rest of the list below the
   fold of this fixed-height modal) plus the category and tags, and it keeps
   the follow control on the row so following never costs a round trip through
   the channel itself.
   Scoped to the browser modal: `.teams-newchat__row` is a single-line people
   picker row and must keep its own shape. */
.teams-modal-overlay .teams-modal--oc-browse .oc-browse__intro {
    margin: 0 0 10px;
    color: var(--tm-text-3);
    font-size: 12.5px;
    line-height: 1.45;
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__item {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 4px;
    border-radius: 8px;
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__item:hover {
    background: var(--tm-bg-alt);
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    /* min-width:0 lets the long description and label actually shrink instead
       of forcing the row wider than the modal. */
    flex: 1 1 auto;
    min-width: 0;
    padding: 4px;
    border: none;
    background: none;
    border-radius: 8px;
    text-align: left;
    color: var(--tm-text-1);
    cursor: pointer;
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__avatar {
    flex: 0 0 auto;
    margin-top: 2px;
    border-radius: 999px;
    background: var(--tm-accent);
    color: var(--tm-real-white);
    font-size: 12px;
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 auto;
    min-width: 0;
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__label {
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__sub {
    font-size: 12px;
    color: var(--tm-text-3);
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__desc {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-top: 2px;
    color: var(--tm-text-2);
    font-size: 12.5px;
    line-height: 1.45;
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 4px;
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__chip {
    padding: 1px 7px;
    border: 1px solid var(--tm-border);
    border-radius: 999px;
    color: var(--tm-text-3);
    font-size: 11px;
    line-height: 1.6;
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__chip--category {
    border-color: transparent;
    background: var(--tm-accent-subtle);
    color: var(--tm-text-2);
    font-weight: 600;
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__follow {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    align-self: center;
    padding: 6px 11px;
    border: 1px solid var(--tm-accent);
    border-radius: 999px;
    background: var(--tm-accent);
    color: var(--tm-real-white);
    font: 600 12px/1 var(--tm-font-ui);
    white-space: nowrap;
    cursor: pointer;
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__follow:hover:not(:disabled) {
    filter: brightness(1.08);
}

/* Following is a state, not a dead end: the button stays live so the same
   control takes the follow back. */
.teams-modal-overlay .teams-modal--oc-browse .oc-browse__follow.is-following {
    border-color: var(--tm-border);
    background: transparent;
    color: var(--tm-text-2);
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__role {
    flex: 0 0 auto;
    align-self: center;
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--tm-accent-subtle);
    color: var(--tm-text-2);
    font: 600 12px/1.2 var(--tm-font-ui);
}

.teams-modal-overlay .teams-modal--oc-browse .oc-browse__follow:disabled {
    opacity: 0.6;
    cursor: default;
}

@media (max-width: 480px) {
    .teams-modal-overlay .teams-modal--oc-browse .oc-browse__follow span { display: none; }
    .teams-modal-overlay .teams-modal--oc-browse .oc-browse__follow { padding: 7px 9px; }
}

/* =============================================================================
   Teams create hub
   -----------------------------------------------------------------------------
   The shared Create entry point coordinates chat, Team and Open Channel flows.
   Keep this separate from the legacy modal rules so the tab UI remains scoped.
   ============================================================================= */

.teams-modal .teams-create-hub__tabs {
    display: flex;
    gap: 4px;
    width: fit-content;
    max-width: 100%;
    padding: 4px;
    overflow-x: auto;
    border-radius: var(--tm-r);
    justify-content: center;
}

/* In the shared create hub, the tabs replace the modal heading and belong in
   the fixed header beside the close control. The form body remains the only
   scrolling area, so switching modes is always available. */
.teams-modal__header .teams-create-hub__tabs {
    flex: 1;
    margin: 0 12px 0 0;
}

/* One window size for every tab. Each flow brought its own (chat 520px wide at
   640px, team/channel 560px capped at 80vh, action item 480px content-high), so
   switching tabs made the window jump. All take the widest/tallest — Create
   team / Open channel — and each body flexes to fill it, footer at the bottom.
   Only the hub: the standalone modals keep their own sizes. */
.teams-modal-overlay .teams-modal.teams-modal--create-hub {
    width: 560px;
    max-width: 100%;
    height: min(860px, 80vh);
    max-height: 80vh;
}
.teams-modal-overlay .teams-modal--create-hub > .teams-form,
.teams-modal-overlay .teams-modal--create-hub > .teams-modal__body,
.teams-modal-overlay .teams-modal--create-hub > .teams-form > .teams-modal__body {
    flex: 1 1 auto;
    min-height: 0;
}
@media (max-width: 768px) {
    /* Phones/tablets: the same one size, as tall as the tallest mobile form. */
    .teams-modal-overlay .teams-modal.teams-modal--create-hub {
        height: min(88dvh, calc(100vh - 24px));
        max-height: min(88dvh, calc(100vh - 24px));
    }
}

/* The form body is the only scrolling area; it never scrolls sideways. */
.teams-modal--form .teams-modal__body {
    overflow-x: hidden;
}

.teams-modal .teams-create-hub__tabs [role="tab"] {
    appearance: none;
    flex: 0 0 auto;
    min-height: 34px;
    padding: 7px 12px;
    border: 1px solid transparent;
    border-radius: calc(var(--tm-r) - 2px);
    background: transparent;
    color: var(--tm-text-2);
    font: 600 13px/1.2 var(--tm-font-ui);
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease,
        box-shadow 150ms ease;
}

/* Full names on a desktop; the short ones are for phones (below). */
.teams-modal .teams-create-hub__tabs .teams-create-hub__tab-short {
    display: none;
}

.teams-modal .teams-create-hub__tabs [role="tab"]:hover {
    background: var(--tm-accent-subtle);
    color: var(--tm-text-1);
}

.teams-modal .teams-create-hub__tabs [role="tab"][aria-selected="true"] {
    border-color: var(--tm-accent);
    background: var(--tm-accent);
    color: var(--tm-white);
    box-shadow: var(--tm-shadow-sm);
}

.teams-modal .teams-create-hub__tabs [role="tab"]:focus-visible {
    outline: 2px solid var(--tm-accent);
    outline-offset: 2px;
}

.teams-modal .teams-create-hub__content {
    display: grid;
    gap: 16px;
    padding-top: 20px;
}

.teams-modal .teams-create-hub__content p {
    margin: 0;
    color: var(--tm-text-2);
    font: 400 15px/1.5 var(--tm-font-ui);
}

.teams-modal .teams-create-hub__content .teams-btn {
    justify-self: start;
}

@media (max-width: 480px) {
    .teams-modal .teams-create-hub__tabs {
        width: 100%;
        /* Creation modes are primary navigation, not form content: keep all
           of them visible in the one fixed header row. A wrapping strip pushed
           Open channel into the form area on iPhone and made each tab appear
           to belong to a different layout. */
        flex-wrap: nowrap;
        overflow: hidden;
        justify-content: flex-start;
        min-width: 0;
    }

    .teams-modal .teams-create-hub__tabs [role="tab"] {
        /* Four equal columns with SHORT names — "Chat · Team · Channel ·
           Action": the window already says what it is for, so the long names
           only cost truncation. Each tab looks like what it is, a button you
           can press: a raised surface, the selected one filled. */
        flex: 1 1 0;
        min-width: 0;
        min-height: 40px;
        overflow: hidden;
        padding-inline: 4px;
        border-color: var(--tm-border);
        background: var(--tm-real-white);
        box-shadow: var(--tm-shadow-sm);
        font-size: 14px;
        text-overflow: ellipsis;
    }
    .teams-modal .teams-create-hub__tabs .teams-create-hub__tab-full {
        display: none;
    }
    .teams-modal .teams-create-hub__tabs .teams-create-hub__tab-short {
        display: inline;
    }
    .teams-modal .teams-create-hub__tabs {
        gap: 6px;
    }

    .teams-modal__header .teams-create-hub__tabs {
        margin-right: 0;
    }

    /* Close leaves the header row to the tabs and floats on the corner, a
       round button half outside the card — the way a sheet on iOS does it.
       The card stops clipping so the button can overhang it; its rounded
       corners are kept by the header and footer themselves. */
    .teams-modal-overlay .teams-modal.teams-modal--create-hub {
        overflow: visible;
    }
    .teams-modal-overlay .teams-modal--create-hub .teams-modal__header {
        border-radius: var(--tm-r-lg) var(--tm-r-lg) 0 0;
    }
    .teams-modal-overlay .teams-modal--create-hub > :last-child {
        border-radius: 0 0 var(--tm-r-lg) var(--tm-r-lg);
    }
    .teams-modal-overlay .teams-modal--create-hub .teams-modal__close {
        position: absolute;
        top: -14px;
        right: -10px;
        z-index: 2;
        width: 36px;
        height: 36px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 1px solid var(--tm-border);
        border-radius: 50%;
        background: var(--tm-real-white);
        box-shadow: var(--tm-shadow-md);
        font-size: 20px;
        line-height: 1;
    }
    .teams-modal-overlay .teams-modal--create-hub {
        position: relative;
    }
    /* The Action tab is a full-width bottom sheet: overhanging the right edge
       would put Close off-screen, so it sits just inside, above the sheet. */
    .teams-action-form-overlay .teams-modal--create-hub .teams-modal__close {
        top: -18px;
        right: 12px;
    }

    /* A form's body is the sole mobile scroll region. Keeping its flex basis
       bounded prevents long Create team/Open channel forms from being clipped
       beneath the action footer. */
    .teams-modal-overlay .teams-modal--form {
        max-height: min(88dvh, calc(100vh - 24px));
    }

    .teams-modal-overlay .teams-modal--form .teams-modal__body {
        flex: 1 1 auto;
        min-height: 0;
    }

    .teams-modal-overlay .teams-modal--form .teams-modal__footer {
        flex-shrink: 0;
    }
}

/* Teams people card + the account-menu status controls.
 *
 * THE ONLY definition of these components. An earlier cut had a second copy in
 * main-chat.css that disagreed with this one about z-index, avatar size and
 * padding; `body .teams-user-card` quietly outranked `.teams-user-card`, so
 * this file was dead and every edit here did nothing.
 *
 * EVERY `--tm-*` READ CARRIES A FALLBACK, deliberately. The card is appended to
 * <body> so it can escape transcript clipping and Space-feed stacking contexts
 * — which also means it sits OUTSIDE the `.teams-panel` subtree those tokens
 * are defined on. Without fallbacks the card renders unstyled on exactly the
 * surfaces it exists to work on (the same trap the `--sp-*` tokens hit). */

.teams-user-card {
    position: fixed;
    z-index: 20000;
    box-sizing: border-box;
    width: min(340px, calc(100vw - 24px));
    padding: 18px 18px 14px;
    border: 1px solid var(--tm-border, #dedbd3);
    border-radius: 14px;
    background: var(--tm-white, #fff);
    box-shadow: 0 18px 44px rgba(20, 18, 14, .22), 0 2px 6px rgba(20, 18, 14, .08);
    color: var(--tm-text-1, #252525);
    font-family: var(--tm-font-ui, inherit);
    /* Opens FROM the avatar: teams-user-card.js sets transform-origin to the
       avatar's horizontal centre, so the card unfolds out of the face that was
       clicked rather than materialising as an unrelated panel. */
    opacity: 0;
    transform: scale(.9) translateY(-6px);
    transition: opacity 240ms cubic-bezier(.16, 1, .3, 1),
                transform 320ms cubic-bezier(.16, 1, .3, 1);
}
.teams-user-card.is-open { opacity: 1; transform: none; }
/* The card takes focus on open (tabindex="-1") so Escape and Tab work. It is
   the container, not a control, so it must not wear a ring for it. */
.teams-user-card:focus,
.teams-user-card:focus-visible { outline: none; }
.teams-user-card *,
.teams-user-card *::before,
.teams-user-card *::after { box-sizing: border-box; }

/* Content settles a beat after the frame, so the card reads as opening rather
   than as a block that snapped into place. */
.teams-user-card.is-open > * { animation: teamsUserCardContent 320ms both cubic-bezier(.16, 1, .3, 1); }
.teams-user-card.is-open > *:nth-child(2) { animation-delay: 40ms; }
.teams-user-card.is-open > *:nth-child(3) { animation-delay: 75ms; }
.teams-user-card.is-open > *:nth-child(4) { animation-delay: 105ms; }
@keyframes teamsUserCardContent {
    from { opacity: 0; transform: translateY(7px); }
    to   { opacity: 1; transform: none; }
}

.teams-user-card__head { display: flex; align-items: center; gap: 14px; }
.teams-user-card__avatar {
    position: relative;
    flex: 0 0 72px;
    width: 72px;
    height: 72px;
    overflow: hidden;
    border: 3px solid var(--tm-surface, #fff);
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--tm-avatar-placeholder, #dbddda);
    box-shadow: 0 5px 14px rgba(20, 18, 14, .16);
    color: var(--tm-accent, #2d5f84);
    font-size: 26px;
    font-weight: 700;
}
.teams-user-card__identity { display: grid; gap: 4px; min-width: 0; }
.teams-user-card__identity strong {
    font-size: 17px;
    line-height: 1.25;
    overflow-wrap: anywhere;
}

/* Direct contact rows — extension and email. Head content is identity only;
   team and office belong to the details list below. */
.teams-user-card__contact {
    display: flex;
    align-items: center;
    gap: 7px;
    min-width: 0;
    color: var(--tm-text-2, #6f6e6d);
    font-size: 12.5px;
}
.teams-user-card__contact > i { flex: 0 0 12px; font-size: 11px; opacity: .75; }
.teams-user-card__contact-value {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-user-card__copy {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--tm-text-3, #8a8882);
    cursor: pointer;
    opacity: 0;
    transition: opacity 140ms ease, background 140ms ease, color 140ms ease;
}
/* Revealed on hover/focus so two copy buttons do not compete with the name for
   attention, but always reachable by keyboard. */
.teams-user-card__contact:hover .teams-user-card__copy,
.teams-user-card__copy:focus-visible,
.teams-user-card__copy.is-copied { opacity: 1; }
.teams-user-card__copy:hover { background: var(--tm-bg-alt, #f6f5f2); color: var(--tm-accent, #2d5f84); }
.teams-user-card__copy.is-copied { color: #2fac5a; }

.teams-user-card__status {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin: 15px 0 0;
    padding: 10px 12px;
    border-radius: 9px;
    background: var(--tm-bg-alt, #f6f5f2);
    font-size: 13px;
    line-height: 1.35;
}
.teams-user-card__status > i { margin-top: 2px; font-size: 13px; }
.teams-user-card__status span { display: grid; gap: 2px; min-width: 0; }
.teams-user-card__status strong { font-weight: 650; }
.teams-user-card__status-detail { color: var(--tm-text-2, #6f6e6d); overflow-wrap: anywhere; }
/* Tone comes from the shared state table, so the card cannot disagree with the
   avatar badge about whether a state is "good" or "interrupting". */
.teams-user-card__status--positive > i { color: #2fac5a; }
.teams-user-card__status--negative > i { color: #c53540; }
.teams-user-card__status--caution  > i { color: #e49a12; }
.teams-user-card__status--muted    > i { color: #7d858d; }

.teams-user-card__details {
    display: grid;
    grid-template-columns: 104px minmax(0, 1fr);
    gap: 7px 10px;
    margin: 15px 0;
    font-size: 12.5px;
}
.teams-user-card__details dt { color: var(--tm-text-3, #8a8882); }
.teams-user-card__details dd { margin: 0; overflow-wrap: anywhere; }

.teams-user-card__actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 9px;
    padding-top: 13px;
    border-top: 1px solid var(--tm-border, #dedbd3);
}
.teams-user-card__action {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    min-height: 34px;
    border: 1px solid var(--tm-border, #dedbd3);
    border-radius: 9px;
    background: var(--tm-surface, #fff);
    color: var(--tm-text-1, #252525);
    cursor: pointer;
    box-shadow: 0 5px 12px rgba(20, 18, 14, .13);
    transition: transform 140ms ease, box-shadow 140ms ease,
                background 140ms ease, border-color 140ms ease;
}
.teams-user-card__action i { 
    font-size: 13px; 
    color: var(--tm-accent, #2d5f84); 
}

.teams-user-card__action:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 12px rgba(20, 18, 14, .23);
}
/* Keyboard focus is a RING, never the hover lift.
   Two separate reasons, both of which showed up as the same visual fault:
   • Chrome's default ring is a white inner + dark outer pair, which on a
     filled accent button reads as a white border somebody forgot to remove.
   • Borrowing hover's `transform` for focus means an element the user has not
     pointed at appears to be under the cursor.
   Drawn with box-shadow so it follows `border-radius` and costs no layout. */
.teams-user-card__action:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px var(--tm-white, #fff),
                0 0 0 4px var(--tm-accent, #2d5f84);
}
.teams-user-card__action:active { transform: translateY(0); box-shadow: none;}
/* Message is the primary action: it is what the card is opened for. */

.teams-user-card__action--message {
    /* Full width above the two call kinds. With three buttons in a 2-column
       grid something has to take the odd cell, and it should be the primary
       action rather than leaving Video stranded beside a gap. */
    grid-column: 1 / -1;
    border-color: var(--tm-accent, #2d5f84);
    background: var(--tm-accent, #2d5f84);
    color: #fff;
}
.teams-user-card__action--message i { color: #fff; }

.teams-user-card__action--message:hover {
    background: var(--tm-accent-hover, #245070);
    transform: translateY(-2px);
    box-shadow: 0 5px 12px rgba(14, 15, 20, .23);
}
.teams-user-card__action--message:focus-visible {
    background: var(--tm-accent-hover, #245070);
}

/* Only an avatar that can actually open a card claims the pointer. */
.teams-user-card-trigger { cursor: pointer; }

@media (prefers-reduced-motion: reduce) {
    .teams-user-card { transition: none; opacity: 1; transform: none; }
    .teams-user-card.is-open > * { animation: none; }
}

/* ── Account-menu status controls ──────────────────────────────────────────── */

.user-dropdown.user-dropdown--teams-status { 
    width: 270px; 
}

.user-dropdown.user-dropdown--teams-status .dropdown-item:hover { 
    background: var(--bg-hover, #f2f2f2); 
}

.user-dropdown.user-dropdown--teams-status .dropdown-item {
    min-height: 42px;
    padding: 10px 14px;
    border: 0;
    border-radius: 0;
    background: var(--tm-white, #fff);
    color: var(--tm-text-1, #333);
    font-size: 14px;
    line-height: 1.25;
    text-align: left;
    cursor: pointer;
}
.user-dropdown.user-dropdown--teams-status .teams-status-action {
    display: flex;
    align-items: center;
    gap: 10px;
}
.user-dropdown.user-dropdown--teams-status .teams-status-action:hover { background: var(--bg-hover, #f2f2f2); }
/* The menu item reports the CURRENT status, so it is legible without opening
   the dialog — and its icon is tinted by the same state vocabulary as the dot. */
.teams-status-action__text { display: grid; min-width: 0; text-align: left; }
.teams-status-action__detail {
    overflow: hidden;
    color: var(--tm-text-3, #8a8882);
    font-size: 11.5px;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-status-action__detail:empty { display: none; }
.teams-status-action[data-status-state="available"] > i:first-child { color: #2fac5a; }
.teams-status-action[data-status-state="busy"] > i:first-child,
.teams-status-action[data-status-state="do_not_disturb"] > i:first-child { color: #c53540; }
.teams-status-action[data-status-state="be_right_back"] > i:first-child,
.teams-status-action[data-status-state="away"] > i:first-child { color: #e49a12; }
.teams-status-action[data-status-state="offline"] > i:first-child { color: #7d858d; }
.teams-status-separator { border-top: 1px solid var(--border-color, #e5e3dd); margin: 5px 0; }

.teams-status-dialog { max-width: 430px; }
.teams-status-dialog .teams-modal__body { display: grid; gap: 15px; padding: 18px 20px; }
.teams-status-dialog label {
    display: grid;
    gap: 6px;
    color: var(--tm-text-2, #6f6e6d);
    font-size: 13px;
    font-weight: 600;
}
/* `hidden` is only `display: none` at USER-AGENT specificity, so the rule above
   silently defeated it: every conditional row in this dialog ("Clear at",
   "Starts at") rendered permanently even when the code had hidden it. Any
   element given an explicit `display` needs this companion. */
.teams-status-dialog [hidden] { display: none !important; }
.teams-status-dialog select,
.teams-status-dialog textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 9px 10px;
    border: 1px solid var(--tm-border, #dedbd3);
    border-radius: 8px;
    background: var(--tm-surface, #fff);
    color: var(--tm-text-1, #252525);
    font: 14px var(--tm-font-ui, inherit);
}
.teams-status-dialog textarea { resize: vertical; }

.teams-status-dialog .teams-status-picker { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.teams-status-dialog .teams-status-picker__choice {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 36px;
    padding: 8px 10px;
    border: 1px solid var(--tm-border, #dedbd3);
    border-radius: 8px;
    background: var(--tm-surface, #fff);
    color: var(--tm-text-1, #252525);
    cursor: pointer;
    font: 600 12.5px var(--tm-font-ui, inherit);
    text-align: left;
}
.teams-status-dialog .teams-status-picker__choice:hover { border-color: var(--tm-accent, #2d5f84); }
/* THE SELECTED CHOICE MUST BE OBVIOUS AT A GLANCE. A 1px accent border plus a
   faint ring was near-invisible in light mode and effectively absent in dark,
   where the unselected tiles are already a raised panel colour — so selection
   is now carried by three independent signals: a filled accent background,
   inverted text, and an explicit tick. Never by border colour alone. */
.teams-status-dialog .teams-status-picker__choice[aria-selected="true"] {
    border-color: var(--tm-accent, #2d5f84);
    background: var(--tm-accent, #2d5f84);
    color: #fff;
    font-weight: 700;
    box-shadow: 0 2px 8px rgba(20, 18, 14, .18);
}
.teams-status-dialog .teams-status-picker__choice > i:first-child { width: 14px; text-align: center; }
.teams-status-dialog .teams-status-picker__tick {
    margin-left: auto;
    font-size: 11px;
    opacity: 0;
    color: #fff;
}
.teams-status-dialog .teams-status-picker__choice[aria-selected="true"] .teams-status-picker__tick { opacity: 1; }
/* The state colour still has to read against the filled tile. */
.teams-status-dialog .teams-status-picker__choice[aria-selected="true"] > i:first-child { color: #fff; }

/* Message length, mirroring the 280-char server constraint. */
.teams-status-dialog__message { position: relative; }
.teams-status-dialog__count {
    justify-self: end;
    margin-top: -2px;
    color: var(--tm-text-3, #8a8882);
    font-size: 11px;
    font-weight: 500;
}

.teams-status-dialog__notification-note {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 9px;
    align-items: start;
    padding: 10px 12px;
    border: 1px solid #e5b7b7;
    border-radius: 8px;
    background: #fff4f4;
    color: #7d3030;
    font-size: 12px;
    font-weight: 500;
    line-height: 1.4;
}
.teams-status-dialog__notification-note > i { margin-top: 2px; }

/* "Show when people message me" — a checkbox with its consequence spelled out,
   because the setting is only worth enabling if you know what it does. */
.teams-status-dialog__check {
    grid-template-columns: auto 1fr;
    align-items: start;
    gap: 10px;
    padding: 11px 12px;
    border: 1px solid var(--tm-border, #dedbd3);
    border-radius: 8px;
    background: var(--tm-bg-alt, #f6f5f2);
    cursor: pointer;
}
.teams-status-dialog__check input { width: 16px; height: 16px; margin: 2px 0 0; cursor: pointer; }
.teams-status-dialog__check-label { color: var(--tm-text-1, #252525); }
.teams-status-dialog__check small {
    display: block;
    margin-top: 3px;
    color: var(--tm-text-3, #8a8882);
    font-size: 11.5px;
    font-weight: 400;
    line-height: 1.35;
}

.teams-status-dialog__when input[type="datetime-local"] {
    width: 100%;
    box-sizing: border-box;
    padding: 9px 10px;
    border: 1px solid var(--tm-border, #dedbd3);
    border-radius: 8px;
    background: var(--tm-surface, #fff);
    color: var(--tm-text-1, #252525);
    font: 14px var(--tm-font-ui, inherit);
}
/* The two datetime fields of a scheduled window, side by side so the window
   reads as one range rather than two unrelated settings. */
.teams-status-dialog__window { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.teams-status-dialog [data-duration-mode] { display: grid; gap: 15px; }

.teams-status-dialog__schedule {
    justify-self: start;
    padding: 0;
    border: 0;
    background: none;
    color: var(--tm-accent, #2d5f84);
    cursor: pointer;
    font: 600 13px var(--tm-font-ui, inherit);
}
.teams-status-dialog__schedule:hover { text-decoration: underline; }

/* ── The status note above the composer ────────────────────────────────────── */

/* Width and centring come from the composer-slot rule in teams-conversation.css,
   but that is only half of matching the input: `#inputContainer` adds its own
   `padding: 5px 20px` INSIDE the slot, so a note padded to the slot edge
   overhangs the field it belongs to by 18px on each side. The 20px here is that
   same inset — measured, not guessed — so the note's edges line up with the
   composer's. The note is about the box below it and must never be wider than
   it. Bottom padding is 0: the slot and the input container already contribute
   13px, which is the whole gap this needs. */
.teams-status-notes { display: grid; gap: 6px; padding: 0 20px; }
.teams-status-note {
    display: flex;
    align-items: baseline;
    gap: 9px;
    padding: 7px 12px 8px;
    border-radius: 9px;
    background: var(--tm-bg-alt, #f1efeb);
    color: var(--tm-text-2, #6f6e6d);
    font-size: 12.5px;
    line-height: 1.4;
    animation: teamsStatusNoteIn 260ms cubic-bezier(.16, 1, .3, 1) both;
}
@keyframes teamsStatusNoteIn {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: none; }
}
.teams-status-note .teams-presence-dot { align-self: center; }
.teams-status-note__text { min-width: 0; }
.teams-status-note__text strong { color: var(--tm-text-1, #252525); font-weight: 650; }
.teams-status-note__text strong::after {
    content: "\00B7";
    margin: 0 6px;
    color: var(--tm-text-3, #8a8882);
    font-weight: 400;
}
.teams-status-note__close {
    flex: 0 0 auto;
    align-self: center;
    margin-left: auto;
    padding: 0 2px;
    border: 0;
    border-radius: 5px;
    background: none;
    color: var(--tm-text-3, #8a8882);
    cursor: pointer;
    font-size: 16px;
    line-height: 1;
    opacity: .65;
    transition: opacity 140ms ease, color 140ms ease;
}
.teams-status-note:hover .teams-status-note__close,
.teams-status-note__close:focus-visible { opacity: 1; }
.teams-status-note__close:hover { color: var(--tm-text-1, #252525); }

@media (prefers-reduced-motion: reduce) {
    .teams-status-note { animation: none; }
}
/* Two or more statuses fold into one line (teams-status-notes.js). The toggle
   IS the line, so the whole row opens it; the names truncate rather than wrap,
   because a dozen of them is exactly the case this exists for. */
.teams-status-notes .teams-status-note__toggle {
    display: flex;
    align-items: center;
    gap: 9px;
    flex: 1 1 auto;
    min-width: 0;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.teams-status-notes .teams-status-note__toggle i {
    flex: 0 0 auto;
    width: 10px;
    color: var(--tm-text-3, #8a8882);
    font-size: 10px;
}
.teams-status-notes .teams-status-note--summary .teams-status-note__text {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.teams-status-notes .teams-status-note--summary:hover .teams-status-note__close { opacity: 1; }
/* Expanded: the individual notes sit indented under their summary. */
.teams-status-notes .teams-status-note--summary ~ .teams-status-note { margin-left: 16px; }
/* Keyed by the RESOLVED state, matching the badge the person's colleagues see. */
.teams-status-dialog .teams-status-picker__choice--available i { color: #2fac5a; }
.teams-status-dialog .teams-status-picker__choice--busy i,
.teams-status-dialog .teams-status-picker__choice--do_not_disturb i { color: #c53540; }
.teams-status-dialog .teams-status-picker__choice--be_right_back i,
.teams-status-dialog .teams-status-picker__choice--away i { color: #e49a12; }
.teams-status-dialog .teams-status-picker__choice--offline i { color: #7d858d; }

/* ── Dark theme ────────────────────────────────────────────────────────────── */

body.dark-theme .teams-user-card {
    border-color: #3e4754;
    background: #252b33;
    color: #f4f6f8;
    box-shadow: 0 18px 44px rgba(0, 0, 0, .5);
}
body.dark-theme .teams-user-card__contact,
body.dark-theme .teams-user-card__status-detail,
body.dark-theme .teams-user-card__details dt { color: #b9c1ca; }
body.dark-theme .teams-user-card__status { background: #313a46; }
body.dark-theme .teams-user-card__details dd { color: #eef1f5; }
body.dark-theme .teams-user-card__copy { color: #9aa4b0; }
body.dark-theme .teams-user-card__copy:hover { background: #313a46; color: #8ab6de; }
body.dark-theme .teams-user-card__actions { border-color: #3e4754; }
body.dark-theme .teams-user-card__action {
    border-color: #4b5867;
    background: #303946;
    color: #f4f6f8;
}
body.dark-theme .teams-user-card__action i { color: #8ab6de; }
body.dark-theme .teams-user-card__action--message {
    border-color: #4f86bc;
    background: #4f86bc;
    color: #fff;
}
body.dark-theme .teams-user-card__action--message i { color: #fff; }
body.dark-theme .user-dropdown.user-dropdown--teams-status .dropdown-item { 
    background: #252b33; 
    color: #f4f6f8; 
}
body.dark-theme .teams-status-dialog .teams-status-picker__choice {
    border-color: #4b5867;
    background: #303946;
    color: #f4f6f8;
}
/* Dark mode is where a border-only selection disappeared completely: the tiles
   are already a raised panel, so selection must change the FILL. */
body.dark-theme .teams-status-dialog .teams-status-picker__choice[aria-selected="true"] {
    border-color: #6ba3d6;
    background: #4f86bc;
    color: #fff;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .45);
}
body.dark-theme .teams-status-dialog__check {
    border-color: #4b5867;
    background: #2b333d;
}
body.dark-theme .teams-status-dialog__notification-note {
    border-color: #754848;
    background: #3c292c;
    color: #f1c1c1;
}
body.dark-theme .teams-status-dialog__check-label { color: #f4f6f8; }
body.dark-theme .teams-status-dialog__check small,
body.dark-theme .teams-status-dialog__count { color: #9aa4b0; }
/* The dialog is body-appended, so `--tm-surface` never resolves for it and the
   `#fff` fallback wins — which left the message box and the duration select
   glaring white inside an otherwise dark dialog. Every input needs an explicit
   dark value here, not just the ones added most recently. */
body.dark-theme .teams-status-dialog select,
body.dark-theme .teams-status-dialog textarea,
body.dark-theme .teams-status-dialog__when input[type="datetime-local"] {
    border-color: #4b5867;
    background: #303946;
    color: #f4f6f8;
}
body.dark-theme .teams-status-dialog textarea::placeholder { color: #8b95a1; }
body.dark-theme .teams-status-dialog label { color: #b9c1ca; }
body.dark-theme .teams-status-dialog__schedule { color: #8ab6de; }
body.dark-theme .teams-status-note {
    border-color: #3e4754;
    border-left-color: #4f86bc;
    background: #2b333d;
    color: #b9c1ca;
}
body.dark-theme .teams-status-note__text strong { color: #f4f6f8; }
body.dark-theme .teams-status-action__detail { color: #9aa4b0; }

/* ── Responsive / small-screen behaviour ──────────────────────────────────── */
@media (max-width: 768px) {
    /* A landscape desktop photo is the wrong crop on a phone: `cover` throws
       most of it off-screen. A user who uploaded a portrait image for mobile
       gets it here; everyone else keeps the desktop one via the var fallback. */
    .teams-panel--real.teams-panel--has-chat-background .teams-conversation-view,
    .teams-panel--real.teams-panel--has-chat-background.teams-panel--background-spaces .spaces-panel {
        background-image:
            linear-gradient(rgba(20, 24, 28, .28), rgba(20, 24, 28, .28)),
            var(--teams-chat-background-image-mobile, var(--teams-chat-background-image));
    }

    .teams-panel .teams-config__danger-row {
        flex-direction: column;
        align-items: flex-start;
        gap: 10px;
    }

    .teams-modal-overlay .teams-member-actions,
    .teams-panel .teams-member-actions {
        flex-direction: column;
    }

    body.mobile-standalone .chat-area {
        overflow-x: hidden;
    }

    /* The centred "New conversation" FAB floats over the bottom of the sidebar,
       and the last SCROLLING row must be able to clear it.

       The clearance belongs on #sessionsList, not on the container. The
       container also holds the Archived drawer, which is a PINNED FOOTER — the
       list scrolls inside its own box and never travels past it — so padding on
       the container only reserved 64px of dead space BELOW that footer. With
       the drawer's border-top above it, the whole bottom band read as one
       oversized "Archived" section, which is the difference people noticed
       against desktop (where the equivalent rule is deliberately commented out
       in teams-sidebar.css). Padding the list instead keeps the footer compact
       and still lets the last row scroll clear of the FAB. */
    .sidebar[data-mode="teams"] #sessionsList {
        padding-bottom: 64px;
    }

    /* ── Header hide-on-scroll (mirrors the Chat tab) ──────────────────────────
       The Chat tab hides .chat-header on scroll-down and compensates by pulling
       .messages-wrapper up. The Teams conversation is a flex child of .chat-area
       (a flex column), so collapsing the header's box lets #panel-teams grow into
       the reclaimed space with no gap. Scoped to the active Teams tab so the Chat
       tab's own mechanism is untouched; teams-conversation.js toggles .scroll-hidden. */
    body.mobile-standalone.teams-tab-active .chat-header,
    body.mobile-standalone.settings-tab-active .chat-header {
        transition:
            height 0.28s ease,
            padding 0.28s ease,
            border-width 0.28s ease;
        overflow: hidden;
    }
    body.mobile-standalone.teams-tab-active .chat-header.scroll-hidden,
    body.mobile-standalone.settings-tab-active .chat-header.scroll-hidden {
        height: 0;
        min-height: 0;
        padding-top: 0;
        padding-bottom: 0;
        border-bottom-width: 0;
        /* Override the shared translateY(-100%): height-collapse leaves no gap in
           the flex column (a transform would keep the 65px box in place). */
        transform: none;
    }

    /* The generic Chat keyboard handler fixes the app header. In a Teams chat
       that removes it from the flex layout and lets it cover the session
       header (and, lower down, the pinned strip). Keep it in flow here: the
       Teams composer has its own keyboard lift, so this does not compromise
       input visibility. */
    body.mobile-standalone.keyboard-open.teams-tab-active .chat-header {
        position: relative !important;
        top: auto !important;
        right: auto !important;
        left: auto !important;
    }

    /* ── Keep the composer above the soft keyboard ─────────────────────────────
       In an installed PWA the layout viewport does NOT shrink when the keyboard
       opens, so the in-flow bottom composer sits behind it. mobile-core maintains
       --mobile-keyboard-offset (keyboard height) and toggles body.keyboard-open on
       the shared #userInput — which Teams adopts — so we lift the composer by that
       offset while the keyboard is up. This must participate in flex layout,
       rather than using a transform: a transform moves only the painted
       composer and leaves the transcript's scroll viewport behind the keyboard.
       The resulting false bottom is why a reader could not scroll down to the
       latest message while composing on iPhone.
       The same lift applies while an inline message edit has focus: the
       keyboard is up for THAT field, not the composer, so `keyboard-open` is
       not set — and without the lift the edit box and its Save button sat
       behind the keyboard with no way to scroll them out. */
    body.mobile-standalone.keyboard-open.teams-tab-active
        .teams-conversation__composer-slot,
    body.mobile-standalone.teams-tab-active
        .teams-conversation:has(.teams-msg__editor :focus)
        .teams-conversation__composer-slot {
        margin-bottom: var(--mobile-keyboard-offset, 0px);
        transition: margin-bottom 0.2s ease;
        position: relative;
        z-index: 5;
        /* Transparent, not `--tm-bg`: on a phone this strip sits over the
           personal chat background, which an opaque fill would cap. */
        background: transparent;
    }

    .teams-panel
        .teams-conversation__composer-slot
        #inputContainer
        .teams-emoji-btn,
    #inputContainer.teams-input-adopted .teams-emoji-btn {
        display: none;
    }

    /* ── Conversation view ─────────────────────────────────────────────────────
       The desktop layout centers a fixed 60rem column; on a phone that overflows
       horizontally (the whole message stream gets pushed off-screen). Go fluid
       and tighten the chrome so the header actions stay reachable. */
    .teams-panel .teams-conversation {
        width: 100%;
    }

    .teams-panel .teams-conversation__header {
        padding: 9px 15px;
        gap: 8px;
    }

    .teams-panel .teams-conversation__call-banner {
        padding-inline: 20px;
    }

    /* Five faces squeeze "Video call in progress" to one letter on a phone —
       show the compact head count instead (teams-call-banner.js renders both). */
    .teams-panel .teams-conversation__call-banner .teams-conversation__call-pill,
    .teams-panel .teams-conversation__call-banner .teams-conversation__call-pill-more {
        display: none;
    }

    .teams-panel .teams-conversation__call-banner .teams-conversation__call-count {
        display: inline-flex;
    }

    .teams-panel .teams-pinbar__summary {
        padding-inline: 20px;
    }

    .teams-panel .teams-conversation__title {
        min-width: 0;
    }

    .teams-panel .teams-conversation__name {
        max-width: 60vw;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .teams-panel .teams-conversation__header-actions {
        gap: 6px;
        flex-shrink: 0;
    }

    /* Once the Automations row is opened it takes the whole screen. As a card
       inside the ⋮ menu it was cramped, overlapped the rows around it and its
       close "×" was a 16px glyph in a corner. A full-screen sheet gives the
       observer and webhook forms room, and a real close control. The inline
       max-height that _fitToViewport() writes is overridden: it sizes a popover
       to the space under the header, which a sheet does not have. */
    .teams-panel .teams-conversation__overflow-actions.is-open > .teams-observers[data-collapsed="false"] {
        position: fixed;
        inset: 0;
        z-index: 10010;
        width: 100%;
        max-width: none;
        height: 100%;
        max-height: none !important;
        box-sizing: border-box;
        margin: 0;
        padding: calc(var(--safe-top, 0px) + 16px) 18px calc(env(safe-area-inset-bottom, 0px) + 28px);
        border: 0;
        border-radius: 0;
        box-shadow: none;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        font-size: 0.95rem;
    }

    .teams-panel .teams-conversation__overflow-actions.is-open > .teams-observers[data-collapsed="false"] .teams-observers__head {
        padding-right: 52px;
    }

    .teams-panel .teams-conversation__overflow-actions.is-open > .teams-observers[data-collapsed="false"] .teams-observers__title {
        font-size: 1.25rem;
    }

    .teams-panel .teams-conversation__overflow-actions.is-open > .teams-observers[data-collapsed="false"] .teams-observers__fold {
        top: -6px;
        right: -4px;
        width: 44px;
        height: 44px;
        border-radius: 50%;
        background: color-mix(in srgb, currentColor 8%, transparent);
        font-size: 26px;
    }
    .teams-panel .teams-conversation__scroll {
        padding: 14px 10px 96px 10px;
        /* iOS momentum scrolling is noticeably smoother when this isolated
           scroller is compositor-promoted. `contain` prevents the page itself
           from rubber-banding while the transcript is being read. */
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-y: contain;
        transform: translateZ(0);
        contain: paint;
    }

    /* Keep the adopted textarea at native iOS editing metrics. The desktop
       26px line height makes a multi-line draft look unusually loose on a
       phone and exaggerates the composer growth beside the keyboard. */
    .teams-panel .teams-conversation__composer-slot #inputContainer #userInput,
    .teams-panel .teams-conversation__composer-slot #inputContainer .mention-input-highlight {
        font-size: 16px;
        line-height: 22px;
    }

    /* Same treatment the Space feed gets on a phone: the transcript fades in at
       the top rather than being cut by the header, and out at the bottom rather
       than running into the composer. A mask, not overlays — the conversation
       may be painting a background photo (`--has-chat-background`), and two
       `--tm-bg` gradients would sit on it as grey bars.

       The floating controls (scroll-to-latest, "N new messages"), the typing
       indicator and the composer are all SIBLINGS of `__scroll`, so none of them
       is dimmed. The bottom fade is the shorter of the two: it has a composer
       under it, not open space. */
    .teams-panel .teams-conversation__scroll {
        -webkit-mask-image: linear-gradient(
            to bottom,
            transparent 0,
            #000 20px,
            #000 calc(100% - 16px),
            transparent 100%);
        mask-image: linear-gradient(
            to bottom,
            transparent 0,
            #000 20px,
            #000 calc(100% - 16px),
            transparent 100%);
    }

    .header-tab {
        padding: 7px 15px;
    }

    /* Keep the whole roster on ONE line: the names live in a truncating box that
       clips at the right edge, and the people-count pill is pinned (flex-shrink: 0)
       so it never drops to a third line. */
    .teams-panel .teams-conversation__participants {
        gap: 8px;
        flex-wrap: nowrap;
        min-width: 0;
    }
    .teams-panel .teams-conversation__pnames {
        display: flex;
        align-items: center;
        flex-wrap: nowrap;
        gap: 4px 8px;
        min-width: 0;
        overflow: hidden;
        -webkit-mask-image: linear-gradient(
            to right,
            #000 calc(100% - 18px),
            transparent
        );
        mask-image: linear-gradient(
            to right,
            #000 calc(100% - 18px),
            transparent
        );
    }
    .teams-panel .teams-people-pill {
        flex-shrink: 0;
        font-size: 10px;
    }

    /* ── Modals: use the full width with a small safe gutter ───────────────────── */
    .teams-modal-overlay {
        padding: 12px;
    }
    .teams-modal-overlay .teams-modal {
        max-width: 100%;
        max-height: 92vh;
    }
    .teams-modal-overlay .teams-modal--newchat {
        max-height: 90vh;
    }

    /* ── System notes (call ended / summary ready): give the chip the full row
          width so it wraps between phrases instead of breaking mid-word, and drop
          the flanking dotted rules that would otherwise squeeze it. ──────────── */
    .teams-conversation .teams-sysnote {
        margin: 6px 0;
    }
    .teams-conversation .teams-sysnote--video-call-ended {
        width: 100%;
        margin: 10px auto;
        gap: 0;
    }
    .teams-conversation .teams-sysnote--video-call-ended::before,
    .teams-conversation .teams-sysnote--video-call-ended::after {
        display: none;
    }
    /* A system note is chrome around the conversation, not a message in it.
       10px of padding inside a 90%-wide pill gave every one of them the mass of
       a real bubble — a run of them (a group add, a sequence of calls) then
       owned the whole screen. */
    .teams-conversation .teams-sysnote__chip {
        padding: 6px 12px;
        gap: 6px;
        font-size: 12px;
        line-height: 1.35;
        width: 98%;
        justify-content: space-between;
    }

    .message-container-bot .tooltip-container {
        display: none;
    }

    .teams-panel .teams-msg {
        gap: 5px;
    }

    .teams-panel .teams-msg-repliable {
        box-sizing: unset;
    }

    .teams-panel .teams-msg__reply-quote, 
    .teams-panel .teams-msg__reply-quote--missing {
        max-width: 270px;
    }

    .teams-panel .teams-msg__quickreact {
        font-size: 20px;
        width: 34px;
        height: 30px;
    }

    /* Incoming message toolbars must grow into the message area on a phone.
       The desktop right overhang clips quick reactions on short bubbles and
       pushes the More-actions target against the viewport on wide bubbles. */
    .teams-panel .teams-msg:not(.teams-msg--mine) .teams-msg__actions {
        left: 0;
        right: auto;
    }

    .teams-panel .teams-msg__reactmore {
        font-size: 18px;
    }

    .teams-panel .teams-msg__action {
        font-size: 14px;
        width: 30px;
    }

    .teams-panel .teams-msg__menu-item {
        font-size: 14px;
    }

    .teams-panel .teams-msg__menu-item i {
        font-size: 14px;
    }

    .teams-panel .teams-conversation__hint {
        display: none;
    }

    /* .teams-panel .teams-avatar,
    .teams-modal-overlay .teams-avatar {
        display: none;
    } */

    .space-post .space-post__announcement-open {
        width: -webkit-fill-available;
    }

    .message-container-bot .bot-message,
    .internal-message-container .bot-message {
        padding: 5px 10px;
    }

    body.mobile-standalone .chat-area .chat-header {
        box-sizing: border-box;
    }

    /* Room for the paperclip, which is laid OVER the left of the field (see the
       block below) exactly as the mic/send button is over its right. Mirrors
       that side's 54px inset. The mention mirror is grid-stacked on the
       textarea and must carry the IDENTICAL value, or coloured @names drift off
       the raw text they sit over. */
    .teams-panel .teams-conversation__composer-slot #inputContainer #userInput,
    .teams-panel
        .teams-conversation__composer-slot
        #inputContainer
        .mention-input-highlight {
        padding-left: 44px;
    }

    /* ── Attaching a file from a phone (TEAM CHATS ONLY) ──────────────────────
       `frontend/css/mobile-chat.css` hides `.file-upload-button` outright on
       every mobile surface, and for the Ask AI composer that is still right:
       its send endpoint has no attachment path, so a paperclip there leads
       nowhere. A Team conversation does have one — the same picker, staging
       tray and upload flow the desktop composer uses — and on a phone the
       paperclip is the ONLY door to it, because there is no drag-and-drop and
       nothing in the clipboard to paste.

       Ask AI and Teams share ONE textarea: Teams borrows `#inputContainer` into
       `.teams-conversation__composer-slot` while a conversation is open (see
       teams-conversation-composer.js). That slot ancestor is therefore exactly
       "the composer while Teams owns it", which is what this is scoped to —
       the same element is untouched back on the Ask AI tab.

       `display: flex !important` is REQUIRED, not stylistic: the rule being
       overridden is itself `!important`, so importance has to be matched before
       the higher specificity here can decide it.

       INSIDE THE FIELD, not beside it. On this layout the rounded white pill IS
       `#userInput` (`border-radius: 20px`, mobile-chat.css) — `.input-row` is
       transparent — and the mic/send button is already laid over its right edge
       with `position: absolute; right: 0`. A paperclip left in the flex flow
       therefore renders OUTSIDE the pill, floating on the page background
       beside it. Mirroring the mic's geometry on the left is what puts it in
       the field, and matches the desktop composer. The offsets resolve against
       `#inputContainer`, whose horizontal padding is the inset both buttons
       sit at. */
    .teams-panel .teams-conversation__composer-slot #inputContainer .file-upload-button {
        display: flex !important;
        align-items: center;
        justify-content: center;
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        z-index: 10;
        width: 42px;
        height: 42px;
        margin: 0;
        padding: 0;
        border: none;
        border-radius: 50%;
        background: transparent;
        color: var(--tm-text-2, rgba(64, 80, 98, 0.75));
        /* The composer is inside the keyboard's reach on a phone; a lingering
           grey flash on the tap target reads as a stuck button. */
        -webkit-tap-highlight-color: transparent;
    }

    .teams-panel .teams-conversation__composer-slot #inputContainer .file-upload-button i {
        font-size: 18px;
    }

    .teams-panel .teams-conversation__composer-slot #inputContainer .file-upload-button:active {
        background: var(--tm-bg-alt, rgba(64, 80, 98, 0.08));
    }

    /* ── Video call: fill the screen; wrap the control cluster so it never
          overflows a narrow viewport. The minimized thumbnail is excluded so it
          stays a small floating window (see the :not() below). ────────────────── */
    .teams-video-overlay {
        padding: 0;
    }
    .teams-video-overlay:not(.teams-video-overlay--minimized)
        .teams-video-modal {
        width: 100vw;
        height: 100vh;
        height: 100dvh;
        max-width: 100%;
        border-radius: 0;
        border: none;
    }
    .teams-video-overlay .teams-video-header {
        padding: 10px 12px;
    }

    /* Controls: a single row of primary actions (Video / Mute / Raise / Chat /
       More / Leave). The secondary actions live in the "More" tray, which floats
       above the bar when opened so the row itself never wraps. */
    .teams-video-overlay .teams-video-controls {
        gap: 6px;
        padding: 10px 8px;
        flex-wrap: nowrap;
        justify-content: center;
        position: relative;
    }
    .teams-video-overlay .teams-video-ctrl {
        flex: 1 1 0;
        min-width: 0;
        max-width: 74px;
        padding: 8px 4px;
        font-size: 12px;
    }
    .teams-video-overlay .teams-video-ctrl span {
        font-size: 11px;
    }
    .teams-video-overlay .teams-video-ctrl i {
        font-size: 15px;
    }
    .teams-video-overlay .teams-video-more-toggle {
        display: inline-flex;
    }

    /* Collapsed by default; opens as a floating popover centered above the bar. */
    .teams-video-overlay .teams-video-more-tray {
        display: none;
    }
    .teams-video-overlay .teams-video-more-tray.is-open {
        display: flex;
        gap: 8px;
        align-items: stretch;
        justify-content: center;
        flex-wrap: wrap;
        position: absolute;
        left: 50%;
        bottom: calc(100% + 8px);
        transform: translateX(-50%);
        max-width: calc(100vw - 24px);
        box-sizing: border-box;
        padding: 8px;
        border-radius: 14px;
        background: var(--tm-surface-1, #1a1d24);
        border: 1px solid #2a2f3a;
        box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
        z-index: 7;
        width: 100%;
    }

    .teams-video-overlay .teams-video-more-tray.is-open .teams-video-ctrl {
        flex: 0 0 auto;
        min-width: 40px;
        max-width: none;
    }
    .teams-video-overlay .teams-video-more-tray.is-open .teams-video-reactions {
        flex: 0 0 auto;
    }

    /* Video stage: a phone is portrait, so the desktop `minmax(360px, 1fr)` track
       overflows the width. Switch the stage to a real vertical stack so the
       active tile can consume the available height instead of staying locked to
       the desktop 16:9 grid geometry. Multiple remotes stack naturally; the
       local self-view PiP still floats above them when remotes are present. */
    .teams-video-overlay .teams-video-grid {
        display: flex;
        flex-direction: column;
        justify-content: stretch;
        align-content: stretch;
        gap: 8px;
        padding: 8px;
        overflow: hidden;
    }
    .teams-video-overlay .teams-video-grid.has-remotes {
        overflow: hidden;
    }
    .teams-video-overlay .teams-video-tile {
        min-height: 0;
        flex: 1 1 auto;
        align-self: stretch;
        aspect-ratio: auto;
    }
    .teams-video-overlay .teams-video-tile video {
        object-fit: cover;
    }
    /* A camera-off tile fills most of a portrait screen, so its avatar needs a
       similarly substantial focal point. The desktop size remains unchanged. */
    .teams-video-overlay .teams-video-avatar {
        width: clamp(132px, 32vw, 216px);
        font-size: clamp(34px, 10vw, 64px);
    }
    /* The 330px side chat won't fit beside the stage on a phone — make it a
       full-cover panel that slides over the video instead. */
    .teams-video-overlay .teams-video-chat {
        position: absolute;
        inset: 0;
        width: 100%;
        border-left: none;
        z-index: 6;
    }
    /* Keep the minimized window comfortably on-screen on small viewports. */
    .teams-video-overlay--minimized .teams-video-modal {
        width: min(74vw, 260px);
        right: 12px;
        bottom: 12px;
    }
    .teams-video-overlay--minimized .teams-video-stage {
        height: 132px;
    }
}
/* Session-only participant management. Kept inside the existing roster modal
   so Team membership controls remain visually and conceptually separate. */
.teams-people-row__remove {
    margin-left: 8px;
    border: 0;
    background: transparent;
    color: var(--text-muted, #777);
    font-size: 20px;
    cursor: pointer;
}
.teams-people-row__remove:hover {
    color: #b42318;
}
.teams-participants-modal .teams-btn--danger {
    background: #b42318;
    border-color: #b42318;
    color: #fff;
}
.teams-participants-modal .teams-btn--danger:hover {
    background: #8f1c14;
    border-color: #8f1c14;
    color: #fff;
}
.teams-add-participant {
    position: relative;
    margin: 14px 0 2px;
    padding: 16px;
    border: 1px solid var(--tm-border, #ded8cd);
    border-radius: 12px;
    background: var(--tm-surface, #fbfaf7);
    box-shadow: 0 5px 16px rgba(44, 39, 31, 0.08);
    color: var(--tm-text-1, #393630);
    font-family: inherit;
    font-size: 14px;
}
/* Replaces the history picker when a 1:1 chat is gaining a third person: the
   server forces "no history" there (`_forced_history_mode`), so the dialog
   states the outcome instead of offering a choice that cannot be honoured. */
.teams-add-participant .teams-add-participant__note {
    margin: 12px 0 2px;
    padding: 10px 12px;
    border-left: 3px solid var(--tm-accent, #b08a4a);
    border-radius: 0 8px 8px 0;
    background: var(--tm-bg-alt, #f3efe7);
    color: var(--tm-text-2, #5f594f);
    font-size: 13px;
    line-height: 1.45;
}

.teams-add-participant > label {
    display: block;
    margin: 0 0 12px;
    font-size: 14px;
    font-weight: 650;
}
.teams-add-participant__selected {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 10px;
}
.teams-add-participant__selected[hidden] {
    display: none;
}
.teams-add-participant__chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 8px;
    border-radius: 999px;
    background: var(--tm-accent-subtle, #e8f1fb);
    color: var(--tm-text-1, #393630);
    font-size: 13px;
    font-weight: 600;
}
.teams-add-participant__chip button {
    width: 16px;
    height: 16px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 16px;
    line-height: 14px;
    cursor: pointer;
}
.teams-add-participant__chip button:hover {
    background: rgba(43, 91, 129, 0.16);
}
.teams-add-participant input[data-search] {
    width: 100%;
    box-sizing: border-box;
    margin-top: 6px;
    padding: 9px 10px;
    border: 1px solid var(--tm-border, #cfc8bd);
    border-radius: 8px;
    background: var(--tm-white, #fff);
    color: var(--tm-text-1, #393630);
    font: inherit;
}
.teams-add-participant input[data-search]::placeholder {
    color: var(--tm-text-3, #777168);
}

/* Floating search suggestions: they intentionally overlay the history controls
   rather than reflowing the editor below the input. */
.teams-add-participant__results {
    display: none;
    position: absolute;
    z-index: 4;
    top: 71px;
    left: 16px;
    right: 16px;
    max-height: 280px;
    overflow: auto;
    margin: 0;
    padding: 5px;
    border: 1px solid var(--tm-border, #d8d1c6);
    border-radius: 9px;
    background: var(--tm-surface, #fbfaf7);
    box-shadow: 0 10px 24px rgba(39, 34, 27, 0.18);
}
.teams-add-participant__results:not(:empty) {
    display: block;
}
.teams-add-participant .teams-add-participant__results .teams-newchat__row {
    padding: 6px 8px;
}
.teams-add-participant .teams-add-participant__results .teams-newchat__row.is-selected {
    background: var(--tm-accent-subtle, #e8f1fb);
}
.teams-add-participant .teams-add-participant__results .teams-newchat__check {
    display: none;
}
.teams-add-participant fieldset {
    border: 0;
    padding: 0;
    margin: 0 0 14px;
}
.teams-add-participant legend {
    margin-bottom: 7px;
    font-size: 14px;
    font-weight: 650;
}
.teams-add-participant fieldset label {
    display: block;
    margin: 7px 0;
    font-size: 14px;
    font-weight: 400;
}
.teams-add-participant [data-days] {
    width: 58px;
    padding: 3px 5px;
    border: 1px solid var(--tm-border, #cfc8bd);
    border-radius: 6px;
    background: var(--tm-white, #fff);
    color: var(--tm-text-1, #393630);
    font: inherit;
}
.teams-add-participant__actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

.space-post-modal .teams-btn[data-cancel] {
    display: none;
}

.teams-modal-overlay .teams-modal__footer {
    padding: 14px 10px;
    justify-content: space-between;
}


/* Phone-only attachment source sheet. Standalone component, overrides
   nothing — position here is not load-bearing. */
/* =============================================================================
   Amby Teams — the "what are you attaching?" sheet
   -----------------------------------------------------------------------------
   The phone's "+" sheet: the three attachment sources (photo library,
   camera, files), then a video message and the Praise / Poll / Survey cards. Each source needs a differently-configured `<input
   type="file">`, which is the whole reason the sheet exists rather than letting
   iOS show its own — see frontend/chat_page/js/teams-attach-source-sheet.js.

   Its own leaf rather than more of teams-responsive.css: that file is the
   catch-all for small-screen overrides and was heading past the 800-line mark,
   while this is one self-contained component. Nothing here overrides anything
   else, so its position in the teams.css manifest does not matter.

   PHONE ONLY. `TeamsAttachSourceSheet` is never opened on a desktop layout
   (`_openAttachSource` clicks the file input directly there), so the whole
   sheet lives inside the same breakpoint the rest of the mobile composer uses.
   ============================================================================= */

@media (max-width: 768px) {
    /* ── The "what are you attaching?" sheet ──────────────────────────────────
       Three sources, three differently-configured file inputs, one choice made
       before the OS picker opens — the why is in
       frontend/chat_page/js/teams-attach-source-sheet.js.

       `position: fixed` over the whole viewport, above the composer: that is
       `z-index: 1001` and `position: fixed` itself (mobile-chat.css), so a
       sheet stacked in normal flow would open behind the thing that opened it.
       Scoped under `.teams-attach-sheet`, which is what the module mounts. */
    .teams-attach-sheet {
        position: fixed;
        inset: 0;
        z-index: 1100;
        display: flex;
        flex-direction: column;
        justify-content: flex-end;
    }

    .teams-attach-sheet__scrim {
        position: absolute;
        inset: 0;
        background: rgba(12, 16, 22, 0.42);
        opacity: 0;
        transition: opacity 0.18s ease;
    }

    .teams-attach-sheet--in .teams-attach-sheet__scrim {
        opacity: 1;
    }

    .teams-attach-sheet__panel {
        position: relative;
        display: flex;
        flex-direction: column;
        gap: 4px;
        padding: 8px 12px calc(12px + env(safe-area-inset-bottom, 0px));
        border-radius: 18px 18px 0 0;
        background: var(--tm-surface, #ffffff);
        box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.18);
        transform: translateY(100%);
        transition: transform 0.2s ease;
        /* The "+" sheet lists the three sources AND the recordings and cards;
           on a short phone in landscape that is taller than the screen. */
        max-height: calc(100% - 24px);
        overflow-y: auto;
        overscroll-behavior: contain;
    }

    .teams-attach-sheet--in .teams-attach-sheet__panel {
        transform: translateY(0);
    }

    .teams-attach-sheet__divider {
        flex: 0 0 auto;
        height: 1px;
        margin: 2px 10px;
        background: var(--tm-border, rgba(64, 80, 98, 0.16));
    }

    .teams-attach-sheet__grip {
        width: 38px;
        height: 4px;
        margin: 2px auto 8px;
        border-radius: 2px;
        background: var(--tm-border, rgba(64, 80, 98, 0.22));
    }

    .teams-attach-sheet__item,
    .teams-attach-sheet__cancel {
        display: flex;
        align-items: center;
        gap: 14px;
        width: 100%;
        padding: 12px 10px;
        border: none;
        border-radius: 12px;
        background: transparent;
        color: var(--tm-msg-text, #1f1e1d);
        font: inherit;
        text-align: left;
        -webkit-tap-highlight-color: transparent;
    }

    .teams-attach-sheet__item:active,
    .teams-attach-sheet__cancel:active {
        background: var(--tm-bg-alt, rgba(64, 80, 98, 0.08));
    }

    .teams-attach-sheet__icon {
        display: flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 auto;
        width: 38px;
        height: 38px;
        border-radius: 50%;
        background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.09));
        color: var(--tm-agent, #0f79e4);
        font-size: 16px;
    }

    .teams-attach-sheet__text {
        display: flex;
        flex-direction: column;
        min-width: 0;
    }

    .teams-attach-sheet__label {
        font-size: 15px;
        font-weight: 600;
    }

    .teams-attach-sheet__hint {
        font-size: 12px;
        color: var(--tm-text-3, rgba(64, 80, 98, 0.6));
    }

    .teams-attach-sheet__cancel {
        justify-content: center;
        margin-top: 4px;
        border-top: 1px solid var(--tm-border, rgba(64, 80, 98, 0.16));
        border-radius: 0;
        padding-top: 14px;
        color: var(--tm-text-2, rgba(64, 80, 98, 0.75));
        font-weight: 600;
    }

    .teams-attach-sheet .teams-attach-sheet__chevron {
        margin-left: auto;
        color: var(--tm-text-3, rgba(64, 80, 98, 0.6));
        font-size: 13px;
        transition: transform 0.15s ease;
    }
    .teams-attach-sheet .teams-attach-sheet__group[aria-expanded="true"] .teams-attach-sheet__chevron {
        transform: rotate(180deg);
    }
    .teams-attach-sheet .teams-attach-sheet__submenu[hidden] { display: none; }
    .teams-attach-sheet .teams-attach-sheet__item--sub { padding-left: 24px; }
    .teams-attach-sheet .teams-attach-sheet__check {
        margin-left: auto;
        color: var(--tm-agent, #0f79e4);
        visibility: hidden;
    }
    .teams-attach-sheet .teams-attach-sheet__item--sub[aria-checked="true"] .teams-attach-sheet__check {
        visibility: visible;
    }

    @media (prefers-reduced-motion: reduce) {
        .teams-attach-sheet__scrim,
        .teams-attach-sheet__panel {
            transition: none;
        }
    }
}

/* Recorded video messages / screen recordings + their recorder. Self-contained
   (every selector under .teams-clip*), so position here is not load-bearing. */
/* =============================================================================
   Amby Teams — recorded video messages and screen recordings
   -----------------------------------------------------------------------------
   Three self-contained blocks, each scoped to its own root (CLAUDE.md rule 2):

     .teams-clip            a recorded clip in a message (teams-clip-player.js)
     .teams-clip-rec        the recorder dialog (teams-clip-recorder.js)
     .teams-attach__chip-clip  the clip's preview in the pending tray

   The shapes are drawn here and on a canvas in teams-clip-shapes.js
   (`traceClipShape`, for the camera bubble baked into a screen recording) —
   keep the two in step. `.teams-clip` is a component block rather than a
   `.teams-panel` descendant on purpose: a message renders in search previews
   and the catch-up viewer too.
   ============================================================================= */

/* ── A clip in a message ─────────────────────────────────────────────────── */
.teams-clip {
    position: relative;
    display: inline-flex;
    flex-direction: column;
    max-width: 100%;
}
.teams-clip .teams-clip__frame {
    position: relative;
    width: 220px;
    height: 220px;
    overflow: hidden;
    cursor: pointer;
    background: #000;
    border-radius: 14px;
    outline-offset: 3px;
}

/* The length, inside the frame: bottom-centre on a shape (the one spot every
   shape is wide enough at), top-left on a rectangle (clear of the controls). */
.teams-clip .teams-clip__badge {
    position: absolute;
    left: 50%;
    bottom: 12%;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 8px;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
}
.teams-clip .teams-clip__badge i {
    font-size: 10px;
    opacity: 0.85;
}

/* Rectangle: the native player, at the video's own proportions. */
.teams-clip.teams-clip--rectangle .teams-clip__frame {
    width: auto;
    height: auto;
    cursor: default;
    background: transparent;
    border-radius: 10px;
}
/* A FIXED width, not `min(100%, …)`. The bubble shrink-wraps to its content,
   and a percentage width cannot be resolved while measuring that — so the
   bubble measured the video's natural size instead (the 300px max-height ×
   the recording's ratio: ~560px for a 1.86:1 window) and the 480px video then
   sat left-aligned in it, leaving an empty strip on the right of a sent clip.
   With a definite width the measurement and the drawn box agree. Height
   follows the real ratio (fitVideoToContent); `max-width` still keeps it on a
   narrow screen. */
.teams-panel .teams-clip.teams-clip--rectangle .teams-clip__video {
    display: block;
    width: 480px;
    max-width: 100%;
    height: auto;
    max-height: none;
}
.teams-panel .teams-clip.teams-clip--rectangle .teams-clip__video[data-orientation="portrait"] {
    width: auto;
    height: min(420px, 60vh);
}
.teams-clip.teams-clip--rectangle .teams-clip__badge {
    left: 10px;
    top: 10px;
    bottom: auto;
    transform: none;
    transition: opacity 0.18s ease;
}
/* Playing: the native controls own the clock. */
.teams-clip.teams-clip--rectangle.is-playing .teams-clip__badge {
    opacity: 0;
}

/* Shaped: a square crop that plays on a tap. Specificity beats the plain
   `.teams-panel .teams-att--video` box (teams-messages.css). */
.teams-panel .teams-clip .teams-clip__frame .teams-clip__video[data-clip-shaped],
.teams-clip .teams-clip__frame .teams-clip__video[data-clip-shaped] {
    display: block;
    width: 100%;
    height: 100%;
    max-height: none;
    aspect-ratio: auto;
    object-fit: cover;
    border-radius: 0;
}
.teams-clip .teams-clip__play {
    position: absolute;
    top: 50%;
    left: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 54px;
    height: 54px;
    margin: -27px 0 0 -27px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.45);
    color: #fff;
    font-size: 20px;
    pointer-events: none;
    transition: opacity 0.18s ease;
}
.teams-clip .teams-clip__play i {
    margin-left: 3px;
}
.teams-clip.is-playing .teams-clip__play {
    opacity: 0;
}

/* A message that is ONLY a clip (no text, no quote) has no bubble: the frame
   is the message, like a WhatsApp video note. Pictures and videos sent with no
   words get the same treatment (`--media-only`). Both are set by
   syncClipOnlyMessage (teams-clip-player.js) on render and edit. */
.teams-panel .teams-msg.teams-msg--clip-only .teams-msg__bubble,
.teams-panel .teams-msg.teams-msg--media-only .teams-msg__bubble {
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
}
.teams-panel .teams-msg.teams-msg--clip-only .teams-msg__attachments,
.teams-panel .teams-msg.teams-msg--media-only .teams-msg__attachments {
    margin-top: 0;
}
.teams-panel .teams-msg.teams-msg--media-only .teams-att--image img,
.teams-panel .teams-msg.teams-msg--media-only .teams-msg__inline-img img,
.teams-panel .teams-msg.teams-msg--media-only .teams-att--video {
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}
.teams-panel .teams-msg.teams-msg--clip-only .teams-clip:not(.teams-clip--rectangle) .teams-clip__frame {
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}
.teams-panel .teams-msg.teams-msg--clip-only.teams-msg--important .teams-msg__bubble,
.teams-panel .teams-msg.teams-msg--clip-only.teams-msg--urgent .teams-msg__bubble,
.teams-panel .teams-msg.teams-msg--media-only.teams-msg--important .teams-msg__bubble,
.teams-panel .teams-msg.teams-msg--media-only.teams-msg--urgent .teams-msg__bubble {
    padding-left: 8px;
}

/* ── The pending-tray preview ────────────────────────────────────────────── */
.teams-panel .teams-attach__chip-clip {
    display: block;
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    object-fit: cover;
    border-radius: 8px;
    background: #000;
}
.teams-panel .teams-attach__chip-clip--rectangle {
    width: 60px;
}

/* ── The recorder dialog ─────────────────────────────────────────────────── */
.teams-clip-rec {
    position: fixed;
    inset: 0;
    z-index: 1150;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    font-family: var(--tm-font-ui, system-ui, sans-serif);
}
.teams-clip-rec .teams-clip-rec__scrim {
    position: absolute;
    inset: 0;
    background: rgba(12, 16, 22, 0.55);
}
.teams-clip-rec .teams-clip-rec__panel {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 14px;
    width: min(620px, 100%);
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    padding: 16px;
    border-radius: 16px;
    background: var(--tm-surface, #f8f5f0);
    color: var(--tm-msg-text, #1f1e1d);
    box-shadow: 0 18px 50px rgba(0, 0, 0, 0.3);
}
.teams-clip-rec .teams-clip-rec__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.teams-clip-rec .teams-clip-rec__title {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 16px;
    font-weight: 700;
}
.teams-clip-rec .teams-clip-rec__title i {
    color: var(--tm-accent, #2d5f84);
}
.teams-clip-rec .teams-clip-rec__close {
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--tm-text-2, #6f6e6d);
    cursor: pointer;
    font-size: 16px;
}
.teams-clip-rec .teams-clip-rec__close:hover {
    background: var(--tm-bg-alt, #f0ede6);
}

/* The stage: a 16:9 box (screen, rectangle camera) or a centred square. */
.teams-clip-rec .teams-clip-rec__stage {
    position: relative;
    align-self: center;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: 12px;
    background: #111;
    overflow: hidden;
}
.teams-clip-rec .teams-clip-rec__stage:not(.teams-clip-rec__stage--rectangle) {
    width: min(340px, 72vw);
    aspect-ratio: 1;
    background: transparent;
    overflow: visible;
}
.teams-clip-rec .teams-clip-rec__media {
    position: absolute;
    inset: 0;
    overflow: hidden;
    background: #111;
}
.teams-clip-rec .teams-clip-rec__media:empty {
    background: transparent;
}
.teams-clip-rec .teams-clip-rec__stage--rectangle .teams-clip-rec__media:empty {
    background: #111;
}
.teams-clip-rec .teams-clip-rec__live,
.teams-clip-rec .teams-clip-rec__review {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    background: #000;
}
.teams-clip-rec--screen .teams-clip-rec__live,
.teams-clip-rec--screen .teams-clip-rec__review {
    object-fit: contain;
}
/* Front camera: shown like a mirror. The recording is mirrored to match in
   the frames themselves (teams-clip-compositor.js), so the review needs none. */
.teams-clip-rec .teams-clip-rec__live.is-mirrored {
    transform: scaleX(-1);
}
.teams-clip-rec .teams-clip-rec__review:not([controls]) {
    cursor: pointer;
}
.teams-clip-rec .teams-clip-rec__placeholder {
    position: relative;
    max-width: 80%;
    color: rgba(255, 255, 255, 0.82);
    font-size: 14px;
    text-align: center;
}
.teams-clip-rec .teams-clip-rec__stage:not(.teams-clip-rec__stage--rectangle) .teams-clip-rec__placeholder {
    color: var(--tm-text-2, #6f6e6d);
}
.teams-clip-rec[data-state="error"] .teams-clip-rec__placeholder {
    color: var(--tm-danger, #c0392b);
}
.teams-clip-rec .teams-clip-rec__media:not(:empty) ~ .teams-clip-rec__placeholder {
    display: none;
}
.teams-clip-rec .teams-clip-rec__bubble {
    position: absolute;
    left: 4%;
    bottom: 6%;
    width: 26%;
    aspect-ratio: 1;
    overflow: hidden;
    border-radius: 10%;
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.9);
}
.teams-clip-rec .teams-clip-rec__timer {
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.62);
    color: #fff;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    z-index: 1;
}
.teams-clip-rec .teams-clip-rec__timer::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #e53935;
    animation: teams-clip-rec-pulse 1.2s ease-in-out infinite;
}
.teams-clip-rec .teams-clip-rec__timer[hidden] {
    display: none;
}
@keyframes teams-clip-rec-pulse {
    50% { opacity: 0.25; }
}

/* Options + shapes */
.teams-clip-rec .teams-clip-rec__options {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 18px;
    justify-content: center;
    font-size: 14px;
}
.teams-clip-rec .teams-clip-rec__option {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    cursor: pointer;
}
.teams-clip-rec .teams-clip-rec__option i {
    color: var(--tm-text-3, #6f6e6d);
}
.teams-clip-rec .teams-clip-rec__shapes {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: center;
}
.teams-clip-rec .teams-clip-rec__shapes[hidden] {
    display: none;
}
.teams-clip-rec .teams-clip-rec__shape {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 10px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 999px;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}
.teams-clip-rec .teams-clip-rec__shape.is-active {
    border-color: var(--tm-accent, #2d5f84);
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.09));
    font-weight: 600;
}
.teams-clip-rec .teams-clip-rec__shape:disabled {
    opacity: 0.5;
    cursor: default;
}
.teams-clip-rec .teams-clip-rec__swatch {
    display: inline-block;
    width: 16px;
    height: 16px;
    background: var(--tm-accent, #2d5f84);
    border-radius: 3px;
}
.teams-clip-rec .teams-clip-rec__swatch--rectangle {
    width: 20px;
    height: 13px;
}
.teams-clip-rec .teams-clip-rec__swatch--rounded { border-radius: 5px; }
.teams-clip-rec .teams-clip-rec__swatch--circle { border-radius: 50%; }
.teams-clip-rec .teams-clip-rec__swatch--hexagon {
    border-radius: 0;
    clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
}
.teams-clip-rec .teams-clip-rec__swatch--heart {
    border-radius: 0;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 95C-15 50 5-5 50 25C95-5 115 50 50 95Z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 95C-15 50 5-5 50 25C95-5 115 50 50 95Z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}

/* Actions */
.teams-clip-rec .teams-clip-rec__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
}
.teams-clip-rec .teams-clip-rec__btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 40px;
    padding: 0 18px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 999px;
    background: var(--tm-white, #f6f5f3);
    color: inherit;
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}
.teams-clip-rec .teams-clip-rec__btn:hover {
    background: var(--tm-bg-alt, #f0ede6);
}
.teams-clip-rec .teams-clip-rec__btn--record i {
    color: #e53935;
}
.teams-clip-rec .teams-clip-rec__btn--stop {
    border-color: #e53935;
    background: #e53935;
    color: #fff;
}
.teams-clip-rec .teams-clip-rec__btn--stop:hover {
    background: #c62828;
}
.teams-clip-rec .teams-clip-rec__btn--primary {
    border-color: var(--tm-accent, #2d5f84);
    background: var(--tm-accent, #2d5f84);
    color: #fff;
}
.teams-clip-rec .teams-clip-rec__btn--primary:hover {
    background: var(--tm-accent-hover, #245070);
}

/* ── Shapes (shared by the player, the recorder stage and the tray chip) ──────
   Last, and one class more specific than each block's base box, so a shape
   always wins over the default corner radius. */
.teams-clip.teams-clip--rounded .teams-clip__frame,
.teams-clip-rec .teams-clip-rec__stage--rounded .teams-clip-rec__media,
.teams-clip-rec .teams-clip-rec__stage[data-bubble-shape="rounded"] .teams-clip-rec__bubble,
.teams-panel .teams-attach__chip-clip.teams-attach__chip-clip--rounded {
    border-radius: 22%;
}
.teams-clip.teams-clip--circle .teams-clip__frame,
.teams-clip-rec .teams-clip-rec__stage--circle .teams-clip-rec__media,
.teams-clip-rec .teams-clip-rec__stage[data-bubble-shape="circle"] .teams-clip-rec__bubble,
.teams-panel .teams-attach__chip-clip.teams-attach__chip-clip--circle {
    border-radius: 50%;
}
.teams-clip.teams-clip--hexagon .teams-clip__frame,
.teams-clip-rec .teams-clip-rec__stage--hexagon .teams-clip-rec__media,
.teams-clip-rec .teams-clip-rec__stage[data-bubble-shape="hexagon"] .teams-clip-rec__bubble,
.teams-panel .teams-attach__chip-clip.teams-attach__chip-clip--hexagon {
    border-radius: 0;
    clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
}
.teams-clip.teams-clip--heart .teams-clip__frame,
.teams-clip-rec .teams-clip-rec__stage--heart .teams-clip-rec__media,
.teams-clip-rec .teams-clip-rec__stage[data-bubble-shape="heart"] .teams-clip-rec__bubble,
.teams-panel .teams-attach__chip-clip.teams-attach__chip-clip--heart {
    border-radius: 0;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 95C-15 50 5-5 50 25C95-5 115 50 50 95Z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 95C-15 50 5-5 50 25C95-5 115 50 50 95Z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}

@media (max-width: 768px) {
    .teams-clip:not(.teams-clip--rectangle) .teams-clip__frame {
        width: 180px;
        height: 180px;
    }
    .teams-clip-rec {
        padding: 0;
        align-items: stretch;
    }
    .teams-clip-rec .teams-clip-rec__panel {
        width: 100%;
        max-height: none;
        border-radius: 0;
        justify-content: center;
        padding: calc(14px + env(safe-area-inset-top, 0px)) 16px calc(16px + env(safe-area-inset-bottom, 0px));
    }
}

@media (prefers-reduced-motion: reduce) {
    .teams-clip-rec .teams-clip-rec__timer::before {
        animation: none;
    }
    .teams-clip .teams-clip__play,
    .teams-clip .teams-clip__badge {
        transition: none;
    }
}

.teams-clip .teams-clip__mute {
    position: absolute;
    right: 2px;
    bottom: 2px;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 1px solid rgba(255,255,255,.6);
    color: #fff;
    background: rgba(0,0,0,.75);
    cursor: pointer;
}

/* Day pills: one per calendar day, before that day's first message
   (teams-date-pills.js). Self-contained; position in the manifest is not
   load-bearing. */
.teams-conversation__messages .teams-date-pill {
    display: flex;
    justify-content: center;
    margin: 18px 16px 10px;
    pointer-events: none;
    user-select: none;
}

.teams-conversation__messages .teams-date-pill span {
    padding: 3px 12px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary, #5f6368);
    background: color-mix(in srgb, var(--surface-color, #fff) 82%, transparent);
    border: 1px solid color-mix(in srgb, currentColor 18%, transparent);
    backdrop-filter: blur(6px);
}

/* One sender header per run of consecutive messages (teams-message-runs.js).
   `teams-msg--cont` marks a bubble that continues the run above it: its name,
   time and avatar are hidden. The avatar keeps its box (visibility, not
   display) so the bubbles stay aligned with the run's first one. Self-contained;
   position in the manifest is not significant. */

.teams-panel .teams-conversation__messages .teams-msg.teams-msg--cont > .teams-avatar {
    visibility: hidden;
}
.teams-panel .teams-conversation__messages .teams-msg.teams-msg--cont .teams-msg__meta {
    display: none;
}

/* ── Team / group image picker (teams-avatar-picker.js) ────────────────────── */
/* Used in the Create-team modal, Team settings, and the New-conversation modal.
   Scoped under the Teams containers so it cannot leak into other panels. */
.teams-panel .teams-avatar-picker__row,
.teams-modal-overlay .teams-avatar-picker__row {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-top: 6px;
}
/* The preview is a real avatar circle, larger than the 30px list variant so the
   user can actually judge the crop before committing. */
.teams-panel .teams-avatar-picker__preview,
.teams-modal-overlay .teams-avatar-picker__preview {
    width: 56px;
    height: 56px;
    font-size: 22px;
    margin-right: 0;
    margin-top: 0;
}
.teams-panel .teams-avatar-picker__actions,
.teams-modal-overlay .teams-avatar-picker__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}
/* The "Choose image" control is a <label for> the hidden file input, so it needs
   the button's affordances without being a <button>. */
.teams-panel .teams-avatar-picker__choose,
.teams-modal-overlay .teams-avatar-picker__choose {
    cursor: pointer;
    margin: 0;
}
.teams-panel .teams-avatar-picker__actions .teams-field__hint,
.teams-modal-overlay .teams-avatar-picker__actions .teams-field__hint {
    flex-basis: 100%;
    margin: 0;
}
/* The group-image slot sits between the scroll area and the footer. */
.teams-modal-overlay .teams-newchat__avatar {
    padding: 10px 16px 0;
    border-top: 1px solid var(--tm-border, #e2dcd2);
}

/* ── Conversation image in the chat header (teams-conversation.js) ─────────── */
/* Sits left of the name + participant summary. Painted for every conversation
   kind; only a group chat also gets the change control next to the rename pen. */
.teams-panel .teams-conversation__avatar {
    width: 38px;
    height: 38px;
    font-size: 15px;
    margin-right: 12px;
    flex-shrink: 0;
    margin-top: 0;
}
/* The header is a space-between flex row, so the avatar must not be separated
   from the heading block it belongs to. */
.teams-panel .teams-conversation__header {
    justify-content: flex-start;
}
.teams-panel .teams-conversation__header .teams-conversation__heading {
    flex: 1 1 auto;
}

.teams-conversation__heading .teams-people-pill {
    line-height: 1.2;
}
/* Clickable when the viewer may change it (group chats only) — opens the
   dedicated conversation-image modal. */
.teams-panel .teams-conversation__avatar--editable {
    cursor: pointer;
    transition:
        filter 120ms ease,
        box-shadow 120ms ease;
}
.teams-panel .teams-conversation__avatar--editable:hover,
.teams-panel .teams-conversation__avatar--editable:focus-visible {
    filter: brightness(0.92);
    box-shadow: 0 0 0 2px var(--tm-accent, #4a90e2);
    outline: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Personal AI Queries — the private "Ask AI" drawer
   ═══════════════════════════════════════════════════════════════════════════
   Mounted inside .teams-panel so it inherits the --tm-* tokens (and their
   body.dark-theme overrides). Scoped under .teams-panel per CLAUDE.md rule 2.
   ─────────────────────────────────────────────────────────────────────────── */

/* Header entry point ------------------------------------------------------ */
/* `hidden` MUST win over the display rule below. The markup ships the button
   hidden and the wiring reveals it, so without this the attribute is silently
   overridden and the button flashes into view on every conversation before
   wiring runs — the UA stylesheet's [hidden]{display:none} loses to any author
   rule that sets `display`. */
.teams-panel .teams-conversation__ask-ai[hidden] {
    display: none !important;
}

.teams-panel .teams-conversation__ask-ai {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    border: 1px solid var(--tm-border);
    background: #ffffff9e;
    color: var(--tm-text-2);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    transition:
        background var(--tm-t),
        color var(--tm-t),
        border-color var(--tm-t);
}
body.dark-theme .teams-panel .teams-conversation__ask-ai {
    background: var(--tm-surface);
}
.teams-panel .teams-conversation__ask-ai:hover,
.teams-panel .teams-conversation__ask-ai.is-active {
    background: var(--tm-accent);
    color: #fff;
    border-color: var(--tm-accent);
}

/* Drawer shell ------------------------------------------------------------
   Geometry deliberately MIRRORS .workflow-widget-container (the Chat tab's
   widget panel): a floating rounded card inset from the viewport edges, NOT a
   full-height edge drawer. Two reasons it must not be `top: 0`:
     1. the app's .chat-header is 65px tall with z-index 2000, so a drawer at
        top:0 has its own header hidden behind it — leaving no visible
        expand/close controls at all;
     2. matching the widget geometry is what makes this read as the same
        product rather than a bolted-on panel.                                */
.teams-panel .teams-ai-drawer {
    position: fixed;
    z-index: 1000; /* same layer as the Chat tab's widgets */
    display: flex;
    flex-direction: column;
    background: var(--tm-bg);
    border: 1px solid var(--tm-border);
    border-radius: 8px;
    box-shadow: var(--tm-shadow-md);
    font-family: var(--tm-font-ui);
    color: var(--tm-text-2);
    overflow: hidden; /* keep children inside the rounded corners */
    opacity: 0;
    transform: translateX(38px);
    transition:
        opacity 0.28s ease,
        transform 0.42s cubic-bezier(0.22, 1, 0.36, 1);
}
.teams-panel .teams-ai-drawer.is-open {
    opacity: 1;
    transform: translateX(0);
}

/* Half — side panel, chat still visible on the left (widget `state-half`). */
.teams-panel .teams-ai-drawer--half {
    top: 80px;
    right: 10px;
    bottom: 10px;
    left: auto;
    width: 460px;
    max-width: 50%;
}
/* Full — covers the conversation area (widget `state-full`). */
.teams-panel .teams-ai-drawer--full {
    top: 65px;
    left: 265px;
    right: 5px;
    bottom: 5px;
    width: auto;
    max-width: none;
}

@media (prefers-reduced-motion: reduce) {
    .teams-panel .teams-ai-drawer {
        transition: none;
    }
}

/* Header — the widget-style title bar. The control icons live here and MUST
   stay reachable: they are the only way to resize or dismiss the panel. */
.teams-panel .teams-ai-drawer__header {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 14px;
    border-bottom: 1px solid var(--tm-border);
    background: var(--tm-surface);
}
.teams-panel .teams-ai-drawer__heading {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.teams-panel .teams-ai-drawer__title {
    font-family: var(--tm-font-display);
    font-size: 15px;
    font-weight: 600;
    color: var(--tm-msg-text);
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.teams-panel .teams-ai-drawer__subtitle {
    font-size: 12px;
    color: var(--tm-text-3);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-panel .teams-ai-drawer__chrome {
    display: flex;
    gap: 4px;
    margin-left: auto;
}
/* Mirrors the widget header's .btn-icon controls. */
.teams-panel .teams-ai-drawer__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 7px;
    border: 1px solid var(--tm-border);
    background: var(--tm-bg);
    color: var(--tm-text-1);
    cursor: pointer;
    font-size: 13px;
    line-height: 1;
    transition:
        background var(--tm-t),
        color var(--tm-t),
        border-color var(--tm-t);
}
.teams-panel .teams-ai-drawer__btn:hover {
    background: var(--tm-accent);
    color: #fff;
    border-color: var(--tm-accent);
}

/* The privacy promise is part of the UI, not a tooltip: this is the whole
   reason the feature is safe to use in a shared conversation. */
.teams-panel .teams-ai-drawer__privacy {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 9px 16px;
    background: var(--tm-note-bg);
    color: var(--tm-msg-text);
    font-size: 12px;
    line-height: 1.45;
    border-bottom: 1px solid var(--tm-border);
}
/* The lock must not shrink, and the copy is ONE flex item so the sentence
   wraps as a sentence (see the note in _shellHtml). */
.teams-panel .teams-ai-drawer__privacy > i {
    flex: 0 0 auto;
    margin-top: 2px;
}
.teams-panel .teams-ai-drawer__privacy > span {
    flex: 1 1 auto;
    min-width: 0;
}
body.dark-theme .teams-panel .teams-ai-drawer__privacy {
    background: var(--tm-accent-subtle);
    color: var(--tm-text-1);
}

/* Quick actions ----------------------------------------------------------- */
.teams-panel .teams-ai-drawer__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--tm-border);
}
/* Second-tier actions stay collapsed until "More". Hidden with display:none so
   they are out of the tab order too — a keyboard user must not tab into chips
   nobody can see. */
.teams-panel .teams-ai-drawer__actions .teams-ai-chip--more {
    display: none;
}
.teams-panel .teams-ai-drawer__actions.is-expanded .teams-ai-chip--more {
    display: inline-flex;
}
.teams-panel .teams-ai-chip--toggle {
    border-style: dashed;
    color: var(--tm-text-3, var(--tm-text-2));
}
.teams-panel .teams-ai-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 11px;
    border-radius: 999px;
    border: 1px solid var(--tm-border);
    background: var(--tm-surface);
    color: var(--tm-text-2);
    font-family: var(--tm-font-ui);
    font-size: 12px;
    cursor: pointer;
    transition:
        background var(--tm-t),
        color var(--tm-t),
        border-color var(--tm-t);
}
.teams-panel .teams-ai-chip:hover:not(:disabled) {
    background: var(--tm-accent);
    color: #fff;
    border-color: var(--tm-accent);
}
.teams-panel .teams-ai-chip:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
.teams-panel .teams-ai-chip i {
    font-size: 11px;
}

/* Conversation ------------------------------------------------------------ */
.teams-panel .teams-ai-drawer__scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
}

.teams-panel .teams-ai-drawer__messages {
    padding: 14px 16px 50px;
}

.teams-panel .teams-ai-drawer__messages .message bot-message {
    padding: 0;
    max-width: 100%;
}

.teams-panel .teams-ai-drawer__messages .message-container-bot .bot-message, 
.teams-panel .teams-ai-drawer__messages .internal-message-container .bot-message {
    padding: 0;
    max-width: 100%;
}

.teams-panel .teams-ai-drawer__messages .message-container-bot .tooltip-container {
    display: none;
}

.teams-panel .teams-ai-drawer__empty {
    text-align: center;
    padding: 36px 18px;
    color: var(--tm-text-3);
    font-size: 13px;
}
.teams-panel .teams-ai-drawer__empty i {
    font-size: 26px;
    color: var(--tm-accent);
    opacity: 0.55;
    margin-bottom: 12px;
    display: block;
}
.teams-panel .teams-ai-drawer__empty p {
    margin: 0 0 6px;
}
.teams-panel .teams-ai-drawer__empty-hint {
    font-size: 12px;
    opacity: 0.85;
}

.teams-panel .teams-ai-drawer__notice {
    margin: 10px 0;
    padding: 9px 12px;
    border-radius: var(--tm-r);
    background: var(--tm-danger-bg);
    color: var(--tm-danger);
    font-size: 12.5px;
}

/* The user's own question. Right-aligned like their own message elsewhere. */
.teams-panel .teams-ai-q {
    max-width: 88%;
    margin: 0 0 12px auto;
    padding: 8px 12px;
    border-radius: var(--tm-r-lg) var(--tm-r-lg) 4px var(--tm-r-lg);
    background: var(--tm-accent);
    color: #fff;
    font-size: 13px;
    line-height: 1.45;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* Share control on an answer ---------------------------------------------- */
.teams-panel .teams-ai-answer__actions {
    display: flex;
    justify-content: flex-end;
    margin: 6px 0 14px;
}
.teams-panel .teams-ai-answer__share {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 11px;
    border-radius: 999px;
    border: 1px solid var(--tm-border);
    background: var(--tm-surface);
    color: var(--tm-text-2);
    font-family: var(--tm-font-ui);
    font-size: 12px;
    cursor: pointer;
    transition:
        background var(--tm-t),
        color var(--tm-t),
        border-color var(--tm-t);
}
.teams-panel .teams-ai-answer__share:hover:not(:disabled) {
    background: var(--tm-accent);
    color: #fff;
    border-color: var(--tm-accent);
}
.teams-panel .teams-ai-answer__share.is-shared,
.teams-panel .teams-ai-answer__share:disabled {
    opacity: 0.7;
    cursor: default;
}

/* Composer ---------------------------------------------------------------- */
.teams-panel .teams-ai-drawer__composer {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    padding: 12px 16px;
    border-top: 1px solid var(--tm-border);
    background: var(--tm-surface);
}
.teams-panel .teams-ai-drawer__composer textarea {
    flex: 1 1 auto;
    resize: none;
    max-height: 160px;
    padding: 9px 12px;
    border-radius: var(--tm-r-lg);
    border: 1px solid var(--tm-border);
    background: var(--tm-bg);
    color: var(--tm-msg-text);
    font-family: var(--tm-font-ui);
    font-size: 13px;
    line-height: 1.45;
}
.teams-panel .teams-ai-drawer__composer textarea:focus {
    outline: none;
    border-color: var(--tm-accent);
}
.teams-panel .teams-ai-drawer__composer textarea:disabled {
    opacity: 0.6;
}
.teams-panel .teams-ai-drawer__send {
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: none;
    background: var(--tm-accent);
    color: #fff;
    cursor: pointer;
    font-size: 13px;
    transition: background var(--tm-t);
}
.teams-panel .teams-ai-drawer__send:hover:not(:disabled) {
    background: var(--tm-accent-hover);
}
.teams-panel .teams-ai-drawer__send:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Mobile / tablet: a full-height sheet, not a side panel. Teams is used on
   phones, so a 440px drawer over a 375px viewport is not an edge case. */
@media (max-width: 768px) {
    /* A true full-screen sheet on phones. The half/full geometry is a desktop
       affordance; anchoring below the app header left the panel visibly
       "off" — a strip of the conversation showing above it and the composer
       fighting the soft keyboard for the bottom edge. Covering the screen is
       safe here because the header's Close button is always rendered (and the
       expand toggle below is what gets hidden, never Close). */
    .teams-panel .teams-ai-drawer--half,
    .teams-panel .teams-ai-drawer--full {
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        width: auto;
        max-width: none;
        border: none;
        border-radius: 0;
        /* Above .chat-header and the mobile tab bar, which this now covers. */
        z-index: 2500;
        /* Keep the title bar clear of the notch and the Home indicator. */
        padding-top: env(safe-area-inset-top);
        padding-bottom: env(safe-area-inset-bottom);
    }
    /* Expand/collapse is meaningless once the sheet already fills the screen —
       but Close must never be hidden, or the panel becomes inescapable. */
    .teams-panel .teams-ai-drawer__btn[data-ai-expand] {
        display: none;
    }

    /* ── Sidebar: the Teams rail is a desktop-only shape ──────────────────────
       On phones the sidebar is an off-canvas drawer owned by mobile-chat.css.
       The Teams width rule above (`[data-mode="teams"]:not(.collapsed)`) is
       more specific than `body.mobile-standalone .sidebar { width: 0 }`, so it
       used to hold the rail open at its persisted desktop width — picking a
       team or a chat removed `.expanded` but the rail stayed on screen. Reset
       it here (same specificity, later in the file) and let the mobile drawer
       rules decide the width. */
    .sidebar[data-mode="teams"]:not(.collapsed) {
        width: 0;
        flex: 0 0 auto;
    }
    /* Drag-to-resize needs a pointer and a rail to resize — neither applies on
       a phone, where its 12px hit strip only sat over the conversation. */
    .sidebar[data-mode="teams"] .teams-sidebar-width-resizer {
        display: none;
    }
}

/* ── A shared Ask-AI answer, rendered in the team conversation ───────────── */
.teams-conversation .teams-shared-ai {
    margin: 12px 0;
    border: 1px solid var(--tm-agent-border);
    border-radius: var(--tm-r-lg);
    background: var(--tm-surface);
    overflow: hidden;
}
.teams-conversation .teams-shared-ai__header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 13px;
    background: var(--tm-accent-subtle);
    border-bottom: 1px solid var(--tm-border);
    font-size: 12.5px;
}
.teams-conversation .teams-shared-ai__header i {
    color: var(--tm-accent);
}
.teams-conversation .teams-shared-ai__title {
    font-weight: 600;
    color: var(--tm-msg-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Never let a shared answer read as something a colleague typed. */
.teams-conversation .teams-shared-ai__badge {
    flex: 0 0 auto;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--tm-agent);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.04em;
}
.teams-conversation .teams-shared-ai__time {
    margin-left: auto;
    color: var(--tm-text-3);
    font-size: 11px;
    white-space: nowrap;
}
.teams-conversation .teams-shared-ai__body {
    padding: 12px 13px;
    color: var(--tm-msg-text);
    font-size: 13.5px;
    line-height: 1.55;
    overflow-wrap: anywhere;
}

.teams-conversation .teams-shared-ai__body ul {
    padding-left: 15px;
}

.teams-conversation .teams-shared-ai__body table {
    display: block;
    overflow-x: auto;
}
.teams-conversation .teams-shared-ai__footer {
    padding: 7px 13px 9px;
    border-top: 1px solid var(--tm-border);
    color: var(--tm-text-3);
    font-size: 11.5px;
}

/* ============================================================================
   TEAM VISIBILITY FIELDS (teams-visibility-fields.js)
   Private/public toggle, discovery role gate, member anonymization. Mounted in
   both the Create-team modal (.teams-modal-overlay) and the Team settings page
   (.teams-panel), so every rule is scoped to both hosts — never bare.
   ============================================================================ */
.teams-panel .teams-visibility,
.teams-modal-overlay .teams-visibility {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
/* Label on the left, switch hard right — the same shape as a Settings →
   Notifications row, so the two toggle surfaces read as one control type. */
.teams-panel .teams-visibility__row,
.teams-modal-overlay .teams-visibility__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding-bottom: 10px;
}
.teams-panel .teams-visibility__row--stack,
.teams-modal-overlay .teams-visibility__row--stack {
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
}
.teams-panel .teams-visibility__label-row,
.teams-modal-overlay .teams-visibility__label-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
/* The shared .settings-switch is sized for the Settings page; a slightly
   smaller one sits better in a modal without becoming a different control. */
.teams-panel .teams-visibility .settings-switch,
.teams-modal-overlay .teams-visibility .settings-switch,
.teams-desk .teams-visibility__row .settings-switch,
.teams-desk .teams-desk__schedule .settings-switch {
    width: 44px;
    height: 25px;
}
/* The shared switch paints its track from --at-*, which amby-tasks.css defines
   on :root. Restate it from the Teams palette so the control cannot come out
   invisible if that sheet is ever reordered or dropped from a surface. */
.teams-panel .teams-visibility .settings-switch__slider,
.teams-modal-overlay .teams-visibility .settings-switch__slider {
    background: var(--at-border-strong, var(--tm-border-strong, #b0ab9f));
}
.teams-panel
    .teams-visibility
    .settings-switch
    input:checked
    + .settings-switch__slider,
.teams-modal-overlay
    .teams-visibility
    .settings-switch
    input:checked
    + .settings-switch__slider {
    background: var(--at-accent, var(--tm-accent));
}
.teams-panel .teams-visibility .settings-switch__slider::before,
.teams-modal-overlay .teams-visibility .settings-switch__slider::before,
.teams-desk .teams-visibility__row .settings-switch__slider::before, 
.teams-desk .teams-desk__schedule .settings-switch__slider::before {
    width: 19px;
    height: 19px;
    left: 3px;
    top: 3px;
}
.teams-panel
    .teams-visibility
    .settings-switch
    input:checked
    + .settings-switch__slider::before,
.teams-modal-overlay
    .teams-visibility
    .settings-switch
    input:checked
    + .settings-switch__slider::before,
.teams-desk
    .teams-visibility__row
    input:checked
    + .settings-switch__slider::before,
.teams-desk
    .teams-desk__schedule 
    input:checked
    + .settings-switch__slider::before {
    transform: translateX(19px);
}
.teams-panel
    .teams-visibility
    .settings-switch
    input[disabled]
    + .settings-switch__slider,
.teams-modal-overlay
    .teams-visibility
    .settings-switch
    input[disabled]
    + .settings-switch__slider {
    cursor: not-allowed;
    opacity: 0.55;
}
.teams-panel .teams-visibility__toggle-label,
.teams-modal-overlay .teams-visibility__toggle-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--tm-text-1);
}

/* The "?" affordance. Native `title` carries the text, so the tooltip works
   with the positioned bubble from teams-help-tip.js and stays readable to
   screen readers via aria-label. */
.teams-panel .teams-visibility__help,
.teams-modal-overlay .teams-visibility__help {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--tm-text-3);
    font-size: 13px;
    cursor: help;
}
.teams-panel .teams-visibility__help:hover,
.teams-modal-overlay .teams-visibility__help:hover {
    color: var(--tm-agent);
}

/* Public-only controls. Hidden wholesale while the team is private — they stay
   in the DOM so a re-opened toggle still shows the configured role gate. */
.teams-panel .teams-visibility__public,
.teams-modal-overlay .teams-visibility__public {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 12px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    box-shadow: var(--tm-shadow-md);
}
.teams-panel .teams-visibility__public[hidden],
.teams-modal-overlay .teams-visibility__public[hidden] {
    display: none;
}

.teams-panel .teams-visibility__warning,
.teams-modal-overlay .teams-visibility__warning {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 10px 12px;
    border-radius: var(--tm-r);
    background: rgba(234, 179, 8, 0.12);
    border: 1px solid rgba(234, 179, 8, 0.35);
    color: var(--tm-text-2);
    font-size: 12.5px;
    line-height: 1.5;
}
.teams-panel .teams-visibility__warning i,
.teams-modal-overlay .teams-visibility__warning i {
    margin-top: 2px;
    color: #d97706;
}

/* ============================================================================
   NEW-CONVERSATION PICKER — team chips + external teams
   (teams-new-chat-modal.js). Teams are now SELECTED into chips alongside
   people rather than starting a chat on click.
   ============================================================================ */
/* A public team the user can message but does not belong to. Amber, distinct
   from the accent used for their own teams — pulling in people from outside
   your team should not look identical to messaging your own. */
.teams-modal-overlay .teams-badge--external {
    background: rgba(180, 120, 40, 0.16);
    color: #9a6a1a;
    cursor: help;
}
/* A team running an active Support Desk — shown before Team/External. */
.teams-modal-overlay .teams-badge--desk {
    background: rgba(46, 125, 50, 0.14);
    color: #2e7d32;
    cursor: help;
    margin-right: 6px;
    white-space: nowrap;
}
.teams-modal-overlay .teams-badge--desk i {
    font-size: 10px;
}
.teams-modal-overlay .teams-chip--team {
    background: var(--tm-agent-bg);
    color: var(--tm-agent);
}
.teams-modal-overlay .teams-chip--team button {
    color: var(--tm-agent);
}
.teams-modal-overlay .teams-chip--team button:hover {
    background: var(--tm-agent);
    color: #fff;
}
.teams-modal-overlay .teams-chip--team i {
    font-size: 10px;
}
/* Selected team rows read the same as selected people rows. */
.teams-modal-overlay .teams-newchat__row--team.teams-newchat__row--selected {
    background: var(--tm-accent-subtle);
}

/* ── Roles multi-select (shared ChipSelect) ───────────────────────────────────
   The component ships unstyled; Settings → Projects styles it under its own
   [data-settings-view="projects"] scope, which does not reach the Teams panel
   or a modal. Same visual contract, re-scoped — so the two role pickers in the
   product look identical (CLAUDE.md rule 2: never style .chip-select bare). */
.teams-panel .teams-visibility .chip-select,
.teams-modal-overlay .teams-visibility .chip-select {
    position: relative;
}

.teams-panel .teams-visibility .chip-select__input-area,
.teams-modal-overlay .teams-visibility .chip-select__input-area {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 5px;
    padding: 5px 8px;
    min-height: 34px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-input-bg, var(--tm-real-white, #fff));
    cursor: text;
    transition:
        border-color 0.15s,
        box-shadow 0.15s;
}
.teams-panel .teams-visibility .chip-select--open .chip-select__input-area,
.teams-modal-overlay
    .teams-visibility
    .chip-select--open
    .chip-select__input-area {
    border-color: var(--tm-accent);
    box-shadow: 0 0 0 3px var(--tm-accent-subtle);
}
.teams-panel .teams-visibility .chip-select__search,
.teams-modal-overlay .teams-visibility .chip-select__search {
    flex: 1;
    min-width: 70px;
    padding: 2px 0;
    border: none;
    outline: none;
    background: transparent;
    color: var(--tm-text-1);
    font-family: inherit;
    font-size: 13px;
    cursor: text;
}
.teams-panel .teams-visibility .chip-select__chip,
.teams-modal-overlay .teams-visibility .chip-select__chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
}
.teams-panel .teams-visibility .chip-select__chip-remove,
.teams-modal-overlay .teams-visibility .chip-select__chip-remove {
    padding: 0 1px;
    border: none;
    background: transparent;
    color: var(--tm-accent);
    font-size: 13px;
    line-height: 1;
    opacity: 0.7;
    cursor: pointer;
}
.teams-panel .teams-visibility .chip-select__chip-remove:hover,
.teams-modal-overlay .teams-visibility .chip-select__chip-remove:hover {
    opacity: 1;
}

.teams-panel .teams-visibility .chip-select__dropdown,
.teams-modal-overlay .teams-visibility .chip-select__dropdown {
    position: absolute;
    top: calc(100% + 2px);
    left: 0;
    right: 0;
    max-height: 14rem;
    overflow-y: auto;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-surface, var(--tm-real-white, #fff));
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
    /* Above the modal's own stacking context, or the list opens behind it. */
    z-index: 9999;
}
.teams-panel .teams-visibility .chip-select__option,
.teams-modal-overlay .teams-visibility .chip-select__option {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 6px 10px;
    color: var(--tm-text-1);
    font-size: 13px;
    cursor: pointer;
    transition: background 0.08s;
}
.teams-panel .teams-visibility .chip-select__option:hover,
.teams-modal-overlay .teams-visibility .chip-select__option:hover {
    background: var(--tm-accent-subtle);
}
.teams-panel .teams-visibility .chip-select__option--selected,
.teams-modal-overlay .teams-visibility .chip-select__option--selected {
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}
.teams-panel .teams-visibility .chip-select__option input[type="checkbox"],
.teams-modal-overlay
    .teams-visibility
    .chip-select__option
    input[type="checkbox"] {
    flex-shrink: 0;
    accent-color: var(--tm-accent);
}
.teams-panel .teams-visibility .chip-select__hint,
.teams-modal-overlay .teams-visibility .chip-select__hint {
    padding: 8px 11px;
    color: var(--tm-text-3);
    font-size: 12px;
    font-style: italic;
}

/* ── Team settings: pinned save bar ──────────────────────────────────────────
   A sibling of .teams-config__scroll rather than a child, so it is genuinely
   pinned (the column already gives the scroll area flex:1) and never overlaps
   the content it is saving. */
.teams-panel .teams-config__savebar {
    flex-shrink: 0;
    display: flex;
    justify-content: center;
    padding: 14px 24px;
    border-top: 1px solid var(--tm-border);
    background: var(--tm-surface);
    box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
}
/* Aligns with the cards above it. .teams-config__scroll is a 720px border-box
   with 24px padding, so its CONTENT — the cards — is 672px wide; matching 720
   here would overhang them by exactly one padding. */
.teams-panel .teams-config__savebar-inner {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    width: 100%;
    max-width: 820px;
}

/* ── Roles dropdown: two columns ─────────────────────────────────────────────
   The list is long and the panel is wide; one column meant scrolling past
   most of the roles to find one. */
/* The grid goes on .chip-select__options, the wrapper the component actually
   puts the rows in — the dropdown itself holds a single child, so styling it
   as a grid laid that one wrapper out and changed nothing. */
.teams-panel .teams-visibility .chip-select__options,
.teams-modal-overlay .teams-visibility .chip-select__options {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-content: start;
}
/* The "no matches" hint is not an option — it spans the grid. */
.teams-panel .teams-visibility .chip-select__hint,
.teams-modal-overlay .teams-visibility .chip-select__hint {
    grid-column: 1 / -1;
}
/* Long role names must not force the dropdown wider than its input. */
.teams-panel .teams-visibility .chip-select__option,
.teams-modal-overlay .teams-visibility .chip-select__option {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* A narrow modal has no room for two columns. */
@media (max-width: 620px) {
    .teams-panel .teams-visibility .chip-select__options,
    .teams-modal-overlay .teams-visibility .chip-select__options {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ── Instant help tooltips ───────────────────────────────────────────────────
   Rendered from data-tip by teams-help-tip.js into ONE bubble appended to
   <body>, positioned and clamped to the viewport on every show — so it can
   never run off an edge or be clipped by a modal or scrolling card. Literal
   colours, not tokens: the bubble has no .teams-panel ancestor to inherit
   them from. No transition: it appears the moment the pointer lands. */
.teams-help-tip {
    position: fixed;
    z-index: 100000;
    width: max-content;
    padding: 8px 10px;
    border-radius: 6px;
    background: #2f2e2c;
    color: #fff;
    font: 400 12px/1.45 system-ui, -apple-system, "Segoe UI", sans-serif;
    text-align: left;
    white-space: normal;
    overflow-wrap: anywhere;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.22);
    pointer-events: none;
}
.teams-help-tip[hidden] { display: none; }
.teams-help-tip::before {
    content: "";
    position: absolute;
    left: var(--tip-arrow-x, 50%);
    transform: translateX(-50%);
    border: 5px solid transparent;
}
.teams-help-tip[data-side="below"]::before { bottom: 100%; border-bottom-color: #2f2e2c; }
.teams-help-tip[data-side="above"]::before { top: 100%; border-top-color: #2f2e2c; }
body.dark-theme .teams-help-tip { outline: 1px solid rgba(255, 255, 255, 0.14); }

/* =============================================================================
   Amby Teams — unified search overlay (posts + chat messages)
   -----------------------------------------------------------------------------
   Scoped under `.teams-search` (CLAUDE.md rule 2). It is a SIBLING inside
   `.teams-panel--real`, not a mount: opening and closing search must never tear
   down the feed or a conversation beneath it, because that host also holds the
   page's only chat composer while a conversation is open.

   Colours come from the Teams `--tm-*` tokens, which are already redefined
   under `body.dark-theme .teams-panel` — the overlay lives inside that panel,
   so dark mode follows with no rules of its own.
   ============================================================================= */

.teams-panel .teams-search {
    position: absolute;
    inset: 0;
    z-index: 40;
    display: flex;
    flex-direction: column;
    min-height: 0;
    /* Opaque: this covers a live feed. A translucent panel over scrolling post
       cards makes the results themselves hard to read. */
    background: var(--tm-bg, #faf8f4);
}

/* The overlay is absolutely positioned, so its host has to establish the
   containing block. `.teams-panel--real` is a plain flex column otherwise. */
.teams-panel--real { position: relative; }

/* ── The bar ─────────────────────────────────────────────────────────────── */

.teams-panel .teams-search__bar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 0 0 auto;
    padding: 14px 18px;
    border-bottom: 1px solid var(--tm-border, #d8d3c8);
}

.teams-panel .teams-search__icon {
    flex: 0 0 auto;
    color: var(--tm-text-3, #8a8987);
    font-size: 14px;
}

.teams-panel .teams-search__input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 9px 12px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: var(--tm-r, 8px);
    background: var(--tm-surface, #fff);
    color: var(--tm-text-1, #1f1e1d);
    font-family: var(--tm-font-ui, system-ui, sans-serif);
    font-size: 14px;
    outline: none;
}
.teams-panel .teams-search__input:focus {
    border-color: var(--tm-accent, #2d5f84);
    box-shadow: 0 0 0 3px var(--tm-accent-subtle, rgba(45, 95, 132, 0.15));
}

.teams-panel .teams-search__close {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border: none;
    border-radius: var(--tm-r, 8px);
    background: transparent;
    color: var(--tm-text-2, #6f6e6d);
    cursor: pointer;
}
.teams-panel .teams-search__close:hover { background: var(--tm-bg-alt, #f0ede6); }

/* ── Scope chips ─────────────────────────────────────────────────────────── */

.teams-panel .teams-search__scopes {
    display: flex;
    gap: 8px;
    flex: 0 0 auto;
    /* A fourth chip ("This chat") appears whenever a conversation is open, and
       four of them do not fit a phone on one line. Wrapping keeps every scope
       reachable instead of pushing one off the edge. */
    flex-wrap: wrap;
    padding: 10px 18px;
    border-bottom: 1px solid var(--tm-border, #d8d3c8);
}

.teams-panel .teams-search__scope {
    padding: 5px 12px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 999px;
    background: transparent;
    color: var(--tm-text-2, #6f6e6d);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}
.teams-panel .teams-search__scope:hover { background: var(--tm-bg-alt, #f0ede6); }
.teams-panel .teams-search__scope.is-active {
    border-color: var(--tm-accent, #2d5f84);
    background: var(--tm-accent, #2d5f84);
    color: #fff;
}

/* ── Results ─────────────────────────────────────────────────────────────── */

.teams-panel .teams-search__results {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 12px 18px 24px;
}

.teams-panel .teams-search__hint {
    margin: 18px 0;
    color: var(--tm-text-3, #8a8987);
    font-size: 13px;
    line-height: 1.5;
}

/* Paging: results are newest-first and older history is one click further. */
.teams-panel .teams-search__pager {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 4px 0 8px;
}
.teams-panel .teams-search__pager .teams-search__hint { margin: 6px 0 10px; }
.teams-panel .teams-search__more {
    padding: 7px 16px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 999px;
    background: transparent;
    color: var(--tm-accent, #2d5f84);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}
.teams-panel .teams-search__more:hover:not(:disabled) { background: var(--tm-bg-alt, #f0ede6); }
.teams-panel .teams-search__more:disabled { opacity: 0.6; cursor: default; }

.teams-panel .teams-search__result {
    display: flex;
    flex-direction: column;
    gap: 4px;
    width: 100%;
    margin-bottom: 8px;
    padding: 12px 14px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: var(--tm-r-lg, 12px);
    background: var(--tm-surface, #fff);
    text-align: left;
    cursor: pointer;
}
.teams-panel .teams-search__result:hover {
    border-color: var(--tm-accent, #2d5f84);
    background: var(--tm-bg-alt, #f0ede6);
}

/* WHERE the match was found is the first line of every card, before the text
   itself: with two sources in one list, "which of my surfaces is this?" is the
   question a reader asks before they read the snippet. */
.teams-panel .teams-search__where {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--tm-text-3, #8a8987);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
.teams-panel .teams-search__result--post .teams-search__where { color: var(--tm-accent, #2d5f84); }

.teams-panel .teams-search__title {
    font-size: 14px;
    font-weight: 600;
    color: var(--tm-text-1, #1f1e1d);
}

.teams-panel .teams-search__snippet {
    font-size: 13px;
    line-height: 1.5;
    color: var(--tm-text-1, #1f1e1d);
    overflow-wrap: anywhere;
}
.teams-panel .teams-search__snippet mark {
    padding: 3px 5px;
    border-radius: 3px;
    background: rgb(242 227 0 / 51%);
    color: inherit;
    font-weight: 600;
}

.teams-panel .teams-search__meta {
    display: flex;
    gap: 10px;
    color: var(--tm-text-3, #8a8987);
    font-size: 11px;
}

@media (max-width: 640px) {
    .teams-panel .teams-search__bar,
    .teams-panel .teams-search__scopes,
    .teams-panel .teams-search__results { padding-left: 12px; padding-right: 12px; }
}

/* =============================================================================
   Amby Teams — search result preview pane
   -----------------------------------------------------------------------------
   Scoped under `.teams-search` (CLAUDE.md rule 2). The pane sits BESIDE the
   result list inside `.teams-search__main`; selecting a result must never
   remove or reorder the list. On a narrow viewport there is no room for two
   columns, so the pane covers the list instead — the list is still mounted
   underneath and "Back to results" reveals it exactly as it was.
   ============================================================================= */

.teams-panel .teams-search .teams-search__main {
    flex: 1 1 auto;
    display: flex;
    min-height: 0;
    position: relative;
}

.teams-panel .teams-search .teams-search__main > .teams-search__results {
    flex: 1 1 auto;
    min-width: 0;
}

.teams-panel .teams-search.has-preview .teams-search__main > .teams-search__results {
    flex: 0 0 min(440px, 42%);
}

.teams-panel .teams-search .teams-search__result.is-selected {
    border-color: var(--tm-accent, #2d5f84);
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.1));
}

/* ── The pane ────────────────────────────────────────────────────────────── */

/* The post card is styled from `--sp-*` tokens that spaces-foundation.css only
   defines on Spaces' own roots (and that file's selectors must stay `.space*`).
   Same aliases, restated here for the card this pane embeds. */
.teams-panel .teams-search .teams-search-preview {
    --sp-gap: 16px;
    --sp-radius: var(--tm-r-lg, 12px);
    --sp-card-bg: var(--tm-surface, #f8f5f0);
    --sp-card-border: var(--tm-border, #d8d3c8);
    --sp-text: var(--tm-msg-text, #1f1e1d);
    --sp-text-muted: var(--tm-text-1, #6f6e6d);
    --sp-accent: var(--tm-accent, #2d5f84);
    --sp-accent-hover: var(--tm-accent-hover, #245070);
    --sp-hover: var(--tm-bg-alt, #f0ede6);
    --sp-danger: var(--tm-danger, #c0392b);
    --sp-pin: #f0a500;
    color: var(--sp-text);
}

.teams-panel .teams-search .teams-search-preview {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    background: var(--tm-bg, #faf8f4);
}
.teams-panel .teams-search .teams-search-preview[hidden] { display: none; }

/* A raised card of its own, so the preview reads as a separate surface from the
   result list beside it rather than as more of the same page. */
.teams-panel .teams-search .teams-search-preview {
    margin: 12px 16px 16px 0;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: var(--tm-r-lg, 14px);
    background: var(--tm-bg-alt, #f0ede6);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.14), 0 1px 3px rgba(0, 0, 0, 0.08);
    overflow: hidden;
}
.teams-panel .teams-search .teams-search-preview__head {
    background: var(--tm-surface, #fff);
}
body.dark-theme .teams-panel .teams-search .teams-search-preview {
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.5), 0 1px 3px rgba(0, 0, 0, 0.4);
}

.teams-panel .teams-search .teams-search-preview__head {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--tm-border, #d8d3c8);
}

.teams-panel .teams-search .teams-search-preview__where {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--tm-text-3, #8a8987);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.teams-panel .teams-search .teams-search-preview__open {
    flex: 0 0 auto;
    padding: 6px 14px;
    border: 0;
    border-radius: var(--tm-r, 8px);
    background: var(--tm-accent, #2d5f84);
    color: #fff;
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
}
.teams-panel .teams-search .teams-search-preview__open:hover {
    background: var(--tm-accent-hover, #245070);
}

.teams-panel .teams-search .teams-search-preview__close,
.teams-panel .teams-search .teams-search-preview__back {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: var(--tm-r, 8px);
    background: transparent;
    color: var(--tm-text-2, #6f6e6d);
    cursor: pointer;
}
.teams-panel .teams-search .teams-search-preview__close:hover,
.teams-panel .teams-search .teams-search-preview__back:hover {
    background: var(--tm-bg-alt, #f0ede6);
}
/* The back arrow is the narrow-viewport way out; the X serves the wide layout. */
.teams-panel .teams-search .teams-search-preview__back { display: none; }

.teams-panel .teams-search .teams-search-preview__body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 16px 18px 28px;
}

.teams-panel .teams-search .teams-search-preview__status,
.teams-panel .teams-search .teams-search-preview__more {
    margin: 14px 0;
    color: var(--tm-text-3, #8a8987);
    font-size: 12.5px;
    text-align: center;
}

/* ── A conversation window ───────────────────────────────────────────────── */

/* The transcript is the conversation's own markup and styles (see
   teams-search-preview-transcript.js); this only fits it into the pane. The pane
   body stops scrolling and the transcript's own scroller takes over, exactly as
   in the live view, and the live view's 60rem reading column and 100px of
   composer clearance do not apply here. */
.teams-panel .teams-search .teams-search-preview__body.is-chat {
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
}
.teams-panel .teams-search .teams-search-preview .teams-conversation--preview {
    flex: 1 1 auto;
}
.teams-panel .teams-search .teams-search-preview .teams-conversation__scroll {
    padding: 14px 16px 24px;
}
.teams-panel .teams-search .teams-search-preview .teams-conversation__scroll-content {
    max-width: none;
}
/* The message the result pointed at, kept marked (the live view only flashes it). */
.teams-panel .teams-search .teams-search-preview .teams-msg.is-anchor .teams-msg__bubble {
    outline: 2px solid var(--tm-accent, #2d5f84);
    outline-offset: 1px;
}

/* Same marker as the result snippets, so a hit looks the same in both. */
.teams-panel .teams-search .teams-search-preview__hit {
    padding: 2px 3px;
    border-radius: 3px;
    background: rgb(242 227 0 / 51%);
    color: inherit;
}

/* ── Not enough room for two columns ─────────────────────────────────────── */

@media (max-width: 900px) {
    .teams-panel .teams-search .teams-search-preview {
        position: absolute;
        inset: 0;
        z-index: 1;
        margin: 0;
        border: 0;
        border-radius: 0;
        box-shadow: none;
    }
    .teams-panel .teams-search.has-preview .teams-search__main > .teams-search__results {
        flex: 1 1 auto;
    }
    .teams-panel .teams-search .teams-search-preview__back { display: inline-block; }
    .teams-panel .teams-search .teams-search-preview__close { display: none; }
}

/* =============================================================================
   Amby Teams — message delivery options (teams-delivery-options.js)
   -----------------------------------------------------------------------------
   Scoped under `:is(#inputContainer, .teams-thread-input).teams-input-adopted` / `.teams-panel`
   (CLAUDE.md rule 2). The control and its menu hang off the adopted composer
   container, which is `position: relative` (teams-rich-editor.css). The global
   `.input-container button` rule sizes EVERY button in the composer at 50px, so
   the id-qualified selectors below are what keep this one small.
   ============================================================================= */

:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__toggle {
    position: absolute;
    right: 6px;
    top: -13px;
    z-index: 6;
    width: 24px;
    height: 24px;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 50%;
    background: var(--tm-surface, #fff);
    color: var(--tm-text-2, #6f6e6d);
    font-size: 10px;
    cursor: pointer;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
    transition: background 0.15s ease, color 0.15s ease;
}
:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__toggle.is-awaiting-text { display: none; }
:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__toggle:hover {
    background: var(--tm-bg-alt, #f0ede6);
    color: var(--tm-text-1, #1f1e1d);
}
:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__toggle.is-important {
    border-color: var(--tm-danger, #c0392b);
    background: var(--tm-danger, #c0392b);
    color: #fff;
}

:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__toggle.is-urgent {
    border-color: #a61e1e;
    background: #a61e1e;
    color: #fff;
}

/* The composer itself says the next message is flagged, not only the control. */
:is(#inputContainer, .teams-thread-input).teams-input-adopted.teams-delivery--important #userInput,
:is(#inputContainer, .teams-thread-input).teams-input-adopted.teams-delivery--important .teams-rich__editor {
    border-color: var(--tm-danger, #c0392b);
}
:is(#inputContainer, .teams-thread-input).teams-input-adopted.teams-delivery--urgent #userInput,
:is(#inputContainer, .teams-thread-input).teams-input-adopted.teams-delivery--urgent .teams-rich__editor {
    border-color: #a61e1e;
}

/* In the formatting toolbar (desktop): a labelled pill at the right end, after the
   keyboard hint, in the toolbar's own row rather than floating over the composer. */
:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__toggle.teams-delivery__toggle--inline {
    position: static;
    flex: 0 0 auto;
    width: auto;
    height: 26px;
    margin: 0 0 0 10px;
    padding: 0 10px;
    gap: 6px;
    border-radius: 999px;
    box-shadow: none;
    font-size: 11px;
    font-weight: 600;
}
:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__toggle-label { line-height: 1; }

:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__menu {
    position: absolute;
    right: 6px;
    bottom: calc(100% + 18px);
    z-index: 45;
    min-width: 260px;
    max-width: calc(100vw - 24px);
    padding: 6px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: var(--tm-r-lg, 12px);
    background: var(--tm-surface, #fff);
    color: var(--tm-text-1, #1f1e1d);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
}

:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__option {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    height: auto;
    margin: 0;
    padding: 9px 10px;
    border: 0;
    border-radius: var(--tm-r, 8px);
    background: transparent;
    color: inherit;
    text-align: left;
    cursor: pointer;
}
:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__option:hover,
:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__option:focus-visible {
    background: var(--tm-bg-alt, #f0ede6);
    outline: none;
}

:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__option[data-priority="urgent"]
    .teams-delivery__option-icon {
    color: #a61e1e;
}

:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__option-icon {
    flex: 0 0 20px;
    text-align: center;
    color: var(--tm-text-3, #8a8987);
}
:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__option[data-priority="important"]
    .teams-delivery__option-icon {
    color: var(--tm-danger, #c0392b);
}

:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__option-text {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}
:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__option-label {
    font-size: 14px;
    font-weight: 600;
}
:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__option-hint {
    color: var(--tm-text-3, #8a8987);
    font-size: 12px;
}

:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__option-check {
    visibility: hidden;
    color: var(--tm-accent, #2d5f84);
    font-size: 12px;
}
:is(#inputContainer, .teams-thread-input).teams-input-adopted .teams-delivery__option[aria-checked="true"]
    .teams-delivery__option-check {
    visibility: visible;
}

/* ── The flag on a sent message ──────────────────────────────────────────── */

.teams-panel .teams-msg__important {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--tm-danger-bg, #fdecea);
    color: var(--tm-danger, #c0392b);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.teams-panel .teams-msg__important--urgent {
    background: #a61e1e;
    color: #fff;
}

.teams-panel .teams-msg--important .teams-msg__bubble {
    border-left: 3px solid var(--tm-danger, #c0392b);
}
.teams-panel .teams-msg--urgent .teams-msg__bubble {
    border-left: 3px solid #a61e1e;
    box-shadow: 0 0 0 1px rgba(166, 30, 30, 0.35);
}


/* ============================================================================
 * Amby Teams — Support Desk (settings card + the in-conversation case pill)
 *
 * Every selector is scoped to `.teams-desk` or `.teams-case-pill` per CLAUDE.md
 * rule 2. The chat page loads many stylesheets at once, and an unscoped
 * `.pill` / `.actions` here would reach into the conversation, the sidebar and
 * the modals.
 * ==========================================================================*/

/* ── Settings card ────────────────────────────────────────────────────────── */

.teams-desk {
    margin-top: 18px;
    padding: 16px 18px;
    border: 1px solid var(--sp-border, #e3e0d8);
    border-radius: 10px;
    background: var(--sp-surface, #fff);
    box-shadow: var(--tm-shadow-md);
}

.teams-desk__title {
    margin: 0 0 12px;
    font-size: 1rem;
    font-weight: 600;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--sp-border, #e3e0d8);
}

.teams-desk__loading,
.teams-desk__error {
    margin: 0;
    color: var(--sp-text-muted, #6b6b6b);
    font-size: 0.9rem;
}

.teams-desk__notice {
    margin: 0 0 14px;
    padding: 10px 12px;
    border-radius: 6px;
    font-size: 0.88rem;
    line-height: 1.45;
}

.teams-desk__notice--warn {
    background: var(--sp-warn-bg, #fdf6e3);
    border: 1px solid var(--sp-warn-border, #e8d9a8);
    color: var(--sp-warn-text, #6b5720);
}

.teams-desk__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--sp-border, #e3e0d8);
}

/* `[hidden]` loses to `display: grid` on specificity grounds — a repeat gotcha
 * in this codebase, so it is restated here rather than relied upon. */
.teams-desk__grid[hidden] {
    display: none;
}

.teams-desk__field {
    display: flex;
    flex-direction: column;
    gap: 5px;
    font-size: 0.86rem;
    min-width: 0;   /* let a select shrink inside the grid instead of overflowing */
}

/* The caption and its "?" sit on one line; the help button is the same
 * affordance the Visibility block uses, so hover help behaves identically
 * across the page.
 *
 * The caption is a real `<label for>` and the "?" is its SIBLING, never a child
 * of a wrapping `<label>`: `<button>` is a labelable element, so a help button
 * inside a label before the input becomes that label's control, and hovering
 * the caption text pops the tooltip. */
.teams-desk__field-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 500;
}

.teams-desk__field-label > label {
    cursor: inherit;
}

.teams-desk__field input,
.teams-desk__field select {
    padding: 7px 9px;
    border: 1px solid var(--sp-border, #d9d5cc);
    border-radius: 6px;
    font: inherit;
    background: var(--sp-input-bg, #fff);
    color: inherit;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
}

/* The two widest controls share one full-width row rather than being squeezed
 * into the auto-fit columns, where a long zone name was being clipped. */
.teams-desk__pair {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    min-width: 0;
}

.teams-desk__schedule {
    grid-column: 1 / -1;
}

/* Same reason as `.teams-desk__grid[hidden]` above: `[hidden]` loses to an
 * explicit `display` on specificity, and this block is toggled by the 24/7
 * switch. */
.teams-desk__days[hidden] {
    display: none;
}

.teams-desk__days {
    margin-top: 8px;
}

.teams-desk__copy {
    margin-top: 4px;
    padding: 5px 10px;
    border: 1px solid var(--sp-border, #d9d5cc);
    border-radius: 6px;
    background: var(--sp-surface, #fff);
    font: inherit;
    font-size: 0.8rem;
    cursor: pointer;
}

.teams-desk__day {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
}

.teams-desk__day-name {
    width: 42px;
    font-size: 0.84rem;
    font-weight: 500;
}

.teams-desk__day-sep {
    color: var(--sp-text-muted, #6b6b6b);
}

/* ── The case pill in a conversation header ───────────────────────────────── */

.teams-case-pill {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 12px;
    border-radius: 999px;
    background: var(--sp-surface-alt, #f4f2ec);
    border: 1px solid var(--sp-border, #e3e0d8);
    font-size: 0.85rem;
}

.teams-case-pill[hidden] {
    display: none;
}

.teams-case-pill__label {
    color: var(--sp-text-muted, #6b6b6b);
}

.teams-case-pill__hint {
    color: var(--sp-text-muted, #6b6b6b);
    font-size: 0.8rem;
}

/* The clock is the point of the pill, so it is deliberately the largest thing
 * in the header strip. Tabular numerals stop the countdown jittering as digits
 * change width — a timer that visibly twitches every second reads as broken. */
.teams-case-pill__clock {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: 0.01em;
    color: var(--sp-text, #1c1c1c);
}

.teams-case-pill[data-tone="warn"] {
    background: var(--sp-warn-bg, #fdf6e3);
    border-color: var(--sp-warn-border, #e0c97a);
    box-shadow: 0 0 0 1px var(--sp-warn-border, #e0c97a);
}

.teams-case-pill[data-tone="warn"] .teams-case-pill__clock {
    color: var(--sp-warn-text, #8a6d1f);
}

.teams-case-pill[data-tone="due"] {
    background: var(--sp-danger-bg, #fdecea);
    border-color: var(--sp-danger-border, #e88b80);
    box-shadow: 0 0 0 1px var(--sp-danger-border, #e88b80);
}

.teams-case-pill[data-tone="due"] .teams-case-pill__clock {
    color: var(--sp-danger-text, #b42318);
}

/* Past the deadline the pill pulses. Deliberately slow and low-contrast: the
 * job is to catch peripheral vision in a busy header, not to strobe at someone
 * who is already reading it. Respects reduced-motion. */
@keyframes teams-case-overdue-pulse {
    0%, 100% { box-shadow: 0 0 0 1px var(--sp-danger-border, #e88b80); }
    50%      { box-shadow: 0 0 0 4px rgba(180, 35, 24, 0.18); }
}

.teams-case-pill[data-tone="due"] {
    animation: teams-case-overdue-pulse 2.2s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
    .teams-case-pill[data-tone="due"] {
        animation: none;
    }
}

.teams-case-pill__action {
    padding: 4px 10px;
    border: 1px solid var(--sp-border, #d9d5cc);
    border-radius: 999px;
    background: var(--sp-surface, #fff);
    font: inherit;
    font-size: 0.8rem;
    cursor: pointer;
}

.teams-case-pill__action:disabled {
    opacity: 0.6;
    cursor: default;
}

/* The requester's confirm / decline card and rating moved out of the header
 * into `teams-case-resolution.css`, mounted above the composer. */

/* ── "Which request is that about?" chip selector ─────────────────────────── */
/*
 * Sits directly above the composer, and is never modal: the message it asks
 * about has already been sent. Dismissing it is a valid answer — the server
 * sweep settles anything left unanswered.
 */

.teams-case-attrib {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 6px;
    padding: 7px 10px;
    border: 1px solid var(--sp-border, #e3e0d8);
    border-radius: 8px;
    background: var(--sp-surface-alt, #faf9f6);
    font-size: 0.84rem;
}

.teams-case-attrib[hidden] {
    display: none;
}

.teams-case-attrib__label {
    flex: 0 0 auto;
    color: var(--sp-text-muted, #6b6b6b);
}

.teams-case-attrib__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    flex: 1 1 auto;
    min-width: 0;
}

.teams-case-attrib__chip {
    display: inline-flex;
    align-items: baseline;
    gap: 5px;
    padding: 3px 9px;
    border: 1px solid var(--sp-border, #d9d5cc);
    border-radius: 999px;
    background: var(--sp-surface, #fff);
    font: inherit;
    font-size: 0.8rem;
    cursor: pointer;
}

/* The most recent case is preselected — the same one the sweep would choose,
   so the fast path and the fallback never disagree. */
.teams-case-attrib__chip[data-preselected="true"] {
    border-color: var(--sp-accent, #2f6f4f);
    font-weight: 600;
}

.teams-case-attrib__chip:disabled {
    opacity: 0.6;
    cursor: default;
}

.teams-case-attrib__ref {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.76rem;
}

.teams-case-attrib__age {
    color: var(--sp-text-muted, #6b6b6b);
    font-size: 0.74rem;
}

.teams-case-attrib__skip {
    flex: 0 0 auto;
    border: none;
    background: none;
    color: var(--sp-text-muted, #6b6b6b);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}

@media (max-width: 640px) {
    .teams-case-pill {
        flex-wrap: wrap;
        border-radius: 10px;
    }

    .teams-desk__grid,
    .teams-desk__pair {
        grid-template-columns: 1fr;
    }
}

/* ── Text-entry dialog (replaces window.prompt) ───────────────────────────────
 * Mirrors `.toast-confirm-*` so the resolution note reads as part of the
 * product rather than as the browser's own chrome announcing the site's
 * hostname. */
.teams-prompt-overlay {
    position: fixed;
    inset: 0;
    z-index: 1000001;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.5);
}

.teams-prompt__box {
    width: min(460px, calc(100vw - 32px));
    padding: 24px;
    border-radius: 10px;
    background: var(--tm-surface, #fff);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.22);
    color: var(--tm-msg-text, #1f262c);
}

.teams-prompt__message {
    margin: 0 0 14px;
    color: var(--tm-msg-text, #1f262c);
    font-size: 1rem;
    font-weight: 600;
}

.teams-prompt__field {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 12px;
    border: 1px solid var(--tm-border, #d9d5cc);
    border-radius: 6px;
    font: inherit;
    resize: vertical;
    background: var(--tm-white, #fff);
    color: var(--tm-msg-text, #1f262c);
}

.teams-prompt__field::placeholder {
    color: var(--tm-text-3, #8a8a8a);
}

.teams-prompt__checkbox {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 12px;
    color: var(--text-secondary, #667085);
    font-size: 0.9rem;
    cursor: pointer;
}

.teams-prompt__actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 16px;
}

.teams-prompt__cancel,
.teams-prompt__ok {
    padding: 8px 16px;
    border-radius: 6px;
    font: inherit;
    cursor: pointer;
    border: 1px solid var(--tm-border, #d9d5cc);
    background: var(--tm-surface, #fff);
    color: var(--tm-msg-text, #1f262c);
}

.teams-prompt__ok {
    background: var(--sp-accent, #2f6f4f);
    border-color: var(--sp-accent, #2f6f4f);
    color: #fff;
    font-weight: 600;
}

/* ── Layout of the card ─────────────────────────────────────────────────────
   Three columns of settings while the card has room, one when it does not (the card
   is the container, so a narrow window and a narrow screen behave alike). Anything
   wider than a cell spans the row. */
.teams-desk { container: teams-desk / inline-size; }
.teams-desk .teams-desk__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.teams-desk .teams-desk__grid > .teams-desk__schedule,
.teams-desk .teams-desk__grid > .teams-desk__form,
.teams-desk .teams-desk__grid > .teams-desk__pair { grid-column: 1 / -1; }
.teams-desk .teams-desk__grid > .teams-desk__span-2 { grid-column: span 2; min-width: 0; }
.teams-desk .teams-desk__grid > .teams-desk__toggle-box { grid-column: span 1; }

/* Switches are boxes, so a row of them reads as a set of settings and not as loose text. */
.teams-desk .teams-desk__toggle-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
}
.teams-desk .teams-desk__toggle-grid .teams-visibility__row,
.teams-desk .teams-desk__toggle-box .teams-visibility__row,
.teams-desk > .teams-visibility__row,
.teams-desk .teams-desk__schedule > .teams-visibility__row {
    padding: 10px 14px;
    border: 1px solid var(--sp-border, #e3e0d8);
    border-radius: 8px;
    background: color-mix(in srgb, var(--sp-surface, #fff) 70%, var(--tm-bg, #f5f3ee));
}
.teams-desk > .teams-visibility__row { margin-bottom: 12px; }
@container teams-desk (max-width: 760px) {
    .teams-desk .teams-desk__grid { grid-template-columns: minmax(0, 1fr); }
    .teams-desk .teams-desk__grid > .teams-desk__span-2,
    .teams-desk .teams-desk__grid > .teams-desk__toggle-box { grid-column: 1 / -1; }
    .teams-desk .teams-desk__toggle-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================================
 * Amby Teams — Support Desk case side panel
 *
 * Its own stylesheet, matching its own module (teams-case-panel.js). The panel
 * answers "what is on this desk?" across several cases; the header pill in
 * teams-desk.css answers "am I late?" about one. Different lifecycles, and
 * keeping their styles apart means a change to one cannot reach the other.
 *
 * Every selector is scoped to `.teams-case-panel` per CLAUDE.md rule 2. The
 * chat page loads a dozen stylesheets at once, and an unscoped `.row` /
 * `.tabs` / `.avatar` here would reach into the conversation and the sidebar.
 * ==========================================================================*/

.teams-panel .teams-case-panel {
    /* Shrinkable in the aside column (`0 1`), not fixed: with `flex-shrink: 0`
       the card kept its content height forever, so a desk with thirty closed
       cases grew straight past the bottom of the conversation and its own
       `overflow-y` never had anything to scroll — reported from production
       2026-09-03. The card is bounded by the column; the LIST inside it is
       what scrolls, so the tabs and the title stay put while it does. */
    flex: 0 1 auto;
    /* Wide enough for the request-type pill beside the reference and the clock. */
    width: 320px;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
    padding: 12px 10px 12px;
    /* A FLOATING CARD, NOT A TINT. The panel floats over the transcript, and
       it used to be painted with `--sp-surface-sunken` — a Spaces token that
       never reaches `.teams-panel`, so it fell back to a 3.5% black wash. Over
       a personal chat background that is no surface at all: the rows and the
       messages behind them read as one layer (reported 2026-09-23, desktop and
       phone alike). Near-opaque, blurred and shadowed, it is legible over any
       photo, and it follows dark mode because every colour is a `--tm-*`
       token. */
    border: 1px solid var(--tm-border, #d8d3c8);
    background: color-mix(in srgb, var(--tm-surface, #f8f5f0) 94%, transparent);
    -webkit-backdrop-filter: blur(14px) saturate(1.2);
    backdrop-filter: blur(14px) saturate(1.2);
    box-shadow: var(--tm-shadow-md, 0 8px 28px rgba(28, 25, 20, 0.16));
    color: var(--tm-text-2, #5c5750);
    font-size: 0.86rem;
    border-radius: var(--tm-r-lg, 12px);
}

/* `[hidden]` loses to `display: flex` on specificity grounds — a repeat gotcha
 * in this codebase, so it is restated rather than relied upon. */
.teams-panel .teams-case-panel[hidden] {
    display: none;
}

/* The floating right-hand column. `top`/`bottom` are what give it a HEIGHT:
   an absolute box with neither is sized by its content, so `max-height: 100%`
   in teams-observers.css resolved against nothing and the cards below could
   run off the bottom of the screen with no way to scroll them back. Pinned to
   the conversation body (which is the containing block — see
   teams-conversation.css), the column is exactly as tall as the chat beside
   it and its cards scroll inside themselves. */
.teams-conversation__body .teams-conversation__aside {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 5px;
}

/* ── Collapsed rail ───────────────────────────────────────────────────────────
 * The same idiom the Chat tab's widgets use (workflow-widget-base.css): a
 * narrow strip on the edge with a vertical label and a chevron back out.
 *
 * A member with a desk keeps the panel AVAILABLE at zero open cases rather than
 * losing it. "Nothing open right now" is the state a support team spends most
 * of the day in, and it is exactly when they want to look something up in
 * Closed — a control that vanishes the moment there is no work leaves them no
 * way to get it back. */

.teams-panel .teams-case-panel[data-collapsed="true"] {
    width: 34px;
    padding: 10px 0;
    align-items: center;
    overflow: hidden;
    /* The rail is a handle, not a card: same surface, lighter shadow. */
    box-shadow: var(--tm-shadow-sm, 0 1px 3px rgba(28, 25, 20, 0.08));
}

.teams-panel .teams-case-panel__rail {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 10px 0;
    border: none;
    background: none;
    color: var(--tm-text-1, #6f6e6d);
    font: inherit;
    cursor: pointer;
}

.teams-panel .teams-case-panel__rail:hover {
    color: var(--tm-msg-text, #1f1e1d);
}

.teams-panel .teams-case-panel__rail-chevron {
    font-size: 1.1rem;
    line-height: 1;
}

/* The open count rides the rail, so a desk agent working with the panel closed
   still sees that something has arrived without giving up the width. */
.teams-panel .teams-case-panel__rail-count {
    min-width: 18px;
    padding: 1px 4px;
    border-radius: 999px;
    background: var(--sp-accent, #2f6f4f);
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1.5;
    text-align: center;
}

.teams-panel .teams-case-panel__rail-label {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    white-space: nowrap;
}

.teams-panel .teams-case-panel__collapse {
    flex: 0 0 auto;
    border: none;
    background: none;
    padding: 0 2px;
    color: var(--tm-text-1, #6f6e6d);
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
}

.teams-panel .teams-case-panel__collapse:hover {
    color: var(--tm-msg-text, #1f1e1d);
}

/* ── Header ───────────────────────────────────────────────────────────────── */

.teams-panel .teams-case-panel__head {
    flex: 0 0 auto;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 9px;
}

.teams-panel .teams-case-panel__title {
    margin: 0;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--tm-text-1, #6f6e6d);
}

.teams-panel .teams-case-panel__clear {
    border: none;
    background: none;
    padding: 0;
    color: var(--sp-accent, #2f6f4f);
    font: inherit;
    font-size: 0.74rem;
    cursor: pointer;
}

/* ── Tabs (Open first; Confirming for the desk; Closed available) ──────────── */

.teams-panel .teams-case-panel__tabs {
    flex: 0 0 auto;
    display: flex;
    gap: 3px;
    margin-bottom: 10px;
    padding: 2px;
    border-radius: 8px;
    background: color-mix(in srgb, var(--tm-text-1, #6f6e6d) 12%, transparent);
}

/* Three tabs share a ~280px drawer, so each keeps its label on one line and
   gives up padding before it wraps "Confirming · 12" onto two. */
.teams-panel .teams-case-panel__tabs button {
    flex: 1 1 auto;
    min-width: 0;
    white-space: nowrap;
    padding: 5px 4px;
    border: none;
    border-radius: 6px;
    background: none;
    color: var(--tm-text-1, #6f6e6d);
    font: inherit;
    font-size: 0.8rem;
    cursor: pointer;
}

.teams-panel .teams-case-panel__tabs button[aria-selected="true"] {
    background: var(--tm-real-white, #fff);
    color: var(--tm-msg-text, #1f1e1d);
    font-weight: 600;
    box-shadow: 0 1px 2px rgba(31, 38, 44, 0.1);
}

/* ── Rows: assignee · case id · countdown, on ONE line ────────────────────── */

/* THE SCROLLER. `min-height: 0` is the half that is easy to miss: without it a
   flex item refuses to shrink below its content height, `overflow-y` never
   engages, and the list pushes the card open instead of scrolling. */
.teams-panel .teams-case-panel__list {
    list-style: none;
    margin: 0;
    padding: 0 2px 0 0;
    display: flex;
    flex-direction: column;
    gap: 5px;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* The row and its ball toggle sit side by side. The toggle is NOT inside the
   row button — nesting a button in a button is invalid, and clicking it must
   not also select the case. */
.teams-panel .teams-case-panel__item {
    display: flex;
    align-items: stretch;
    gap: 3px;
}

/* The correction for a misclassified ball position. Deliberately quiet: the
   classifier is right most of the time, and a prominent control would imply
   otherwise. */
.teams-panel .teams-case-panel__ball {
    flex: 0 0 auto;
    width: 22px;
    border: 1px solid transparent;
    border-radius: 6px;
    background: none;
    color: var(--tm-text-1, #6f6e6d);
    font-size: 0.8rem;
    line-height: 1;
    cursor: pointer;
}

.teams-panel .teams-case-panel__ball:hover {
    border-color: var(--tm-border, #d8d3c8);
    background: var(--tm-real-white, #fff);
    color: var(--tm-msg-text, #1f1e1d);
}

.teams-panel .teams-case-panel__ball:disabled {
    opacity: 0.45;
    cursor: default;
}

/* "Mark resolved" beside a row, drawn only once a conversation holds 2+ open
   cases — when the header pill stands down and this is the ONLY place to take
   it, so unlike the ball toggle it stays visible. Teams `--tm-*` tokens, not
   `--sp-*`: those are declared on Spaces surfaces only and never reach
   `.teams-panel`, so they always fell through to their light fallbacks. */
.teams-panel .teams-case-panel__resolve {
    flex: 0 0 auto;
    width: 24px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 6px;
    background: var(--tm-surface, #f8f5f0);
    color: var(--tm-success, #2e7d32);
    font-size: 0.85rem;
    line-height: 1;
    cursor: pointer;
}

.teams-panel .teams-case-panel__resolve:hover {
    border-color: currentColor;
}

.teams-panel .teams-case-panel__resolve:disabled {
    opacity: 0.45;
    cursor: default;
}

/* Each row is a card on its own surface, so the list reads as a set of discrete
   requests rather than as text lines. At six open cases that separation is what
   makes the panel scannable. */
.teams-panel .teams-case-panel__row {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 7px 9px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-left: 3px solid var(--tm-border, #d8d3c8);
    border-radius: 7px;
    background: var(--tm-real-white, #fff);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.teams-panel .teams-case-panel__row:hover {
    border-color: var(--sp-accent-border, #c9d8e8);
}

/* The selected case is the lens on the whole conversation, so it has to read at
   a glance down a long list — a 1px ring alone did not, least of all in dark
   mode. The fill is the accent mixed into the row's own surface, so it follows
   the theme. An overdue row keeps its danger fill (the tone rule comes later
   at equal specificity): that warning outranks "this is the one you picked". */
.teams-panel .teams-case-panel__row[aria-pressed="true"] {
    border-color: var(--sp-accent, #2f6f4f);
    box-shadow: 0 0 0 1px var(--sp-accent, #2f6f4f);
    background: color-mix(in srgb, var(--sp-accent, #2f6f4f) 20%, var(--tm-real-white, #fff));
}

/* The left edge carries the state, so it is readable without parsing the text
   at the other end of the row. */
.teams-panel .teams-case-panel__row[data-state="awaiting_team"] {
    border-left-color: var(--sp-accent, #2f6f4f);
}

.teams-panel .teams-case-panel__row[data-state="pending_confirmation"] {
    border-left-color: var(--sp-star, #e0a80d);
}

.teams-panel .teams-case-panel__row[data-state="in_call"] {
    border-left-color: var(--sp-info, #3b7bbf);
}

/* Working on it — the desk owns the case and the RESOLUTION clock is running.
   Distinct from awaiting_team (owed a reply) and from awaiting_requestor
   (waiting on them), which is the whole point of the state existing. */
.teams-panel .teams-case-panel__row[data-state="in_progress"] {
    border-left-color: var(--sp-info, #3b7bbf);
}

/* The resolution countdown is a slower, less urgent number than the response
   one — hours rather than minutes — so it is not shouted. */
.teams-panel .teams-case-panel__clock--resolution {
    font-weight: 500;
    color: var(--tm-text-1, #6f6e6d);
}

/* The assignee is a photo only; the name lives in the tooltip. A name column
   would cost more width than it returns in a 232px panel. */
.teams-panel .teams-case-panel__avatar {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    object-fit: cover;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--tm-avatar-placeholder, #dbddda);
    color: var(--tm-msg-text, #1f1e1d);
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.teams-panel .teams-case-panel__avatar--none {
    background: transparent;
    border: 1px dashed var(--tm-border, #d8d3c8);
    color: var(--tm-text-1, #6f6e6d);
    font-weight: 400;
}

/* The reference is a handle, not a headline: it exists so two people can name
   the same case out loud. It is deliberately the quietest thing in the row. */
.teams-panel .teams-case-panel__ref {
    flex: 0 0 auto;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.68rem;
    letter-spacing: -0.01em;
    color: var(--tm-text-1, #6f6e6d);
}

/* The request type the requester picked on the desk's form, as a pill. Shrinks
   (ellipsis, full name in the tooltip) before the reference or the clock does. */
.teams-panel .teams-case-panel__type {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 120px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    line-height: 1.35;
    --type-hue: #6d5bd0;
    color: color-mix(in srgb, var(--type-hue) 82%, var(--tm-msg-text, #1f1e1d));
    background: color-mix(in srgb, var(--type-hue) 14%, var(--tm-real-white, #fff));
}
.teams-panel .teams-case-panel__type[data-tone="1"] { --type-hue: #2f78c4; }
.teams-panel .teams-case-panel__type[data-tone="2"] { --type-hue: #2e8b57; }
.teams-panel .teams-case-panel__type[data-tone="3"] { --type-hue: #c0841a; }
.teams-panel .teams-case-panel__type[data-tone="4"] { --type-hue: #c2417a; }
.teams-panel .teams-case-panel__type[data-tone="5"] { --type-hue: #1f8f8f; }

/* Shown only when the session has more than one requester — which is exactly
   when two rows would otherwise be indistinguishable. Truncates rather than
   wraps: a second line here breaks the one-row-per-case rule the panel is
   built on. */
.teams-panel .teams-case-panel__requester {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.78rem;
    color: var(--tm-text-1, #6f6e6d);
}

.teams-panel .teams-case-panel__status {
    flex: 1 1 auto;
    text-align: right;
    font-size: 0.75rem;
    color: var(--tm-text-1, #6f6e6d);
    white-space: nowrap;
}

/* The requester's score, shown in place of the status word on a closed row.
   "Resolved" is identical on every closed case and says nothing; the star is
   the only number the requester produced and the one thing worth scanning a
   closed list for. */
.teams-panel .teams-case-panel__score {
    flex: 1 1 auto;
    text-align: right;
    font-size: 0.72rem;
    letter-spacing: -0.5px;
    color: var(--sp-star, #e0a80d);
    white-space: nowrap;
}

/* The unearned stars stay visible so a 2/5 reads as two-out-of-five rather
   than as "two stars" floating without a scale. */
.teams-panel .teams-case-panel__score-dim {
    color: var(--tm-border, #d8d3c8);
}

.teams-panel .teams-case-panel__clock {
    flex: 1 1 auto;
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--tm-msg-text, #1f1e1d);
    white-space: nowrap;
}

/* ── Tone: derived in the browser from the deadline + the team's warn_at_pct,
      which is why the warning tier needs no server event and no extra sweep. */

.teams-panel .teams-case-panel__row[data-tone="warn"] .teams-case-panel__clock {
    color: var(--sp-warn-text, #8a6a12);
}

.teams-panel .teams-case-panel__row[data-tone="due"] {
    background: var(--tm-danger-bg, #fdecea);
}

.teams-panel .teams-case-panel__row[data-tone="due"] .teams-case-panel__clock {
    color: var(--tm-danger, #c0392b);
}

/* ── Empty + pagination ───────────────────────────────────────────────────── */

.teams-panel .teams-case-panel__empty {
    margin: 10px 4px;
    color: var(--tm-text-1, #6f6e6d);
    font-size: 0.82rem;
}

/* The paged tabs' last row. Scrolling to it fetches the next page; the button is
   for anyone who cannot scroll (keyboard, or a page too short to overflow). */
.teams-panel .teams-case-panel__tail {
    display: flex;
    justify-content: center;
    padding: 4px 0 2px;
}

.teams-panel .teams-case-panel__loading {
    color: var(--tm-text-1, #6f6e6d);
    font-size: 0.78rem;
}

.teams-panel .teams-case-panel__more {
    flex: 0 0 auto;
    width: 100%;
    padding: 6px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 6px;
    background: var(--tm-real-white, #fff);
    font: inherit;
    font-size: 0.8rem;
    cursor: pointer;
}

/* ── Requester settings, pinned below the list ────────────────────────────
 * Two switches that take effect when flipped. Below the list, not above it:
 * the rows are what a requester opens the drawer to find, and settings they
 * change rarely should not push them down. */

.teams-panel .teams-case-panel__options {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--tm-border, #d8d3c8);
}

.teams-panel .teams-case-panel__option {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 8px;
    color: var(--tm-text-2, #5c5750);
    font-size: 0.78rem;
    line-height: 1.3;
    cursor: pointer;
}

/* The native checkbox stays in the DOM (keyboard, screen readers, `change`)
   and is drawn as the switch beside it. */
.teams-panel .teams-case-panel__option input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    margin: 0;
}

.teams-panel .teams-case-panel__switch {
    flex: 0 0 auto;
    position: relative;
    width: 26px;
    height: 15px;
    margin-top: 1px;
    border-radius: 999px;
    background: var(--tm-border-strong, #b0ab9f);
    transition: background var(--tm-t, 0.18s ease);
}

.teams-panel .teams-case-panel__switch::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    transition: transform var(--tm-t, 0.18s ease);
}

.teams-panel .teams-case-panel__option input:checked + .teams-case-panel__switch {
    background: var(--tm-accent, #2d5f84);
}

.teams-panel .teams-case-panel__option input:checked + .teams-case-panel__switch::after {
    transform: translateX(11px);
}

.teams-panel .teams-case-panel__option input:focus-visible + .teams-case-panel__switch {
    outline: 2px solid var(--tm-accent, #2d5f84);
    outline-offset: 2px;
}

.teams-panel .teams-case-panel__option input:disabled + .teams-case-panel__switch {
    opacity: 0.5;
}

/* Narrow content areas (tablet, split screen) cannot afford a fixed column
   beside a 60rem reading column, so the panel becomes a short horizontal strip
   above the chat rather than squeezing it. */
@media (max-width: 900px) {
    .teams-panel .teams-conversation__body {
        flex-direction: column;
    }

    /* Expanded on a phone it floats over the transcript like the desktop card,
       at a width the one-line rows actually fit in — `auto` shrank it to its
       widest control and clipped every row. */
    .teams-panel .teams-case-panel {
        width: min(340px, calc(100vw - 24px));
        max-height: 50vh;
    }

    /* Stacked, a vertical label would be a tall sliver above the chat. The rail
       becomes a normal horizontal strip instead. */
    .teams-panel .teams-case-panel[data-collapsed="true"] {
        width: auto;
        max-height: none;
        padding: 6px 10px;
    }

    .teams-panel .teams-case-panel__rail {
        flex-direction: row;
        justify-content: flex-start;
        padding: 2px 0;
    }

    .teams-panel .teams-case-panel__rail-chevron {
        transform: rotate(-90deg);
    }

    .teams-panel .teams-case-panel__rail-label {
        writing-mode: horizontal-tb;
        transform: none;
    }
}

/* ── Requester lens notice (teams-case-lens-notice.js) ────────────────────────
 * Above the transcript while the requester lens hides other people's messages,
 * so a desk chat never opens silently empty. Opaque, like the rest of the desk
 * furniture: these rooms often run a photo background. */
.teams-panel .teams-case-lens-notice {
    display: flex;
    align-items: center;
    gap: 8px;
    width: calc(100% - 24px);
    max-width: 60rem;
    margin: 8px auto 0;
    padding: 7px 12px;
    box-sizing: border-box;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 10px;
    background: var(--tm-surface, #f8f5f0);
    color: var(--tm-text-2, #5c5750);
    font-size: 0.8rem;
    box-shadow: 0 1px 2px rgba(31, 38, 44, 0.1);
}

.teams-panel .teams-case-lens-notice[hidden] { display: none; }

.teams-panel .teams-case-lens-notice__text { flex: 1 1 auto; min-width: 0; }

.teams-panel .teams-case-lens-notice__show {
    flex: 0 0 auto;
    padding: 4px 10px;
    border: none;
    border-radius: 999px;
    background: var(--tm-accent, #2d5f84);
    color: #fff;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
}

.teams-panel .teams-case-lens-notice__show:focus-visible {
    outline: 2px solid var(--tm-accent, #2d5f84);
    outline-offset: 2px;
}

/**
 * teams-observers.css — the AI observer configuration panel.
 *
 * Scoped under `.teams-observers` throughout (CLAUDE.md rule 2): this renders in
 * two very different hosts — the Team settings page and the conversation's side
 * column — and an unscoped `.mode` or `.evidence` would collide with one of
 * them.
 *
 * The visual priority is deliberate. The *mode* is the setting people come here
 * to change, but the *evidence* beside it is what should stop them changing it
 * carelessly — so the numbers are given real weight rather than being a
 * footnote, and the "posted automatically" option is the only one that carries a
 * warning colour.
 *
 * THEMING: colours read the real `--tm-*` tokens (teams-foundation.css),
 * scoped on `.teams-panel` and re-themed under `body.dark-theme .teams-panel`
 * — the SAME pattern spaces-foundation.css documents for `--sp-*`. Never
 * `--teams-*` (a token family nothing ever defines — every reference to it
 * silently falls back to its hardcoded default, forever) and never
 * `prefers-color-scheme` (this app's theme is the Dark Mode switch, i.e.
 * `body.dark-theme` — not the OS preference, which can disagree with it).
 */

/* ── In Team settings: a section of a settings page ───────────────────────── */

.teams-observers {
    display: block;
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--tm-border, #d8d3c8);
}

/* ── In a conversation: a header-anchored popover ─────────────────────────────
 *
 * The compact trigger sits in the header action row. Expanding it must not
 * reflow the header or transcript, so the card is positioned below that row and
 * given an explicit width. The small-screen cap keeps the popover on-screen.
 */

.teams-conversation__body .teams-conversation__aside {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
    max-height: 100%;
    /* The column floats over the chat, so it must not swallow clicks meant for
       the messages underneath it. Each panel re-enables them for itself. */
    pointer-events: none;
    z-index: 10;
}

.teams-conversation__body .teams-conversation__aside > * {
    pointer-events: auto;
}

/* THE STACKING ORDER IS DECLARED HERE, NOT BY INSERTION ORDER.
 *
 * Both panels are mounted from separate dynamic `import()` calls that each
 * `appendChild` into this column, so the DOM order is whichever module resolved
 * first. On a cold visit that is network fetch order; on a return visit both
 * modules are already in the module cache and resolve in call order instead. So
 * the observer card sat above the case panel on one visit and below it on the
 * next — a panel that moves when you leave and come back, with nothing in the
 * code saying where it belongs.
 *
 * `order` makes the arrangement a stated fact rather than a race. Anything added
 * to this column later needs a number here too; without one it defaults to 0 and
 * lands ahead of both. */
.teams-conversation__body .teams-conversation__aside > .teams-case-panel {
    order: 2;
}

.teams-conversation__header-actions > .teams-observers,
.teams-conversation__overflow-actions > .teams-observers {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    width: 350px;
    max-width: calc(100vw - 24px);
    box-sizing: border-box;
    margin-top: 0;
    padding: 10px 12px 12px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 8px;
    background: var(--default-widget-bg);
    font-size: 0.86rem;
    /* A long observer list must scroll inside its own card rather than pushing
       the column past the bottom of the conversation. */
    overflow-y: auto;
    max-height: 90vh;
    z-index: 20;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
}

/* Collapsed: one line. The default in a conversation, because configuration is
   something people set once, not something they watch — while DISCLOSURE ("is
   something reading this?") is owed to everyone all the time, which is why the
   card shrinks rather than disappearing. */
.teams-conversation__header-actions > .teams-observers[data-collapsed="true"],
.teams-conversation__overflow-actions > .teams-observers[data-collapsed="true"] {
    position: static;
    width: auto;
    max-width: 248px;
    padding: 0;
    overflow: visible;
    box-shadow: none;
}

/* In the header the permanent disclosure is a compact icon. Its accessible
   name and tooltip retain the full state; the badge differentiates none from
   one or more active observers without consuming header width. */
.teams-conversation__header-actions .teams-observers__summary {
    position: relative;
    width: 34px;
    height: 34px;
    padding: 0;
    justify-content: center;
    border-color: var(--tm-border, #d8d3c8);
    background: var(--tm-surface, #f8f5f0);
    color: var(--tm-text-2, #5c5750);
}
.teams-conversation__header-actions .teams-observers__summary > .fa-robot {
    font-size: 15px;
    opacity: 0.5;
}
.teams-conversation__header-actions .teams-observers__summary-text,
.teams-conversation__header-actions .teams-observers__summary-chevron {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
.teams-conversation__header-actions .teams-observers__summary[data-active-count]:not([data-active-count="0"]) {
    color: var(--tm-accent, #2d5f84);
    border-color: var(--tm-accent, #2d5f84);
}
.teams-conversation__header-actions .teams-observers__summary[data-active-count]:not([data-active-count="0"]) > .fa-robot {
    opacity: 1;
}
.teams-conversation__header-actions .teams-observers__summary[data-active-count]:not([data-active-count="0"])::after {
    content: attr(data-active-count);
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: var(--tm-accent, #2d5f84);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
}

.teams-observers__summary {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 8px;
    background: var(--tm-bg-alt, #f0ede6);
    font: inherit;
    font-size: 12px;
    color: var(--tm-text-1, #6f6e6d);
    cursor: pointer;
    text-align: left;
}

.teams-observers__summary:hover {
    background: var(--tm-bg-alt, #f0ede6);
}

.teams-observers__summary-text {
    flex: 1 1 auto;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.teams-observers__summary-chevron {
    font-size: 15px;
    line-height: 1;
    opacity: 0.7;
}

.teams-observers__fold {
    position: absolute;
    top: 8px;
    right: 8px;
    border: 0;
    background: transparent;
    font-size: 16px;
    line-height: 1;
    color: var(--tm-text-1, #6f6e6d);
    cursor: pointer;
}

.teams-conversation__header-actions .teams-observers .teams-observers__head {
    position: relative;
    padding-right: 20px;
}

.teams-observers__head {
    margin-bottom: 12px;
}

.teams-observers__title {
    margin: 0 0 4px;
    font-size: 14px;
    font-weight: 650;
    color: var(--tm-msg-text, #1f1e1d);
}

.teams-observers__blurb {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--tm-text-1, #6f6e6d);
}

.teams-observers__empty {
    margin: 10px 0;
    font-size: 12.5px;
    color: var(--tm-text-1, #6f6e6d);
}

/* ── The list ─────────────────────────────────────────────────────────────── */

.teams-observers__list {
    list-style: none;
    margin: 12px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.teams-observers__item {
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 8px;
    background: var(--tm-real-white, #fff);
    overflow: hidden;
}

/* A paused observer stays listed rather than disappearing: "it is here but not
   running" and "it was never set up" are different answers to the same
   question, and only one of them needs somebody to do something. */
.teams-observers__item[data-inactive="true"] {
    opacity: 0.72;
}

/* MUST WRAP. The card has a fixed width, and this row holds an agent name, a
 * mode pill and the Settings button. A canonical name is long — SC_POLICY_ADVISOR
 * plus "Private to me" overran the original 248px — and on a single nowrap line
 * the button, which is last and pushed right by `margin-left: auto`, was carried
 * outside the card and clipped. Not merely ugly: Settings is the ONLY route to
 * every observer setting, so an unreachable button made the whole configuration
 * surface look as though it did not exist. Widening the card relieves it but
 * does not fix it — the next long name would do the same. */
.teams-observers__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
}

/* Truncate rather than push: a long name must yield the row, not win it. The
   `min-width: 0` is what actually allows a flex item to shrink below its own
   content — without it `text-overflow` never engages. */
.teams-observers__agent {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 13px;
    font-weight: 600;
    color: var(--tm-msg-text, #1f1e1d);
}

/* ── "It is working right now" ─────────────────────────────────────────────
 *
 * The card already discloses that an agent is READING. This is the other half:
 * a compose run is up to a minute of nothing, after which either an answer
 * arrives or — much more often — it does not, and those two look identical to a
 * person watching. They also look identical to a feature that is switched off,
 * which is exactly how it read the first time anybody tried it. */
.teams-observers__working {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 11px;
    color: var(--tm-accent, #2d5f84);
}

.teams-observers__working-dot {
    width: 6px;
    height: 6px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: currentColor;
    animation: teams-observers-pulse 1.1s ease-in-out infinite;
}

/* Screening is about a second; composing can be a minute. Slowing the pulse for
   the long phase keeps it from reading as urgency for the whole of it. */
.teams-observers__working[data-phase="composing"] .teams-observers__working-dot {
    animation-duration: 1.9s;
}

@keyframes teams-observers-pulse {
    0%, 100% { opacity: 0.25; transform: scale(0.8); }
    50%      { opacity: 1;    transform: scale(1.15); }
}

/* Respect a reduced-motion preference: the state must still be legible, so the
   dot stays and only the animation goes. */
@media (prefers-reduced-motion: reduce) {
    .teams-observers__working-dot { animation: none; opacity: 1; }
}

.teams-observers__item[data-working="true"] {
    border-color: var(--tm-accent, #2d5f84);
}

.teams-observers__mode-tag,
.teams-observers__inherited,
.teams-observers__disabled {
    font-size: 11px;
    padding: 2px 7px;
    border-radius: 999px;
    white-space: nowrap;
}

.teams-observers__mode-tag {
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.09));
    color: var(--tm-accent, #2d5f84);
}

.teams-observers__inherited {
    background: var(--tm-bg-alt, #f0ede6);
    color: var(--tm-text-1, #6f6e6d);
}

.teams-observers__disabled {
    background: #fdf0e3;
    color: #9a5b1a;
}

.teams-observers__expand {
    margin-left: auto;
    /* Never shrink and never be shrunk out of view — when the row runs out of
       width the button wraps to its own line instead. */
    flex: 0 0 auto;
    font-size: 12px;
    padding: 4px 10px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 6px;
    background: transparent;
    color: var(--tm-msg-text, #1f1e1d);
    cursor: pointer;
}

.teams-observers__expand:hover {
    background: var(--tm-bg-alt, #f0ede6);
}

/* ── Settings ─────────────────────────────────────────────────────────────── */

.teams-observers__settings {
    padding: 4px 12px 14px;
    border-top: 1px solid var(--tm-border, #d8d3c8);
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.teams-observers__field {
    display: flex;
    flex-direction: column;
    gap: 5px;
    border: 0;
    margin: 0;
    padding: 0;
}

.teams-observers__field legend,
.teams-observers__field-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--tm-msg-text, #1f1e1d);
    padding: 0;
}

/* The help bubble is positioned and viewport-clamped by teams-help-tip.js, so
   this narrow scrolling card needs no tooltip overrides of its own. */
.teams-observers__checkbox-row {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* The label keeps the click target for the checkbox and its text; the help
   button sits beside it rather than inside it. */
.teams-observers__checkbox-row .teams-observers__checkbox {
    flex: 1 1 auto;
    min-width: 0;
}

.teams-observers__required {
    color: #b42318;
    font-weight: 700;
}

.teams-observers__field-hint {
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--tm-text-1, #6f6e6d);
}

.teams-observers__field select,
.teams-observers__field textarea {
    width: 100%;
    padding: 7px 9px;
    font: inherit;
    font-size: 12.5px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 6px;
    background: var(--tm-real-white, #fff);
    color: var(--tm-msg-text, #1f1e1d);
}

.teams-observers__field textarea {
    resize: vertical;
    min-height: 60px;
}

.teams-observers__field input[type="range"] {
    width: 100%;
}

.teams-observers__field output {
    align-self: flex-end;
    font-size: 12px;
    font-weight: 600;
    color: var(--tm-accent, #2d5f84);
}

/* ── Delivery mode ────────────────────────────────────────────────────────── */

.teams-observers__mode {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 2px 8px;
    align-items: start;
    padding: 8px 10px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 6px;
    cursor: pointer;
}

.teams-observers__mode:hover {
    background: var(--tm-bg-alt, #f0ede6);
}

.teams-observers__mode input {
    grid-row: 1 / span 2;
    margin-top: 2px;
}

.teams-observers__mode-label {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--tm-msg-text, #1f1e1d);
}

.teams-observers__mode-hint {
    grid-column: 2;
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--tm-text-1, #6f6e6d);
}

/* "Posted automatically" is the only mode where a wrong answer reaches somebody
   with nobody having read it. There is deliberately no second administrator
   gating it, so the interface carries the weight instead. */
.teams-observers__mode:has(input[value="direct"]:checked) {
    border-color: #d98b2b;
    background: #fdf9f2;
}

/* ── The evidence beside the switch ───────────────────────────────────────── */

/* This is the actual control over `direct`. A tier that hides its own
   performance becomes permanent by default, so these numbers sit INSIDE the
   mode fieldset rather than in a separate stats panel somebody has to go
   looking for. */
.teams-observers__evidence {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 14px;
    margin-top: 8px;
    padding: 8px 10px;
    border-radius: 6px;
    background: var(--tm-bg-alt, #f0ede6);
    font-size: 11.5px;
    color: var(--tm-text-1, #6f6e6d);
}

.teams-observers__evidence-note {
    flex-basis: 100%;
    font-style: normal;
    color: #9a5b1a;
}

/* ── Actions ──────────────────────────────────────────────────────────────── */

.teams-observers__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.teams-observers__actions button,
.teams-observers__add,
.teams-observers__add-form button {
    font: inherit;
    font-size: 12.5px;
    padding: 6px 12px;
    border-radius: 6px;
    border: 1px solid var(--tm-border, #d8d3c8);
    background: var(--tm-real-white, #fff);
    color: var(--tm-msg-text, #1f1e1d);
    cursor: pointer;
}

.teams-observers__actions button:disabled,
.teams-observers__add-form button:disabled {
    opacity: 0.6;
    cursor: default;
}

/* Save is the CTA of this form — pinned right and given the most visual
   weight, so it reads as "the" action. Remove sits at the opposite end,
   deliberately quiet (see below): the two are not equally-weighted choices. */
.teams-observers__save,
.teams-observers__add-form [data-act="add-save"] {
    margin-left: auto;
    background: var(--tm-accent, #2d5f84);
    border-color: var(--tm-accent, #2d5f84);
    color: #fff;
    font-weight: 700;
    padding: 7px 16px;
}

/* Deliberately understated — a borderless, muted "text" button rather than a
   loud danger colour, so it reads as the LEAST prominent control in the row
   and Save is not competing with it for attention. It only gains the warning
   colour on hover/focus, when the intent to click it is already clear. */
.teams-observers__remove {
    background: transparent;
    border-color: transparent;
    color: var(--tm-text-1, #6f6e6d);
    font-weight: 400;
}

.teams-observers__remove:hover,
.teams-observers__remove:focus-visible {
    color: #b42318;
    border-color: #f0cfcb;
    background: #fdf4f3;
}

.teams-observers__add {
    margin-top: 12px;
}

.teams-observers__add-form {
    margin-top: 12px;
    padding: 12px;
    border: 1px dashed var(--tm-border, #d8d3c8);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* The outcome of a save is shown HERE, beside the button that caused it —
   never only in the console. A dead control that says nothing is
   indistinguishable from a frozen page, and what failed may have been "stop
   this agent posting to my customers". */
.teams-observers__status {
    font-size: 12px;
}

.teams-observers__status[data-tone="ok"] {
    color: #1a7f4b;
}

.teams-observers__status[data-tone="error"] {
    color: #b42318;
}

/* This app's theme is `body.dark-theme` (the header's Dark Mode switch), never
 * `prefers-color-scheme` — every element above already re-themes for free
 * because it reads real `--tm-*` tokens, which are redefined under
 * `body.dark-theme .teams-panel` (teams-foundation.css). A stray
 * `prefers-color-scheme` override used to live here instead: it read the
 * OS-level preference, completely independent of the app's own light/dark
 * state, and touched only `.teams-observers__item` + a few children's
 * background/color — never the rest (agent name, mode tag, blurb, hints...),
 * which kept their unconditional LIGHT `color`. A viewer on a light app theme
 * but a dark OS got those few elements' backgrounds flipped dark while their
 * text — and everything around them — stayed dark-on-dark: illegible, and
 * with no relationship at all to whether Dark Mode was actually on. Only the
 * one rule below needs a manual dark variant — it sets a literal colour, not
 * a token. */
body.dark-theme .teams-observers__mode:has(input[value="direct"]:checked) {
    background: #2b2318;
}

/* ── Draft reply from my personal assistant (teams-assistant-drafts.js) ───── */
.teams-panel .teams-assistant-draft {
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-width: 520px;
    margin-top: 6px;
    padding: 8px 10px 10px;
    border: 1px dashed var(--tm-accent);
    border-radius: var(--tm-r, 8px);
    background: var(--tm-accent-subtle);
    font: 400 13px/1.4 var(--tm-font-ui);
    color: var(--tm-text-1);
}
.teams-panel .teams-assistant-draft__reply {
    font-size: 12px;
    color: var(--tm-text-3);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-panel .teams-assistant-draft__badge {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--tm-accent);
}
.teams-panel .teams-assistant-draft__badge span { color: var(--tm-text-3); }
.teams-panel .teams-assistant-draft__text { white-space: pre-wrap; overflow-wrap: anywhere; }
.teams-panel .teams-assistant-draft__edit {
    width: 100%;
    box-sizing: border-box;
    padding: 6px 8px;
    border: 1px solid var(--tm-border, #d8d4cb);
    border-radius: var(--tm-r, 8px);
    font: inherit;
    resize: vertical;
}
.teams-panel .teams-assistant-draft__actions { display: flex; flex-wrap: wrap; gap: 6px; }
.teams-panel .teams-assistant-draft__approve,
.teams-panel .teams-assistant-draft__secondary {
    border-radius: 999px;
    padding: 5px 14px;
    font: 600 12px var(--tm-font-ui);
    cursor: pointer;
}
.teams-panel .teams-assistant-draft__approve {
    border: none;
    background: var(--tm-accent);
    color: #fff;
}
.teams-panel .teams-assistant-draft__secondary {
    border: 1px solid var(--tm-border, #d8d4cb);
    background: transparent;
    color: var(--tm-text-2);
}
.teams-panel .teams-assistant-draft__actions button:disabled { opacity: 0.6; cursor: default; }
.teams-panel .teams-assistant-draft__error { font-size: 12px; color: var(--tm-danger, #b42318); }

/**
 * teams-webhooks.css — Amby Teams chat incoming webhooks.
 *
 * Three surfaces, each scoped to its own host (CLAUDE.md rule 2):
 *   • the "Incoming webhooks" section of the Automations card
 *     (`.teams-observers .teams-webhooks`, teams-webhook-fields.js) — it reuses
 *     the observer card's field / action classes and adds only what differs;
 *   • the report card in the transcript (`.teams-panel .teams-webhook-card`,
 *     teams-webhook-card.js);
 *   • the disclosure rows in the Participants modal
 *     (`.teams-participants-modal .teams-participants-modal__integrations`).
 *
 * Colours read the `--tm-*` tokens (teams-foundation.css), which are defined on
 * both `.teams-panel` and the body-appended `.teams-modal-overlay`.
 */

/* ── Automations card: section ──────────────────────────────────────────── */

.teams-observers .teams-observers__subtitle,
.teams-observers .teams-webhooks__title {
    margin: 10px 0 2px;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--tm-text-2);
}

.teams-observers .teams-webhooks {
    margin-top: 14px;
    padding-top: 10px;
    border-top: 1px solid var(--tm-border);
}

.teams-observers .teams-webhooks[hidden] {
    display: none;
}

.teams-observers .teams-webhooks__item .fa-link {
    color: var(--tm-text-3);
    margin-right: 2px;
}

.teams-observers .teams-webhooks__status {
    flex: none;
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}

.teams-observers .teams-webhooks__status[data-state="paused"] {
    background: var(--tm-bg-alt);
    color: var(--tm-text-2);
}

.teams-observers .teams-webhooks__status[data-state="suspended"] {
    background: var(--tm-danger-bg);
    color: var(--tm-danger);
}

/* The row above carries 12px of side padding; the lines under it match it so
   the name, its facts and its buttons read as one aligned block. */
.teams-observers .teams-webhooks__item .teams-observers__row {
    padding-bottom: 2px;
}

.teams-observers .teams-webhooks__meta,
.teams-observers .teams-webhooks__reason {
    margin: 0;
    padding: 0 12px;
    font-size: 0.75rem;
    color: var(--tm-text-1);
}

.teams-observers .teams-webhooks__prefix {
    margin: 0;
    font-size: 0.75rem;
    color: var(--tm-text-1);
}

.teams-observers .teams-webhooks__reason {
    color: var(--tm-danger);
}

.teams-observers .teams-webhooks__prefix code {
    font-size: 0.72rem;
}

.teams-observers .teams-webhooks__row-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 6px;
    padding: 8px 12px 10px;
}

/* The observer card pushes its lone Settings button right with
   `margin-left: auto`; here several buttons share the line, so the container
   aligns them instead and each keeps its natural place. */
.teams-observers .teams-webhooks__row-actions .teams-observers__expand,
.teams-observers .teams-webhooks__row-actions .teams-observers__remove {
    margin-left: 0;
    font-size: 12px;
    padding: 4px 10px;
    border-radius: 6px;
    cursor: pointer;
}

/* The one-time URL. Deliberately loud: it is shown once and never again. */
.teams-observers .teams-webhooks__reveal {
    margin: 8px 0;
    padding: 10px;
    border: 1px solid var(--tm-accent);
    border-radius: var(--tm-r);
    background: var(--tm-accent-subtle);
}

.teams-observers .teams-webhooks__reveal-title {
    margin: 0 0 6px;
    font-weight: 600;
}

.teams-observers .teams-webhooks__reveal-row {
    display: flex;
    gap: 6px;
}

.teams-observers .teams-webhooks__reveal-row input {
    flex: 1;
    min-width: 0;
    padding: 5px 7px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.72rem;
    border: 1px solid var(--tm-border);
    border-radius: 6px;
    background: var(--tm-real-white);
    color: var(--tm-msg-text);
}

.teams-observers .teams-webhooks__reveal-row button,
.teams-observers .teams-webhooks__reveal-done {
    padding: 5px 10px;
    border: 1px solid var(--tm-accent);
    border-radius: 6px;
    background: var(--tm-accent);
    color: var(--tm-real-white);
    font-size: 0.78rem;
    cursor: pointer;
}

.teams-observers .teams-webhooks__reveal-done {
    margin-top: 6px;
    background: transparent;
    color: var(--tm-accent);
}

.teams-observers .teams-webhooks__reveal-warn {
    margin: 6px 0 0;
    font-size: 0.75rem;
    color: var(--tm-text-2);
}

.teams-observers .teams-webhooks__deliveries {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 180px;
    overflow-y: auto;
    font-size: 0.72rem;
}

.teams-observers .teams-webhooks__deliveries li {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 2px 8px;
    padding: 4px 0;
    border-bottom: 1px solid var(--tm-border);
    color: var(--tm-text-1);
}

.teams-observers .teams-webhooks__deliveries li:not([data-outcome="delivered"]):not([data-outcome="duplicate"]) {
    color: var(--tm-danger);
}

.teams-observers .teams-webhooks__deliveries .teams-webhooks__ip {
    grid-column: 1 / -1;
    color: var(--tm-text-3);
}

/* ── Report card in the transcript ──────────────────────────────────────── */

.teams-panel .teams-webhook-card {
    width: min(720px, 100%);
    margin: 12px auto;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r-lg);
    background: var(--tm-surface);
    overflow: hidden;
}

.teams-panel .teams-webhook-card__head {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--tm-border);
}

.teams-panel .teams-webhook-card__icon {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}

.teams-panel .teams-webhook-card__heading {
    flex: 1;
    min-width: 0;
}

.teams-panel .teams-webhook-card__title {
    font-weight: 600;
    color: var(--tm-msg-text);
    overflow-wrap: anywhere;
}

.teams-panel .teams-webhook-card__title a {
    color: var(--tm-accent);
    text-decoration: underline;
    font-size: 0.95rem;
}

.teams-panel .teams-webhook-card__source,
.teams-panel .teams-webhook-card__time,
.teams-panel .teams-webhook-card__note,
.teams-panel .teams-webhook-card__none {
    font-size: 0.75rem;
    color: var(--tm-text-1);
}

.teams-panel .teams-webhook-card__time {
    flex: none;
}

/* Wide reports scroll INSIDE the card — never the page (phones included). */
.teams-panel .teams-webhook-card__scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.teams-panel .teams-webhook-card__table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.82rem;
    color: var(--tm-msg-text);
}

.teams-panel .teams-webhook-card__table th,
.teams-panel .teams-webhook-card__table td {
    padding: 7px 12px;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--tm-border);
    white-space: nowrap;
}

.teams-panel .teams-webhook-card__table th {
    font-weight: 600;
    /* Tint as an image layer over an opaque surface: the sticky first column must not show through. */
    background-color: var(--tm-surface);
    background-image: linear-gradient(var(--tm-accent-subtle), var(--tm-accent-subtle));
}

.teams-panel .teams-webhook-card__table td.teams-webhook-card__num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.teams-panel .teams-webhook-card__table td.teams-webhook-card__empty {
    color: var(--tm-text-3);
}

.teams-panel .teams-webhook-card__table tbody tr:last-child td {
    border-bottom: 0;
}

.teams-panel .teams-webhook-card__note,
.teams-panel .teams-webhook-card__none {
    margin: 0;
    padding: 8px 12px;
}

/* Looker table roles. Tints are mixed into the card surface so they follow the theme. */
.teams-panel .teams-webhook-card__table th[data-kind="measure"] {
    background-image: linear-gradient(color-mix(in srgb, #c98a4b 24%, transparent), color-mix(in srgb, #c98a4b 24%, transparent));
}

.teams-panel .teams-webhook-card__table th[data-kind="calculation"] {
    background-image: linear-gradient(color-mix(in srgb, #4b9a5d 24%, transparent), color-mix(in srgb, #4b9a5d 24%, transparent));
}

.teams-panel .teams-webhook-card__table th[data-kind="total"] {
    background-image: linear-gradient(color-mix(in srgb, #c98a4b 34%, transparent), color-mix(in srgb, #c98a4b 34%, transparent));
}

.teams-panel .teams-webhook-card__table tr[data-kind="total"] td,
.teams-panel .teams-webhook-card__table tr[data-kind="subtotal"] td {
    font-weight: 700;
    background-image: linear-gradient(var(--tm-accent-subtle), var(--tm-accent-subtle));
}

.teams-panel .teams-webhook-card__table tr[data-kind="total"] td {
    border-top: 2px solid var(--tm-border);
}

/* Wide tables keep their first column (the date / label) in view while scrolling. */
@media (min-width: 641px) {
    .teams-panel .teams-webhook-card__table th:first-child,
    .teams-panel .teams-webhook-card__table td:first-child {
        background-color: var(--tm-surface);
        position: sticky;
        left: 0;
        z-index: 1;
        box-shadow: 1px 0 0 var(--tm-border);
    }
}

/* A PNG snapshot (Looker dashboard): scaled to the card, click opens the Teams gallery. */
.teams-panel .teams-webhook-card__image {
    display: block;
    line-height: 0;
}

.teams-panel .teams-webhook-card__image img {
    display: block;
    width: 100%;
    height: auto;
    max-height: 70vh;
    object-fit: contain;
    background: var(--tm-surface);
}

/* Phones: a wide table would scroll sideways inside the card, hiding most columns.
   Each row becomes a block of "column  value" pairs instead — nothing is cut off and
   nothing scrolls. The header row stays in the DOM (screen readers) but is not drawn. */
@media (max-width: 640px) {
    .teams-panel .teams-webhook-card__table thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
    }

    .teams-panel .teams-webhook-card__table,
    .teams-panel .teams-webhook-card__table tbody,
    .teams-panel .teams-webhook-card__table tr {
        display: block;
    }

    .teams-panel .teams-webhook-card__table tbody tr {
        border-bottom: 1px solid var(--tm-border);
    }

    .teams-panel .teams-webhook-card__table tbody tr:last-child {
        border-bottom: 0;
    }

    .teams-panel .teams-webhook-card__table td {
        display: grid;
        grid-template-columns: minmax(0, 42%) minmax(0, 1fr);
        gap: 10px;
        padding: 5px 12px;
        border-bottom: 0;
        white-space: normal;
        overflow-wrap: anywhere;
        text-align: left;
    }

    .teams-panel .teams-webhook-card__table td::before {
        content: attr(data-label);
        font-weight: 600;
        font-size: 0.75rem;
        color: var(--tm-text-1);
    }

    .teams-panel .teams-webhook-card__table td.teams-webhook-card__num {
        text-align: left;
    }
}

/* ── Participants modal: disclosure rows ────────────────────────────────── */

.teams-participants-modal .teams-participants-modal__integrations {
    padding: 4px 20px 12px;
    border-top: 1px solid var(--tm-border);
}

.teams-participants-modal .teams-participants-modal__integrations[hidden] {
    display: none;
}

.teams-participants-modal .teams-webhooks__disclosure-title {
    margin: 10px 0 4px;
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    color: var(--tm-text-2);
}

.teams-participants-modal .teams-webhooks__disclosure-icon {
    color: var(--tm-accent);
}

.teams-participants-modal .teams-webhooks__disclosure-manage {
    margin-top: 6px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--tm-accent);
    font-size: 0.8rem;
    cursor: pointer;
    text-decoration: underline;
}

/* Text inputs + the IP list. The observer card has no single-line inputs, so
   its field styles stop at textareas; these match them and keep both inside the
   card (border-box, so padding cannot push them past its edge). */
.teams-observers .teams-webhooks input[type="text"],
.teams-observers .teams-webhooks textarea {
    box-sizing: border-box;
    width: 100%;
    padding: 6px 8px;
    border: 1px solid var(--tm-border);
    border-radius: 6px;
    background: var(--tm-real-white);
    color: var(--tm-msg-text);
    font: inherit;
    font-size: 12.5px;
}

.teams-observers .teams-webhooks textarea {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    resize: vertical;
}

/* Touch long-press spotlight on a report card. The actions toolbar is built into
   the card but never shown in place: the spotlight lifts it onto <body>. */
.teams-panel .teams-webhook-card > .teams-msg__actions {
    display: none;
}

.teams-panel .teams-webhook-card > .teams-msg__reactions {
    padding: 0 12px 10px;
}

/* iOS would raise its own image callout and swallow the hold. */
.teams-panel .teams-webhook-card {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
}

.teams-panel .teams-webhook-card .teams-webhook-card__scroll {
    -webkit-user-select: text;
    user-select: text;
}

/* ── AI observer inside one webhook's settings ─────────────────────────────── */
.teams-webhooks .wh-observer {
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--tm-border);
}
.teams-webhooks .wh-observer .wh-observer__title {
    margin: 0 0 6px;
    font-size: 0.8rem;
    color: var(--tm-text-1);
}
.teams-webhooks .wh-observer .wh-observer__summary,
.teams-webhooks .wh-observer .wh-observer__empty {
    margin: 0 0 8px;
    font-size: 0.8rem;
    color: var(--tm-text-2);
}
.teams-webhooks .wh-observer .teams-observers__field input[type="number"] {
    width: 100%;
    box-sizing: border-box;
    font: inherit;
}
.teams-webhooks .wh-observer .wh-observer__check {
    display: flex;
    gap: 6px;
    margin-bottom: 10px;
    font-size: 0.8rem;
}
.teams-webhooks .wh-observer .wh-observer__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    margin-bottom: 8px;
}
.teams-webhooks .wh-observer .wh-observer__status,
.teams-webhooks .wh-observer .wh-observer__error {
    font-size: 0.75rem;
    color: var(--tm-danger);
}
.teams-webhooks .wh-observer .wh-observer__runs {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 260px;
    overflow-y: auto;
}
.teams-webhooks .wh-observer .wh-observer__runs li {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 10px;
    padding: 6px 0;
    border-bottom: 1px solid var(--tm-border);
    font-size: 0.75rem;
    color: var(--tm-text-2);
}
.teams-webhooks .wh-observer .wh-observer__runs li[data-outcome="preview"],
.teams-webhooks .wh-observer .wh-observer__runs li[data-outcome="posted"] {
    color: var(--tm-text-1);
}
.teams-webhooks .wh-observer .wh-observer__runs details {
    flex-basis: 100%;
}
.teams-webhooks .wh-observer .wh-observer__text {
    margin: 4px 0 0;
    white-space: pre-wrap;
    font: inherit;
    color: var(--tm-text-1);
}

/* ── Highlights an AI observer posted under a report ───────────────────────── */
.teams-observer-note {
    max-width: 640px;
    margin: 8px auto;
    padding: 10px 14px;
    border: 1px solid var(--tm-border);
    border-radius: 12px;
    background: var(--tm-bg-alt);
    color: var(--tm-text-1);
}
.teams-observer-note .teams-observer-note__head {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 6px;
    font-size: 0.78rem;
    color: var(--tm-accent);
}
.teams-observer-note .teams-observer-note__time {
    margin-left: auto;
    color: var(--tm-text-3);
}
.teams-observer-note .teams-observer-note__text {
    white-space: pre-wrap;
    font-size: 0.9rem;
    line-height: 1.4;
    overflow-wrap: anywhere;
}
.teams-observer-note .teams-observer-note__artifacts {
    margin-top: 8px;
}

/* Praise + Survey/Poll cards. Self-contained (every selector is under an
   .amby-card* root), so position here is not load-bearing. */
/* =============================================================================
   Amby cards — Praise and Surveys/Polls (frontend/chat_page/js/cards/*)
   -----------------------------------------------------------------------------
   Every selector is namespaced under one of the card roots below, so nothing here
   can reach — or be reached by — another feature's styles (CLAUDE.md rule 2):

     .amby-card-slot / .amby-card   a card drawn in a chat bubble or a Space post
     .amby-card-dialog              every card dialog (builders, answer, results)
     .amby-card-menu                the Praise / Poll / Survey menu and the Teams
                                    composer "+" menu (body-appended,
                                    teams-action-menu.js)
     .amby-card-lightbox            full-size image (body-appended)
     .amby-card-launch/-chip        the Space composer launcher

   Dialogs ride the Teams modal chrome, which supplies the colour tokens and the
   dark theme. The body-appended menu and lightbox are outside any `.teams-*`
   ancestor, so they carry literal fallbacks and a `body.dark-theme` block.
   ============================================================================= */

/* ── A card inside a message bubble / post ─────────────────────────────────── */
.teams-msg.teams-msg--card .teams-msg__bubble {
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
}

/* Cards are the content of their message, so they are drawn generously: a poll
   needs room for its options and tallies, and a praise card is meant to be seen. */
.amby-card-slot {
    width: 560px;
    max-width: 100%;
}
.amby-card-slot.amby-card--poll,
.amby-card-slot.amby-card--survey {
    width: 700px;
}
.amby-card-slot.amby-card--praise {
    width: 600px;
}
.space-post.space-post--card .amby-card-slot {
    width: 100%;
    margin: 6px 0 10px;
}
.space-post.space-post--card .amby-card-slot.amby-card--poll,
.space-post.space-post--card .amby-card-slot.amby-card--survey {
    max-width: 760px;
}
.space-post.space-post--card .amby-card-slot.amby-card--praise {
    max-width: 680px;
}
.amby-card {
    --amby-card-bg: var(--tm-surface, #f8f5f0);
    --amby-card-border: var(--tm-border, #d8d3c8);
    --amby-card-text: var(--tm-msg-text, #1f1e1d);
    --amby-card-muted: var(--tm-text-3, #6f6e6d);
    --amby-card-accent: var(--tm-accent, #2d5f84);
    --amby-card-accent-soft: var(--tm-accent-subtle, rgba(45, 95, 132, 0.12));
    box-sizing: border-box;
    padding: 14px 16px;
    border: 1px solid var(--amby-card-border);
    border-radius: var(--tm-r-lg, 12px);
    background: var(--amby-card-bg);
    color: var(--amby-card-text);
    font-family: var(--tm-font-ui, system-ui, sans-serif);
    font-size: 14px;
    line-height: 1.4;
    text-align: left;
    white-space: normal;
}
.amby-card.amby-card--loading,
.amby-card.amby-card--missing {
    color: var(--amby-card-muted);
    font-size: 13px;
}
.amby-card .amby-card__brand {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
}
.amby-card .amby-card__brand-name {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.02em;
}
.amby-card__brand-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 7px;
    flex: 0 0 auto;
    background: #6264a7;
    color: #fff;
    font-size: 13px;
}
.amby-card .amby-card__title {
    font-size: 16px;
    font-weight: 700;
    margin-bottom: 4px;
    overflow-wrap: anywhere;
}
.amby-card .amby-card__desc {
    color: var(--amby-card-muted);
    margin-bottom: 6px;
    overflow-wrap: anywhere;
    white-space: pre-wrap;
}
.amby-card .amby-card__sub {
    color: var(--amby-card-muted);
    font-size: 13px;
}
.amby-card .amby-card__img {
    display: block;
    max-width: 100%;
    height: auto;
    max-height: 260px;
    border-radius: 8px;
    cursor: zoom-in;
}
.amby-card .amby-card__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: 10px;
    font-size: 12px;
    color: var(--amby-card-muted);
}
.amby-card .amby-card__chip {
    padding: 1px 8px;
    border-radius: 999px;
    font-weight: 600;
    background: var(--amby-card-accent-soft);
    color: var(--amby-card-accent);
}
.amby-card .amby-card__closed {
    color: var(--tm-danger, #c0392b);
    font-weight: 600;
}
.amby-card .amby-card__footer:empty {
    display: none;
}
.amby-card .amby-card__footer {
    margin-top: 8px;
}
.amby-card .amby-card__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
}
.amby-card .amby-card__done {
    font-size: 12px;
    color: var(--tm-success, #2e7d32);
}

/* Buttons shared by cards and their dialogs. */
.amby-card .amby-card__btn,
.amby-card-dialog .amby-card__btn {
    padding: 7px 14px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 8px;
    background: var(--tm-surface, #fff);
    color: var(--tm-text-1, #1f1e1d);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.amby-card .amby-card__btn:hover:not(:disabled),
.amby-card-dialog .amby-card__btn:hover:not(:disabled) {
    background: var(--tm-bg-alt, #f0ede6);
}
.amby-card .amby-card__btn--primary,
.amby-card-dialog .amby-card__btn--primary {
    border-color: var(--tm-accent, #2d5f84);
    background: var(--tm-accent, #2d5f84);
    color: #fff;
}
.amby-card .amby-card__btn--primary:hover:not(:disabled),
.amby-card-dialog .amby-card__btn--primary:hover:not(:disabled) {
    background: var(--tm-accent-hover, #245070);
}
.amby-card .amby-card__btn:disabled,
.amby-card-dialog .amby-card__btn:disabled {
    opacity: 0.55;
    cursor: default;
}
.amby-card .amby-card__link,
.amby-card-dialog .amby-card__link {
    border: 0;
    background: none;
    padding: 2px 0;
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    color: var(--tm-accent, #2d5f84);
    cursor: pointer;
    text-decoration: underline;
}

/* ── Praise ─────────────────────────────────────────────────────────────────── */
.amby-card.amby-card--poll,
.amby-card.amby-card--survey {
    padding: 18px 22px;
}
.amby-card.amby-card--praise {
    padding: 18px 24px 24px;
    color: #1f1e1d;
    border-color: rgba(0, 0, 0, 0.08);
}
.amby-card--praise .amby-card__brand-name {
    color: #1f1e1d;
}
.amby-card--praise[data-bg="bg1"] {
    background: linear-gradient(135deg, #d9ecf2, #e6e2f7);
}
.amby-card--praise[data-bg="bg2"] {
    background: linear-gradient(135deg, #e9dff5, #f4efe3);
}
.amby-card--praise[data-bg="bg3"] {
    background: linear-gradient(135deg, #dfe3f7, #d7ece8);
}
.amby-card--praise[data-bg="bg4"] {
    background: linear-gradient(135deg, #d9efe9, #eef3d2);
}
.amby-card--praise[data-bg="bg5"] {
    background: linear-gradient(135deg, #e3f1d6, #f6f5d8);
}
.amby-card--praise[data-bg="bg6"] {
    background: linear-gradient(135deg, #f7e6d9, #f3d9d6);
}
.amby-card--praise[data-bg="bg7"] {
    background: linear-gradient(135deg, #f3dbdd, #d9e4f1);
}
.amby-card--praise[data-bg="bg8"] {
    background: linear-gradient(135deg, #f7e3d6, #f1d9ec);
}
.amby-card--praise .amby-praise__stage {
    padding: 14px 8px 0;
}
.amby-card--praise .amby-praise__badge {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 104px;
    height: 104px;
    margin: 0 auto 14px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.85);
    border: 4px solid #fff;
    font-size: 54px;
    font-family: var(--tm-font-emoji, "Apple Color Emoji", "Segoe UI Emoji", sans-serif);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.amby-card--praise .amby-praise__title {
    font-size: 28px;
    font-weight: 300;
    text-align: center;
}
.amby-card--praise .amby-praise__to {
    font-size: 22px;
    font-weight: 700;
    text-align: center;
    margin-bottom: 12px;
    overflow-wrap: anywhere;
}
.amby-card--praise .amby-praise__note {
    margin: 12px 0;
    font-size: 18px;
    line-height: 1.5;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}
.amby-card--praise .amby-praise__from {
    margin-top: 16px;
    font-size: 14px;
    opacity: 0.85;
}

/* ── Poll ───────────────────────────────────────────────────────────────────── */
.amby-card--poll .amby-poll__question {
    font-size: 18px;
    font-weight: 700;
    margin-bottom: 8px;
    overflow-wrap: anywhere;
}
.amby-card--poll .amby-poll__qimage {
    margin-bottom: 10px;
}
.amby-card--poll .amby-poll__hint {
    font-size: 12px;
    color: var(--amby-card-muted);
    margin-bottom: 6px;
}
.amby-card--poll .amby-poll__options {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.amby-card--poll .amby-poll__options.has-images {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr));
    align-items: start;
}
.amby-card--poll .amby-poll__options.has-images > * {
    min-width: 0;
}
.amby-card--poll .amby-poll__item {
    display: flex;
    flex-direction: column;
    gap: 5px;
    min-width: 0;
}
.amby-card--poll .amby-poll__voters {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin: 0 2px;
}
.amby-card--poll .amby-poll__voter {
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 11px;
    line-height: 1.5;
    background: var(--amby-card-accent-soft);
    color: var(--amby-card-muted);
}
.amby-card--poll .amby-poll__option {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    min-width: 400px;
    min-height: 46px;
    padding: 10px 14px;
    text-align: left;
    font-size: 15px;
    border: 1px solid var(--amby-card-border);
    border-radius: 8px;
    background: var(--tm-white, #fff);
    color: inherit;
    font: inherit;
    cursor: pointer;
}
.amby-card--poll .amby-poll__option:disabled {
    cursor: default;
}
.amby-card--poll .amby-poll__option.is-chosen {
    border-color: var(--amby-card-accent);
}
.amby-card--poll .amby-poll__option {
    min-width: 0;
}

/* An option with a picture: the picture on top, then [mark  label  count] on one line. */
.amby-card--poll .amby-poll__option.has-image {
    flex-wrap: wrap;
    align-items: center;
    row-gap: 8px;
}
.amby-card--poll .amby-poll__option.has-image .amby-poll__thumb {
    flex: 0 0 100%;
}
.amby-card--poll .amby-poll__bar {
    position: absolute;
    inset: 0 auto 0 0;
    background: var(--amby-card-accent-soft);
    transition: width 0.3s ease;
    pointer-events: none;
}
.amby-card--poll .amby-poll__option > :not(.amby-poll__bar) {
    position: relative;
}
.amby-card--poll .amby-poll__mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    font-size: 10px;
    border: 2px solid var(--amby-card-border);
    color: #fff;
}
.amby-card--poll .amby-poll__option.is-chosen .amby-poll__mark {
    background: var(--amby-card-accent);
    border-color: var(--amby-card-accent);
}
.amby-card--poll .amby-poll__label {
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
}
.amby-card--poll .amby-poll__count {
    flex: 0 0 auto;
    font-weight: 700;
    font-size: 13px;
}
.amby-card--poll .amby-poll__count small {
    margin-left: 6px;
    font-weight: 400;
    color: var(--amby-card-muted);
}
.amby-card--poll .amby-poll__thumb {
    display: block;
    min-width: 0;
    overflow: hidden;
    border-radius: 6px;
}
.amby-card--poll .amby-poll__img {
    display: block;
    width: 100%;
    max-width: 100%;
    height: 150px;
    object-fit: cover;
    border-radius: 6px;
    cursor: zoom-in;
}
.amby-card--poll.is-busy .amby-poll__options {
    opacity: 0.7;
    pointer-events: none;
}
.amby-card--poll.is-closed .amby-poll__option {
    cursor: default;
}
.amby-chart .amby-chart__row {
    min-width: 400px;
}

/* The read-only poll: horizontal bars. Leader strongest, your own answer ticked. */
.amby-card--results .amby-chart {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-top: 12px;
}
.amby-card--results .amby-chart__head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 6px;
}
.amby-card--results .amby-chart__label {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 15px;
    overflow-wrap: anywhere;
}
.amby-card--results .amby-chart__row.is-mine .amby-chart__label {
    font-weight: 700;
}
.amby-card--results .amby-chart__mine {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    margin-left: 6px;
    border-radius: 50%;
    background: var(--amby-card-accent);
    color: #fff;
    font-size: 10px;
    vertical-align: middle;
}
.amby-card--results .amby-chart__pct {
    flex: 0 0 auto;
    font-size: 13px;
    color: var(--amby-card-muted);
}
.amby-card--results .amby-chart__bar {
    display: flex;
    align-items: center;
    gap: 12px;
}
.amby-card--results .amby-chart__n {
    flex: 0 0 auto;
    min-width: 26px;
    text-align: right;
    font-size: 15px;
    font-weight: 700;
}
.amby-card--results .amby-chart__track {
    flex: 1 1 auto;
    min-width: 0;
    height: 12px;
    border-radius: 6px;
    background: var(--amby-card-border);
    overflow: hidden;
}
.amby-card--results .amby-chart__fill {
    display: block;
    height: 100%;
    border-radius: 6px;
    min-width: 0;
    background: var(--amby-card-accent);
    opacity: 0.42;
    transition: width 0.4s ease;
}
.amby-card--results .amby-chart__row.is-top .amby-chart__fill,
.amby-card--results .amby-chart__row.is-mine .amby-chart__fill {
    opacity: 1;
}
.amby-card--results .amby-chart__thumb {
    flex: 0 0 auto;
    width: 52px;
}
.amby-card--results .amby-chart__img {
    display: block;
    width: 52px;
    height: 40px;
    object-fit: cover;
    border-radius: 6px;
    cursor: zoom-in;
}
.amby-card--results .amby-poll__voters {
    margin: 4px 0 0;
    white-space: normal;
}
.amby-card--results .amby-card__done {
    margin-top: 14px;
}

/* The poll's footer: [ + Add option .......... Submit ], a quiet caption, then a
   hairline and the meta line with the creator's "Close now" at its far end — a
   toolbar and a status bar rather than a stack of loose rows. */
.amby-card--poll .amby-poll__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px 12px;
    margin-top: 14px;
}
.amby-card--poll .amby-poll__add {
    flex: 1 1 200px;
    min-width: 0;
}
.amby-card--poll .amby-poll__add-open {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 9px 14px;
    border: 1px dashed var(--amby-card-border);
    border-radius: 8px;
    background: transparent;
    color: var(--amby-card-accent);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.amby-card--poll .amby-poll__add-open:hover {
    background: var(--amby-card-accent-soft);
}
.amby-card--poll .amby-poll__add-open[hidden] {
    display: none;
}
.amby-card--poll .amby-poll__add-form {
    display: flex;
    gap: 8px;
}
.amby-card--poll .amby-poll__add-form[hidden] {
    display: none;
}
.amby-card--poll .amby-poll__add-input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 8px 10px;
    font: inherit;
    font-size: 14px;
    border: 1px solid var(--amby-card-border);
    border-radius: 8px;
    background: var(--tm-white, #fff);
    color: inherit;
}
.amby-card--poll .amby-poll__actions .amby-card__btn--primary {
    min-width: 110px;
    padding: 9px 20px;
    font-size: 14px;
    margin-left: auto;
}
.amby-card--poll .amby-poll__actions .amby-card__done {
    margin: 0 0 0 auto;
}
.amby-card--poll > .amby-card__note {
    margin-top: 6px;
    text-align: right;
}
.amby-card .amby-card__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 6px 12px;
    margin-top: 14px;
    padding-top: 10px;
    border-top: 1px solid var(--amby-card-border);
}
.amby-card .amby-card__foot .amby-card__meta {
    margin-top: 0;
}
.amby-card .amby-card__close {
    margin-left: auto;
    color: var(--tm-danger, #c0392b);
    text-decoration: none;
}
.amby-card .amby-card__close:hover {
    text-decoration: underline;
}
.amby-card .amby-card__note,
.amby-card-dialog .amby-card__note {
    font-size: 12px;
    color: var(--tm-text-3, #6f6e6d);
}
.amby-card .amby-card__done {
    margin-top: 10px;
}

/* ── Dialogs ────────────────────────────────────────────────────────────────── */
.amby-card-overlay {
    z-index: 10020;
}
.amby-card-dialog {
    max-width: 520px;
}
.amby-card-dialog.amby-card-dialog--wide {
    max-width: 680px;
}
.amby-card-dialog .amby-card-dialog__heading {
    display: flex;
    align-items: center;
    gap: 10px;
}
.amby-card-dialog .amby-card-dialog__subtitle {
    font-size: 12px;
    color: var(--tm-text-3, #6f6e6d);
}
.amby-card-dialog .amby-card-dialog__body {
    padding: 14px 20px;
    overflow-y: auto;
}
.amby-card-dialog .amby-card-dialog__footer {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 20px;
    border-top: 1px solid var(--tm-border, #d8d3c8);
}
.amby-card-dialog .amby-card-dialog__spacer {
    flex: 1 1 auto;
}
.amby-card-dialog .amby-card-dialog__error {
    margin-top: 10px;
    color: var(--tm-danger, #c0392b);
    font-size: 13px;
}
.amby-card-dialog .amby-card-dialog__loading {
    padding: 24px;
    text-align: center;
    color: var(--tm-text-3, #6f6e6d);
}
.amby-card-dialog .amby-field__label {
    display: block;
    margin: 12px 0 5px;
    font-size: 13px;
    font-weight: 600;
}
.amby-card-dialog .amby-field__input,
.amby-card-dialog .amby-field__textarea,
.amby-card-dialog .amby-field__select {
    box-sizing: border-box;
    width: 100%;
    padding: 8px 10px;
    font: inherit;
    font-size: 14px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 8px;
    background: var(--tm-white, #fff);
    color: var(--tm-msg-text, #1f1e1d);
}
.amby-card-dialog .amby-field__textarea {
    resize: vertical;
}
.amby-card-dialog .amby-field__select {
    width: auto;
}
.amby-card-dialog .amby-field__input--sm,
.amby-card-dialog .amby-field__select--sm {
    width: auto;
    padding: 4px 8px;
    font-size: 13px;
}
.amby-card-dialog .amby-field__counter {
    text-align: right;
    font-size: 11px;
    color: var(--tm-text-3, #6f6e6d);
}

/* People picker */
.amby-card-dialog .amby-people {
    position: relative;
}
.amby-card-dialog .amby-people__box {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    padding: 5px 8px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 8px;
    background: var(--tm-white, #fff);
}
.amby-card-dialog .amby-people__chips {
    display: contents;
}
.amby-card-dialog .amby-people__chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 4px 2px 10px;
    border-radius: 999px;
    background: var(--tm-bg-alt, #f0ede6);
    font-weight: 600;
    font-size: 13px;
}
.amby-card-dialog .amby-people__chip button {
    border: 0;
    background: none;
    cursor: pointer;
    color: inherit;
    padding: 2px 6px;
}
.amby-card-dialog .amby-people__input {
    flex: 1 1 120px;
    min-width: 120px;
    border: 0;
    outline: 0;
    padding: 4px;
    background: transparent;
    font: inherit;
    font-size: 14px;
    color: inherit;
}
.amby-card-dialog .amby-people__results {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(100% + 4px);
    z-index: 5;
    max-height: 320px;
    overflow-y: auto;
    padding: 4px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 8px;
    background: var(--tm-surface, #fff);
    box-shadow: var(--tm-shadow-md, 0 8px 24px rgba(0, 0, 0, 0.16));
}
/* Rows are the shared people-picker rows (teams-person-row.js, styled as
   .teams-newchat__row in teams-modals.css); they are two lines tall. */
.amby-card-dialog .amby-people__results .teams-newchat__row {
    padding: 6px 8px;
}

/* Praise builder */
.amby-card-dialog .amby-praise-titles {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.amby-card-dialog .amby-praise-titles__pill {
    padding: 6px 12px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 999px;
    background: var(--tm-white, #fff);
    color: inherit;
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}
.amby-card-dialog .amby-praise-titles__pill.is-on {
    border-color: var(--tm-accent, #2d5f84);
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.12));
    font-weight: 600;
}
.amby-card-dialog .amby-praise-bgs {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}
.amby-card-dialog .amby-praise-bgs__swatch {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    border: 2px solid var(--tm-border, #d8d3c8);
    cursor: pointer;
}
.amby-card-dialog .amby-praise-bgs__swatch.is-on {
    border-color: var(--tm-accent, #2d5f84);
    box-shadow: 0 0 0 2px var(--tm-accent-subtle, rgba(45, 95, 132, 0.2));
}
.amby-card-dialog .amby-praise-bgs__swatch[data-bg="bg1"] {
    background: linear-gradient(135deg, #d9ecf2, #e6e2f7);
}
.amby-card-dialog .amby-praise-bgs__swatch[data-bg="bg2"] {
    background: linear-gradient(135deg, #e9dff5, #f4efe3);
}
.amby-card-dialog .amby-praise-bgs__swatch[data-bg="bg3"] {
    background: linear-gradient(135deg, #dfe3f7, #d7ece8);
}
.amby-card-dialog .amby-praise-bgs__swatch[data-bg="bg4"] {
    background: linear-gradient(135deg, #d9efe9, #eef3d2);
}
.amby-card-dialog .amby-praise-bgs__swatch[data-bg="bg5"] {
    background: linear-gradient(135deg, #e3f1d6, #f6f5d8);
}
.amby-card-dialog .amby-praise-bgs__swatch[data-bg="bg6"] {
    background: linear-gradient(135deg, #f7e6d9, #f3d9d6);
}
.amby-card-dialog .amby-praise-bgs__swatch[data-bg="bg7"] {
    background: linear-gradient(135deg, #f3dbdd, #d9e4f1);
}
.amby-card-dialog .amby-praise-bgs__swatch[data-bg="bg8"] {
    background: linear-gradient(135deg, #f7e3d6, #f1d9ec);
}
.amby-card-dialog .amby-praise-preview .amby-card {
    max-width: 100%;
}

/* Survey builder */
.amby-card-dialog .amby-b__question {
    margin: 18px 0;
    padding: 12px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 10px;
    background: var(--tm-bg-alt, #f0ede6);
}
.amby-card-dialog .amby-b__qhead {
    display: flex;
    align-items: center;
    gap: 8px;
}
.amby-card-dialog .amby-b__qtools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin: 8px 0;
}
.amby-card-dialog .amby-b__options {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.amby-card-dialog .amby-b__option {
    display: flex;
    align-items: center;
    gap: 8px;
}
.amby-card-dialog .amby-b__marker {
    color: var(--tm-text-3, #6f6e6d);
}
.amby-card-dialog .amby-b__check {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
}
.amby-card-dialog .amby-b__settings {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 14px;
}
.amby-card-dialog .amby-b__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border: 0;
    border-radius: 6px;
    background: none;
    color: var(--tm-text-2, #5c5750);
    cursor: pointer;
}
.amby-card-dialog .amby-b__icon:hover:not(:disabled) {
    background: var(--tm-border, #d8d3c8);
}
.amby-card-dialog .amby-b__icon:disabled {
    opacity: 0.35;
    cursor: default;
}
.amby-card-dialog .amby-b__image {
    position: relative;
    display: inline-block;
}
.amby-card-dialog .amby-b__image img {
    display: block;
    width: 44px;
    height: 44px;
    object-fit: cover;
    border-radius: 6px;
}
.amby-card-dialog .amby-b__image .amby-b__icon {
    position: absolute;
    top: -8px;
    right: -8px;
    width: 20px;
    height: 20px;
    font-size: 10px;
    background: var(--tm-surface, #fff);
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 50%;
}

/* Answering and results */

/* The answer and results dialogs sit on a tinted body so each question can be a
   raised card of its own: question, then its answers, clearly grouped. */
.amby-card-dialog.amby-card-dialog--survey {
    --amby-q-indent: 38px;
}
@media (max-width: 520px) {
    .amby-card-dialog.amby-card-dialog--survey {
        --amby-q-indent: 0px;
    }
    .amby-card-dialog.amby-card-dialog--survey .amby-q {
        padding: 14px 12px;
    }
}
.amby-card-dialog.amby-card-dialog--survey .amby-card-dialog__body {
    padding: 18px 20px 22px;
    background: var(--tm-bg-alt, #f0ede6);
}
.amby-card-dialog .amby-q-intro {
    margin: 0 0 16px;
    padding: 0 2px;
    font-size: 14px;
    line-height: 1.55;
    color: var(--tm-text-2, #5c5750);
}
.amby-card-dialog .amby-q-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-bottom: 14px;
    font-size: 12px;
    color: var(--tm-text-3, #6f6e6d);
}
.amby-card-dialog .amby-q-meta .amby-card__chip {
    padding: 1px 8px;
    border-radius: 999px;
    font-weight: 600;
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.12));
    color: var(--tm-accent, #2d5f84);
}
.amby-card-dialog .amby-q-list {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.amby-card-dialog .amby-q {
    margin: 0;
    padding: 18px 18px 16px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 12px;
    background: var(--tm-surface, #fff);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}
.amby-card-dialog .amby-q__title {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 14px;
}
.amby-card-dialog .amby-q__num {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.12));
    color: var(--tm-accent, #2d5f84);
    font-size: 13px;
    font-weight: 700;
}
.amby-card-dialog .amby-q__label {
    flex: 1 1 auto;
    min-width: 0;
    padding-top: 2px;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.4;
    overflow-wrap: anywhere;
}
.amby-card-dialog .amby-q__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: -6px 0 12px var(--amby-q-indent);
}
.amby-card-dialog .amby-q__req {
    padding: 1px 8px;
    border-radius: 999px;
    background: rgba(192, 57, 43, 0.1);
    color: var(--tm-danger, #c0392b);
    font-size: 11px;
    font-weight: 600;
}
.amby-card-dialog .amby-q__hint,
.amby-card-dialog .amby-q__note {
    font-size: 12px;
    color: var(--tm-text-3, #6f6e6d);
}
.amby-card-dialog .amby-q__note {
    margin: 0 0 6px var(--amby-q-indent);
}
.amby-card-dialog .amby-q__image {
    margin: 0 0 12px var(--amby-q-indent);
}
.amby-card-dialog .amby-q__options,
.amby-card-dialog .amby-q__text,
.amby-card-dialog .amby-q > .amby-res__row,
.amby-card-dialog .amby-q > .amby-q__texts,
.amby-card-dialog .amby-q > .amby-q__mine {
    margin-left: var(--amby-q-indent);
}
.amby-card-dialog .amby-q__text {
    width: calc(100% - var(--amby-q-indent));
}
.amby-card-dialog .amby-q__options {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-left: 10px;
}
.amby-card-dialog .amby-q__options.has-images {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 190px), 1fr));
}
.amby-card-dialog .amby-q__options.has-images > * {
    min-width: 0;
}
.amby-card-dialog .amby-q__option {
    display: block;
    cursor: pointer;
}

/* Only the native radio / checkbox is hidden (the whole row is its label); the
   text box inside the "Other" row must stay visible. A drawn indicator stands in. */
.amby-card-dialog .amby-q__option input[type="radio"],
.amby-card-dialog .amby-q__option input[type="checkbox"] {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}
.amby-card-dialog .amby-q__option-body {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 11px 14px 11px 44px;
    border: 1.5px solid var(--tm-border, #d8d3c8);
    border-radius: 10px;
    background: var(--tm-white, #fff);
    line-height: 1.4;
    transition: border-color 0.12s, background 0.12s;
    background: var(--tm-real-white);
}
.amby-card-dialog .amby-q__option-body::before {
    content: "";
    position: absolute;
    left: 14px;
    top: 13px;
    box-sizing: border-box;
    width: 18px;
    height: 18px;
    border: 2px solid var(--tm-border-strong, #b0ab9f);
    border-radius: 50%;
    background: var(--tm-white, #fff);
    transition: border-color 0.12s, background 0.12s, box-shadow 0.12s;
}
.amby-card-dialog .amby-q__option input[type="checkbox"] + .amby-q__option-body::before {
    border-radius: 5px;
}
.amby-card-dialog .amby-q__option:hover input:not(:checked) + .amby-q__option-body {
    border-color: var(--tm-accent, #2d5f84);
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.06));
}
.amby-card-dialog .amby-q__option input[type="radio"]:checked + .amby-q__option-body,
.amby-card-dialog .amby-q__option input[type="checkbox"]:checked + .amby-q__option-body {
    border-color: var(--tm-accent, #2d5f84);
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.1));
    font-weight: 600;
}
.amby-card-dialog .amby-q__option input[type="radio"]:checked + .amby-q__option-body::before {
    border-color: var(--tm-accent, #2d5f84);
    background: var(--tm-accent, #2d5f84);
    box-shadow: inset 0 0 0 3px var(--tm-white, #fff);
}
.amby-card-dialog .amby-q__option input[type="checkbox"]:checked + .amby-q__option-body::before {
    border-color: var(--tm-accent, #2d5f84);
    background: var(--tm-accent, #2d5f84)
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-6.5' fill='none' stroke='white' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
        center / 12px no-repeat;
}
.amby-card-dialog .amby-q__option input[type="radio"]:focus-visible + .amby-q__option-body,
.amby-card-dialog .amby-q__option input[type="checkbox"]:focus-visible + .amby-q__option-body {
    outline: 2px solid var(--tm-accent, #2d5f84);
    outline-offset: 2px;
}
.amby-card-dialog .amby-q__img {
    display: block;
    width: 100%;
    max-width: 100%;
    height: auto;
    max-height: 220px;
    object-fit: contain;
    border-radius: 6px;
    cursor: zoom-in;
}
.amby-card-dialog .amby-q__text {
    box-sizing: border-box;
    padding: 10px 12px;
    font: inherit;
    border: 1.5px solid var(--tm-border, #d8d3c8);
    border-radius: 10px;
    background: var(--tm-white, #fff);
    color: inherit;
    resize: vertical;
}
.amby-card-dialog .amby-q__text:focus {
    outline: none;
    border-color: var(--tm-accent, #2d5f84);
}
.amby-card-dialog .amby-q__texts {
    margin: 0 0 0 var(--amby-q-indent);
    padding: 0;
    list-style: none;
}
.amby-card-dialog .amby-q__texts li {
    margin: 6px 0;
    padding: 8px 12px;
    border-radius: 8px;
    background: var(--tm-bg-alt, #f0ede6);
    overflow-wrap: anywhere;
}
.amby-card-dialog .amby-q__mine {
    margin-top: 0;
    margin-bottom: 8px;
    font-size: 13px;
    color: var(--tm-text-2, #5c5750);
}

/* Results: label and figures on one line, a thick bar under them. The leading
   option is drawn in the accent, the rest muted, and your own pick is ticked. */
.amby-card-dialog .amby-res__row {
    margin: 0 0 14px var(--amby-q-indent);
}
.amby-card-dialog .amby-q > .amby-res__row {
    margin-left: var(--amby-q-indent);
}
.amby-card-dialog .amby-res__row:last-child {
    margin-bottom: 0;
}
.amby-card-dialog .amby-res__label {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 6px;
    line-height: 1.4;
}
.amby-card-dialog .amby-res__text {
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
    font-weight: 400;
    font-size: 0.9rem;
    text-rendering: geometricPrecision;
    font-style: italic;
}

.amby-card-dialog .amby-res__row.is-mine .amby-res__text::after {
    content: "\2713";
    margin-left: 8px;
    color: var(--tm-accent, #2d5f84);
    font-weight: 700;
}
.amby-card-dialog .amby-res__label .amby-q__thumb {
    width: 56px;
    flex: 0 0 auto;
    align-self: center;
}
.amby-card-dialog .amby-res__n {
    flex: 0 0 auto;
    margin-left: auto;
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    white-space: nowrap;
}
.amby-card-dialog .amby-res__n b {
    font-size: 14px;
    font-weight: 700;
}
.amby-card-dialog .amby-res__n small {
    min-width: 18px;
    text-align: right;
    font-size: 12px;
    color: var(--tm-text-3, #6f6e6d);
}
.amby-card-dialog .amby-res__track {
    height: 10px;
    border-radius: 5px;
    background: var(--tm-bg-alt, #ece8df);
    overflow: hidden;
}
.amby-card-dialog .amby-res__track span {
    display: block;
    height: 100%;
    border-radius: 5px;
    background: var(--tm-text-3, #9a968c);
    opacity: 0.55;
}
.amby-card-dialog .amby-res__row.is-top .amby-res__track span {
    background: var(--tm-accent, #2d5f84);
    opacity: 1;
}
.amby-card-dialog .amby-res__row.is-top .amby-res__text {
    font-weight: 600;
}
.amby-card-dialog .amby-res__people {
    margin-top: 4px;
    font-size: 12px;
    color: var(--tm-text-3, #6f6e6d);
    overflow-wrap: anywhere;
}

/* ── Launchers ──────────────────────────────────────────────────────────────── */

/* Space post: a labelled pill at the end of the formatting toolbar. */
.space-post-modal .amby-card-launch.amby-card-launch--inline {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 26px;
    margin-left: 10px;
    padding: 0 10px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 999px;
    background: var(--tm-surface, #fff);
    color: var(--tm-text-2, #5c5750);
    font: inherit;
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
}
.space-post-modal .amby-card-launch.amby-card-launch--inline:hover {
    background: var(--tm-bg-alt, #f0ede6);
}
.space-post-modal .amby-card-chip {
    margin: 6px 0;
    padding: 8px 10px;
    border: 1px dashed var(--tm-border-strong, #b0ab9f);
    border-radius: 8px;
    background: var(--tm-bg-alt, #f0ede6);
    font-size: 13px;
}
.space-post-modal .amby-card-chip[hidden] {
    display: none;
}
.space-post-modal .amby-card-chip .amby-card-chip__bar {
    display: flex;
    align-items: center;
    gap: 8px;
}
.space-post-modal .amby-card-chip .amby-card-chip__text {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.space-post-modal .amby-card-chip .amby-card-chip__hint {
    font-size: 11px;
    color: var(--tm-text-3, #6f6e6d);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.space-post-modal .amby-card-chip .amby-card-chip__remove {
    border: 0;
    background: none;
    color: inherit;
    cursor: pointer;
    padding: 2px 6px;
}
.space-post-modal .amby-card-chip .amby-card-chip__preview {
    margin-top: 8px;
    max-width: 440px;
    pointer-events: none;
}

/* ── Menu + lightbox (body-appended: literal fallbacks, own dark block) ─────── */
.amby-card-menu {
    position: fixed;
    z-index: 10030;
    min-width: 260px;
    max-width: calc(100vw - 16px);
    padding: 6px;
    border: 1px solid #d8d3c8;
    border-radius: 12px;
    background: #fff;
    color: #1f1e1d;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
    font-family: var(--tm-font-ui, system-ui, sans-serif);
}
.amby-card-menu .amby-card-menu__item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    border: 0;
    border-radius: 8px;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.amby-card-menu .amby-card-menu__item:hover {
    background: #f0ede6;
}
.amby-card-menu .amby-card-menu__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 7px;
    background: #6264a7;
    color: #fff;
    font-size: 13px;
}
.amby-card-menu .amby-card-menu__text {
    display: flex;
    flex-direction: column;
}
.amby-card-menu .amby-card-menu__label {
    font-size: 14px;
    font-weight: 600;
}
.amby-card-menu .amby-card-menu__hint {
    font-size: 12px;
    color: #6f6e6d;
}
.amby-card-menu .amby-card-menu__divider {
    height: 1px;
    margin: 5px 8px;
    background: #e6e1d6;
}
.amby-card-lightbox {
    position: fixed;
    inset: 0;
    z-index: 10040;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(0, 0, 0, 0.82);
    cursor: zoom-out;
}
.amby-card-lightbox .amby-card-lightbox__img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: 6px;
}
.amby-card-lightbox .amby-card-lightbox__close {
    position: absolute;
    top: 14px;
    right: 14px;
    width: 36px;
    height: 36px;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.18);
    color: #fff;
    font-size: 16px;
    cursor: pointer;
}
body.dark-theme .amby-card-menu {
    border-color: #3a3a3a;
    background: #242424;
    color: #e8e6e3;
}
body.dark-theme .amby-card-menu .amby-card-menu__item:hover {
    background: #2e2e2e;
}
body.dark-theme .amby-card-menu .amby-card-menu__hint {
    color: #9a9a9a;
}
body.dark-theme .amby-card-menu .amby-card-menu__divider {
    background: #3a3a3a;
}
@media (max-width: 600px) {
    .amby-card-dialog .amby-card-dialog__body {
        padding: 12px 14px;
    }
    .teams-msg__bubble .amby-card {
        width: 100%;
    }
    .amby-card--poll .amby-poll__options.has-images {
        grid-template-columns: repeat(2, 1fr);
    }
    .amby-card--poll .amby-poll__option,
    .amby-chart .amby-chart__row {
        min-width: 0;
    }
}

/* "Other": the option that carries its own text box. */
.amby-card-dialog .amby-q__option--other .amby-q__option-body {
    flex-direction: row;
    align-items: center;
    gap: 12px;
}
.amby-card-dialog .amby-q__other {
    flex: 1 1 auto;
    min-width: 0;
    padding: 6px 10px;
    font: inherit;
    font-size: 14px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 6px;
    background: var(--tm-white, #fff);
    color: inherit;
}

/* The status line at the top of the results / answer dialogs. */
.amby-card-dialog .amby-card__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-bottom: 6px;
    font-size: 12px;
    color: var(--tm-text-3, #6f6e6d);
}

/* In an image grid the "Other" row takes the whole row instead of being squeezed
   into one picture-sized cell. */
.amby-card-dialog .amby-q__options.has-images .amby-q__option--other {
    grid-column: 1 / -1;
}

/* Hover: a text-only answer option lights up under the pointer (an option that
   carries a picture is left alone). A chosen option keeps its chosen look. */
.amby-card-dialog .amby-q__option:not(.has-image) .amby-q__option-body {
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}
.amby-card-dialog .amby-q__option:not(.has-image):hover input:not(:checked) + .amby-q__option-body {
    background: var(--tm-bg-alt, #f0ede6);
    border-color: var(--tm-border-strong, #b0ab9f);
}
.amby-card--poll .amby-poll__option:not(.has-image) {
    transition: background-color 0.15s ease, border-color 0.15s ease;
}
.amby-card--poll .amby-poll__option:not(.has-image):not(:disabled):not(.is-chosen):hover {
    background: var(--tm-bg-alt, #f0ede6);
    border-color: var(--tm-border-strong, #b0ab9f);
}

/* The viewer's own typed answer, in a results view. */
.amby-card-dialog .amby-q__mine {
    display: flex;
    align-items: baseline;
    gap: 6px;
    margin: 8px 0 0;
    padding: 8px 12px;
    border-radius: 8px;
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.1));
    font-size: 14px;
    overflow-wrap: anywhere;
}
.amby-card-dialog .amby-q__mine span {
    font-weight: 600;
}

/* ============================================================================
 * Amby Teams — the requester's resolution card (above the composer)
 *
 * Its own stylesheet to match its own module. This is the requester's half of
 * the two-step resolution protocol: confirm / decline, then an optional rating.
 *
 * It sits directly above the composer rather than in the header, because it is
 * a QUESTION, not a status. The member's countdown pill is header furniture —
 * something you glance at — while this stops and asks you to decide, so it
 * belongs next to the thing you answer with. In the header it also had to share
 * a row with the video and calendar icons, which is how a two-button decision
 * ended up looking like chrome.
 *
 * Every selector is scoped to `.teams-case-resolve` per CLAUDE.md rule 2.
 * ==========================================================================*/

.teams-panel .teams-case-resolve {
    margin: 0 0 8px;
}

.teams-panel .teams-case-resolve[hidden] {
    display: none;
}

.teams-panel .teams-case-resolve__card {
    position: relative;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px 16px;
    padding: 12px 14px;
    border: 1px solid var(--tm-border, #cfe0d4);
    border-left: 3px solid var(--sp-accent, #2f6f4f);
    border-radius: 10px;
    background: var(--tm-surface, #fff);
    color: var(--tm-msg-text, #1f262c);
    box-shadow: 0 1px 3px rgba(31, 38, 44, 0.06);
}

.teams-panel .teams-case-resolve__text {
    flex: 1 1 240px;
    min-width: 0;
}

.teams-panel .teams-case-resolve__question {
    margin: 0;
    font-size: 0.94rem;
    font-weight: 600;
}

/* The team's note is the substance of the claim being made, so it reads as
   quoted material rather than as another line of UI copy. */
.teams-panel .teams-case-resolve__note {
    margin: 4px 0 0;
    padding-left: 9px;
    border-left: 2px solid var(--tm-border, #e3e0d8);
    color: var(--tm-msg-text, #1f262c);
    font-size: 0.86rem;
    line-height: 1.45;
}

/* Silence auto-confirms, so the deadline is stated — quietly. It is a
   consequence to be aware of, not the thing being asked. */
.teams-panel .teams-case-resolve__lapse {
    margin: 5px 0 0;
    color: var(--tm-text-1, #6b6b6b);
    font-size: 0.78rem;
    line-height: 1.4;
}

.teams-panel .teams-case-resolve__actions {
    flex: 0 0 auto;
    display: flex;
    gap: 8px;
}

.teams-panel .teams-case-resolve__yes,
.teams-panel .teams-case-resolve__no {
    padding: 7px 14px;
    border: 1px solid var(--tm-border, #d9d5cc);
    border-radius: 7px;
    font: inherit;
    font-size: 0.85rem;
    cursor: pointer;
    white-space: nowrap;
}

.teams-panel .teams-case-resolve__yes {
    background: var(--sp-accent, #2f6f4f);
    border-color: var(--sp-accent, #2f6f4f);
    color: #fff;
    font-weight: 600;
}

.teams-panel .teams-case-resolve__no {
    background: var(--tm-surface, #fff);
    color: var(--tm-msg-text, #1f262c);
}

/* Declining must not read as the discouraged option — a requester who still
   needs help saying so is the single most valuable signal this card collects. */
.teams-panel .teams-case-resolve__no:hover {
    border-color: var(--sp-accent, #2f6f4f);
}

.teams-panel .teams-case-resolve__yes:disabled,
.teams-panel .teams-case-resolve__no:disabled,
.teams-panel .teams-case-resolve__star:disabled {
    opacity: 0.55;
    cursor: default;
}

/* A failed action is shown IN the card, never only in the console. A dead
   button that says nothing is indistinguishable from a frozen page, and the
   requester's remaining option — waiting — silently auto-confirms the case they
   were trying to decline. */
.teams-panel .teams-case-resolve__error {
    flex: 1 1 100%;
    margin: 0;
    color: var(--tm-danger, #b42318);
    font-size: 0.82rem;
}

.teams-panel .teams-case-resolve__error[hidden] {
    display: none;
}

/* ── Rating ───────────────────────────────────────────────────────────────── */

/* Stars are rendered 5→1 in the DOM and flipped back visually, so CSS can fill
   "this star and every lower one" on hover — there is no previous-sibling
   selector, only `~`. */
.teams-panel .teams-case-resolve__stars {
    flex: 0 0 auto;
    display: flex;
    flex-direction: row-reverse;
    justify-content: flex-end;
    gap: 2px;
}

.teams-panel .teams-case-resolve__star {
    padding: 0 3px;
    border: none;
    background: none;
    font-size: 1.45rem;
    line-height: 1;
    color: var(--tm-border, #d9d5cc);
    cursor: pointer;
    transition: color 90ms ease;
}

.teams-panel .teams-case-resolve__stars:hover .teams-case-resolve__star:hover,
.teams-panel .teams-case-resolve__stars:hover .teams-case-resolve__star:hover ~ .teams-case-resolve__star,
.teams-panel .teams-case-resolve__star[data-filled="true"] {
    color: var(--sp-star, #e0a80d);
}

/* The comment and its Send sit on one row. The button is not optional chrome:
   saving on blur alone gave no signal that anything had happened, so people
   could not tell their note from a discarded draft. */
.teams-panel .teams-case-resolve__comment-row {
    flex: 1 1 100%;
    display: flex;
    align-items: flex-end;
    gap: 8px;
}

.teams-panel .teams-case-resolve__comment {
    flex: 1 1 auto;
    box-sizing: border-box;
    padding: 7px 9px;
    border: 1px solid var(--tm-border, #d9d5cc);
    border-radius: 7px;
    font: inherit;
    font-size: 0.85rem;
    resize: vertical;
    background: var(--tm-white, #fff);
    color: var(--tm-msg-text, #1f262c);
}

.teams-panel .teams-case-resolve__send {
    flex: 0 0 auto;
    padding: 7px 14px;
    border: 1px solid var(--sp-accent, #2f6f4f);
    border-radius: 7px;
    background: var(--sp-accent, #2f6f4f);
    color: #fff;
    font: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
}

.teams-panel .teams-case-resolve__send:disabled {
    opacity: 0.55;
    cursor: default;
}

.teams-panel .teams-case-resolve__done {
    margin: 0;
    color: var(--tm-text-1, #6b6b6b);
    font-size: 0.86rem;
}

/* The rating is optional, so it must be dismissible without answering. */
.teams-panel .teams-case-resolve__dismiss {
    position: absolute;
    top: 6px;
    right: 8px;
    border: none;
    background: none;
    color: var(--tm-text-1, #6b6b6b);
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
}

@media (max-width: 640px) {
    .teams-panel .teams-case-resolve__actions {
        flex: 1 1 100%;
    }

    .teams-panel .teams-case-resolve__yes,
    .teams-panel .teams-case-resolve__no {
        flex: 1 1 auto;
    }
}

/* "An AI thinks this is finished" — on the card asking a person to agree their
   problem is solved. Deliberately given weight rather than a footnote: the
   difference between a colleague saying it is fixed and a machine saying so
   should change how carefully the answer above is read. */
.teams-panel .teams-case-resolve__by-ai {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 4px 0 0;
    font-size: 0.82rem;
    color: var(--teams-accent, #3f51b5);
}

/* ═══════════════════════════════════════════════════════════════════════════
 * Support Desk — "resolved" markers in the transcript
 * (teams-case-resolution-marker.js)
 *
 * A chip under the requester's last message on a resolved case, which opens the
 * resolution details inline. Desk members only.
 *
 * Its own opaque surface, not a tint: desk rooms often run a photo background
 * (see the case panel's styling note), and a translucent chip over a mountain
 * range is unreadable. Built on `--tm-*` tokens, which reach `.teams-panel`;
 * `--sp-*` tokens do not.
 * ═══════════════════════════════════════════════════════════════════════════ */

.teams-panel .teams-case-marker {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    margin-top: 4px;
    max-width: min(420px, 100%);
}

.teams-panel .teams-msg--mine .teams-case-marker {
    align-items: flex-end;
    margin-left: auto;
}

.teams-panel .teams-case-marker__chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 999px;
    background: var(--tm-surface, #fff);
    color: var(--tm-text-1, #6f6e6d);
    font: inherit;
    font-size: 0.76rem;
    line-height: 1.4;
    cursor: pointer;
    box-shadow: var(--tm-shadow-sm, 0 1px 2px rgba(31, 38, 44, 0.08));
}

.teams-panel .teams-case-marker__chip:hover,
.teams-panel .teams-case-marker__chip:focus-visible,
.teams-panel .teams-case-marker__chip[aria-expanded="true"] {
    border-color: var(--tm-accent, #3b6fd8);
    color: var(--tm-msg-text, #1f1e1d);
}

.teams-panel .teams-case-marker[data-state="resolved"] .teams-case-marker__chip .fas {
    color: var(--tm-success, #2e8b57);
}

.teams-panel .teams-case-marker[data-state="pending_confirmation"] .teams-case-marker__chip .fas {
    color: var(--tm-accent, #3b6fd8);
}

.teams-panel .teams-case-marker__ref {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.72rem;
    color: var(--tm-text-3, #8a8883);
}

.teams-panel .teams-case-marker__details {
    padding: 8px 12px;
    border: 1px solid var(--tm-border, #d8d3c8);
    border-radius: 10px;
    background: var(--tm-surface, #fff);
    color: var(--tm-msg-text, #1f1e1d);
    font-size: 0.8rem;
    box-shadow: var(--tm-shadow-sm, 0 1px 2px rgba(31, 38, 44, 0.08));
}

.teams-panel .teams-case-marker__details[hidden] {
    display: none;
}

.teams-panel .teams-case-marker__meta {
    color: var(--tm-text-1, #6f6e6d);
    font-size: 0.76rem;
    line-height: 1.5;
}

.teams-panel .teams-case-marker__score {
    color: #e0a526;
    letter-spacing: 1px;
}

.teams-panel .teams-case-marker__score-dim {
    color: var(--tm-border, #d8d3c8);
}

/* The note is the desk's own words — shown as written, line breaks kept. */
.teams-panel .teams-case-marker__note {
    margin-top: 6px;
    padding-left: 8px;
    border-left: 3px solid var(--tm-success, #2e8b57);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.teams-panel .teams-case-marker__note--empty {
    border-left-color: var(--tm-border, #d8d3c8);
    color: var(--tm-text-3, #8a8883);
    font-style: italic;
}

/* ============================================================================
 * Amby Teams — Support Desk requests ("cases as threads" mode)
 *
 * The requester's side of a desk chat created with the mode on
 * (js/teams-desk-requests.js, teams-desk-request-form.js): the composer is taken
 * away, and the desk's WELCOME CARD sits first in the chat — its name, logo and
 * description, intro, tutorial video, request types and the form. A request opens
 * in the thread drawer, which lends the composer to it.
 *
 * Every selector is scoped to `.teams-desk-card` / `.teams-desk-requests__*`
 * (CLAUDE.md rule 2). Colours are --tm-* tokens only, so the card follows dark mode.
 * ==========================================================================*/

/* The composer is taken away from the transcript. While a thread drawer has it on
   loan the slot sits OUTSIDE this section, so the rule no longer matches and the
   drawer shows it; the "replying in a thread" bar that would take its place here
   is redundant next to the desk's own card. */
.teams-panel .teams-conversation--desk-readonly [data-composer-slot],
.teams-panel .teams-conversation--desk-readonly .teams-conversation__composer-away {
    display: none;
}

/* ── The welcome card ────────────────────────────────────────────────────── */
.teams-panel .teams-desk-card {
    position: absolute;
    z-index: 2;
    flex: none;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    /* Never more than the chat can spare: the card scrolls inside itself, so the transcript
       under it (the desk's announcements) always keeps some room. */
    max-height: 100%;
    margin: 10px 12px 0;
    /* Clear of the thread drawers, which sit over the right of the chat. */
    /* margin-right: calc(12px + var(--tm-thread-dock-width, 0px)); */
    align-self: anchor-center;
    overflow: hidden;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r-lg, 12px);
    background: color-mix(in srgb, var(--tm-surface) 50%, transparent);
    -webkit-backdrop-filter: blur(14px) saturate(1.2);
    backdrop-filter: blur(14px) saturate(1.2);
    box-shadow: var(--tm-shadow-md);
    color: var(--tm-text-2);
    font-family: var(--tm-font-ui);
    container-type: inline-size;
    container-name: desk-card;
    width: 880px;
}
@media (max-width: 768px) {
    .teams-panel .teams-desk-card { margin-right: 12px; }
}
.teams-panel .teams-desk-card__status {
    margin: 0;
    padding: 14px 16px;
    font-size: 13px;
    color: var(--tm-text-3);
}

.teams-panel .teams-desk-card__welcome {
    flex: none;
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 14px 16px;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.teams-panel .teams-desk-card__logo {
    flex: none;
    width: 44px;
    height: 44px;
}
.teams-panel .teams-desk-card__who {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1 1 auto;
}
.teams-panel .teams-desk-card__name {
    color: var(--tm-msg-text);
    font: 700 18px/1.25 var(--tm-font-display);
}
.teams-panel .teams-desk-card__about {
    color: var(--tm-text-1);
    font-size: 13px;
    line-height: 1.4;
}
.teams-panel .teams-desk-card__chevron {
    flex: none;
    color: var(--tm-text-1);
    transition: transform var(--tm-t);
}
.teams-panel .teams-desk-card.is-collapsed .teams-desk-card__chevron {
    transform: rotate(180deg);
}

.teams-panel .teams-desk-card__content {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 0 16px 16px;
    border-top: 1px solid var(--tm-border);
}
.teams-panel .teams-desk-card__content[hidden] {
    display: none;
}
/* Narrow: the guide (intro, video) over the request. Wide: side by side, so the card stays short. */
.teams-panel .teams-desk-card__content {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    column-gap: 24px;
    align-items: start;
}
@container desk-card (min-width: 820px) {
    .teams-panel .teams-desk-card__content { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); }
}
.teams-panel .teams-desk-card__intro {
    margin: 14px 0 0;
    color: var(--tm-text-2);
    font-size: 14px;
    line-height: 1.5;
    overflow-wrap: anywhere;
}

.teams-panel .teams-desk-card__intro ul {
    margin-left: 15px;
}

.teams-panel .teams-desk-card__video {
    position: relative;
    margin-top: 14px;
    width: min(100%, 420px);
    aspect-ratio: 16 / 9;
    border-radius: var(--tm-r);
    overflow: hidden;
    background: #000;
}
.teams-panel .teams-desk-card__video iframe,
.teams-panel .teams-desk-card__video video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}
.teams-panel .teams-desk-card__heading {
    margin: 18px 0 10px;
    color: var(--tm-msg-text);
    font: 600 15px/1.3 var(--tm-font-display);
    text-align: center;
}

/* Request types: the choice IS the first step of the form. */
.teams-panel .teams-desk-card__types {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 8px;
}
.teams-panel .teams-desk-card__type {
    padding: 10px 12px;
    border: 1px solid var(--tm-border-strong);
    border-radius: var(--tm-r);
    background: var(--tm-white);
    color: var(--tm-text-1);
    font: 600 13px/1.3 var(--tm-font-ui);
    cursor: pointer;
    overflow-wrap: anywhere;
}
.teams-panel .teams-desk-card__type:hover {
    border-color: var(--tm-accent);
    color: var(--tm-accent);
}
.teams-panel .teams-desk-card__type.is-chosen {
    border-color: var(--tm-accent);
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}

.teams-panel .teams-desk-card__form {
    margin-top: 14px;
}
.teams-panel .teams-desk-card__form[hidden] {
    display: none;
}
.teams-panel .teams-desk-card__field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-bottom: 12px;
}
.teams-panel .teams-desk-card__field label {
    font-size: 13px;
    font-weight: 600;
    color: var(--tm-text-2);
}
.teams-panel .teams-desk-card__field input,
.teams-panel .teams-desk-card__field textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 8px 10px;
    border: 1px solid var(--tm-border-strong);
    border-radius: var(--tm-r);
    background: var(--tm-white);
    color: var(--tm-text-1);
    font-family: var(--tm-font-ui);
    font-size: 14px;
}
.teams-panel .teams-desk-card__help {
    margin: 0;
    font-size: 12px;
    color: var(--tm-text-3);
}
.teams-panel .teams-desk-card__error {
    margin: 0 0 10px;
    font-size: 13px;
    color: var(--tm-danger, #b3261e);
}
.teams-panel .teams-desk-card__error[hidden] {
    display: none;
}
.teams-panel .teams-desk-card__actions {
    display: flex;
    justify-content: flex-end;
}

/* ── The desk team's block: welcome card + the last-24-hours gallery ──────── */
.teams-panel .teams-desk-stack {
    position: absolute;
    z-index: 2;
    top: 0;
    left: 0;
    /* Clear of the thread drawers, which dock over the right of the chat. */
    right: var(--tm-thread-dock-width, 0px);
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: 880px;
    max-width: calc(100% - 24px - var(--tm-thread-dock-width, 0px));
    margin: 10px auto 0;
}
/* The card is a size container (inline-size): in a column of flex items it needs to be
   stretched, or it shrinks to nothing. */
.teams-panel .teams-desk-stack > .teams-desk-card {
    position: static;
    align-self: stretch;
    width: auto;
    margin: 0;
}

.teams-panel .teams-desk-pulse {
    --pulse-blue: #3b82c4;
    --pulse-green: #2f9e66;
    --pulse-orange: #e08a2e;
    --pulse-purple: #8b5cc4;
    box-sizing: border-box;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r-lg, 12px);
    background: color-mix(in srgb, var(--tm-surface) 62%, transparent);
    -webkit-backdrop-filter: blur(14px) saturate(1.2);
    backdrop-filter: blur(14px) saturate(1.2);
    box-shadow: var(--tm-shadow-md);
    color: var(--tm-text-2);
    font-family: var(--tm-font-ui);
    padding: 30px 18px 18px;
    min-height: 300px;
    align-content: space-between;
}
.teams-panel .teams-desk-pulse[hidden] { display: none; }
.teams-panel .teams-desk-pulse__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 30px;
}
.teams-panel .teams-desk-pulse__title {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--tm-text-1);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.teams-panel .teams-desk-pulse__head { flex-wrap: wrap; }
/* Named report tabs (no rotation). Scroll sideways when they do not fit. */
.teams-panel .teams-desk-pulse__tabs {
    display: flex;
    gap: 4px;
    min-width: 0;
    max-width: 100%;
    padding: 3px;
    overflow-x: auto;
    scrollbar-width: none;
    border-radius: 999px;
    background: color-mix(in srgb, var(--tm-border) 45%, transparent);
}
.teams-panel .teams-desk-pulse__tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    padding: 6px 12px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--tm-text-1);
    font: 600 12px/1.2 var(--tm-font-ui);
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--tm-t), color var(--tm-t);
}
.teams-panel .teams-desk-pulse__tab i { font-size: 11px; opacity: .75; }
.teams-panel .teams-desk-pulse__tab:hover { color: var(--tm-msg-text); }
.teams-panel .teams-desk-pulse__tab.is-current {
    background: var(--tm-real-white, #fff);
    color: var(--pulse-blue);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .12);
}
.teams-panel .teams-desk-pulse__tab:focus-visible { outline: 2px solid var(--pulse-blue); outline-offset: 1px; }
.teams-panel .teams-desk-pulse__slide {
    min-height: 168px;
    animation: teams-desk-pulse-in 0.4s ease;
}
@keyframes teams-desk-pulse-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
    .teams-panel .teams-desk-pulse__slide { animation: none; }
}

/* KPI cards, after the admin dashboard's: tinted icon, caption, big number, note. */
.teams-panel .teams-desk-pulse__kpis {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 14px;
}
.teams-panel .teams-desk-pulse__kpi {
    --tone: var(--pulse-blue);
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 16px 16px 16px 14px;
    border-radius: 10px;
    border-left: 4px solid var(--tone);
    background: var(--tm-surface);
    box-shadow: var(--tm-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.08));
}
.teams-panel .teams-desk-pulse__kpi--green { --tone: var(--pulse-green); }
.teams-panel .teams-desk-pulse__kpi--orange { --tone: var(--pulse-orange); }
.teams-panel .teams-desk-pulse__kpi--purple { --tone: var(--pulse-purple); }
.teams-panel .teams-desk-pulse__kpi-icon {
    flex: none;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: 10px;
    background: color-mix(in srgb, var(--tone) 14%, transparent);
    color: var(--tone);
    font-size: 20px;
}
.teams-panel .teams-desk-pulse__kpi-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.teams-panel .teams-desk-pulse__label { color: var(--tm-text-2); font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; }
.teams-panel .teams-desk-pulse__value { color: var(--tm-msg-text); font: 700 34px/1.1 var(--tm-font-display); }
.teams-panel .teams-desk-pulse__note { color: var(--tm-text-1); font-size: 12.5px; }
.teams-panel .teams-desk-pulse__progress { height: 6px; border-radius: 3px; background: color-mix(in srgb, var(--tone) 16%, transparent); overflow: hidden; margin: 4px 0 2px; }
.teams-panel .teams-desk-pulse__progress i { display: block; height: 100%; background: var(--tone); border-radius: 3px; }

/* Requests per hour */
.teams-panel .teams-desk-pulse__chart { display: flex; flex-direction: column; gap: 8px; }
.teams-panel .teams-desk-pulse__bars {
    display: flex;
    align-items: stretch;
    gap: 4px;
    height: 132px;
    padding: 4px 4px 0;
    border-radius: 10px;
    background: var(--tm-surface);
    box-shadow: var(--tm-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.08));
}
.teams-panel .teams-desk-pulse__bar-col {
    flex: 1 1 0;
    min-width: 0;
    display: grid;
    grid-template-rows: 14px 1fr 16px;
    justify-items: center;
}
.teams-panel .teams-desk-pulse__bar-value { color: var(--tm-text-1); font-size: 10.5px; line-height: 14px; }
.teams-panel .teams-desk-pulse__bar {
    align-self: end;
    width: 100%;
    max-width: 22px;
    border-radius: 4px 4px 0 0;
    background: color-mix(in srgb, var(--pulse-blue) 55%, transparent);
}
.teams-panel .teams-desk-pulse__bar.is-peak { background: var(--pulse-blue); }
.teams-panel .teams-desk-pulse__bar-label { color: var(--tm-text-3); font-size: 10px; line-height: 16px; white-space: nowrap; }

/* Waiting longest / top handlers */
.teams-panel .teams-desk-pulse__list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.teams-panel .teams-desk-pulse__list li {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    border-radius: 10px;
    background: var(--tm-surface);
    box-shadow: var(--tm-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.08));
    font-size: 14px;
}
.teams-panel .teams-desk-pulse__avatar {
    flex: none;
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--pulse-blue) 16%, transparent);
    color: var(--pulse-blue);
    font-size: 12px;
    font-weight: 700;
}
.teams-panel .teams-desk-pulse__who { flex: 1 1 0; min-width: 0; color: var(--tm-msg-text); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.teams-panel .teams-desk-pulse__pill {
    flex: none;
    padding: 3px 10px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--pulse-orange) 16%, transparent);
    color: var(--pulse-orange);
    font-size: 12px;
    font-weight: 600;
}
.teams-panel .teams-desk-pulse__pill--in_progress { background: color-mix(in srgb, var(--pulse-blue) 16%, transparent); color: var(--pulse-blue); }
.teams-panel .teams-desk-pulse__pill--awaiting_requestor { background: color-mix(in srgb, var(--pulse-purple) 16%, transparent); color: var(--pulse-purple); }
.teams-panel .teams-desk-pulse__age { flex: none; min-width: 56px; text-align: right; color: var(--tm-msg-text); font: 700 16px/1 var(--tm-font-display); }
.teams-panel .teams-desk-pulse__rank { flex: none; width: 18px; color: var(--tm-text-3); font-weight: 700; text-align: center; }
.teams-panel .teams-desk-pulse__meter { flex: 1 1 0; height: 8px; border-radius: 4px; background: color-mix(in srgb, var(--pulse-blue) 14%, transparent); overflow: hidden; }
.teams-panel .teams-desk-pulse__meter i { display: block; height: 100%; background: var(--pulse-blue); border-radius: 4px; }

/* The requester's confirm / rate card inside a request's thread drawer. The stack's
   right padding exists to clear the dock in the chat page; the drawer is the dock. */
.teams-panel .teams-thread-drawer__resolution .teams-case-resolve-stack { padding-right: 0; }
.teams-panel .teams-thread-drawer__resolution:has(> .teams-case-resolve-stack:not([hidden])) { padding: 8px 10px 0; }

/* `[hidden]` loses to the explicit display above: a question for another request type
   must really disappear. */
.teams-panel .teams-desk-card__field[hidden] { display: none; }

/* Files and pasted screenshots on the request form (teams-desk-form-attachments.js). */
.teams-panel .teams-desk-card__attach { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 4px 0 8px; }
.teams-panel .teams-desk-card__files { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.teams-panel .teams-desk-card__attach[hidden] { display: none; }

/* ============================================================================
 * Amby Teams — the request form builder inside the Support Desk settings card
 * (js/teams-desk-form-builder.js)
 *
 * Every selector is scoped to `.teams-desk` (CLAUDE.md rule 2). The card already
 * styles `.teams-desk__field` and its label row; this adds what the builder needs.
 * ==========================================================================*/

.teams-desk .teams-desk__form {
    grid-column: 1 / -1;
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--sp-border, #e3e0d8);
}
.teams-desk .teams-desk__form[hidden] {
    display: none;
}
.teams-desk .teams-desk__subtitle {
    margin: 0;
    font-size: 0.95rem;
    font-weight: 600;
}
.teams-desk .teams-desk__subtext {
    margin: -8px 0 0;
    font-size: 0.85rem;
    color: var(--sp-text-muted, #6b6b6b);
}

.teams-desk .teams-desk-form {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.teams-desk .teams-desk-form input[type="text"],
.teams-desk .teams-desk-form input[type="url"],
.teams-desk .teams-desk-form input[type="number"],
.teams-desk .teams-desk-form select,
.teams-desk .teams-desk-form textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 7px 9px;
    border: 1px solid var(--sp-border, #e3e0d8);
    border-radius: 6px;
    background: var(--sp-surface, #fff);
    color: inherit;
    font: inherit;
}
.teams-desk .teams-desk-form input.is-invalid {
    border-color: #b3261e;
}
.teams-desk .teams-desk-form__error {
    margin: 4px 0 0;
    font-size: 0.82rem;
    color: #b3261e;
}
.teams-desk .teams-desk-form__error[hidden] {
    display: none;
}

.teams-desk .teams-desk-form__editor {
    border: 1px solid var(--sp-border, #e3e0d8);
    border-radius: 6px;
    background: var(--sp-surface, #fff);
    min-height: 120px;
}

.teams-desk .teams-desk-form__list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 8px;
}
.teams-desk .teams-desk-form__row {
    display: flex;
    align-items: center;
    gap: 6px;
}
.teams-desk .teams-desk-form__icon {
    flex: none;
    width: 30px;
    height: 30px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--sp-text-muted, #6b6b6b);
    cursor: pointer;
}
.teams-desk .teams-desk-form__icon:hover:not(:disabled) {
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.09));
    color: var(--tm-accent, #2d5f84);
}
.teams-desk .teams-desk-form__icon:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.teams-desk .teams-desk-form__field {
    padding: 10px;
    border: 1px solid var(--sp-border, #e3e0d8);
    border-radius: 8px;
    background: var(--sp-surface, #fff);
}
.teams-desk .teams-desk-form__field-head {
    display: flex;
    align-items: center;
    gap: 6px;
}
.teams-desk .teams-desk-form__tools {
    display: inline-flex;
    flex: none;
}
.teams-desk .teams-desk-form__field-body {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 10px;
    margin-top: 10px;
}
.teams-desk .teams-desk-form__cell {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}
.teams-desk .teams-desk-form__cell--check {
    flex-direction: row;
    align-items: center;
    gap: 8px;
}
.teams-desk .teams-desk-form__cell--check label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* ── One block per request type ─────────────────────────────────────────── */
.teams-desk .teams-desk-form__groups { display: flex; flex-direction: column; gap: 14px; }
.teams-desk .teams-desk-form__group {
    border: 1px solid var(--sp-border, #e3e0d8);
    border-left: 4px solid var(--tm-accent, #3b6ea5);
    border-radius: 10px;
    background: color-mix(in srgb, var(--sp-surface, #fff) 60%, transparent);
    overflow: hidden;
    box-shadow: var(--tm-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.08));
}
.teams-desk .teams-desk-form__group--common { border-left-color: var(--tm-text-3, #8a877f); }
.teams-desk .teams-desk-form__group-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    background: color-mix(in srgb, var(--tm-accent, #3b6ea5) 8%, transparent);
    border-bottom: 1px solid var(--sp-border, #e3e0d8);
}
.teams-desk .teams-desk-form__group--common .teams-desk-form__group-head {
    background: color-mix(in srgb, var(--tm-text-3, #8a877f) 10%, transparent);
}
.teams-desk .teams-desk-form__group-title { font-weight: 600; font-size: 14px; }
.teams-desk .teams-desk-form__type-name { flex: 1 1 auto; font-weight: 600; }
.teams-desk .teams-desk-form__group-body { display: flex; flex-direction: column; gap: 10px; padding: 12px; }
.teams-desk .teams-desk-form__empty { margin: 0; color: var(--tm-text-3); font-size: 13px; }

/* ── Introduction and tutorial video, side by side ───────────────────────── */
.teams-desk .teams-desk-form__top {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px 24px;
    align-items: start;
    margin-bottom: 14px;
}
.teams-desk .teams-desk-form__top [data-video-preview] video { width: 100%; max-height: 220px; border-radius: 8px; background: #000; }
.teams-desk .teams-desk-form__top [data-video-remove] { align-self: flex-start; width: auto; }
.teams-desk .teams-desk-form__top [data-video-progress]:empty { display: none; }
@container teams-desk (max-width: 760px) {
    .teams-desk .teams-desk-form__top { grid-template-columns: minmax(0, 1fr); }
}

/* Two different adders, two different looks: a TYPE is a whole block (blue, solid), a FIELD is a row
   inside a block (neutral, dashed). The blocks they add carry the same colours: types blue, the
   questions-for-every-request block grey. */
.teams-desk .teams-desk-form__add { width: 100%; justify-content: center; }
.teams-desk .teams-desk-form__add--type {
    border: 1px solid var(--tm-accent, #2d5f84);
    color: var(--tm-accent, #2d5f84);
    background: var(--tm-accent-subtle, rgba(45, 95, 132, 0.1));
    font-weight: 600;
}
.teams-desk .teams-desk-form__add--type:hover:not(:disabled) { color: #fff; background: var(--tm-accent, #2d5f84); }
.teams-desk .teams-desk-form__add--field {
    border: 1px dashed var(--tm-border-strong, #bdb7ab);
    color: var(--tm-text-2, #5c5750);
    background: transparent;
}
.teams-desk .teams-desk-form__add--field:hover:not(:disabled) { border-style: solid; color: var(--tm-text-1); background: var(--tm-bg-alt, rgba(0, 0, 0, 0.04)); }

/* Shared action geometry for the chat header and the Spaces header chassis. */
/* ── Shared Teams / Spaces header controls ─────────────────────────────────
   Chats and Spaces render the same header chassis. Keep every action button
   in this one rule so switching between the two views never changes the
   control geometry, surface, border, or interaction treatment. */

.teams-panel .teams-conversation__header-actions > button:not(.teams-conversation__video):not(.teams-conversation__video-select):not(.teams-conversation__more-actions),
.teams-panel .teams-conversation__overflow-actions > .teams-conversation__action-list,
.teams-panel .teams-conversation__header-actions .space-filter > .space-filter__trigger,
.spaces-panel .teams-conversation__header-actions > button:not(.teams-conversation__video):not(.teams-conversation__video-select):not(.teams-conversation__more-actions),
.spaces-panel .teams-conversation__header-actions .space-filter > .space-filter__trigger {
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    margin: 0;
    padding: 0;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-surface);
    color: var(--tm-text-2);
    font: 14px/1 var(--tm-font-ui);
    cursor: pointer;
    transition:
        background var(--tm-t),
        color var(--tm-t),
        border-color var(--tm-t);
}

/* The filter owns a popover, so its shell remains the positioning anchor;
   visually it is deliberately indistinguishable from the other icon buttons.
   DESCENDANT, not child: the panel mounts the component into a
   `[data-space-filter-slot]` span, so `.space-filter` is a grandchild of the
   actions row. A `>` here silently matched nothing once that slot arrived,
   which is why these declarations were briefly duplicated in
   spaces-filter.css under a slot-specific selector. */
.teams-panel .teams-conversation__header-actions .space-filter,
.spaces-panel .teams-conversation__header-actions .space-filter {
    position: relative;
    box-sizing: border-box;
    width: 34px;
    height: 34px;
    border: 0;
    border-radius: var(--tm-r);
    background: transparent;
    box-shadow: none;
}

.teams-panel .teams-conversation__header-actions > button:not(.teams-conversation__video):not(.teams-conversation__video-select):not(.teams-conversation__more-actions):hover:not(:disabled),
.teams-panel .teams-conversation__overflow-actions > .teams-conversation__action-list:hover,
.teams-panel .teams-conversation__header-actions .space-filter > .space-filter__trigger:hover,
.spaces-panel .teams-conversation__header-actions > button:not(.teams-conversation__video):not(.teams-conversation__video-select):not(.teams-conversation__more-actions):hover:not(:disabled),
.spaces-panel .teams-conversation__header-actions .space-filter > .space-filter__trigger:hover {
    background: var(--tm-accent);
    color: #fff;
    border-color: var(--tm-accent);
}

.teams-panel .teams-conversation__header-actions > button:not(.teams-conversation__video):not(.teams-conversation__video-select):not(.teams-conversation__more-actions):focus-visible,
.teams-panel .teams-conversation__overflow-actions > .teams-conversation__action-list:focus-visible,
.teams-panel .teams-conversation__header-actions .space-filter > .space-filter__trigger:focus-visible,
.spaces-panel .teams-conversation__header-actions > button:not(.teams-conversation__video):not(.teams-conversation__video-select):not(.teams-conversation__more-actions):focus-visible,
.spaces-panel .teams-conversation__header-actions > button:not(.teams-conversation__video):not(.teams-conversation__video-select):not(.teams-conversation__more-actions):focus-visible {
    outline: 2px solid var(--tm-accent);
    outline-offset: 2px;
}

/* The filter's popover trigger retains pointer focus after it is clicked. An
   outline there reads as a second permanent border, unlike the other actions,
   so its active state is the visual indication instead. */
.teams-panel .teams-conversation__header-actions .space-filter > .space-filter__trigger:focus-visible,
.spaces-panel .teams-conversation__header-actions .space-filter > .space-filter__trigger:focus-visible {
    outline: none;
}

/* Active filters retain their semantic accent at rest, but use the same hover
   treatment as every other header control. */
.teams-panel .teams-conversation__header-actions .space-filter > .space-filter__trigger.is-active,
.spaces-panel .teams-conversation__header-actions .space-filter > .space-filter__trigger.is-active {
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
    border-color: var(--tm-accent);
}

.teams-panel .teams-conversation__header-actions > button:not(.teams-conversation__video):not(.teams-conversation__video-select):not(.teams-conversation__more-actions):disabled,
.spaces-panel .teams-conversation__header-actions > button:not(.teams-conversation__video):not(.teams-conversation__video-select):not(.teams-conversation__more-actions):disabled {
    cursor: not-allowed;
    opacity: 0.55;
}

/* The chat header's ⋯ menu. After the shared geometry: its rows restyle
   buttons that rule shapes as icons. */
/* ── Chat header ⋯ menu ─────────────────────────────────────────────────────
   teams-header-menu.js. The header keeps Ask AI and the calls; every other
   chat control lives in this popover at every width, and earns its header
   slot back only while its state is news (open action items, a muted chat,
   an active observer). On a desktop the menu hangs under the actions row; on
   a phone it is `position: fixed` (see the media query at the end). */
.teams-panel .teams-conversation__more-actions {
    display: inline-flex;
}
.teams-panel .teams-conversation__more-actions:hover,
.teams-panel .teams-conversation__more-actions[aria-expanded="true"] {
    background: var(--tm-accent-subtle);
    color: var(--tm-text);
}

.teams-panel .teams-conversation__overflow-actions {
    display: none;
}

.teams-panel .teams-conversation__overflow-actions.is-open {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 40;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    min-width: 200px;
    padding: 6px;
    border: 1px solid var(--tm-border);
    border-radius: 10px;
    background: var(--tm-surface);
    box-shadow: var(--tm-shadow-md);
}

/* The pin bar is the context's next sibling, so it otherwise paints over
   the menu even though the menu has its own z-index. The menu handler
   adds this class to the context itself; explicit state is reliable across
   all mobile WebViews, unlike a relational selector here. */
.teams-panel .teams-conversation__context.teams-conversation__context--overflow-open {
    z-index: 32;
}

/* Lifting the context is not enough once a personal chat background is
   set. That gives the HEADER a `backdrop-filter`, which both opens a
   stacking context and makes the header the containing block for the
   `position: fixed` menu inside it. The menu can then never escape the
   header, so its z-index is resolved against the header's SIBLING — the
   pinned bar, which carries `z-index: 1` and a backdrop-filter context of
   its own, and comes later in the DOM. Both elements live inside the
   context, so raising the context moves them together and the pin bar
   still wins. Raise the header itself for exactly as long as the menu is
   open; at rest the pin bar must keep painting over the header's shadow. */
.teams-panel .teams-conversation__context--overflow-open .teams-conversation__header {
    z-index: 3;
}

.teams-panel .teams-conversation__overflow-actions.is-open > button {
    justify-content: flex-start;
    width: 100%;
    padding: 0 10px;
    border: 0;
    border-radius: 6px;
    background: transparent;
}

.teams-panel .teams-conversation__overflow-actions.is-open > button:hover:not(:disabled) {
    background: var(--tm-accent-subtle);
    color: var(--tm-text);
}

.teams-panel .teams-conversation__overflow-actions.is-open > button:disabled {
    cursor: not-allowed;
    opacity: 0.55;
}

.teams-panel .teams-conversation__overflow-actions.is-open > button::after {
    margin-left: 9px;
    font: 13px/1 var(--tm-font-ui);
}

.teams-panel .teams-conversation__overflow-actions.is-open [data-conv-video]::after { content: attr(data-menu-label); }
.teams-panel .teams-conversation__overflow-actions.is-open [data-conv-to-feed]::after { content: 'Team feed'; }

/* "Call selected people" — "call these two of the eight in this chat". */
.teams-panel .teams-conversation__overflow-actions.is-open [data-conv-video-select]::after {
    content: 'Call selected people';
}

.teams-panel .teams-conversation__overflow-actions.is-open [data-conv-mute]::after { content: attr(data-menu-label); }
.teams-panel .teams-conversation__overflow-actions.is-open [data-conv-schedule]::after { content: 'Scheduled calls'; }
.teams-panel .teams-conversation__overflow-actions.is-open [data-conv-documents]::after { content: attr(data-menu-label); }
.teams-panel .teams-conversation__overflow-actions.is-open [data-conv-threads]::after { content: attr(data-menu-label); }

/* Documents is dynamically mounted into the overflow group, so it does not
   inherit the header's direct-child icon geometry. Give it the exact same
   row box as the other menu controls to keep the icon and label aligned. */
.teams-panel .teams-conversation__overflow-actions.is-open > [data-conv-documents],
.teams-panel .teams-conversation__overflow-actions.is-open > [data-conv-threads] {
    display: inline-flex;
    align-items: center;
    min-height: 34px;
    color: var(--tm-text-2);
    font: 14px/1 var(--tm-font-ui);
}
.teams-panel .teams-conversation__overflow-actions.is-open > [data-conv-documents] > i,
.teams-panel .teams-conversation__overflow-actions.is-open > [data-conv-threads] > i {
    width: 16px;
    text-align: center;
}

/* The observer control was designed as a compact desktop icon. In this
   menu it needs a visible name; otherwise it renders as a blank-looking
   robot button beneath the other labelled actions. */
.teams-panel .teams-conversation__overflow-actions.is-open > .teams-observers {
    width: 100%;
    max-width: none;
    margin: 0;
}

.teams-panel .teams-conversation__overflow-actions.is-open .teams-observers__summary {
    width: 100%;
    padding: 0 10px;
    box-sizing: border-box;
}

.teams-panel .teams-conversation__overflow-actions.is-open .teams-observers__summary-text,
.teams-panel .teams-conversation__overflow-actions.is-open .teams-observers__summary-chevron {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip: auto;
    white-space: nowrap;
}


/* A phone: fixed, so the menu escapes the header/pinned-strip stacking
   contexts; teams-header-menu.js anchors it to the ⋮ trigger. */
@media (max-width: 768px) {
    .teams-panel .teams-conversation__overflow-actions.is-open {
        position: fixed;
        z-index: 2100;
        min-width: 180px;
        max-height: calc(100vh - 92px);
    }
}

/* "View answers" popover of a submitted structured form. */
/* ============================================================================
   "View answers" popover — a submitted structured form (teams-structured-form.js).

   Every visual choice lives here; the script only sets the two position variables
   (--form-popover-left / --form-popover-top, in px) and toggles the element. It floats
   (position: fixed) and opens ABOVE its link, so it never moves the transcript.
   The card look matches the static "Structured feedback submitted" card
   (feedback-ui.css .structured-feedback-card).
   ============================================================================ */

.teams-form-popover {
    --form-popover-width: 420px;          /* edit me */
    --form-popover-max-height: 50vh;      /* edit me */

    position: fixed;
    left: var(--form-popover-left, 12px);
    top: var(--form-popover-top, 12px);
    z-index: 10030;
    box-sizing: border-box;
    width: min(var(--form-popover-width), calc(100vw - 24px));
    max-height: var(--form-popover-max-height);
    overflow: auto;
    padding: 12px 14px;
    border: 1px solid #d7dfef;
    border-radius: 12px;
    background: #f7f9fc;
    box-shadow: 0 12px 32px rgba(15, 23, 42, 0.22);
    color: #334155;
    text-align: left;
}

.teams-form-popover .teams-form-popover__title {
    font-size: 0.92rem;
    font-weight: 600;
    color: #1f2937;
}

.teams-form-popover .teams-form-popover__sub {
    margin-top: 2px;
    font-size: 0.82rem;
    color: #5f6b7a;
}

.teams-form-popover .teams-form-popover__list {
    margin: 10px 0 0;
    padding-left: 18px;
    font-size: 0.85rem;
    line-height: 1.45;
}

.teams-form-popover .teams-form-popover__item + .teams-form-popover__item {
    margin-top: 6px;
}

/* The question … */
.teams-form-popover .teams-form-popover__q {
    display: block;
    font-size: 0.78rem;
    color: #5f6b7a;
}

/* … and the answer, set apart from it. */
.teams-form-popover .teams-form-popover__a {
    display: block;
    font-weight: 600;
    color: #0f3d73;
    overflow-wrap: anywhere;
}

body.dark-theme .teams-form-popover {
    background: #162030;
    border-color: #263448;
    color: #b2c0d1;
}
body.dark-theme .teams-form-popover .teams-form-popover__title { color: #e5edf6; }
body.dark-theme .teams-form-popover .teams-form-popover__sub,
body.dark-theme .teams-form-popover .teams-form-popover__q { color: #b2c0d1; }
body.dark-theme .teams-form-popover .teams-form-popover__a { color: #9cc7f5; }

/* Chat Action list. After the shared header geometry: its active state must
   out-rank that rule (see the file). */
/* ═══════════════════════════════════════════════════════════════════════════
   Amby Teams — chat Action list
   ═══════════════════════════════════════════════════════════════════════════
   Header button + badges (teams-action-list.js), the create/edit form
   (teams-action-item-form.js), the draft review (teams-action-item-review.js)
   and the "Track as action item?" chip (teams-action-item-suggest.js). The
   panel itself — a chat's list and My action items alike — is
   teams-action-items-view.js, styled in teams-reminders.css.

   Scoped under .teams-panel (the button and the chip, inside it, so they
   inherit the --tm-* tokens and their dark overrides) and under
   .teams-action-form-overlay (the form, appended to <body> on a
   .teams-modal-overlay, which carries the same tokens). CLAUDE.md rule 2.
   ─────────────────────────────────────────────────────────────────────────── */

/* ── Header button ──────────────────────────────────────────────────────────
   Geometry comes from the shared header-actions rule. `hidden` must win over
   its `display`, or the button flashes in on chats where the list is absent
   (desk chats, anonymised readers). */
.teams-panel .teams-conversation__action-list[hidden] {
    display: none !important;
}
.teams-panel .teams-conversation__action-list {
    position: relative;
}
/* A chat's button moves into the overflow group (the ⋮ menu on a phone) while
   it has no open items; otherwise it is a direct child of the actions row.
   Each selector matches the shared header rule for its placement and wins by
   import order. */
.teams-panel .teams-conversation__overflow-actions > .teams-conversation__action-list.is-active,
.teams-panel .teams-conversation__header-actions > button.teams-conversation__action-list.is-active:not(.teams-conversation__video):not(.teams-conversation__more-actions) {
    background: var(--tm-accent);
    color: #fff;
    border-color: var(--tm-accent);
}
.teams-panel .teams-conversation__action-list .teams-action-list-badge {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    box-sizing: border-box;
    border-radius: 9px;
    background: var(--tm-accent);
    color: #fff;
    font: 600 10px/17px var(--tm-font-ui);
    text-align: center;
    box-shadow: 0 0 0 2px var(--tm-surface);
    pointer-events: none;
}
/* The same badge shows the overdue count instead of the total while any is late. */
.teams-panel .teams-conversation__action-list .teams-action-list-badge--overdue {
    background: var(--tm-danger);
}
.teams-panel .teams-conversation__action-list .teams-action-list-badge[hidden] {
    display: none;
}

/* In the ⋯ menu (no open items, so no badge): the first row, labelled. */
.teams-panel .teams-conversation__overflow-actions.is-open > .teams-conversation__action-list {
    order: -1;
}
.teams-panel .teams-conversation__overflow-actions.is-open > .teams-conversation__action-list::after {
    content: attr(data-menu-label);
}
/* "Load more" under the panel's Completed view (teams-action-items-view.js). */
.teams-panel .teams-action-list__more {
    display: block;
    margin: 10px auto 0;
    padding: 6px 14px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-surface);
    color: var(--tm-text-2);
    cursor: pointer;
}
.teams-panel .teams-action-list__more[hidden] {
    display: none;
}

/* ── Create / edit form ──────────────────────────────────────────────────── */
.teams-action-form-overlay .teams-action-form {
    max-width: 480px;
    max-height: 88vh;
}
.teams-action-form-overlay .teams-action-form__grip {
    display: none;
}
.teams-action-form-overlay .teams-action-form__body {
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}
/* Each part is a shared .teams-field card, like the Create team / Open channel
   forms beside it in the create window. Who follows the target via [hidden],
   which the card's own display would otherwise override. */
.teams-action-form-overlay .teams-field[hidden] {
    display: none;
}
.teams-action-form-overlay .teams-action-form__label {
    margin-top: 8px;
    font-size: 12px;
    font-weight: 600;
    color: var(--tm-text-2);
}
.teams-action-form-overlay .teams-action-form__title,
.teams-action-form-overlay .teams-action-form__notes-input,
.teams-action-form-overlay .teams-action-form__select,
.teams-action-form-overlay .teams-action-form__date,
.teams-action-form-overlay .teams-action-form__time {
    box-sizing: border-box;
    width: 100%;
    padding: 9px 10px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-white);
    color: var(--tm-msg-text);
    font: 14px/1.35 var(--tm-font-ui);
    resize: vertical;
}
/* The native arrow hugs the right border and can't be moved, so draw our own
   chevron inset from the edge. A mid grey reads on both themes. */
.teams-action-form-overlay .teams-action-form__select {
    appearance: none;
    -webkit-appearance: none;
    padding-right: 40px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23888' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 12px 12px;
    cursor: pointer;
}
.teams-action-form-overlay .teams-action-form__title:focus,
.teams-action-form-overlay .teams-action-form__notes-input:focus,
.teams-action-form-overlay .teams-action-form__select:focus,
.teams-action-form-overlay .teams-action-form__date:focus,
.teams-action-form-overlay .teams-action-form__time:focus {
    outline: none;
    border-color: var(--tm-accent);
    box-shadow: 0 0 0 3px var(--tm-accent-subtle);
    background-color: var(--tm-real-white);
}
/* Over the length limit: marked, with the reason right under the field. */
.teams-action-form-overlay .teams-action-form__title.is-invalid,
.teams-action-form-overlay .teams-action-form__notes-input.is-invalid {
    border-color: var(--tm-danger);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--tm-danger) 18%, transparent);
}
.teams-action-form-overlay .teams-action-form__field-error {
    margin: 4px 2px 0;
    color: var(--tm-danger);
    font-size: 12px;
    font-weight: 600;
}
.teams-action-form-overlay .teams-action-form__field-error[hidden] {
    display: none;
}
.teams-action-form-overlay .teams-action-form__row {
    display: flex;
    gap: 8px;
    align-items: center;
}
.teams-action-form-overlay .teams-action-form__row[hidden] {
    display: none;
}
.teams-action-form-overlay .teams-action-form__me {
    flex: 0 0 auto;
    white-space: nowrap;
}
.teams-action-form-overlay .teams-action-form__time {
    max-width: 130px;
}
.teams-action-form-overlay .teams-action-form__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.teams-action-form-overlay .teams-action-form__chip {
    padding: 6px 12px;
    border: 1px solid var(--tm-border);
    border-radius: 999px;
    background: var(--tm-surface);
    color: var(--tm-text-2);
    font: 13px var(--tm-font-ui);
    cursor: pointer;
}
.teams-action-form-overlay .teams-action-form__chip[aria-checked="true"] {
    background: var(--tm-accent);
    border-color: var(--tm-accent);
    color: #fff;
}
.teams-action-form-overlay .teams-action-form__when {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.teams-action-form-overlay .teams-action-form__when[hidden] {
    display: none;
}
.teams-action-form-overlay .teams-action-form__remind-row {
    flex-wrap: wrap;
}
.teams-action-form-overlay .teams-action-form__remind-row .teams-action-form__select {
    width: auto;
    flex: 1 1 160px;
}
.teams-action-form-overlay .teams-action-form__reminders {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.teams-action-form-overlay .teams-action-form__reminder-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
}
.teams-action-form-overlay .teams-action-form__reminder-row .teams-action-form__select {
    width: auto;
    flex: 1 1 160px;
}
.teams-action-form-overlay .teams-action-form__reminder-remove {
    border: 0;
    background: transparent;
    color: var(--tm-text-3);
    cursor: pointer;
    padding: 6px 8px;
    border-radius: 6px;
}
.teams-action-form-overlay .teams-action-form__reminder-remove:hover {
    color: var(--tm-text-1);
    background: var(--tm-surface-2, rgba(127, 127, 127, 0.12));
}
.teams-action-form-overlay .teams-action-form__reminder-add {
    align-self: flex-start;
}
.teams-action-form-overlay .teams-action-form__reminder-when {
    display: flex;
    flex: 1 1 100%;
    gap: 8px;
}
.teams-action-form-overlay .teams-action-form__reminder-when .teams-action-form__date,
.teams-action-form-overlay .teams-action-form__reminder-when .teams-action-form__time {
    width: auto;
    flex: 1 1 0;
}
.teams-action-form-overlay .teams-action-form__hint {
    font-size: 12px;
    color: var(--tm-text-3);
}
.teams-action-form-overlay .teams-action-form__notes summary {
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    color: var(--tm-text-1);
}
.teams-action-form-overlay .teams-action-form__notes[open] summary {
    margin-bottom: 6px;
}
.teams-action-form-overlay .teams-action-form__error {
    margin: 6px 0 0;
    color: var(--tm-danger);
    font-size: 13px;
}
.teams-action-form-overlay .teams-action-form__error[hidden] {
    display: none;
}
.teams-action-form-overlay .teams-action-form__delete {
    margin-right: auto;
    color: var(--tm-danger);
}

/* ── Review AI drafts (teams-action-item-review.js) ─────────────────────── */
.teams-action-form-overlay .teams-action-review {
    max-width: 560px;
}
.teams-action-form-overlay .teams-action-review__intro {
    margin: 0 0 6px;
    font-size: 13px;
    color: var(--tm-text-1);
}
.teams-action-form-overlay .teams-action-review__list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.teams-action-form-overlay .teams-action-review__list[hidden],
.teams-action-form-overlay .teams-action-review__empty[hidden],
.teams-action-form-overlay .teams-loading[hidden] {
    display: none;
}
.teams-action-form-overlay .teams-action-review__row {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    gap: 8px;
    padding: 10px 0;
    border-top: 1px solid var(--tm-border);
}
.teams-action-form-overlay .teams-action-review__row:first-child {
    border-top: none;
}
.teams-action-form-overlay .teams-action-review__row.is-duplicate .teams-action-review__title {
    color: var(--tm-text-3);
}
.teams-action-form-overlay .teams-action-review__fields {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}
.teams-action-form-overlay .teams-action-review__title {
    box-sizing: border-box;
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-real-white);
    color: var(--tm-msg-text);
    font: 16px/1.35 var(--tm-font-ui);
}
.teams-action-form-overlay .teams-action-review__controls {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.teams-action-form-overlay .teams-action-review__controls .teams-action-form__select {
    flex: 1 1 150px;
    width: auto;
}
.teams-action-form-overlay .teams-action-review__controls .teams-action-form__date {
    flex: 1 1 130px;
    width: auto;
}
.teams-action-form-overlay .teams-action-review__dup {
    font-size: 12px;
    color: var(--tm-text-1);
}
.teams-action-form-overlay .teams-action-review__notes {
    margin: 0;
    font-size: 12px;
    color: var(--tm-text-1);
    white-space: pre-line;
}
.teams-action-form-overlay .teams-action-review__empty {
    margin: 20px 0;
    text-align: center;
    color: var(--tm-text-3);
}

/* "Add to action list" beside "Share to chat" on a Personal AI answer. */
.teams-panel .teams-ai-answer__actions .teams-ai-answer__to-action-list {
    margin-left: 8px;
}

/* The summary modal's way into the review. */
.teams-meeting-summary-modal .teams-meeting-summary__action-list {
    margin-top: 12px;
}

/* ── Who: the assignee picker (teams-assignee-picker.js) ───────────────────
   In the form ("Who") and in the quick "Assign to…" sheet behind a row's
   avatar. The search box and the rows are the New conversation dialog's
   (`.teams-newchat__search`, `.teams-newchat__row` in teams-modals.css, under
   .teams-modal-overlay, which both overlays are). */
.teams-action-form-overlay .teams-assignee__current {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
    padding: 6px 6px 6px 8px;
    border: 1px solid var(--tm-border);
    border-radius: 8px;
    background: var(--tm-real-white, var(--tm-white));
}
.teams-action-form-overlay .teams-assignee__current[hidden] {
    display: none;
}
/* The shared overlay avatar carries a message-row offset (margin-top: 18px). */
.teams-action-form-overlay .teams-assignee__avatar {
    flex: none;
    margin: 0;
}
.teams-action-form-overlay .teams-assignee__name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    font-size: 14px;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-action-form-overlay .teams-assignee__you {
    color: var(--tm-text-3);
    font-weight: 400;
}
.teams-action-form-overlay .teams-assignee__clear {
    padding: 6px 8px;
    border: 0;
    border-radius: 6px;
    background: none;
    color: var(--tm-text-3);
    cursor: pointer;
}
.teams-action-form-overlay .teams-assignee__clear:hover {
    background: var(--tm-bg-alt);
    color: var(--tm-danger);
}
/* The search box, with "Assign to me" beside it in the form. */
.teams-action-form-overlay .teams-assignee__bar,
.teams-assign-overlay .teams-assignee__bar {
    display: flex;
    align-items: center;
    gap: 8px;
}
.teams-action-form-overlay .teams-assignee__input,
.teams-assign-overlay .teams-assignee__input {
    flex: 1;
    min-width: 0;
    margin: 0;
}
.teams-action-form-overlay .teams-assignee__bar .teams-action-form__me[hidden] {
    display: none;
}
/* In the form the results open IN the flow, under the box, rather than over
   the fields: the form body scrolls, and a floating list would be clipped. */
.teams-action-form-overlay .teams-assignee__results,
.teams-assign-overlay .teams-assignee__results {
    max-height: 280px;
    margin-top: 6px;
    overflow-y: auto;
}
.teams-action-form-overlay .teams-assignee__results[hidden] {
    display: none;
}
.teams-action-form-overlay .teams-assignee__results .teams-newchat__row.is-active,
.teams-assign-overlay .teams-assignee__results .teams-newchat__row.is-active {
    background: var(--tm-bg-alt);
}
.teams-action-form-overlay .teams-assignee__empty,
.teams-assign-overlay .teams-assignee__empty {
    margin: 8px 4px;
    color: var(--tm-text-3);
    font-size: 13px;
}

/* The quick "Assign to…" sheet. */
.teams-assign-overlay .teams-assign-dialog {
    max-width: 440px;
}
.teams-assign-overlay .teams-assign-dialog__body {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}
.teams-assign-overlay .teams-assignee__search {
    display: flex;
    flex-direction: column;
    min-height: 0;
}
.teams-assign-overlay .teams-assignee__results {
    max-height: 50vh;
}
.teams-assign-overlay .teams-assign-dialog__body .teams-newchat__section-title {
    padding-top: 12px;
}
.teams-assign-overlay .teams-assignee__quick-list {
    display: flex;
    flex-direction: column;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--tm-border);
}
.teams-assign-overlay .teams-assignee__quick-icon {
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
}
.teams-assign-overlay .teams-assignee__quick-icon.is-dashed {
    border: 1.5px dashed var(--tm-border-strong);
    background: transparent;
    color: var(--tm-text-3);
}

/* ── Phones: the form becomes a bottom sheet ───────────────────────────────
   Above .chat-header and the mobile tab bar; clear of the Home indicator. */
@media (max-width: 768px) {
    .teams-assign-overlay {
        align-items: flex-end;
        padding: 0;
    }
    .teams-assign-overlay .teams-assign-dialog {
        max-width: none;
        max-height: 85vh;
        border-radius: 16px 16px 0 0;
        padding-bottom: env(safe-area-inset-bottom);
    }
    .teams-assign-overlay .teams-assignee__input {
        font-size: 16px;
    }

    /* While the action items panel is up the bottom tab bar must not
       scroll-hide: it is the way out (teams-reminders.css keeps the panel under it). */
    body.mobile-standalone.amby-action-list-open .mobile-tab-bar--page.is-scroll-hidden {
        transform: none;
        opacity: 1;
    }

    .teams-action-form-overlay {
        align-items: flex-end;
        padding: 0;
    }
    /* 16px keeps iOS Safari from zooming the page when a field takes focus. */
    .teams-action-form-overlay .teams-assignee__input,
    .teams-action-form-overlay .teams-action-form__title,
    .teams-action-form-overlay .teams-action-form__notes-input,
        .teams-action-form-overlay .teams-action-form__select,
    .teams-action-form-overlay .teams-action-form__date,
    .teams-action-form-overlay .teams-action-form__time {
        font-size: 16px;
    }
    .teams-action-form-overlay .teams-action-form {
        max-width: none;
        max-height: 92vh;
        border-radius: 16px 16px 0 0;
        padding-bottom: env(safe-area-inset-bottom);
        transform: translateY(24px);
        transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
    }
    .teams-action-form-overlay.is-open .teams-action-form {
        transform: none;
    }
    .teams-action-form-overlay .teams-action-form__grip {
        display: block;
        width: 36px;
        height: 4px;
        margin: 8px auto 0;
        border-radius: 2px;
        background: var(--tm-border-strong);
    }
    .teams-action-form-overlay .teams-action-form__footer .teams-btn {
        flex: 1 1 0;
        min-height: 44px;
    }
    .teams-action-form-overlay .teams-action-form__delete {
        flex: 0 0 auto;
    }
}

@media (prefers-reduced-motion: reduce) {
    .teams-action-form-overlay .teams-action-form {
        transition: none;
    }
}

/* ── "Track as action item?" under my own tagged message (FR-8) ──────────── */
.teams-panel .teams-ai-suggest {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    max-width: 100%;
    margin-top: 4px;
    padding: 4px 4px 4px 10px;
    border: 1px dashed var(--tm-accent);
    border-radius: 999px;
    background: var(--tm-accent-subtle);
    font: 500 12px/1.3 var(--tm-font-ui);
    color: var(--tm-text-2);
    animation: teams-ai-suggest-in 0.18s ease-out;
}
.teams-panel .teams-msg--mine .teams-ai-suggest { align-self: flex-end; }
.teams-panel .teams-ai-suggest__icon { color: var(--tm-accent); }
.teams-panel .teams-ai-suggest__text { font-weight: 600; color: var(--tm-text-1); }
.teams-panel .teams-ai-suggest__title {
    min-width: 0;
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-panel .teams-ai-suggest__track {
    border: none;
    border-radius: 999px;
    padding: 4px 12px;
    background: var(--tm-accent);
    color: #fff;
    font: 600 12px var(--tm-font-ui);
    cursor: pointer;
}
.teams-panel .teams-ai-suggest__dismiss {
    width: 26px;
    height: 26px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--tm-text-3);
    cursor: pointer;
}
.teams-panel .teams-ai-suggest__dismiss:hover,
.teams-panel .teams-ai-suggest__dismiss:focus-visible { background: var(--tm-surface); color: var(--tm-text-1); }
@keyframes teams-ai-suggest-in {
    from { opacity: 0; transform: translateY(-2px); }
    to { opacity: 1; transform: none; }
}
@media (max-width: 768px) {
    /* Thumb-sized targets; the quoted title gives way first. */
    .teams-panel .teams-ai-suggest__title { max-width: 150px; }
    .teams-panel .teams-ai-suggest__track { padding: 7px 14px; }
    .teams-panel .teams-ai-suggest__dismiss { width: 34px; height: 34px; }
}
@media (prefers-reduced-motion: reduce) {
    .teams-panel .teams-ai-suggest { animation: none; }
}

/* ── Resolve dialog ("How did it end?") ──────────────────────────────────── */
.teams-action-resolve-overlay .teams-action-resolve__item {
    margin: 0 0 4px;
    font-weight: 600;
    color: var(--tm-text-1);
    overflow-wrap: anywhere;
}
.teams-action-resolve-overlay .teams-action-resolve__count {
    margin: 4px 0 0;
    font-size: 12px;
    text-align: right;
    color: var(--tm-text-2);
}
.teams-action-resolve-overlay .teams-action-resolve__count.is-over {
    color: var(--tm-danger, #d93025);
}
.teams-action-resolve-overlay [data-save]:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* The outcome and comment on a resolved card and in the transcript chip. */
.teams-panel .teams-reminders__resolution {
    margin-top: 3px;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 6px;
    font-size: 12.5px;
    color: var(--tm-text-1);
}
.teams-panel .teams-reminders__outcome {
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--tm-surface-2, rgba(127, 127, 127, 0.15));
    color: var(--tm-text-2);
    font-size: 11.5px;
    font-weight: 600;
    white-space: nowrap;
}
.teams-panel .teams-reminders__resolution-comment {
    overflow-wrap: anywhere;
    white-space: pre-wrap;
}
.teams-panel .teams-sysnote--action-item .teams-sysnote__resolution {
    display: block;
    margin-top: 2px;
    overflow-wrap: anywhere;
    color: var(--tm-accent-hover);
    font-size: 12px;
    line-height: 1.3;
}
.teams-panel .teams-sysnote--action-item .teams-sysnote__outcome {
    margin-right: 6px;
}
.teams-panel .teams-sysnote--action-item .teams-sysnote__comment {
    white-space: normal;
}
.teams-sysnote-popover {
    position: fixed;
    z-index: 10050;
    box-sizing: border-box;
    max-width: min(360px, calc(100vw - 16px));
    max-height: 50vh;
    overflow: auto;
    padding: 10px 12px;
    border: 1px solid var(--tm-border, #d9e0e6);
    border-radius: 12px;
    background: var(--tm-surface, #fff);
    color: var(--tm-text-1, inherit);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    font-size: 13px;
}
.teams-sysnote-popover .teams-sysnote-popover__title,
.teams-sysnote-popover .teams-sysnote-popover__comment {
    margin: 0 0 6px;
    overflow-wrap: anywhere;
    white-space: pre-wrap;
}
.teams-sysnote-popover .teams-sysnote-popover__title { font-weight: 600; }
.teams-sysnote-popover .teams-sysnote-popover__outcome {
    display: inline-block;
    margin-bottom: 6px;
    font-size: 12px;
    color: var(--tm-text-2);
}

/* Phones: the chip is one short line of text; outcome + comment are in the popover. */
@media (max-width: 768px) {
    .teams-panel .teams-sysnote--action-item .teams-sysnote__resolution { display: none; }
}
@media (min-width: 769px) {
    .teams-panel .teams-sysnote--action-item .teams-sysnote__link--phone-only { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Amby Teams — action items: the wide two-column item card, its comments, and
   the "In progress" badge on a row.
   ═══════════════════════════════════════════════════════════════════════════
   teams-action-item-form.js (layout), teams-action-item-comments.js (thread),
   teams-action-items-view.js (badge). Scoped under .teams-action-form-overlay
   (the form, appended to <body> on a .teams-modal-overlay, which carries the
   --tm-* tokens) and .teams-panel (the rows). CLAUDE.md rule 2.
   ─────────────────────────────────────────────────────────────────────────── */

/* ── The item card: wide, two columns ───────────────────────────────────────
   Left: who / status / list / options. Right: when / reminders / notes. The
   comments run across the bottom. One column on a phone (the bottom sheet). */
.teams-action-form-overlay .teams-action-form.teams-action-form--wide {
    width: min(920px, 94vw);
    max-width: 920px;
}
.teams-action-form-overlay .teams-action-form__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 0 16px;
    align-items: start;
}
.teams-action-form-overlay .teams-action-form__col {
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.teams-action-form-overlay .teams-action-form__reopen {
    margin-right: auto;
}
/* With Delete beside it, Delete already takes the free space. */
.teams-action-form-overlay .teams-action-form__delete ~ .teams-action-form__reopen {
    margin-right: 0;
}

/* ── Comments ───────────────────────────────────────────────────────────────── */
.teams-action-form-overlay .teams-action-comments {
    margin-top: 12px;
    padding: 12px 14px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-surface);
}
.teams-action-form-overlay .teams-action-comments__title {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 8px;
    font: 600 13px/1.2 var(--tm-font-ui);
    color: var(--tm-text-2);
}
.teams-action-form-overlay .teams-action-comments__count {
    min-width: 18px;
    padding: 0 6px;
    border-radius: 9px;
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
    font-size: 11px;
    line-height: 18px;
    text-align: center;
}
.teams-action-form-overlay .teams-action-comments__count:empty {
    display: none;
}
.teams-action-form-overlay .teams-action-comments__list {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 260px;
    overflow-y: auto;
    overscroll-behavior: contain;
}
.teams-action-form-overlay .teams-action-comments__item {
    display: flex;
    gap: 10px;
    padding: 8px 0;
}
.teams-action-form-overlay .teams-action-comments__item + .teams-action-comments__item {
    border-top: 1px solid var(--tm-border);
}
.teams-action-form-overlay .teams-action-comments__avatar {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    margin: 0;
    border-radius: 50%;
    font-size: 13px;
}
.teams-action-form-overlay .teams-action-comments__main {
    flex: 1 1 auto;
    min-width: 0;
}
.teams-action-form-overlay .teams-action-comments__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 8px;
}
.teams-action-form-overlay .teams-action-comments__name {
    font: 600 13px/1.3 var(--tm-font-ui);
    color: var(--tm-text-1);
}
.teams-action-form-overlay .teams-action-comments__time {
    font-size: 11px;
    color: var(--tm-text-3);
}
.teams-action-form-overlay .teams-action-comments__badge {
    padding: 0 6px;
    border-radius: 8px;
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
.teams-action-form-overlay .teams-action-comments__delete {
    margin-left: auto;
    padding: 2px 6px;
    border: 0;
    background: none;
    color: var(--tm-text-3);
    font-size: 12px;
    cursor: pointer;
    opacity: 0;
}
.teams-action-form-overlay .teams-action-comments__item:hover .teams-action-comments__delete,
.teams-action-form-overlay .teams-action-comments__delete:focus-visible {
    opacity: 1;
}
.teams-action-form-overlay .teams-action-comments__delete:hover {
    color: var(--tm-danger);
}
.teams-action-form-overlay .teams-action-comments__body {
    margin: 2px 0 0;
    font-size: 14px;
    line-height: 1.4;
    color: var(--tm-text-1);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}
.teams-action-form-overlay .teams-action-comments__empty {
    margin: 4px 0 10px;
    font-size: 13px;
    color: var(--tm-text-3);
}
.teams-action-form-overlay .teams-action-comments__empty[hidden],
.teams-action-form-overlay .teams-action-comments__over[hidden] {
    display: none;
}
.teams-action-form-overlay .teams-action-comments__composer {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-top: 8px;
    padding: 8px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: #fff;
}
body.dark-theme .teams-action-form-overlay .teams-action-comments__composer {
    background: #2b303b;
}
.teams-action-form-overlay .teams-action-comments__field {
    flex: 1 1 auto;
    min-width: 0;
}
.teams-action-form-overlay .teams-action-comments__input {
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: 6px 4px;
    border: 0;
    border-radius: 0;
    background: transparent;
    color: var(--tm-text-1);
    font: 14px/1.4 var(--tm-font-ui);
    resize: vertical;
}
.teams-action-form-overlay .teams-action-comments__input:focus {
    outline: none;
}
.teams-action-form-overlay .teams-action-comments__composer:focus-within {
    border-color: var(--tm-accent);
    box-shadow: 0 0 0 3px var(--tm-accent-subtle);
}
.teams-action-form-overlay .teams-action-comments__composer:has(.is-invalid) {
    border-color: var(--tm-danger);
}
.teams-action-form-overlay .teams-action-comments__tools {
    display: flex;
    align-items: center;
    gap: 8px;
}
.teams-action-form-overlay .teams-action-comments__emoji {
    padding: 2px 6px;
    border: 0;
    border-radius: var(--tm-r);
    background: none;
    color: var(--tm-text-2);
    font-size: 18px;
    cursor: pointer;
}
.teams-action-form-overlay .teams-action-comments__emoji:hover {
    background: var(--tm-accent-subtle);
}
.teams-action-form-overlay .teams-action-comments__over {
    font-size: 12px;
    color: var(--tm-danger);
}
.teams-action-form-overlay .teams-action-comments__send {
    flex: 0 0 auto;
    align-self: flex-end;
}
/* The shared button turns its text accent-coloured on hover — the same colour as
   this one's background, so a disabled Comment lost its label under the pointer. */
.teams-action-form-overlay .teams-action-comments__send:disabled:hover {
    color: #fff;
    border-color: transparent;
}

/* ── Card regrouping: Status + List side by side; options in one card ────────── */
.teams-action-form-overlay .teams-action-form__pair {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 0 12px;
}
.teams-action-form-overlay .teams-action-form__option[hidden] {
    display: none;
}
.teams-action-form-overlay .teams-action-form__option {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--tm-border);
}
/* Notes grow with their text (teams-action-item-form.js) up to a cap, then scroll. */
.teams-action-form-overlay .teams-action-form__notes-input {
    min-height: 72px;
    max-height: 320px;
    resize: vertical;
}

/* ── Comment count and "In progress" on a row ───────────────────────────────── */
/* Right side of a card, under the assignee's avatar: the two things worth seeing at a glance. */
.teams-panel .teams-reminders__side {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 6px;
}
.teams-panel .teams-reminders__comments {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--tm-text-2);
    font-size: 12px;
    font-weight: 600;
    margin-right: 8px;
    margin-top: 4px;
}
/* ── "In progress" on a row ─────────────────────────────────────────────────── */
.teams-panel .teams-reminders__progress {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 0 7px;
    border-radius: 9px;
    background: var(--tm-accent-subtle);
    color: var(--tm-accent);
    font-weight: 600;
}

/* ── Phones: one column inside the bottom sheet ─────────────────────────────── */
@media (max-width: 768px) {
    .teams-action-form-overlay .teams-action-form.teams-action-form--wide {
        width: auto;
        max-width: none;
    }
    .teams-action-form-overlay .teams-action-form__grid {
        grid-template-columns: minmax(0, 1fr);
    }
    .teams-action-form-overlay .teams-action-comments__input {
        font-size: 16px;
    }
    .teams-action-form-overlay .teams-action-comments__delete {
        opacity: 1;
    }
    .teams-action-form-overlay .teams-action-comments__list {
        max-height: 40vh;
    }
}

/* Per-chat documents drawer, opened from the chat-actions menu. */
/* Files & documents — the chat's side panel. Geometry mirrors the Ask AI drawer
   (teams-ai-drawer.css): a floating card inside .teams-panel, so the --tm-* tokens
   and their dark-theme overrides apply. Scoped under .teams-panel. */
.teams-panel .teams-documents-drawer {
    position: fixed; z-index: 1000; top: 80px; right: 10px; bottom: 10px; width: 400px; max-width: 50%;
    display: flex; flex-direction: column; overflow: hidden;
    border: 1px solid var(--tm-border); border-radius: 8px; color: var(--tm-text-2); background: var(--tm-bg);
    box-shadow: var(--tm-shadow-md); font-family: var(--tm-font-ui);
    opacity: 0; transform: translateX(38px);
    transition: opacity .28s ease, transform .42s cubic-bezier(.22, 1, .36, 1);
}
.teams-panel .teams-documents-drawer.is-open { opacity: 1; transform: translateX(0); }
@media (prefers-reduced-motion: reduce) { .teams-panel .teams-documents-drawer { transition: none; } }
/* Full screen on phones: pad by the safe area so the header (and its Close button) clears the status bar / Dynamic Island. */
@media (max-width: 768px) {
    .teams-panel .teams-documents-drawer {
        top: 0; right: 0; bottom: 0; width: 100%; max-width: none; border-radius: 0;
        padding: var(--safe-top, env(safe-area-inset-top, 0px)) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
    }
    .teams-panel .teams-documents-drawer__close { width: 44px; height: 44px; }
}

.teams-panel .teams-documents-drawer__header { display: flex; align-items: center; gap: 12px; padding: 13px 14px; border-bottom: 1px solid var(--tm-border); background: var(--tm-surface); }
.teams-panel .teams-documents-drawer__heading { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.teams-panel .teams-documents-drawer__title { display: inline-flex; align-items: center; gap: 8px; color: var(--tm-msg-text); font: 600 15px/1.3 var(--tm-font-display); }
.teams-panel .teams-documents-drawer__subtitle { color: var(--tm-text-3); font-size: 12px; }
.teams-panel .teams-documents-drawer__close { margin-left: auto; width: 32px; height: 32px; border: 0; border-radius: 8px; color: var(--tm-text-1); background: transparent; cursor: pointer; }
.teams-panel .teams-documents-drawer__close:hover { color: var(--tm-accent); background: var(--tm-accent-subtle); }

.teams-panel .teams-documents-drawer__tools { display: flex; gap: 8px; padding: 10px 14px; border-bottom: 1px solid var(--tm-border); }
.teams-panel .teams-documents-drawer__tools button { display: inline-flex; align-items: center; gap: 6px; padding: 6px 11px; border: 1px solid var(--tm-border-strong); border-radius: var(--tm-r); color: var(--tm-msg-text); background: var(--tm-real-white); font: 600 12px/1.2 var(--tm-font-ui); cursor: pointer; }
.teams-panel .teams-documents-drawer__tools button:hover { border-color: var(--tm-accent); color: var(--tm-accent); }

.teams-panel .teams-documents-drawer__body { flex: 1; min-height: 0; padding: 8px; overflow: auto; }
.teams-panel .teams-documents-drawer__status { padding: 16px 10px; color: var(--tm-text-1); font-size: 13px; text-align: center; }
.teams-panel .teams-documents-drawer__list { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.teams-panel .teams-documents-drawer__item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px; border: 0; border-radius: var(--tm-r); color: var(--tm-msg-text); background: transparent; text-align: left; font: inherit; cursor: pointer; }
.teams-panel .teams-documents-drawer__item:hover { background: var(--tm-accent-subtle); }
.teams-panel .teams-documents-drawer__icon { display: grid; flex: none; width: 34px; height: 34px; place-items: center; border-radius: 8px; color: var(--tm-accent); background: var(--tm-accent-subtle); font-size: 15px; }
.teams-panel .teams-documents-drawer__icon--pdf { color: #c0392b; background: rgba(192, 57, 43, .12); }
.teams-panel .teams-documents-drawer__icon--sheet { color: #2e7d32; background: rgba(46, 125, 50, .12); }
.teams-panel .teams-documents-drawer__icon--word { color: #2b579a; background: rgba(43, 87, 154, .12); }
.teams-panel .teams-documents-drawer__icon--image { color: #b9770e; background: rgba(185, 119, 14, .14); }
.teams-panel .teams-documents-drawer__icon--video, .teams-panel .teams-documents-drawer__icon--audio { color: #8e44ad; background: rgba(142, 68, 173, .12); }
.teams-panel .teams-documents-drawer__text { display: grid; min-width: 0; }
.teams-panel .teams-documents-drawer__text strong, .teams-panel .teams-documents-drawer__text small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.teams-panel .teams-documents-drawer__text strong { font-size: 13px; font-weight: 600; }
.teams-panel .teams-documents-drawer__text small { color: var(--tm-text-1); font-size: 12px; }
.teams-panel .teams-documents-drawer__empty { margin: 40px 16px; color: var(--tm-text-1); text-align: center; }
.teams-panel .teams-documents-drawer__empty strong { color: var(--tm-msg-text); }
.teams-panel .teams-documents-drawer__empty p { font-size: 13px; }
.teams-panel .teams-documents-drawer footer { padding: 12px 14px; border-top: 1px solid var(--tm-border); background: var(--tm-surface); }
.teams-panel .teams-documents-drawer footer button { width: 100%; padding: 9px; border: 1px solid var(--tm-accent); border-radius: var(--tm-r); color: #fff; background: var(--tm-accent); font: 700 13px/1.25 var(--tm-font-ui); cursor: pointer; }
.teams-panel .teams-documents-drawer footer button:hover { background: var(--tm-accent-hover); }

/* Drag-and-drop upload: the overlay covers the whole card while a file is dragged over it. */
.teams-panel .teams-documents-drawer.is-uploading .teams-documents-drawer__body { opacity: .55; pointer-events: none; }
.teams-panel .teams-documents-drawer .teams-documents-drawer__drop { position: absolute; inset: 0; z-index: 2; display: flex; align-items: center; justify-content: center; gap: 8px; border: 2px dashed var(--tm-accent); border-radius: inherit; color: var(--tm-accent); background: var(--tm-accent-subtle); font-weight: 700; backdrop-filter: blur(2px); }
.teams-panel .teams-documents-drawer .teams-documents-drawer__drop[hidden] { display: none; }
.teams-panel .teams-documents-drawer .teams-documents-drawer__more { padding: 12px; color: var(--tm-text-1); font-size: 12px; text-align: center; }

/* Threads — the side panel, the reply-count footer under a root message, and the
   hover-pill button. Geometry mirrors the Files drawer (teams-documents-drawer.css):
   a floating card inside .teams-panel, so the --tm-* tokens and dark theme apply. */
/* The dock holds every open thread panel side by side, newest to the LEFT of the
   older ones. It passes clicks through everywhere but the panels themselves. */
.teams-panel .teams-thread-dock {
    position: fixed; 
    z-index: 1000; 
    top: 80px; 
    right: 10px; 
    bottom: 10px; 
    max-width: calc(100vw - 20px);
    /* `.teams-panel--real > *` makes every direct child of the panel full width; the dock is as wide as its panels. */
    width: max-content; 
    flex: none;
    display: flex; 
    flex-direction: row-reverse; 
    align-items: flex-end; 
    gap: 10px; 
    pointer-events: none;
}
.teams-panel .teams-thread-drawer {
    position: relative; pointer-events: auto;
    /* An explicit width, not just a flex-basis: the dock sizes itself to its panels, and a basis is
       not part of what it measures. */
    width: var(--tm-thread-width, 400px); flex: 0 1 auto; min-width: 300px; max-width: calc(100vw - 40px);
    height: var(--tm-thread-height, 100%); max-height: 100%;
    display: flex; flex-direction: column; overflow: hidden;
    /* No border: a drawer is a card lifted off the page by its shadow (a wide soft one plus a tight
       contact one), which reads on the busy photo backgrounds a border would disappear into. */
    border: 0; border-radius: 12px; color: var(--tm-text-2); background: var(--tm-bg);
    /* The third layer, offset upward, is what makes the shadow show above the drawer as well. */
    --thread-shadow: 0 18px 12px rgba(15, 23, 42, 0.34), 0 4px 12px rgba(15, 23, 42, 0.2), 0 -6px 12px rgba(15, 23, 42, 0.16);
    box-shadow: var(--thread-shadow);
    font-family: var(--tm-font-ui);
    opacity: 0; transform: translateX(38px);
    transition: opacity .28s ease, transform .42s cubic-bezier(.22, 1, .36, 1);
}
.teams-panel .teams-thread-drawer.is-open { opacity: 1; transform: translateX(0); }
@media (prefers-reduced-motion: reduce) { .teams-panel .teams-thread-drawer { transition: none; } }
/* On the dark theme a black shadow is invisible: a faint light halo takes its place. */
body.dark-theme .teams-panel .teams-thread-drawer { --thread-shadow: 0 18px 12px rgb(255 255 255 / 34%), 0 4px 12px rgb(121 161 255 / 20%), 0 -6px 12px rgb(121 161 255 / 20%); }
/* With several open, the one that has the composer is marked. */
.teams-panel .teams-thread-dock:has(> 
.teams-thread-drawer:nth-child(2)) > 
.teams-thread-drawer.is-active { 
   /* The drawer holding the composer lifts a little more than its neighbours. */
   box-shadow: var(--thread-shadow);
}

@media (max-width: 768px) {
    .teams-panel .teams-thread-dock { top: 0; right: 0; bottom: 0; left: 0; max-width: none; width: auto; }
    .teams-panel .teams-thread-drawer {
        flex: 1 1 100%; height: 100%; width: 100%; max-width: none; min-width: 0; border-radius: 0; box-shadow: none;
        padding: var(--safe-top, env(safe-area-inset-top, 0px)) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
    }
    .teams-panel .teams-thread-drawer__close { width: 44px; height: 44px; }
}

/* The drawer is its own size container: the header decides what to show from the drawer's width,
   not the window's. */
.teams-panel .teams-thread-drawer { container-type: inline-size; container-name: thread-drawer; }
.teams-panel .teams-thread-drawer__header { 
   display: flex; 
   flex-direction: column; 
   gap: 0; 
   padding: 8px 14px 8px 22px; 
   border-bottom: 1px solid var(--tm-border); 
   background: var(--tm-surface); 
}

/* One row that never wraps: the title gives way (ellipsis), the buttons never move down. */
.teams-panel .teams-thread-drawer__bar { display: flex; align-items: center; gap: 8px; min-width: 0; }
.teams-panel .teams-thread-drawer__title { display: inline-flex; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; color: var(--tm-msg-text); font: 600 15px/1.3 var(--tm-font-display); }
.teams-panel .teams-thread-drawer__title [data-thread-title] { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.teams-panel .teams-thread-drawer__close, .teams-panel .teams-thread-drawer__ai, .teams-panel .teams-thread-drawer__follow { flex: none; }
.teams-panel .teams-thread-drawer__close { width: 32px; height: 32px; border: 0; border-radius: 8px; color: var(--tm-text-1); background: transparent; cursor: pointer; }
.teams-panel .teams-thread-drawer__close:hover { color: var(--tm-accent); background: var(--tm-accent-subtle); }

.teams-panel .teams-thread-drawer__body { 
   flex: 1; 
   min-height: 0; 
   /* Top: room for the first message's reaction pill, which hangs 30px above its bubble. */
   padding: 30px 10px 40px 8px; 
   overflow-x: hidden; 
   overflow-y: auto; 
}

/* Nothing in a message may widen the drawer past itself: long words wrap, media scales. */
.teams-panel .teams-thread-drawer__body .teams-conversation, 
.teams-panel .teams-thread-drawer__body .teams-conversation__messages { 
   min-width: 0; 
   max-width: 100%; 
}

.teams-panel .teams-thread-drawer__body .teams-conversation__messages { 
   overflow-wrap: anywhere; 
}

.teams-panel .teams-thread-drawer__body .teams-conversation__messages > * { 
   min-width: 0; 
   max-width: 100%; 
}

.teams-panel .teams-thread-drawer__body .teams-msg { 
   min-width: 0; 
   max-width: 100%; 
}

.teams-panel .teams-thread-drawer__body .teams-msg__bubble, 
.teams-panel .teams-thread-drawer__body .teams-msg__text { 
   max-width: 100%; 
   overflow-wrap: anywhere; 
   font-size: 0.9rem;
}

.teams-panel .teams-thread-drawer__body .message-container-bot .bot-message, 
.teams-panel .teams-thread-drawer__body .internal-message-container .bot-message {
   font-size: 0.9rem;
   padding: 0;
}

.teams-panel .teams-thread-drawer__body .message-container-bot .bot-icon,
.teams-panel .teams-thread-drawer__body .internal-message-container .bot-icon {
   width: 20px;
   height: 20px;
   margin-right: 6px;
   margin-top: 5px;
}

.teams-panel .teams-thread-drawer__body img, .teams-panel .teams-thread-drawer__body video, .teams-panel .teams-thread-drawer__body table { max-width: 100%; height: auto; }
.teams-panel .teams-thread-drawer__body pre { max-width: 100%; overflow-x: auto; }
.teams-panel .teams-thread-drawer__status { padding: 16px 10px; color: var(--tm-text-1); font-size: 13px; text-align: center; }
.teams-panel .teams-thread-drawer__root { padding-bottom: 6px; }
.teams-panel .teams-thread-drawer__divider { height: 1px; margin: 6px 0 10px; background: var(--tm-border); }
.teams-panel .teams-thread-drawer__divider[hidden] { display: none; }

/* The chat's own composer slot is lent to this panel while it is open (teams-threads.js),
   so its chrome comes from teams-messages.css; only the frame is set here. */
/* Match the inactive reply field's gutter without changing the main composer. */
.teams-panel .teams-thread-drawer__composer {
    flex: none;
    position: relative;
    padding: 0 8px 8px;
}

.teams-panel .teams-thread-drawer__composer .teams-conversation__composer-slot :is(#inputContainer, .teams-thread-input) {
    padding: 0;
    gap: 0;
}

.teams-panel .teams-thread-drawer__composer :is(#inputContainer, .teams-thread-input) .input-row {
    position: relative;
    align-items: center;
    margin: 0;
}

.teams-panel .teams-thread-drawer__composer :is(#inputContainer, .teams-thread-input) :is(#userInput, .teams-thread-text-input),
.teams-panel .teams-thread-drawer__composer :is(#inputContainer, .teams-thread-input) .mention-input-highlight,
.teams-panel .teams-thread-drawer__composer :is(#inputContainer, .teams-thread-input) .teams-rich__editor {
    min-height: 40px;
    padding-top: 8px;
    padding-bottom: 8px;
    line-height: 22px;
}

/* The textarea's inline autosizing still wins as a reply grows. */
.teams-panel .teams-thread-drawer__composer :is(#inputContainer, .teams-thread-input) :is(#userInput, .teams-thread-text-input) {
    height: 40px;
}

.teams-panel .teams-thread-drawer__composer :is(#inputContainer, .teams-thread-input) .input-row :is(.file-upload-button, .teams-emoji-btn, .mic-button, .send-button) {
    top: 50%;
    bottom: auto;
    transform: translateY(-50%);
    margin-top: 0;
    margin-bottom: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* The "tag @Amby for an AI reply" hint is about the chat; AI is not available in a thread yet. */
.teams-panel .teams-thread-drawer__composer .teams-conversation__hint { display: none; }

/* In the chat's place while the composer is away: says where it went, brings it back. */
.teams-panel .teams-conversation__composer-away { display: flex; align-items: center; gap: 8px; width: 100%; margin: 0; padding: 12px 16px; border: 0; border-top: 1px solid var(--tm-border); color: var(--tm-text-1); background: var(--tm-surface); font: 13px/1.3 var(--tm-font-ui); text-align: left; cursor: pointer; }
.teams-panel .teams-conversation__composer-away:hover { background: var(--tm-accent-subtle); }
.teams-panel .teams-conversation__composer-away strong { color: var(--tm-accent); }

/* One handle in the top-left corner changes width and height together (the drawer is anchored
   bottom-right, so up and left is larger). */
.teams-panel .teams-thread-drawer__resizer { position: absolute; z-index: 3; top: 0; left: 0; width: 18px; height: 18px; cursor: nwse-resize; touch-action: none; }
.teams-panel .teams-thread-drawer__resizer::after { content: ""; position: absolute; top: 5px; left: 5px; width: 8px; height: 8px; border-top: 2px solid var(--tm-border-strong); border-left: 2px solid var(--tm-border-strong); border-top-left-radius: 3px; opacity: .55; transition: opacity var(--tm-t); }
.teams-panel .teams-thread-drawer__resizer:hover::after, body.amby-drawer-resizing-corner .teams-panel .teams-thread-drawer__resizer::after { opacity: 1; border-color: var(--tm-accent); }
body.amby-drawer-resizing-corner { cursor: nwse-resize; user-select: none; }
@media (max-width: 768px) { .teams-panel .teams-thread-drawer__resizer { display: none; } }

/* A panel that does not have the composer offers it; a closed request offers nothing but the reason. */
/* A drawer without the composer shows a composer's worth of box: there is ONE real composer (it moves to
   whichever drawer is clicked), so this stands in for it, looking the same. */
.teams-panel .teams-thread-drawer__activate { 
   display: flex; 
   align-items: center; 
   gap: 12px; 
   flex: none; 
   border: 0; 
   color: var(--tm-text-3); 
   background: var(--tm-surface); 
   font: 14px/1.3 var(--tm-font-ui); 
   text-align: left; 
   cursor: text; 
   box-shadow: inset 0 0 0 1px var(--tm-border); 
   border-radius: 22px; 
   margin: 0 8px 0; 
   width: calc(100% - 16px); 
   padding: 12px 16px; 
   border-top: 0; 
}

.teams-panel .teams-thread-drawer__activate i { color: var(--tm-text-1); font-size: 16px; }
.teams-panel .teams-thread-drawer__activate[hidden] { display: none; }
.teams-panel .teams-thread-drawer__activate:hover, .teams-panel .teams-thread-drawer__activate:focus-visible { color: var(--tm-text-1); box-shadow: inset 0 0 0 1px var(--tm-accent); outline: none; }
.teams-panel .teams-thread-drawer__readonly { flex: none; margin: 0; padding: 12px 14px; border-top: 1px solid var(--tm-border); color: var(--tm-text-2); background: var(--tm-surface); font: 13px/1.4 var(--tm-font-ui); }
.teams-panel .teams-thread-drawer__readonly[hidden], .teams-panel .teams-thread-drawer__also[hidden], .teams-panel .teams-thread-drawer__composer[hidden] { display: none; }

/* A desk request's case: its type and state (requester) or its countdown (desk team). */
/* The case gets its own row under the title bar: a countdown and "Mark resolved" do not fit beside the
   title and the buttons in a drawer that may be 300px wide. */
.teams-panel .teams-thread-drawer__case { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; min-width: 0; }
.teams-panel .teams-thread-drawer__case[hidden] { display: none; }
.teams-panel .teams-thread-drawer__case-type { padding: 1px 8px; border: 1px solid var(--tm-border); border-radius: 999px; background: var(--tm-white); color: var(--tm-text-2); font: 12px/1.4 var(--tm-font-ui); }
.teams-panel .teams-thread-drawer__case-state { color: var(--tm-text-2); font: 12px/1.3 var(--tm-font-ui); }
.teams-panel .teams-thread-drawer__case-state--resolved { color: var(--tm-accent); font-weight: 600; }
.teams-panel .teams-case-resolve-stack { display: flex; flex-direction: column; gap: 8px; padding-right: var(--tm-thread-dock-width, 0px); }
@media (max-width: 768px) {
    .teams-panel .teams-case-resolve-stack { padding-right: 0; }
}
.teams-panel .teams-case-resolve-stack[hidden] { display: none; }
.teams-panel .teams-case-resolve__case { margin: 0 0 4px; color: var(--tm-text-2); font: 600 12px/1.3 var(--tm-font-ui); }
.teams-panel .teams-case-resolve__open { margin-left: 6px; padding: 0; border: 0; background: transparent; color: var(--tm-accent); font: inherit; text-decoration: underline; cursor: pointer; }

/* "N replies · 2h ago" under a root message. */
.teams-panel .teams-msg__thread-footer { display: inline-flex; align-items: center; gap: 6px; margin-top: 4px; padding: 3px 8px; border: 0; border-radius: var(--tm-r); color: var(--tm-accent); background: transparent; font: 600 12px/1.3 var(--tm-font-ui); cursor: pointer; }
.teams-panel .teams-msg__thread-footer:hover { background: var(--tm-accent-subtle); }
.teams-panel .teams-msg__thread-last { color: var(--tm-text-3); font-weight: 400; }

/* The switch is per chat. Off: no "Reply in thread" pill, and a footer on an old
   root stays (history is not erased by turning the setting off). */
.teams-panel .teams-threads-off .teams-msg__action--thread { display: none; }

/* Transient "X replied in a thread" row at the foot of the transcript. */
.teams-panel .teams-conversation__messages .teams-thread-activity { display: flex; align-items: center; gap: 8px; margin: 8px auto; max-width: 90%; padding: 6px 12px; border: 1px solid var(--tm-border); border-radius: 999px; color: var(--tm-text-1); background: var(--tm-surface); font: 12px/1.3 var(--tm-font-ui); cursor: pointer; }
.teams-panel .teams-conversation__messages .teams-thread-activity span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.teams-panel .teams-conversation__messages .teams-thread-activity strong { color: var(--tm-accent); }
.teams-panel .teams-conversation__messages .teams-thread-activity:hover { background: var(--tm-accent-subtle); }

/* Header "Threads" list (teams-threads-list.js) — a popover under the button. */
.teams-panel .teams-threads-list { display: block; position: fixed; z-index: 1001; width: 380px; max-width: calc(100vw - 20px); max-height: min(78vh, 720px); overflow: auto; padding: 6px; border: 1px solid var(--tm-border); border-radius: 8px; background: var(--tm-bg); box-shadow: var(--tm-shadow-md); font-family: var(--tm-font-ui); }
.teams-panel .teams-threads-list__title { padding: 6px 8px 8px; color: var(--tm-text-3); font: 600 11px/1.2 var(--tm-font-ui); letter-spacing: .04em; text-transform: uppercase; }
.teams-panel .teams-threads-list__item { display: grid; gap: 2px; width: 100%; padding: 8px; border: 0; border-radius: var(--tm-r); color: var(--tm-msg-text); background: transparent; text-align: left; font: inherit; cursor: pointer; }
.teams-panel .teams-threads-list__item:hover { background: var(--tm-accent-subtle); }
.teams-panel .teams-threads-list__head { display: flex; gap: 6px; min-width: 0; font-size: 13px; }
.teams-panel .teams-threads-list__head strong { flex: none; white-space: nowrap; }
.teams-panel .teams-threads-list__head span { min-width: 0; overflow: hidden; color: var(--tm-text-1); text-overflow: ellipsis; white-space: nowrap; }
.teams-panel .teams-threads-list__meta { color: var(--tm-accent); font-size: 12px; font-weight: 600; }
@media (max-width: 768px) { .teams-panel .teams-threads-list { left: 10px; right: 10px !important; width: auto; max-width: none; } }

/* Panel header: follow toggle. */
.teams-panel .teams-thread-drawer__follow { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border: 1px solid var(--tm-border-strong); border-radius: 999px; color: var(--tm-text-1); background: transparent; font: 600 12px/1.2 var(--tm-font-ui); cursor: pointer; }
.teams-panel .teams-thread-drawer__follow[hidden] { display: none; }
.teams-panel .teams-thread-drawer__follow:hover { color: var(--tm-accent); border-color: var(--tm-accent); }
.teams-panel .teams-thread-drawer__follow.is-following { color: var(--tm-accent); border-color: var(--tm-accent); background: var(--tm-accent-subtle); }
/* Narrow drawer: the follow button is just the bell. */
@container thread-drawer (max-width: 420px) {
    .teams-panel .teams-thread-drawer__follow-label { display: none; }
    .teams-panel .teams-thread-drawer__follow { width: 32px; height: 32px; padding: 0; justify-content: center; }
}
.teams-panel .teams-thread-drawer__ai { width: 32px; height: 32px; border: 0; border-radius: 8px; color: var(--tm-text-1); background: transparent; cursor: pointer; }
.teams-panel .teams-thread-drawer__ai:hover { color: var(--tm-accent); background: var(--tm-accent-subtle); }

/* A long root is clamped so the replies stay in view. */
.teams-panel .teams-thread-drawer__root.is-clamped { max-height: 200px; overflow: hidden; -webkit-mask-image: linear-gradient(#000 70%, transparent); mask-image: linear-gradient(#000 70%, transparent); }
.teams-panel .teams-thread-drawer__root-toggle { display: block; margin: 2px 0 6px; padding: 2px 8px; border: 0; color: var(--tm-accent); background: transparent; font: 600 12px/1.3 var(--tm-font-ui); cursor: pointer; }

/* "Also send to chat", above the lent composer. */
.teams-panel .teams-thread-drawer__also { display: flex; align-items: center; gap: 6px; flex: none; padding: 6px 14px 0; border-top: 1px solid var(--tm-border); background: var(--tm-surface); color: var(--tm-text-1); font: 12px/1.3 var(--tm-font-ui); cursor: pointer; }
.teams-panel .teams-thread-drawer__also + .teams-thread-drawer__composer { border-top: 0; }
/* Inside the formatting toolbar: at its end, in front of the keyboard hint. */
.teams-panel .teams-thread-drawer__also.is-in-toolbar { margin-left: auto; padding: 0 0 0 10px; border: 0; background: transparent; white-space: nowrap; flex: 0 0 auto; }
.teams-panel .teams-thread-drawer__also.is-in-toolbar + .teams-rich__hint { margin-left: 0; min-width: 0; flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; }

/* Threads list: unread. */
.teams-panel .teams-threads-list__item.is-unread .teams-threads-list__head span { color: var(--tm-msg-text); font-weight: 600; }
.teams-panel .teams-threads-list__follow { margin-left: 6px; color: var(--tm-text-3); font-weight: 400; }

/* Ask AI drawer narrowed to a thread (teams-personal-ai.js). */
.teams-panel .teams-ai-drawer__scope { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; padding: 8px 14px; border-bottom: 1px solid var(--tm-border); color: var(--tm-text-1); font: 12px/1.3 var(--tm-font-ui); }
.teams-panel .teams-ai-drawer__scope[hidden] { display: none; }
.teams-panel .teams-ai-drawer__scope-label { display: inline-flex; align-items: center; gap: 6px; margin-right: 2px; }
.teams-panel .teams-ai-drawer__scope-opt { padding: 3px 10px; border: 1px solid var(--tm-border-strong); border-radius: 999px; color: var(--tm-text-1); background: transparent; font: 600 12px/1.3 var(--tm-font-ui); cursor: pointer; }
.teams-panel .teams-ai-drawer__scope-opt.is-on { color: #fff; border-color: var(--tm-accent); background: var(--tm-accent); }

/* A followed thread with replies you have not read. */
.teams-panel .teams-msg__thread-footer.has-unread .teams-msg__thread-count { font-weight: 700; }
.teams-panel .teams-msg__thread-new { padding: 1px 7px; border-radius: 999px; color: #fff; background: var(--tm-accent); font-size: 11px; font-weight: 700; }

/* Cross-chat list: which chat a thread is in; the empty state. */
.teams-panel .teams-threads-list__chat { color: var(--tm-text-3); font: 600 11px/1.2 var(--tm-font-ui); letter-spacing: .03em; text-transform: uppercase; }
.teams-panel .teams-threads-list__empty { padding: 14px 10px; color: var(--tm-text-1); font-size: 13px; text-align: center; }

/* Page-owned drawers survive tab changes; only the cards receive pointer input. */
.teams-panel.teams-thread-workspace { 
   position: fixed; 
   inset: 0; 
   z-index: 1000; 
   pointer-events: none; 
   background: transparent; 
}

.teams-thread-workspace .teams-thread-dock { 
   overflow-x: auto; 
   /* The dock is taller than its panels (bottom-aligned): let clicks through the empty part so
      whatever is behind it — the artifact drawer's tab, the chat — stays usable. The panels
      themselves are `pointer-events: auto` (see .teams-thread-drawer). */
   pointer-events: none; 
   height: min(1000px, calc(100dvh - 160px));
   top: auto; 
   bottom: 0; 
   padding: 0 10px;
}

.teams-panel .teams-thread-drawer__body .teams-msg__content {
   max-width: 90%;
}

.teams-thread-workspace .teams-thread-drawer { flex-shrink: 0; }
.teams-panel .teams-thread-drawer__participants { 
   display: flex; 
   align-items: center; 
   gap: 8px; 
   font-size: 12px; 
   min-width: 0; 
   margin-top: -8px; 
}

.teams-panel .teams-thread-drawer__participants[hidden] { display: none; }
.teams-panel .teams-thread-drawer__participants .teams-participant-chip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The independent composer uses the same surfaces as the shared input. Keep
   editor layers below the controls; a rich editor paints after those buttons. */
.teams-panel .teams-thread-input {
    position: relative; display: flex; flex-direction: column; width: 100%;
    border: 0; border-radius: 22px; background: transparent; box-shadow: none;
}
.teams-panel .teams-thread-input:is(:focus-within, .has-text) {
    background: var(--tm-real-white, #fff);
    box-shadow: 0 0 5px rgba(97, 98, 98, .5);
}
.teams-panel .teams-thread-input .input-row {
    position: relative; width: 100%; min-height: 40px; display: flex;
    align-items: center; background: transparent; border: 0; box-shadow: none;
}
.teams-panel .teams-thread-input .teams-thread-text-input {
    box-sizing: border-box; width: 100%; border: 1px solid var(--tm-border);
    border-radius: 22px; resize: none; background: var(--tm-surface);
    color: var(--tm-msg-text); font: 1rem/22px var(--tm-font-ui);
    padding: 8px 54px 8px 70px; outline: none; box-shadow: none;
}
.teams-panel .teams-thread-input:is(:focus-within, .has-text) .teams-thread-text-input {
    background: var(--tm-real-white, #fff); outline: none; box-shadow: none;
}
.teams-panel .teams-thread-input .teams-thread-text-input::placeholder { color: var(--tm-text-3); font-size: .95em; }
.teams-panel .teams-thread-input .teams-rich__editor { position: relative; z-index: 0; outline: none; box-shadow: none; }
.teams-panel .teams-thread-input .input-row :is(.file-upload-button, .teams-emoji-btn, .mic-button, .send-button) {
    position: absolute; z-index: 5; width: 30px; height: 32px; border: 0;
    padding: 0; margin: 0; border-radius: 50%; background: transparent;
    color: var(--tm-text-1); box-shadow: none; cursor: pointer;
    opacity: 1; visibility: visible; pointer-events: auto;
}
.teams-panel .teams-thread-input .file-upload-button { left: 8px; }
.teams-panel .teams-thread-input .teams-emoji-btn { left: 34px; }
.teams-panel .teams-thread-input :is(.mic-button, .send-button) { right: 12px; }
.teams-panel .teams-thread-input .send-button.has-content { background: transparent; box-shadow: none; color: var(--tm-msg-text); }
.teams-panel .teams-thread-input .input-row button:hover { background: var(--tm-accent-subtle); color: var(--tm-msg-text); }
.teams-panel .teams-thread-input .input-row button:focus-visible { outline: 2px solid var(--tm-accent); outline-offset: 2px; }
.teams-panel .teams-thread-input .send-button:not(.has-content), .teams-panel .teams-thread-input .mic-button.has-content { display: none !important; }
/* Popovers mounted on the page owner must receive clicks despite its transparent overlay. */
.teams-thread-workspace > :not(.teams-thread-dock) { pointer-events: auto; }
/* Phones: a drawer is the whole screen, one at a time (swipe sideways between
   several). It is sized from the VISIBLE viewport (teams-thread-workspace.js
   tracks it), so an open keyboard shortens it instead of pushing its header off
   the top. The drawer's own padding keeps its content out of the safe areas. */
@media (max-width: 768px) {
    .teams-thread-workspace .teams-thread-dock {
      inset: var(--thread-vv-top, 0px) 0 auto 0;
      height: var(--thread-vv-height, 100dvh);
      width: auto;
      max-width: none;
      padding: 0;
      gap: 0;
      scroll-snap-type: x mandatory;
   }
    .teams-thread-workspace .teams-thread-drawer {
      flex: 0 0 100vw;
      width: 100vw;
      max-width: 100vw;
      height: 100%;
      box-sizing: border-box; /* the safe-area padding is inside the screen, not added to it */
      border: 0;
      box-shadow: none;
      scroll-snap-align: start;
   }
    /* mobile-chat.css hides every `.file-upload-button` on a phone (`!important`); a thread
       reply can carry attachments like a chat message, so its "+" stays (teams-responsive.css
       does the same for the chat's own composer). */
    .teams-panel .teams-thread-input .input-row .file-upload-button { display: flex !important; }
    /* The keyboard covers the home indicator: no bottom inset above it. */
    .teams-thread-workspace.is-keyboard-open .teams-thread-drawer { padding-bottom: 0; }
    /* A full-screen drawer is what the person is looking at; minimizing it brings the bubbles back. */
    .teams-thread-workspace:has(.teams-thread-drawer:not(.is-minimized)) > .teams-thread-bubbles { display: none; }
}
/* With every drawer minimized the dock is empty, but still a box that takes
   touches (it scrolls) — on a phone, the whole screen. Nothing to show: no box. */
.teams-thread-workspace .teams-thread-dock:not(:has(> .teams-thread-drawer:not(.is-minimized))) { display: none; }

.teams-panel .teams-thread-input .mention-input-highlight { padding: 8px 54px 8px 70px; border: 1px solid transparent; line-height: 22px; }
.teams-panel .teams-thread-input .mention-input-shell > textarea { color: var(--tm-msg-text); caret-color: var(--tm-msg-text); }

.teams-thread-workspace .teams-thread-drawer__rename { border: 0; background: transparent; color: inherit; font: inherit; cursor: pointer; padding: 0; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.teams-thread-workspace .teams-thread-drawer__rename:hover { text-decoration: underline; }
.teams-thread-workspace .teams-thread-drawer__participants { flex-wrap: wrap; max-height: 150px; overflow-y: auto; }
.teams-thread-workspace .teams-thread-drawer__participants .teams-people-pill { cursor: pointer; }

/* Compact thread chrome; request metadata stays outside the scrolling transcript. */
.teams-panel .teams-thread-drawer__header { flex: none; padding: 10px; }
.teams-panel .teams-thread-drawer__bar { gap: 4px; }
.teams-panel .teams-thread-drawer__bar > .teams-avatar { 
   width: 30px; 
   height: 30px; 
   flex: 0 0 30px; 
   font-size: 13px; 
   margin: 0;
}

.teams-panel .teams-thread-drawer__bar .teams-thread-drawer__participants { flex: none; margin: 0; padding: 0; overflow: visible; }
.teams-panel .teams-thread-drawer__bar .teams-people-pill { padding: 3px 6px; }
.teams-panel .teams-thread-drawer__bar .teams-thread-drawer__close { width: 26px; height: 32px; flex: 0 0 26px; }
.teams-panel .teams-thread-drawer > .teams-thread-drawer__case { flex: none; margin: 0; padding: 8px 12px; border-bottom: 1px solid var(--tm-border); background: var(--tm-surface); }
.teams-panel .teams-thread-drawer > .teams-thread-drawer__case[hidden] { display: none; }
.teams-panel .teams-thread-drawer__root .teams-msg__bubble { background: color-mix(in srgb, var(--tm-surface) 85%, #eab94d); border: 1px solid color-mix(in srgb, var(--tm-border) 65%, #eab94d); }
.teams-panel .teams-thread-menu { position: absolute; top: 54px; right: 12px; z-index: 20; min-width: 210px; padding: 6px; border: 1px solid var(--tm-border); border-radius: 12px; background: var(--tm-surface); box-shadow: var(--tm-shadow-md); }
.teams-panel .teams-thread-menu[hidden] { display: none; }
.teams-panel .teams-thread-menu button { display: flex; gap: 12px; align-items: center; width: 100%; padding: 10px; border: 0; border-radius: 6px; background: transparent; color: var(--tm-text-1); text-align: left; cursor: pointer; }
.teams-panel .teams-thread-menu button:hover, .teams-panel .teams-thread-menu button:focus-visible { background: var(--tm-accent-subtle); }
.teams-panel .teams-thread-drawer.is-minimized { display: none; }
/* Transparent rail: never clip the circular controls' outlines into rectangles. */
.teams-panel .teams-thread-bubbles {
    position: fixed; z-index: 1002; right: 12px; bottom: min(100px, 15vh);
    display: flex; flex-direction: column; align-items: center; gap: 8px;
    width: 56px; padding: 4px; overflow: visible; pointer-events: none;
    background: transparent; border: 0; box-shadow: none;
}

.teams-panel .teams-thread-bubble { 
   position: relative; 
   flex: 0 0 52px; 
   width: 52px; 
   height: 52px; 
   border: 2px solid var(--active-workflow-bg); 
   border-radius: 50%; 
   padding: 4px; 
   background: var(--tm-surface); 
   box-shadow: none; 
   cursor: pointer; 
   pointer-events: auto; 
   color: var(--tm-text-1); 
}

.teams-panel .teams-thread-bubble .teams-avatar { width: 40px; height: 40px; }
.teams-panel .teams-thread-bubble > i { 
   position: absolute; 
   left: -1px; 
   top: 0; 
   padding: 3px; 
   font-size: 10px; 
   background: var(--tm-surface); 
   border-radius: 50%; 
}

.teams-panel .teams-thread-bubble:focus-visible { outline: 3px solid var(--tm-accent); outline-offset: 2px; }

.teams-panel .teams-thread-bubble .teams-avatar {
   margin-top: 0;
}
/* .teams-panel .teams-thread-drawer__root { border-radius: 10px; background: color-mix(in srgb, var(--tm-bg) 90%, #eab94d); } */

.teams-panel .teams-thread-bubble { display: grid; place-items: center; }
.teams-panel .teams-thread-bubble-item { position: relative; flex: 0 0 52px; width: 52px; height: 52px; }
.teams-panel .teams-thread-bubbles .teams-thread-bubble {
    transition: transform .18s cubic-bezier(.2, .8, .3, 1.3), box-shadow .18s ease;
}
.teams-panel .teams-thread-bubbles .teams-thread-bubble:hover,
.teams-panel .teams-thread-bubble-item:focus-within .teams-thread-bubble {
    transform: translateX(-4px) scale(1.12); box-shadow: 0 6px 16px rgba(0, 0, 0, .22);
}
.teams-panel .teams-thread-bubbles .teams-thread-bubble:active { transform: scale(.96); }
.teams-panel .teams-thread-bubbles.is-dragging .teams-thread-bubble { transform: none; box-shadow: none; }
.teams-panel .teams-thread-bubbles__close {
    position: absolute; right: -5px; bottom: -3px; z-index: 2; width: 20px; height: 20px; padding: 0;
    display: grid; place-items: center; border: 1px solid var(--tm-border); border-radius: 50%;
    background: var(--tm-surface); color: var(--tm-text-2, var(--tm-text-1)); font-size: 10px; cursor: pointer;
    pointer-events: auto; opacity: 0; transform: scale(.6);
    transition: opacity .15s ease, transform .15s ease, background .15s ease, color .15s ease;
}
.teams-panel .teams-thread-bubble-item:hover .teams-thread-bubbles__close,
.teams-panel .teams-thread-bubble-item:focus-within .teams-thread-bubbles__close { opacity: 1; transform: scale(1); }
.teams-panel .teams-thread-bubbles__close:hover { background: #c62b37; border-color: #c62b37; color: #fff; }
@media (hover: none) {
    .teams-panel .teams-thread-bubbles__close { opacity: 1; transform: scale(1); }
}
.teams-panel .teams-thread-bubbles__overflow .teams-thread-bubbles__overflow-row { display: flex; gap: 6px; align-items: center; margin-top: 6px; }
.teams-panel .teams-thread-bubbles__overflow .teams-thread-bubbles__overflow-row > button:first-child { flex: 1; margin-top: 0; width: auto; }
.teams-panel .teams-thread-bubbles__overflow .teams-thread-bubbles__close { position: static; flex: 0 0 24px; width: 24px; height: 24px; opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
    .teams-panel .teams-thread-bubbles .teams-thread-bubble,
    .teams-panel .teams-thread-bubbles__close { transition: none; }
    .teams-panel .teams-thread-bubbles .teams-thread-bubble:hover { transform: none; }
}
@media (min-width: 769px) {
    .teams-panel:has(> .teams-thread-bubbles) .teams-thread-dock { right: 78px; max-width: calc(100vw - 88px); }
}

/* Sender photos share the attribution row, leaving no avatar gutter beside bubbles. */
.teams-panel .teams-thread-drawer__body .teams-msg > .teams-msg__body { 
   width: 100%; 
}

.teams-panel .teams-thread-drawer__body .teams-msg__meta { 
   align-items: center; 
   gap: 6px; 
   min-height: 22px; 
   margin-bottom: 5px; 
}

.teams-panel .teams-thread-drawer__body .teams-msg--mine .teams-msg__meta {
   margin-bottom: 0;
}

.teams-panel .teams-thread-drawer__body .teams-msg__meta > .teams-avatar { 
   width: 20px; 
   height: 20px; 
   flex: 0 0 22px; 
   font-size: 10px; 
   margin: 0;
}

.teams-panel .teams-thread-drawer__body .teams-msg__meta > .teams-avatar .teams-presence-badge { 
   width: 7px; 
   height: 7px; 
   border-width: 1px; 
}

/* Minimized thread controls are scoped to the page-owned stack. */
.teams-panel .teams-thread-bubbles :is(.teams-thread-bubble, .teams-thread-bubbles__move) { touch-action: none; user-select: none; -webkit-user-select: none; }
.teams-panel .teams-thread-bubbles img { -webkit-user-drag: none; pointer-events: none; }
.teams-panel .teams-thread-bubbles [hidden] { display: none !important; }
.teams-panel .teams-thread-bubbles__move, .teams-panel .teams-thread-bubbles__more {
    pointer-events: auto; border: 1px solid var(--tm-border); background: var(--tm-surface);
    color: var(--tm-text-1); border-radius: 999px; font: 600 13px/1.2 var(--tm-font-ui);
    cursor: pointer; padding: 6px;
}
.teams-panel .teams-thread-bubbles__move { width: 40px; height: 28px; cursor: grab; }
.teams-panel .teams-thread-bubbles.is-dragging, .teams-panel .teams-thread-bubbles.is-dragging button { cursor: grabbing; }
.teams-panel .teams-thread-bubbles__more { width: 48px; height: 40px; }
.teams-panel .teams-thread-bubbles__more.has-unread { border: 2px solid var(--tm-accent); font-weight: 800; }
.teams-panel .teams-thread-bubble__unread {
    position: absolute; top: -4px; right: -5px; min-width: 20px; height: 20px;
    box-sizing: border-box; padding: 0 4px; border-radius: 999px;
    background: #c62b37; color: #fff; border: 2px solid var(--tm-surface);
    font: 700 11px/16px var(--tm-font-ui); text-align: center;
}
.teams-panel :is(.teams-thread-bubbles__overflow, .teams-thread-bubbles__preview) {
    position: fixed; box-sizing: border-box; pointer-events: auto; padding: 12px;
    max-height: min(420px, calc(100dvh - 16px)); overflow-y: auto;
    border: 1px solid var(--tm-border); border-radius: 12px; background: var(--tm-surface);
    color: var(--tm-text-1); box-shadow: var(--tm-shadow-sm); font: 13px/1.4 var(--tm-font-ui);
    overflow-wrap: anywhere;
}
.teams-panel :is(.teams-thread-bubbles__overflow, .teams-thread-bubbles__preview) p { margin: 0 0 10px; }
.teams-panel .teams-thread-bubbles__preview strong { display: block; margin-bottom: 6px; }
.teams-panel :is(.teams-thread-bubbles__overflow, .teams-thread-bubbles__preview) button {
    border: 1px solid var(--tm-border); border-radius: 7px; padding: 8px 10px;
    background: var(--tm-surface); color: var(--tm-text-1); font: inherit; cursor: pointer;
}
.teams-panel .teams-thread-bubbles__preview button + button { margin-left: 8px; }
.teams-panel .teams-thread-bubbles__overflow button { display: block; width: 100%; margin-top: 6px; text-align: left; }
.teams-panel .teams-thread-bubbles button:focus-visible { outline: 2px solid var(--tm-accent); outline-offset: 2px; }
.teams-panel :is(.teams-thread-bubbles__overflow, .teams-thread-bubbles__preview) button:hover { background: var(--tm-accent-subtle); }

/* Keep the notch outside the card while long previews scroll inside it. */
.teams-panel .teams-thread-bubbles__preview { overflow: visible; padding: 0; }
.teams-panel .teams-thread-bubbles__preview-content { padding: 12px; max-height: min(394px, calc(100dvh - 42px)); overflow-y: auto; }
.teams-panel .teams-thread-bubbles__preview::after {
    content: ''; position: absolute; width: 10px; height: 10px;
    background: var(--tm-surface); border: solid var(--tm-border); border-width: 0;
    transform: rotate(45deg); pointer-events: none;
}
.teams-panel .teams-thread-bubbles__preview[data-anchor-side="right"]::after { right: -6px; top: calc(var(--thread-notch-offset) - 5px); border-top-width: 1px; border-right-width: 1px; }
.teams-panel .teams-thread-bubbles__preview[data-anchor-side="left"]::after { left: -6px; top: calc(var(--thread-notch-offset) - 5px); border-bottom-width: 1px; border-left-width: 1px; }
.teams-panel .teams-thread-bubbles__preview[data-anchor-side="bottom"]::after { bottom: -6px; left: calc(var(--thread-notch-offset) - 5px); border-bottom-width: 1px; border-right-width: 1px; }
.teams-panel .teams-thread-bubbles__preview[data-anchor-side="top"]::after { top: -6px; left: calc(var(--thread-notch-offset) - 5px); border-top-width: 1px; border-left-width: 1px; }

/* A reply that arrived in an open drawer nobody has touched: a count on the avatar's corner (like a
   minimized bubble's), so the title keeps its width, plus an accent edge on the drawer. */
.teams-panel .teams-thread-drawer .teams-thread-drawer__bar { position: relative; }
.teams-panel .teams-thread-drawer .teams-thread-drawer__unread {
    position: absolute; top: -7px; left: 20px; z-index: 2; box-sizing: border-box;
    min-width: 20px; height: 20px; padding: 0 5px; border-radius: 999px;
    background: #c62b37; color: #fff; border: 2px solid var(--tm-surface);
    font: 700 11px/16px var(--tm-font-ui); text-align: center; pointer-events: none;
}
.teams-panel .teams-thread-drawer .teams-thread-drawer__unread[hidden] { display: none; }
.teams-panel .teams-thread-drawer.has-unread { box-shadow: inset 3px 0 0 var(--tm-accent), var(--tm-shadow-md); }

/* The Threads popovers: each thread is its own card. Three states read at a glance —
   UNREAD: accent bar, full-strength text, a filled "N new" pill;
   OPEN in a drawer: tinted background;
   anything else: plain and muted. The whole card is the click target. */
.teams-panel .teams-threads-list .teams-threads-list__item {
    position: relative; 
    margin-top: 8px; 
    padding: 9px 16px;
    border: 1px solid var(--tm-border); 
    border-radius: 10px; 
    background: var(--tm-surface);
    background: var(--tm-real-white);
}
.teams-panel .teams-threads-list .teams-threads-list__title + .teams-threads-list__item { margin-top: 0; }

.teams-panel .teams-threads-list .teams-threads-list__item.is-open:hover {
    border: none;
}

.teams-panel .teams-threads-list .teams-threads-list__item:hover { 
    border-color: var(--tm-accent); 
}

.teams-panel .teams-threads-list .teams-threads-list__item.is-open { 
    background: var(--tm-accent-subtle); 
    cursor: auto;
}

.teams-panel .teams-threads-list .teams-threads-list__item.is-unread { border-color: var(--tm-accent); box-shadow: inset 4px 0 0 var(--tm-accent); }
.teams-panel .teams-threads-list .teams-threads-list__head strong { color: var(--tm-text-1); font-weight: 600; }
.teams-panel .teams-threads-list .teams-threads-list__item.is-unread .teams-threads-list__head strong { color: var(--tm-msg-text); font-weight: 800; }
.teams-panel .teams-threads-list .teams-threads-list__new {
   position: absolute;
   top: 2px;
   right: 3px;
   padding: 1px 8px;
   border-radius: 999px;
   background: var(--tm-accent);
   color: #fff;
   font: 700 11px / 18px var(--tm-font-ui);
}

/* ── Phones: the drawer's composer looks and behaves like the chat's own ───────
   The reply box is built like the shared composer (`.input-container`), so
   mobile-chat.css pins it `position: fixed` and lifts it by the keyboard height.
   The drawer is already sized from the visible viewport (teams-thread-workspace.js),
   so that lifted it twice and left the box floating over the transcript. Here it is
   an ordinary in-flow block, with the same pill field, "+" and mic/send placement
   the chat uses (teams-responsive.css, mobile-chat.css). */
@media (max-width: 768px) {
    body .teams-thread-drawer .teams-thread-drawer__composer {
        padding: 0;
    }
    body .teams-thread-drawer .teams-thread-input.input-container {
        position: relative;
        inset: auto;
        transform: none;
        width: 100%;
        padding: 5px;
        padding-bottom: max(5px, env(safe-area-inset-bottom, 0px));
        box-sizing: border-box;
        border-radius: 0;
        background: transparent;
        box-shadow: none;
        transition: none;
    }
    body .teams-thread-workspace.is-keyboard-open .teams-thread-drawer .teams-thread-input.input-container {
        padding-bottom: 5px;
    }
    body .teams-thread-drawer .teams-thread-input .input-row {
        min-height: 44px;
        overflow: visible;
        box-shadow: none;
    }
    body .teams-thread-drawer .teams-thread-input .teams-thread-text-input {
        min-height: 44px;
        max-height: 150px;
        padding: 10px 50px 10px 44px;
        font-size: 16px;
        line-height: 22px;
        border: 0;
        border-radius: 22px;
        background: #fff;
        box-shadow: 0 0 5px rgba(97, 98, 98, 0.35);
        color: #2b2b2b;
    }
    body .teams-thread-drawer .teams-thread-input:is(:focus-within, .has-text) .teams-thread-text-input {
        background: #fff;
        color: #2b2b2b;
        box-shadow: 0 0 5px rgba(97, 98, 98, 0.5);
    }
    body .teams-thread-drawer .teams-thread-input .mention-input-highlight { padding: 10px 50px 10px 44px; }
    body .teams-thread-drawer .teams-thread-input .teams-emoji-btn { display: none !important; }
    body .teams-thread-drawer .teams-thread-input .input-row :is(.file-upload-button, .mic-button, .send-button) {
        top: 50%;
        width: 42px;
        height: 42px;
        transform: translateY(-50%);
        -webkit-tap-highlight-color: transparent;
    }
    body .teams-thread-drawer .teams-thread-input .file-upload-button { left: 0; }
    body .teams-thread-drawer .teams-thread-input :is(.mic-button, .send-button) { right: 0; }
    body .teams-thread-drawer .teams-thread-input .input-row i { font-size: 18px; }
    /* "Also send to chat" lives under "+" → Delivery options; this note shows it is on. */
    body .teams-thread-drawer .teams-thread-drawer__also { display: none; }
    body .teams-thread-drawer .teams-thread-drawer__also-note {
        display: flex; align-items: center; gap: 6px; margin: 0 12px 2px; padding: 4px 10px;
        border: 0; border-radius: 999px; background: var(--tm-accent-subtle); color: var(--tm-text-1);
        font: 12px/1.3 var(--tm-font-ui); align-self: flex-start;
    }
    body .teams-thread-drawer .teams-thread-drawer__also-note[hidden] { display: none; }
}
@media (min-width: 769px) {
    .teams-thread-drawer .teams-thread-drawer__also-note { display: none; }
}

/* The reaction / reply pill must stay inside the drawer. Anchored to a short incoming bubble's
   right edge (the chat's desktop rule) its 190px grow leftward past the drawer's edge, where the
   body clips it — so the quick reactions could not be reached. It grows into the drawer instead. */
.teams-panel .teams-thread-drawer__body .teams-msg:not(.teams-msg--mine) .teams-msg__actions {
    left: 0;
    right: auto;
}
.teams-panel .teams-thread-drawer__body .teams-msg--mine .teams-msg__actions {
    left: auto;
    right: 0;
}

/* Thread list: search + "Unread only" row, sticky above the rows. */
.teams-panel .teams-threads-list .teams-threads-list__tools { display: none; }
.teams-panel .teams-threads-list.has-controls .teams-threads-list__tools { position: sticky; top: 0; z-index: 1; display: flex; gap: 6px; align-items: center; padding: 2px 2px 8px; background: var(--tm-bg); }
.teams-panel .teams-threads-list .teams-threads-list__search { flex: 1; min-width: 0; padding: 6px 10px; border: 1px solid var(--tm-border); border-radius: 999px; color: var(--tm-msg-text); background: var(--tm-surface); font: 13px/1.3 var(--tm-font-ui); outline: none; }
.teams-panel .teams-threads-list .teams-threads-list__search:focus { border-color: var(--tm-accent); }
.teams-panel .teams-threads-list .teams-threads-list__chip { flex: none; padding: 5px 11px; border: 1px solid var(--tm-border-strong); border-radius: 999px; color: var(--tm-text-1); background: transparent; font: 600 12px/1.2 var(--tm-font-ui); cursor: pointer; white-space: nowrap; }
.teams-panel .teams-threads-list .teams-threads-list__chip.is-on { color: var(--tm-accent); border-color: var(--tm-accent); background: var(--tm-accent-subtle); }
.teams-panel .teams-threads-list .teams-threads-list__label { color: var(--tm-text-3); font-style: normal; font-weight: 600; }
.teams-panel .teams-threads-list .teams-threads-list__empty { padding: 14px 8px; color: var(--tm-text-3); font-size: 13px; text-align: center; }

/* Scroll-to-latest arrow inside a drawer (teams-thread-panel.js). */
.teams-panel .teams-thread-drawer__body .teams-thread-drawer__jump-wrap { position: sticky; bottom: 6px; height: 0; z-index: 5; }
.teams-panel .teams-thread-drawer__body .teams-thread-drawer__jump { position: absolute; right: 4px; bottom: 0; display: flex; align-items: center; justify-content: center; width: 34px; height: 34px; border: 1px solid var(--tm-border); border-radius: 50%; color: var(--tm-text-2); background: var(--tm-white); box-shadow: var(--tm-shadow-md); cursor: pointer; }
.teams-panel .teams-thread-drawer__body .teams-thread-drawer__jump:hover { color: var(--tm-accent); }
.teams-panel .teams-thread-drawer__body .teams-thread-drawer__jump[hidden] { display: none; }

/* Short actions bar over a text selection inside one message. */
/* Selection actions bar — the short pill over selected text inside one message
 * (teams-selection-bar.js). Lives inside the message element, positioned
 * relative to it like the hover pill, so it inherits the --tm-* tokens. */

.teams-panel .teams-msg__selbar {
    position: absolute;
    z-index: 4;
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 2px;
    border: 1px solid var(--tm-border);
    border-radius: 999px;
    background: var(--tm-white);
    box-shadow: var(--tm-shadow-md);
    white-space: nowrap;
    /* Controls, not message text: never part of a selection or a copy. */
    -webkit-user-select: none;
    user-select: none;
    animation: teams-selbar-in 0.12s ease-out;
}

.teams-panel .teams-msg__selbar .teams-msg__selbar-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: inherit;
    font-size: 0.85rem;
    cursor: pointer;
    transition: background var(--tm-t);
}

.teams-panel .teams-msg__selbar .teams-msg__selbar-btn[hidden] {
    display: none;
}

.teams-panel .teams-msg__selbar .teams-msg__selbar-btn:hover,
.teams-panel .teams-msg__selbar .teams-msg__selbar-btn:focus-visible {
    background: rgba(0, 0, 0, 0.07);
}

/* The selection bar stands in for the hover pill while it shows. */
.teams-panel .teams-msg--selecting .teams-msg__actions {
    opacity: 0 !important;
    pointer-events: none !important;
}

@keyframes teams-selbar-in {
    from { opacity: 0; transform: translateY(3px); }
    to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .teams-panel .teams-msg__selbar { animation: none; }
}

/* Thread started from a selection: the excerpt stands in for the root message. */
.teams-panel .teams-thread-drawer__excerpt {
    display: flex;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 8px;
    margin: 8px 12px;
    padding: 10px 12px;
    border-left: 3px solid var(--tm-border);
    border-radius: 8px;
    background: rgba(0, 0, 0, 0.04);
    font-size: 0.95rem;
}

.teams-panel .teams-thread-drawer__excerpt .teams-thread-drawer__excerpt-text {
    flex: 1;
    min-width: 0;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.teams-panel .teams-thread-drawer__excerpt .teams-thread-drawer__excerpt-toggle {
    border: none;
    background: none;
    padding: 0;
    font-size: 0.8rem;
    color: inherit;
    opacity: 0.7;
    cursor: pointer;
    text-decoration: underline;
}

/* Followed threads as sub-rows under a chat in Recent sessions
   (teams-sidebar-threads.js). They live inside the row's .session-content, so
   they follow the row through sorting, folders and rebuilds. */
.sidebar[data-mode="teams"] .session-item .session-threads { margin: 3px 0 2px; }
/* The one-line indicator that is all a collapsed chat shows. */
.sidebar[data-mode="teams"] .session-item .session-threads__toggle {
    display: flex; align-items: center; gap: 6px; max-width: 100%; padding: 2px 6px 2px 2px;
    border: 0; border-radius: 6px; color: var(--tm-text-1, inherit); background: transparent;
    font: 600 11px/1.3 var(--tm-font-ui, inherit); cursor: pointer;
}
.sidebar[data-mode="teams"] .session-item .session-threads__toggle:hover { background: var(--tm-accent-subtle, rgba(37, 99, 235, .1)); }
.sidebar[data-mode="teams"] .session-item .session-threads__toggle.has-new { color: var(--tm-accent, #2563eb); }
.sidebar[data-mode="teams"] .session-item .session-threads__chevron { width: 8px; font-size: 8px; transition: transform .15s ease; }
.sidebar[data-mode="teams"] .session-item .session-threads.is-expanded .session-threads__chevron { transform: rotate(90deg); }
.sidebar[data-mode="teams"] .session-item .session-threads__list {
    display: flex; flex-direction: column; gap: 1px; margin: 2px 0 0 4px; padding-left: 8px;
    border-left: 2px solid var(--tm-border, rgba(127, 127, 127, .25));
}
.sidebar[data-mode="teams"] .session-item .session-threads__list[hidden] { display: none; }
.sidebar[data-mode="teams"] .session-item .session-thread {
    display: flex; align-items: center; gap: 6px; width: 100%; min-width: 0; padding: 3px 6px;
    border: 0; border-radius: 6px; color: var(--tm-text-1, inherit); background: transparent;
    font: 12px/1.3 var(--tm-font-ui, inherit); text-align: left; cursor: pointer;
}
.sidebar[data-mode="teams"] .session-item .session-thread:hover { background: var(--tm-accent-subtle, rgba(37, 99, 235, .1)); }
.sidebar[data-mode="teams"] .session-item .session-thread i { flex: none; opacity: .7; font-size: 11px; }
.sidebar[data-mode="teams"] .session-item .session-thread__text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar[data-mode="teams"] .session-item .session-thread.is-unread { color: var(--tm-msg-text, inherit); font-weight: 600; }
.sidebar[data-mode="teams"] .session-item .session-thread.is-unread i { color: var(--tm-accent, #2563eb); opacity: 1; }
.sidebar[data-mode="teams"] .session-item .session-thread__new {
    flex: none; min-width: 16px; padding: 0 5px; border-radius: 999px; color: #fff;
    background: var(--tm-accent, #2563eb); font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}
.sidebar[data-mode="teams"] .session-item .session-thread--more { color: var(--tm-text-3, inherit); font-size: 11px; cursor: inherit; }
/* "+N more" expands the list in place; "N closed requests" opens the chat. */
.sidebar[data-mode="teams"] .session-item button.session-thread--more { cursor: pointer; }
.sidebar[data-mode="teams"] .session-item .session-thread--closed { font-style: italic; }
/* The collapsed rail shows icons only. */
.sidebar[data-mode="teams"].collapsed .session-item .session-threads { display: none; }

#sessionsList .session-thread.is-open { box-shadow: inset 3px 0 var(--tm-accent, #2d5f84); }
#sessionsList .session-thread__open { flex: none; font-size: 10px; color: var(--tm-accent, #2d5f84); margin-left: auto; }

/* My action items (Reminders-style) + personal list colours. */
/* ═══════════════════════════════════════════════════════════════════════════
   Amby Teams — "My action items" (Reminders-style) + personal lists
   ═══════════════════════════════════════════════════════════════════════════
   teams-action-items-view.js — THE panel for a chat's Action list and My
   action items (collapsible sidebar beside the items, cards, resize, FAB) —
   teams-action-list-editor.js (a list's name + colour), the List row and the
   toggles of the item form.

   Scoped under .teams-panel (the view is mounted inside it) and
   .teams-action-form-overlay (body-appended modals carrying the same tokens).
   CLAUDE.md rule 2.

   LIST COLOURS are palette keys (migration 418's CHECK), mapped here to tones
   that read on both themes. Nothing else may hard-code a list colour.
   ─────────────────────────────────────────────────────────────────────────── */

.teams-panel,
.teams-modal-overlay {
    --ai-list-red: #e5484d;
    --ai-list-orange: #f2811d;
    --ai-list-yellow: #d9a400;
    --ai-list-green: #30a46c;
    --ai-list-teal: #12a594;
    --ai-list-blue: #0a84ff;
    --ai-list-indigo: #5856d6;
    --ai-list-purple: #af52de;
    --ai-list-pink: #e93d82;
    --ai-list-brown: #a2845e;
    --ai-list-gray: #8e8e93;
    /* An item card on the panel's background. */
    --ai-card-bg: #fff;
}
body.dark-theme .teams-panel,
body.dark-theme .teams-modal-overlay {
    --ai-list-red: #ff6369;
    --ai-list-orange: #ff9f45;
    --ai-list-yellow: #f5c518;
    --ai-list-green: #4cc38a;
    --ai-list-teal: #2ec4b6;
    --ai-list-blue: #409cff;
    --ai-list-indigo: #7d7aff;
    --ai-list-purple: #c77dff;
    --ai-list-pink: #ff6fa3;
    --ai-list-brown: #c4a57f;
    --ai-list-gray: #a1a1a6;
    --ai-card-bg: var(--tm-white);
}

/* ── The view: desktop = one wide card, two panes ───────────────────────── */
.teams-panel .teams-reminders {
    position: fixed;
    top: 80px;
    right: 10px;
    bottom: 10px;
    z-index: 1000;
    /* --ai-panel-width is the ITEMS column, dragged by the left-edge handle and
       remembered per browser. The sidebar opens beside it, never into it. */
    --ai-sidebar-width: 300px;
    --ai-items-width: min(var(--ai-panel-width, 450px), calc(100vw - 22px));
    box-sizing: content-box;
    width: var(--ai-items-width);
    /* Items pinned to the right edge at their own width; the sidebar sits to
       their left and is revealed as the panel widens. Toggling it animates the
       panel's width only — the items never reflow (flex-end lets the sidebar
       overflow the start edge, which the panel clips). */
    display: flex;
    justify-content: flex-end;
    background: var(--tm-bg);
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r-lg);
    box-shadow: var(--tm-shadow-md);
    font-family: var(--tm-font-ui);
    color: var(--tm-text-2);
    overflow: hidden;
    opacity: 0;
    transform: translateX(38px);
    transition: opacity 0.24s ease, transform 0.36s cubic-bezier(0.22, 1, 0.36, 1),
                width 0.24s cubic-bezier(0.22, 1, 0.36, 1);
}
body.amby-action-list-resizing .teams-panel .teams-reminders {
    transition: none;    /* the handle drives the width directly */
}
.teams-panel .teams-reminders.is-open {
    opacity: 1;
    transform: none;
}
.teams-panel .teams-reminders [hidden] {
    display: none !important;
}
/* The sidebar (tiles + My lists) is collapsed by default; the header toggle shows it. */
.teams-panel .teams-reminders.is-sidebar-open {
    width: min(calc(var(--ai-items-width) + var(--ai-sidebar-width)), calc(100vw - 22px));
}
/* Collapsed: still laid out (so closing can slide it away), but invisible to
   pointer, keyboard and screen readers once the width transition ends. */
.teams-panel .teams-reminders:not(.is-sidebar-open) .teams-reminders__overview {
    visibility: hidden;
    transition: visibility 0s linear 0.24s;
}
.teams-panel .teams-reminders.is-sidebar-open .teams-reminders__sidebar-toggle {
    color: var(--tm-accent);
    background: var(--tm-accent-subtle);
}

/* Left-edge handle: drag to resize (desktop). */
.teams-panel .teams-reminders__resizer {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 3;
    width: 8px;
    cursor: col-resize;
    touch-action: none;
}
.teams-panel .teams-reminders__resizer::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 2px;
    width: 4px;
    height: 40px;
    border-radius: 2px;
    background: var(--tm-border-strong);
    transform: translateY(-50%);
    opacity: 0;
    transition: opacity var(--tm-t);
}
.teams-panel .teams-reminders__resizer:hover::after,
body.amby-action-list-resizing .teams-panel .teams-reminders__resizer::after {
    opacity: 1;
}
body.amby-action-list-resizing {
    cursor: col-resize;
    user-select: none;
}

.teams-panel .teams-reminders__overview {
    flex: 0 0 var(--ai-sidebar-width);
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow-y: auto;
    padding: 0 14px 16px;
    background: var(--tm-surface);
    border-right: 1px solid var(--tm-border);
}
.teams-panel .teams-reminders__view {
    flex: 0 0 var(--ai-items-width);
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
}

.teams-panel .teams-reminders__bar {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 56px;
    padding: 8px 0;
}
.teams-panel .teams-reminders__view .teams-reminders__bar {
    padding: 10px 16px;
    border-bottom: 1px solid var(--tm-border);
}
.teams-panel .teams-reminders__heading {
    margin: 0 auto 0 0;
    font: 600 15px/1.2 var(--tm-font-display);
    color: var(--tm-msg-text);
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.teams-panel .teams-reminders__title {
    margin: 0 auto 0 0;
    font: 700 24px/1.15 var(--tm-font-display);
    color: var(--tm-msg-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-panel .teams-reminders__icon-btn {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--tm-text-1);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}
.teams-panel .teams-reminders__icon-btn:hover {
    background: var(--tm-accent-subtle);
}
.teams-panel .teams-reminders__sidebar-toggle {
    font-size: 15px;
}
.teams-panel .teams-reminders__sidebar-close {
    display: none;   /* desktop: the items' header toggle is the one control */
    font-size: 14px;
    color: var(--tm-text-3);
}

/* "+ New" floats in the bottom-right corner of the items. */
.teams-panel .teams-reminders__fab {
    position: absolute;
    right: 20px;
    bottom: 20px;
    z-index: 2;
    min-height: 44px;
    padding: 0 20px;
    border-radius: 22px;
    box-shadow: var(--tm-shadow-md);
    font-size: 15px;
}

/* ── Smart tiles ─────────────────────────────────────────────────────────── */
.teams-panel .teams-reminders__tiles {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin-top: 12px;
}

.teams-panel .teams-reminders__tile:hover {
    opacity: 1;
}

.teams-panel .teams-reminders__tile {
    position: relative;
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-rows: auto auto;
    align-items: center;
    gap: 6px 8px;
    min-height: 74px;
    padding: 10px 12px;
    border: 2px solid transparent;
    border-radius: 12px;
    color: #fff;
    text-align: left;
    cursor: pointer;
    box-shadow: var(--tm-shadow-sm);
    transition: transform var(--tm-t), border-color var(--tm-t);
    opacity: 0.8;
}

.teams-panel .teams-reminders__tile:active {
    transform: scale(0.97);
}
.teams-panel .teams-reminders__tile.is-selected {
    box-shadow: var(--tm-shadow-md);
    opacity: 1;
}

.teams-panel .teams-reminders__tile--blue { background: var(--ai-list-blue); }
.teams-panel .teams-reminders__tile--red { background: var(--ai-list-red); }
.teams-panel .teams-reminders__tile--ink { background: #3a3a3c; }
.teams-panel .teams-reminders__tile--green { background: var(--ai-list-green); }
.teams-panel .teams-reminders__tile--gray { background: var(--ai-list-gray); }
.teams-panel .teams-reminders__tile--orange { background: var(--ai-list-orange); }
.teams-panel .teams-reminders__tile-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.25);
    font-size: 14px;
}
.teams-panel .teams-reminders__tile-count {
    justify-self: end;
    font: 700 24px/1 var(--tm-font-display);
}
.teams-panel .teams-reminders__tile-label {
    grid-column: 1 / -1;
    font: 600 14px var(--tm-font-ui);
}

/* ── My lists ────────────────────────────────────────────────────────────── */
.teams-panel .teams-reminders__lists-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 20px 2px 6px;
    font: 600 12px var(--tm-font-ui);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--tm-text-3);
}
.teams-panel .teams-reminders__add-list {
    border: none;
    background: transparent;
    color: var(--tm-accent);
    font: 500 13px var(--tm-font-ui);
    text-transform: none;
    letter-spacing: 0;
    cursor: pointer;
}
.teams-panel .teams-reminders__lists {
    list-style: none;
    margin: 0;
    padding: 0;
}
.teams-panel .teams-reminders__list {
    display: flex;
    align-items: center;
    border-radius: 10px;
}
.teams-panel .teams-reminders__list.is-selected,
.teams-panel .teams-reminders__list:hover {
    background: var(--tm-accent-subtle);
}
.teams-panel .teams-reminders__list-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 6px;
    border: none;
    background: transparent;
    color: var(--tm-msg-text);
    font: 500 15px var(--tm-font-ui);
    text-align: left;
    cursor: pointer;
}
.teams-panel .teams-reminders__list-dot {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--list-color);
    color: #fff;
    font-size: 12px;
}
.teams-panel .teams-reminders__list-name {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-panel .teams-reminders__list-count {
    color: var(--tm-text-3);
    font-size: 14px;
}
.teams-panel .teams-reminders__list-edit {
    opacity: 0;
    font-size: 14px;
}
.teams-panel .teams-reminders__list:hover .teams-reminders__list-edit,
.teams-panel .teams-reminders__list-edit:focus-visible {
    opacity: 1;
}
.teams-panel .teams-reminders__lists-empty {
    padding: 6px 4px;
    font-size: 13px;
    color: var(--tm-text-3);
}

/* ── Items ───────────────────────────────────────────────────────────────── */
.teams-panel .teams-reminders__body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    /* Room under the last card for the floating "+ New". */
    padding: 6px 18px 88px;
}
.teams-panel .teams-reminders__group {
    margin-top: 14px;
}
.teams-panel .teams-reminders__group-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    margin: 0 0 4px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--tm-border);
}
.teams-panel .teams-reminders__group-title {
    margin: 0;
    font: 700 18px var(--tm-font-display);
    color: var(--list-color);
}
.teams-panel .teams-reminders__group-toggle {
    flex: 0 0 auto;
    align-self: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--tm-text-3);
    cursor: pointer;
}
.teams-panel .teams-reminders__group-toggle:hover {
    color: var(--tm-text-1);
}
.teams-panel .teams-reminders__group-toggle i {
    transition: transform 0.15s ease;
}
.teams-panel .teams-reminders__group.is-collapsed .teams-reminders__group-toggle i {
    transform: rotate(-90deg);
}
.teams-panel .teams-reminders__group-count {
    align-self: center;
    min-width: 20px;
    padding: 1px 7px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--list-color) 16%, transparent);
    color: var(--list-color);
    font: 600 12px var(--tm-font-ui);
    text-align: center;
    margin-right: auto;
}
.teams-panel .teams-reminders__group-head:has(.teams-reminders__group-toggle):not(:has(.teams-reminders__group-count)) .teams-reminders__group-title {
    margin-right: auto;
}
.teams-panel .teams-reminders__add-head {
    flex: 0 0 auto;
    padding: 2px 4px;
    border: none;
    background: transparent;
    color: var(--tm-text-3);
    font: 13px var(--tm-font-ui);
    cursor: pointer;
}
.teams-panel .teams-reminders__add-head:hover {
    color: var(--tm-accent);
}
.teams-panel .teams-reminders__items {
    list-style: none;
    margin: 0;
    padding: 0;
}
.teams-panel .teams-reminders__item {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr) auto;
    gap: 10px;
    align-items: start;
    margin-bottom: 8px;
    padding: 12px 12px 12px 14px;
    border-radius: 14px;
    background: var(--ai-card-bg);
    box-shadow: var(--tm-shadow-sm);
    /* The colour of the list *I* filed it in. */
    border-left: 5px solid var(--list-color, transparent);
    transition: opacity var(--tm-t), box-shadow var(--tm-t);
}
.teams-panel .teams-reminders__item.is-focused {
    box-shadow: 0 0 0 2px var(--tm-accent);
}
/* The assignee: an avatar on the right, name on hover. */
.teams-panel .teams-reminders__assignee {
    flex: none;
    width: 28px;
    height: 28px;
    margin-top: 1px;
    font-size: 12px;
}
/* On an open item the avatar is a button: a tap opens "Assign to…". */
.teams-panel .teams-reminders__assignee.is-button {
    padding: 0;
    border: 0;
    cursor: pointer;
    transition: box-shadow var(--tm-t);
}
.teams-panel .teams-reminders__assignee.is-button:hover,
.teams-panel .teams-reminders__assignee.is-button:focus-visible {
    box-shadow: 0 0 0 2px var(--tm-accent);
    outline: none;
}
.teams-panel .teams-reminders__assignee.is-unassigned {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1.5px dashed var(--tm-border-strong);
    border-radius: 50%;
    background: transparent;
    color: var(--tm-text-3);
    cursor: pointer;
}
.teams-panel .teams-reminders__assignee.is-unassigned:hover {
    border-color: var(--tm-accent);
    color: var(--tm-accent);
}
.teams-panel .teams-reminders__assignee.is-empty {
    visibility: hidden;
}
.teams-panel .teams-reminders__bell,
.teams-panel .teams-reminders__private {
    color: var(--tm-text-3);
    font-size: 11px;
}
.teams-panel .teams-reminders__resolved-by,
.teams-panel .teams-reminders__by {
    color: var(--tm-text-3);
}
.teams-panel .teams-reminders__by {
    overflow: hidden;
    max-width: 100%;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.teams-panel .teams-reminders__item.is-resolving {
    opacity: 0.4;
}
.teams-panel .teams-reminders__check {
    width: 24px;
    height: 24px;
    margin-top: 1px;
    border: 2px solid var(--tm-border-strong);
    border-radius: 50%;
    background: transparent;
    color: transparent;
    font-size: 11px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.teams-panel .teams-reminders__check:hover {
    border-color: var(--ai-list-green);
    color: var(--ai-list-green);
}
.teams-panel .teams-reminders__item.is-resolved .teams-reminders__check {
    background: var(--ai-list-green);
    border-color: var(--ai-list-green);
    color: #fff;
}
.teams-panel .teams-reminders__item-body {
    min-width: 0;
}
.teams-panel .teams-reminders__item-title {
    display: block;
    width: 100%;
    padding: 2px 0;
    border: none;
    background: transparent;
    color: var(--tm-msg-text);
    font: 15px/1.35 var(--tm-font-ui);
    text-align: left;
    cursor: pointer;
    overflow-wrap: anywhere;
}
.teams-panel .teams-reminders__item.is-resolved .teams-reminders__item-title {
    color: var(--tm-text-3);
    text-decoration: line-through;
}
.teams-panel .teams-reminders__item-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 10px;
    margin-top: 4px;
    font-size: 12px;
    color: var(--tm-text-1);
}
.teams-panel .teams-reminders__chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 100%;
    padding: 2px 8px;
    border: 1px solid var(--tm-border);
    border-radius: 999px;
    background: var(--tm-surface);
    color: var(--tm-accent);
    font: 500 12px var(--tm-font-ui);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: pointer;
}
.teams-panel .teams-reminders__chip.is-static {
    color: var(--tm-text-1);
    cursor: default;
}
.teams-panel .teams-reminders__due.is-overdue {
    color: var(--ai-list-red);
    font-weight: 600;
}
.teams-panel .teams-reminders__list-tag {
    color: var(--list-color);
    font-weight: 600;
}
.teams-panel .teams-reminders__empty {
    margin: 28px 0;
    text-align: center;
    color: var(--tm-text-3);
}

/* ── The item form's List row ────────────────────────────────────────────── */
.teams-action-form-overlay .teams-action-form__list-row {
    gap: 10px;
}
.teams-action-form-overlay .teams-action-form__list-dot {
    flex: 0 0 auto;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--list-color, transparent);
}
/* "No list" has no colour: an empty ring beside the select only looked like
   an unchecked radio button and pushed the select out of line. */
.teams-action-form-overlay .teams-action-form__list-dot.is-empty {
    display: none;
}

/* ── List editor ─────────────────────────────────────────────────────────── */
.teams-action-form-overlay .teams-list-editor {
    max-width: 380px;
}
.teams-action-form-overlay .teams-list-editor__badge {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    margin: 6px auto 12px;
    border-radius: 50%;
    background: var(--list-color);
    color: #fff;
    font-size: 26px;
    box-shadow: var(--tm-shadow-sm);
}
.teams-action-form-overlay .teams-list-editor__name {
    box-sizing: border-box;
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--tm-border);
    border-radius: var(--tm-r);
    background: var(--tm-real-white);
    color: var(--tm-msg-text);
    font: 600 17px var(--tm-font-ui);
    text-align: center;
}
.teams-action-form-overlay .teams-list-editor__swatches {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 10px;
    margin-top: 16px;
    justify-items: center;
}
.teams-action-form-overlay .teams-list-editor__swatch {
    width: 32px;
    height: 32px;
    border: 3px solid transparent;
    border-radius: 50%;
    background: var(--list-color);
    cursor: pointer;
    box-shadow: 0 0 0 1px var(--tm-border);
}
.teams-action-form-overlay .teams-list-editor__swatch[aria-checked="true"] {
    border-color: var(--tm-white);
    box-shadow: 0 0 0 2px var(--list-color);
}

/* ── Phones: one screen at a time, like iOS Reminders ────────────────────
   The items fill the screen; the sidebar (tiles + My lists) opens as a full
   screen over them from the header toggle and closes when a view is picked.
   Both sit under the bottom tab bar (z 890 < its 900 in the same .chat-area
   stacking context), which stays visible as the way out. */
@media (max-width: 768px) {
    .teams-panel .teams-reminders,
    .teams-panel .teams-reminders.is-sidebar-open {
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        width: auto;
        display: block;
        border: none;
        border-radius: 0;
        z-index: 2500;
        transform: translateY(24px);
    }
    .teams-panel .teams-reminders.is-open {
        transform: none;
    }
    body.mobile-standalone.mobile-tabbar-page .teams-panel .teams-reminders {
        z-index: 890;
    }
    .teams-panel .teams-reminders__resizer {
        display: none;
    }
    /* Horizontal swipes belong to the panel's own edge-swipe (open / close the
       sidebar); without this a touch browser takes the pan and cancels the
       pointer stream before the gesture is recognised. A scroll container's
       own touch-action is the one that counts, so the two scrollers (items,
       sidebar) are listed too, not only the panel. */
    .teams-panel .teams-reminders,
    .teams-panel .teams-reminders__body,
    .teams-panel .teams-reminders__overview {
        touch-action: pan-y;
    }
    .teams-panel .teams-reminders__overview,
    .teams-panel .teams-reminders__view {
        position: absolute;
        inset: 0;
        padding-top: env(safe-area-inset-top);
        padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);
    }
    body.mobile-standalone.mobile-tabbar-page .teams-panel .teams-reminders__overview,
    body.mobile-standalone.mobile-tabbar-page .teams-panel .teams-reminders__view {
        padding-bottom: calc(env(safe-area-inset-bottom, 0px) * 0.4 + 82px);
    }
    .teams-panel .teams-reminders__overview {
        z-index: 3;
        border-right: none;
    }
    /* The sidebar slides in from the left like the chat sessions drawer
       (mobile_chat/sidebar.js): a toggle tap animates through this transition,
       a drag follows the finger (inline transform, transition off) and then
       settles through it. Hidden once it is out of the way, for keyboard and
       screen readers. */
    .teams-panel .teams-reminders__overview {
        transform: translate3d(-100%, 0, 0);
        /* Dimmed at rest, full strength once open — the drawer's fade; the floor
           is DRAWER_MIN_OPACITY, which the drag drives inline. */
        opacity: 0.3;
        transition:
            transform 0.3s cubic-bezier(0.22, 1, 0.36, 1),
            opacity 0.2s cubic-bezier(0.22, 0.8, 0.25, 1),
            visibility 0s linear 0.3s;
        will-change: transform, opacity;
    }
    .teams-panel .teams-reminders.is-sidebar-open .teams-reminders__overview {
        transform: none;
        opacity: 1;
        transition:
            transform 0.3s cubic-bezier(0.22, 1, 0.36, 1),
            opacity 0.2s cubic-bezier(0.22, 0.8, 0.25, 1);
    }
    .teams-panel .teams-reminders.is-sidebar-dragging .teams-reminders__overview {
        visibility: visible;
        transition: none;
        box-shadow: 6px 0 24px rgba(0, 0, 0, 0.18);
    }
    /* A phone's sidebar covers the items, so it carries its own way back. */
    .teams-panel .teams-reminders__sidebar-close {
        display: inline-block;
    }
    .teams-panel .teams-reminders__view {
        background: var(--tm-bg);
    }
    .teams-panel .teams-reminders__list-edit {
        opacity: 1;
    }
    .teams-panel .teams-reminders__fab {
        right: 16px;
        bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);
    }
    body.mobile-standalone.mobile-tabbar-page .teams-panel .teams-reminders__fab {
        bottom: calc(env(safe-area-inset-bottom, 0px) * 0.4 + 82px + 8px);
    }
    .teams-panel .teams-reminders__body {
        padding: 6px 12px 96px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .teams-panel .teams-reminders,
    .teams-panel .teams-reminders__overview {
        transition: none;
    }
}

/* "Suggest action items from my messages" — the FR-8 opt-out. */
.teams-panel .teams-reminders__setting { margin: 20px 2px 4px; }
.teams-panel .teams-reminders__setting-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 12px;
    border-radius: var(--tm-r-lg);
    background: var(--tm-surface);
    cursor: pointer;
}
.teams-panel .teams-reminders__setting-label {
    display: block;
    font: 600 13px var(--tm-font-ui);
    color: var(--tm-text-1);
}
.teams-panel .teams-reminders__setting-hint {
    display: block;
    margin-top: 2px;
    font: 400 12px/1.35 var(--tm-font-ui);
    color: var(--tm-text-3);
}


/* Suggested — AI assistant proposals awaiting the person's Keep / Dismiss (FR-10). */
.teams-panel .teams-reminders__tile--purple { background: var(--ai-list-purple); }
.teams-panel .teams-reminders__hint {
    margin: 0 2px 10px;
    font: 400 13px/1.4 var(--tm-font-ui);
    color: var(--tm-text-3);
}
.teams-panel .teams-reminders__proposal { align-items: center; }
.teams-panel .teams-reminders__proposal-icon {
    flex: none;
    width: 22px;
    color: var(--ai-list-purple);
    text-align: center;
}
.teams-panel .teams-reminders__item-title.is-static { cursor: default; }
.teams-panel .teams-reminders__proposal-actions {
    display: flex;
    flex: none;
    align-items: center;
    gap: 4px;
}
.teams-panel .teams-reminders__proposal.is-resolving { opacity: 0.5; pointer-events: none; }
@media (max-width: 768px) {
    .teams-panel .teams-reminders__proposal { flex-wrap: wrap; }
    .teams-panel .teams-reminders__proposal-actions { width: 100%; justify-content: flex-end; }
}

/* The My Feed button's dot: AI proposals wait in My action items → Suggested.
   Top-left, so it never collides with the open (top-right) and overdue
   (bottom-right) counts. */
.teams-panel .teams-conversation__action-list .teams-action-list-dot {
    position: absolute;
    top: -3px;
    left: -3px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--ai-list-purple);
    box-shadow: 0 0 0 2px var(--tm-surface);
    pointer-events: none;
}
.teams-panel .teams-conversation__action-list .teams-action-list-dot[hidden] { display: none; }

/* My lists — drag a list by its grip to reorder (teams-action-list-reorder.js). */
.teams-panel .teams-reminders__list-handle {
    flex: none;
    width: 28px;
    height: 34px;
    margin-left: 2px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--tm-text-3);
    cursor: grab;
    touch-action: none;       /* the grip drags; the rest of the panel still scrolls */
}
.teams-panel .teams-reminders__list-handle:focus-visible { outline: 2px solid var(--tm-accent); }
.teams-panel .teams-reminders__lists.is-reordering { user-select: none; }
.teams-panel .teams-reminders__lists.is-reordering .teams-reminders__list:not(.is-dragging) {
    transition: transform 0.15s ease;
}
.teams-panel .teams-reminders__list.is-dragging {
    position: relative;
    z-index: 2;
    background: var(--tm-surface);
    box-shadow: var(--tm-shadow-md);
    cursor: grabbing;
}
@media (hover: hover) {
    /* With a mouse the grip appears on hover; touch screens always show it. */
    .teams-panel .teams-reminders__list:not(:hover):not(:focus-within) .teams-reminders__list-handle { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .teams-panel .teams-reminders__lists.is-reordering .teams-reminders__list { transition: none; }
}

/* ── Toggles, not checkboxes ───────────────────────────────────────────────
   The shared .settings-switch (main-chat.css, switchControlHtml) at a compact
   size for the item form, the review list and the panel sidebar. Its track is
   restated from the Teams palette so it reads on both themes (the same move
   teams-visibility.css makes). */
.teams-panel .teams-reminders .settings-switch,
.teams-action-form-overlay .settings-switch {
    /* A block box: as a bare inline <span> (inside a plain <label>) the width
       is ignored, the absolutely-positioned track collapses to a sliver and
       only the knob shows. */
    display: block;
    width: 40px;
    height: 23px;
    flex: none;
}
.teams-panel .teams-reminders .settings-switch__slider,
.teams-action-form-overlay .settings-switch__slider {
    background: var(--tm-switch-off, #a8a396);
}
.teams-panel .teams-reminders .settings-switch__slider::before,
.teams-action-form-overlay .settings-switch__slider::before {
    width: 17px;
    height: 17px;
    left: 3px;
    top: 3px;
}
.teams-panel .teams-reminders .settings-switch input:checked + .settings-switch__slider,
.teams-action-form-overlay .settings-switch input:checked + .settings-switch__slider {
    background: var(--tm-accent);
}
.teams-panel .teams-reminders .settings-switch input:checked + .settings-switch__slider::before,
.teams-action-form-overlay .settings-switch input:checked + .settings-switch__slider::before {
    transform: translateX(17px);
}
.teams-panel .teams-reminders .settings-switch input:focus-visible + .settings-switch__slider,
.teams-action-form-overlay .settings-switch input:focus-visible + .settings-switch__slider {
    outline: 2px solid var(--tm-accent);
    outline-offset: 2px;
}
.teams-action-form-overlay .teams-action-review__keep {
    display: flex;
    padding-top: 6px;
}
.teams-action-form-overlay .teams-action-form__toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    color: var(--tm-msg-text);
    cursor: pointer;
}
.teams-action-form-overlay .teams-action-form__share-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    cursor: pointer;
}
.teams-action-form-overlay .teams-action-form__share-title {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--tm-text-1);
}
.teams-action-form-overlay .teams-action-form__share-row small {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    color: var(--tm-text-3);
}

/* Completed/reopened swipes leave in the drag direction, then close the gap. */
@keyframes action-item-swipe-dismiss {
    0% { transform: translateX(0); opacity: 1; max-height: var(--action-dismiss-height); }
    60% {
        transform: translateX(100%); opacity: 0; max-height: var(--action-dismiss-height);
        padding-top: 12px; padding-bottom: 12px; margin-bottom: 8px;
    }
    100% {
        transform: translateX(100%); opacity: 0; max-height: 0;
        padding-top: 0; padding-bottom: 0; margin-top: 0; margin-bottom: 0;
        border-top-width: 0; border-bottom-width: 0;
    }
}
.teams-panel .teams-reminders__item.is-swipe-dismissing {
    box-sizing: border-box;
    min-height: 0;
    pointer-events: none;
    animation: action-item-swipe-dismiss 420ms ease-out forwards;
}
.teams-panel .teams-reminders__undo {
    position: absolute;
    bottom: calc(100px + env(safe-area-inset-bottom, 0px));
    left: 16px;
    right: 16px;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 16px;
    border-radius: 12px;
    background: var(--tm-surface, #fff);
    color: var(--tm-text-1, #333);
    border: 1px solid var(--tm-border, #ccc);
    box-shadow: 0 4px 18px #0003;
}
.teams-panel .teams-reminders__undo button {
    min-height: 44px;
    padding: 8px 12px;
    font: inherit;
    font-weight: 600;
    color: var(--tm-accent, #2d5f84);
    background: transparent;
    border: 0;
    cursor: pointer;
}
@media (prefers-reduced-motion: reduce) {
    .teams-panel .teams-reminders__item.is-swipe-dismissing { animation-duration: 0.01ms; }
}

/* Action item notes under the title: two lines, links clickable. */
.teams-panel .teams-reminders__item-notes {
    margin-top: 2px;
    font-size: 12.5px;
    line-height: 1.35;
    color: var(--tm-text-1);
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.teams-panel .teams-reminders__item-notes a {
    color: var(--tm-link, #2563eb);
    text-decoration: underline;
}
.teams-action-form-overlay .teams-list-editor__state {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--tm-border);
    border-radius: 10px;
    background: transparent;
    color: var(--tm-text-1);
    font: 14px var(--tm-font-ui);
    cursor: pointer;
    text-align: left;
}
.teams-action-form-overlay .teams-list-editor__state i {
    color: var(--tm-text-3);
    transition: transform 0.15s ease;
}
.teams-action-form-overlay .teams-list-editor__state.is-collapsed i {
    transform: rotate(-90deg);
}
.teams-action-form-overlay .teams-list-editor__state-label {
    color: var(--tm-text-3);
}

/* Navigation motion: tab/chat view transitions + sliding highlights. Last so
   its `.amby-glide-target` override wins over the active-row styles above. */
/* =============================================================================
   Amby Teams — navigation motion
   -----------------------------------------------------------------------------
   How moving between tabs and chats LOOKS. The mechanics live in JS:
     • js/shared/view-transition.js  — wraps each swap in a View Transition
       and stamps <html data-nav-transition="tab|chat-switch"> while it runs;
     • js/shared/glide-highlight.js  — the ghost that slides a selection
       highlight from the old tab / sidebar row to the new one.

   Short and quiet on purpose (≤200ms, ease-out): the point is that the eye can
   follow what changed, not that anything performs. Everything here is switched
   off under prefers-reduced-motion (the JS also skips the transitions).

   View-transition pseudo-elements are document-level by definition; they are
   still scoped by the `html[data-nav-transition]` stamp, so no other feature's
   transition (there are none today) could pick these animations up.
   ============================================================================= */

/* ── The content pane ────────────────────────────────────────────────────────
   Exactly one of the four panels is rendered at a time (the others are
   display:none), so they can share one transition name: the old picture is
   whichever panel was visible, the new one whichever is visible now. Named only
   WHILE a transition runs, so outside one they are ordinary boxes. */
html[data-nav-transition] #panel-chat,
html[data-nav-transition] #panel-teams,
html[data-nav-transition] #panel-tasks,
html[data-nav-transition] #panel-settings {
    view-transition-name: amby-main-pane;
}

/* The app header is captured as its OWN layer, which paints above the pane.
   Left inside the root picture it sat UNDER the pane's layer, so its drop
   shadow (which normally falls onto the pane) vanished for the length of every
   transition and then popped back in. Nothing in it needs to animate — the tab
   highlight glides in the live new picture — so the new picture is simply
   shown. */
html[data-nav-transition] .chat-area .chat-header {
    view-transition-name: amby-app-header;
}
html[data-nav-transition]::view-transition-group(amby-app-header),
html[data-nav-transition]::view-transition-new(amby-app-header) {
    animation: none;
}
html[data-nav-transition]::view-transition-old(amby-app-header) {
    display: none;
}
/* The snapshot carries the header's ink overflow — its drop shadow — and is
   painted above EVERYTHING, the sidebar included, so the shadow's left fringe
   showed as a vertical line along the sidebar's edge for the length of every
   Ask AI / Feed / Chat switch. Clip the sides and top to the header's own box;
   the shadow below it stays. */
html[data-nav-transition]::view-transition-new(amby-app-header) {
    clip-path: inset(0 0 -12px 0);
}

/* Clicks during the ~200ms run go to the real (new) page underneath rather
   than being swallowed by the overlay — fast switching must never drop one. */
html[data-nav-transition]::view-transition {
    pointer-events: none;
}

/* Everything outside the pane (the sidebar, the header) crossfades quickly. */
html[data-nav-transition]::view-transition-old(root),
html[data-nav-transition]::view-transition-new(root) {
    animation-duration: 160ms;
}

/* The pane never moves or resizes between the two states; don't morph it. */
html[data-nav-transition]::view-transition-group(amby-main-pane) {
    animation: none;
}

/* Chat → chat: a crossfade. Equal durations and curves on purpose — the pair
   is blended additively, so matching opacities keep what BOTH chats share
   (the header chrome, a wallpaper) perfectly steady while only the
   transcript changes. */
html[data-nav-transition="chat-switch"]::view-transition-old(amby-main-pane) {
    animation: amby-nav-fade-out 180ms cubic-bezier(0.2, 0, 0, 1) both;
}
html[data-nav-transition="chat-switch"]::view-transition-new(amby-main-pane) {
    animation: amby-nav-fade-in 180ms cubic-bezier(0.2, 0, 0, 1) both;
}

/* Tab → tab: the same crossfade, a touch longer. Deliberately NOT a slide: a
   translated pane uncovers a strip of bare page beside the sidebar for the
   length of the move, which read as a flash at the sidebar's edge. */
html[data-nav-transition="tab"]::view-transition-old(amby-main-pane) {
    animation: amby-nav-fade-out 200ms cubic-bezier(0.2, 0, 0, 1) both;
}
html[data-nav-transition="tab"]::view-transition-new(amby-main-pane) {
    animation: amby-nav-fade-in 200ms cubic-bezier(0.2, 0, 0, 1) both;
}

@keyframes amby-nav-fade-out { to { opacity: 0; } }
@keyframes amby-nav-fade-in { from { opacity: 0; } }

/* ── Sliding selection highlight (glide-highlight.js) ────────────────────────
   The host becomes the ghost's positioning context and a stacking context;
   the ghost sits at z-index -1 INSIDE it, i.e. above the host's own
   background but below every item — so the labels stay on top while the
   highlight travels under them. */
.header-tabs.amby-glide-host,
.sessions-list.amby-glide-host {
    position: relative;
    isolation: isolate;
}
.header-tabs > .amby-glide-ghost,
.sessions-list > .amby-glide-ghost {
    position: absolute;
    z-index: -1;
    margin: 0;
    box-sizing: border-box;
    pointer-events: none;
}
/* The destination's own highlight waits for the ghost to arrive. */
.header-tabs > .header-tab.amby-glide-target,
.sessions-list .session-item.amby-glide-target {
    background: transparent !important;
    border-color: transparent !important;
    box-shadow: none !important;
}

/* ── A transcript that had to show its skeleton fades in over it ─────────────
   (A preloaded or cached chat is painted inside the chat-switch transition
   instead and never carries this class.) */
.teams-panel .teams-conversation__messages--reveal {
    animation: amby-nav-fade-in 160ms ease-out both;
}

/* ── Skeleton over a chat wallpaper ──────────────────────────────────────────
   The shimmer bars are drawn in the panel's own surface tones, which vanish
   against a photograph — the loading state read as an empty pane. A frosted
   plate behind them gives the bars something to be seen against. */
.teams-panel--real.teams-panel--has-chat-background .teams-skeleton-messages {
    margin: 12px auto 0;
    width: min(640px, calc(100% - 24px));
    border-radius: 14px;
    background: color-mix(in srgb, var(--tm-bg) 62%, transparent);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
}

@media (prefers-reduced-motion: reduce) {
    html[data-nav-transition]::view-transition-old(*),
    html[data-nav-transition]::view-transition-new(*),
    html[data-nav-transition]::view-transition-group(*) {
        animation: none !important;
    }
    .teams-panel .teams-conversation__messages--reveal {
        animation: none;
    }
}

.teams-catch-up-trigger { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 5px; border: 0; border-radius: 8px; padding: 6px 8px; color: var(--tm-accent, #246b9b); background: transparent; font: inherit; cursor: pointer; }
.teams-catch-up-trigger:hover { background: color-mix(in srgb, var(--tm-accent, #246b9b) 12%, transparent); }
.teams-catch-up-trigger__badge { min-width: 16px; padding: 1px 4px; border-radius: 999px; color: #fff; background: #d94343; font-size: 10px; font-weight: 700; line-height: 14px; }
.teams-catch-up {
    position: absolute;
    z-index: 100;
    inset: 0;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
    color: var(--tm-text-1, #1d2630);
    background: var(--tm-bg, #fff);
    margin: 10px;
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}

body > .teams-catch-up { position: fixed; }
/* The card is the content column; the action buttons are its sibling. Where the
   shell itself is the card (desktop, widget) the buttons still read as inside it. */
.teams-catch-up__card { position: relative; display: flex; flex: 1; flex-direction: column; min-height: 0; overflow: hidden; }
.teams-catch-up__header { display: flex; align-items: center; gap: 10px; min-height: 54px; padding: 8px 12px; border-bottom: 1px solid var(--tm-border, #d9e0e6); background: var(--tm-bg-alt, #f7f9fb); }
.teams-catch-up__header-spacer { flex: 0 0 32px; }
.teams-catch-up__header > div { display: flex; flex: 1; flex-direction: column; min-width: 0; text-align: center; }
.teams-catch-up__header strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.teams-catch-up__header span { color: var(--tm-text-2, #63707b); font-size: 12px; }
.teams-catch-up__icon { width: 32px; height: 32px; border: 0; border-radius: 50%; color: inherit; background: transparent; cursor: pointer; }
.teams-catch-up__icon:hover { background: rgba(0,0,0,.08); }
.teams-catch-up__transcript { flex: 1; min-height: 0; overflow: auto; padding: 14px; background: var(--tm-bg, #fff); }
.teams-catch-up__message { display: flex; align-items: flex-start; gap: 8px; max-width: 92%; margin: 0 0 14px; }
.teams-catch-up__message.is-mine { flex-direction: row-reverse; margin-left: auto; }
.teams-catch-up__message-body { min-width: 0; }
.teams-catch-up__avatar {
    display: grid;
    flex: 0 0 30px;
    width: 30px;
    height: 30px;
    place-items: center;
    overflow: hidden;
    border-radius: 50%;
    color: #fff;
    background: var(--tm-accent, #246b9b);
    font-size: 12px;
    font-weight: 700;
    margin-top: 17px;
}

.is-mine .teams-catch-up__avatar {
    display:none;
}

.teams-catch-up__avatar img { width: 100%; height: 100%; object-fit: cover; }
.teams-catch-up__meta { display: flex; align-items: baseline; gap: 6px; min-height: 15px; }
.teams-catch-up__message.is-mine .teams-catch-up__meta { justify-content: flex-end; }
.teams-catch-up__sender, .teams-catch-up__message time { color: var(--tm-text-2, #63707b); font-size: 11px; }
.teams-catch-up__sender { font-weight: 700; }
.teams-catch-up__bubble { padding: 9px 11px; border-radius: 12px 12px 12px 3px; background: var(--tm-bg-alt, #edf1f4); overflow-wrap: anywhere; }
.teams-catch-up__thread { margin-top: 4px; color: var(--tm-accent, #2563eb); font-size: 12px; font-weight: 600; }
.teams-catch-up__thread strong { font-weight: 700; }
/* "Threads you follow": replies that are not in the transcript above. */
.teams-catch-up__threads { margin-top: 18px; padding-top: 10px; border-top: 1px solid var(--tm-border, #dfe5ea); }
.teams-catch-up__threads-title { margin: 0 0 8px; color: var(--tm-text-2, #63707b); font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.teams-catch-up__thread-block { margin-bottom: 14px; padding: 8px 10px; border-left: 3px solid var(--tm-accent, #246b9b); border-radius: 0 10px 10px 0; background: color-mix(in srgb, var(--tm-accent, #246b9b) 5%, transparent); }
.teams-catch-up__thread-root { display: flex; gap: 6px; align-items: baseline; color: inherit; font-size: 13px; overflow-wrap: anywhere; }
.teams-catch-up__thread-root i { color: var(--tm-accent, #246b9b); }
.teams-catch-up__thread-block .teams-catch-up__unread { margin: 10px 0 8px; }
.teams-catch-up__thread-reply { display: flex; gap: 6px; align-items: end; margin: 8px 0 4px; }
.teams-catch-up__thread-reply textarea { flex: 1; min-height: 34px; max-height: 94px; resize: none; border: 1px solid var(--tm-border, #c6d0d8); border-radius: 9px; padding: 7px 8px; color: inherit; background: var(--tm-bg, #fff); font: inherit; font-size: 14px; }
.teams-catch-up__thread-reply button { border: 1px solid var(--tm-accent, #246b9b); border-radius: 8px; padding: 7px 11px; color: var(--tm-accent, #246b9b); background: transparent; cursor: pointer; }
.teams-catch-up__thread-open { margin-top: 4px; padding: 6px 12px; border: 1px solid var(--tm-accent, #246b9b); border-radius: 999px; color: var(--tm-accent, #246b9b); background: transparent; font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.teams-catch-up__thread-open:hover, .teams-catch-up__thread-open:focus-visible { background: color-mix(in srgb, var(--tm-accent, #246b9b) 12%, transparent); }
.teams-catch-up__message.is-mine .teams-catch-up__bubble {
    border-radius: 12px 12px 3px 12px;
    color: var(--tm-own-message-text, #17212b);
    background: var(--tm-own-message, #c9ccce);
    width: fit-content;
    justify-self: flex-end;
}

/* A recorded clip sent on its own: no bubble, the shaped frame is the message
   (same rule as `.teams-msg--clip-only` in the chat, teams-clips.css). */
.teams-catch-up__bubble.is-clip-only,
.teams-catch-up__message.is-mine .teams-catch-up__bubble.is-clip-only,
body.dark-theme .teams-catch-up__bubble.is-clip-only,
.dark-theme .teams-catch-up__bubble.is-clip-only {
    padding: 0;
    background: transparent;
}
.teams-catch-up__bubble.is-clip-only .teams-msg__attachments { margin-top: 0; }
.teams-catch-up__system { display: flex; justify-content: center; margin: 8px 0 14px; }
.teams-catch-up__system-chip { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 6px 10px; border: 1px solid var(--tm-border, #d9e0e6); border-radius: 999px; color: var(--tm-text-2, #63707b); background: var(--tm-bg, #fff); font-size: 12px; }
.teams-catch-up__system-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.teams-catch-up__system-chip i { color: var(--tm-accent, #246b9b); }
.teams-catch-up__system-chip time { flex: 0 0 auto; font-size: 11px; }

.teams-catch-up .teams-msg__attachments {
    display: flex;
    flex-direction: column;
    gap: 7px;
    max-width: 100%;
    margin-top: 7px;
}

.teams-catch-up .teams-att { display: block; max-width: 100%; }
.teams-catch-up .teams-att--image img {
    display: block;
    max-width: 100%;
    max-height: 280px;
    height: auto;
    border: 1px solid var(--tm-border, #d9e0e6);
    border-radius: 9px;
    width: auto;
}

.teams-catch-up .teams-att--video { width: 100%; max-height: 280px; border-radius: 9px; background: #000; }
.teams-catch-up .teams-audio-player { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto auto; gap: 8px; align-items: center; min-height: 46px; padding: 7px 9px; border: 1px solid var(--tm-border, #d9e0e6); border-radius: 999px; background: var(--tm-bg, #fff); }
.teams-catch-up .teams-audio-player__native { display: none; }
.teams-catch-up .teams-audio-player__play { display: grid; width: 30px; height: 30px; place-items: center; border: 0; border-radius: 50%; color: #fff; background: var(--tm-accent, #246b9b); cursor: pointer; }
.teams-catch-up .teams-audio-player__track { display: grid; grid-template-columns: minmax(42px, 1fr) auto; gap: 6px; align-items: center; min-width: 0; }
.teams-catch-up .teams-audio-player__seek { width: 100%; min-width: 0; accent-color: var(--tm-accent, #246b9b); }
.teams-catch-up .teams-audio-player__time { font-size: 11px; white-space: nowrap; }
.teams-catch-up .teams-audio-player__download { color: var(--tm-accent, #246b9b); text-decoration: none; }
.teams-catch-up .teams-audio-player__speed { min-width: 32px; height: 24px; padding: 0 6px; border: 0; border-radius: 12px; color: var(--tm-accent, #246b9b); background: transparent; font: 600 12px/1 inherit; cursor: pointer; }
.teams-catch-up .teams-audio-player__speed:hover, .teams-catch-up .teams-audio-player__speed:focus-visible { background: rgba(127, 127, 127, 0.18); }
.teams-catch-up .teams-audio-player__wave { display: flex; gap: 2px; align-items: center; height: 19px; }
.teams-catch-up .teams-audio-player__wave i { width: 2px; height: 9px; border-radius: 99px; background: var(--tm-accent, #246b9b); }
.teams-catch-up .teams-audio-player__wave i:nth-child(2), .teams-catch-up .teams-audio-player__wave i:nth-child(4) { height: 15px; }
.teams-catch-up .teams-audio-player__wave i:nth-child(3) { height: 19px; }
.teams-catch-up .teams-att--file { display: flex; gap: 8px; align-items: center; padding: 8px; border: 1px solid var(--tm-border, #d9e0e6); border-radius: 8px; color: inherit; background: var(--tm-bg, #fff); text-decoration: none; }
.teams-catch-up .teams-att__file-main { display: flex; flex: 1; min-width: 0; gap: 6px; align-items: center; }
.teams-catch-up .teams-att__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.teams-catch-up .teams-att__open { color: var(--tm-accent, #246b9b); font-size: 12px; }
.teams-catch-up__reply { display: flex; gap: 8px; align-items: end; padding: 10px 12px; border-top: 1px solid var(--tm-border, #d9e0e6); }
.teams-catch-up__reply textarea { flex: 1; min-height: 36px; max-height: 94px; resize: vertical; border: 1px solid var(--tm-border, #c6d0d8); border-radius: 9px; padding: 8px; color: inherit; background: var(--tm-bg, #fff); font: inherit; }
.teams-catch-up__reply button, .teams-catch-up__actions button, .teams-catch-up__empty button { border: 1px solid var(--tm-accent, #246b9b); border-radius: 8px; padding: 8px 12px; color: var(--tm-accent, #246b9b); background: transparent; font: inherit; cursor: pointer; }
.teams-catch-up__actions { display: flex; gap: 8px; padding: 10px 12px 12px; }
.teams-catch-up__actions button { flex: 1; }
.teams-catch-up__actions .is-primary { color: #fff; background: var(--tm-accent, #246b9b); }
.teams-catch-up__unread { display: flex; align-items: center; gap: 8px; margin: 18px 0 12px; pointer-events: none; user-select: none; }
.teams-catch-up__unread::before, .teams-catch-up__unread::after { content: ''; flex: 1; height: 1px; background: var(--tm-accent, #246b9b); opacity: .5; }
.teams-catch-up__unread span { flex: 0 0 auto; padding: 2px 6px; border-radius: 10px; color: var(--tm-accent, #246b9b); background: color-mix(in srgb, var(--tm-accent, #246b9b) 12%, transparent); font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.teams-catch-up__empty, .teams-catch-up__loading { display: grid; flex: 1; place-content: center; gap: 10px; padding: 24px; text-align: center; color: var(--tm-text-2, #63707b); }
.teams-catch-up__empty h2, .teams-catch-up__empty p { margin: 0; }

/* ── "All caught up" celebration ────────────────────────────────────────────
   `.is-celebrating` is set only when Mark as read cleared the LAST unread chat
   (teams-catch-up-viewer.js). The check pops in with a ring, the copy rises in
   behind it, and a one-shot confetti burst fans out from the badge. */
.teams-catch-up {
    --catch-up-success: #2e9e5b;
    --catch-up-confetti-0: var(--tm-accent, #246b9b);
    --catch-up-confetti-1: #2e9e5b;
    --catch-up-confetti-2: #f2b134;
    --catch-up-confetti-3: #e0607e;
}
.teams-catch-up__badge { position: relative; display: inline-grid; place-items: center; justify-self: center; font-size: 22px; }
.teams-catch-up__empty.is-celebrating .teams-catch-up__badge { color: var(--catch-up-success); font-size: 46px; animation: teams-catch-up-pop 560ms cubic-bezier(0.34, 1.56, 0.64, 1) both; }
.teams-catch-up__empty.is-celebrating .teams-catch-up__badge::after {
    content: '';
    position: absolute;
    inset: -6px;
    border: 3px solid var(--catch-up-success);
    border-radius: 50%;
    opacity: 0;
    animation: teams-catch-up-ring 900ms ease-out 180ms;
}
.teams-catch-up__empty.is-celebrating h2 { color: var(--tm-text-1, #1d2630); animation: teams-catch-up-rise 420ms ease-out 220ms both; }
.teams-catch-up__empty.is-celebrating p { animation: teams-catch-up-rise 420ms ease-out 320ms both; }
.teams-catch-up__empty.is-celebrating button { animation: teams-catch-up-rise 420ms ease-out 420ms both; }
.teams-catch-up__confetti { position: absolute; top: 50%; left: 50%; width: 0; height: 0; pointer-events: none; }
.teams-catch-up__confetti i {
    position: absolute;
    top: -6px;
    left: -4px;
    width: 8px;
    height: 12px;
    border-radius: 2px;
    background: var(--catch-up-confetti-0);
    opacity: 0;
    animation: teams-catch-up-confetti 1300ms cubic-bezier(0.2, 0.7, 0.3, 1) var(--delay, 0ms) forwards;
}
.teams-catch-up__confetti i[data-tone="1"] { background: var(--catch-up-confetti-1); }
.teams-catch-up__confetti i[data-tone="2"] { background: var(--catch-up-confetti-2); border-radius: 50%; height: 8px; }
.teams-catch-up__confetti i[data-tone="3"] { background: var(--catch-up-confetti-3); }

@keyframes teams-catch-up-pop {
    0% { opacity: 0; transform: scale(0.2); }
    60% { opacity: 1; transform: scale(1.18); }
    100% { opacity: 1; transform: scale(1); }
}
@keyframes teams-catch-up-ring {
    0% { opacity: 0.7; transform: scale(0.8); }
    100% { opacity: 0; transform: scale(1.9); }
}
@keyframes teams-catch-up-rise {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: none; }
}
/* Out along (--dx, --dy), then a little gravity on the way down. */
@keyframes teams-catch-up-confetti {
    0% { opacity: 1; transform: translate(0, 0) rotate(0) scale(0.6); }
    70% { opacity: 1; transform: translate(var(--dx), var(--dy)) rotate(var(--spin)) scale(1); }
    100% { opacity: 0; transform: translate(var(--dx), calc(var(--dy) + 60px)) rotate(var(--spin)) scale(1); }
}

/* ── Swipe left = Keep unread, right = previous chat (phones;
   teams-catch-up-swipe.js) ────────────────────────────────────────────────────
   Only the transcript (or the "all caught up" page) moves; header, reply box
   and buttons stay put. The cue sits behind it on the side the conversation
   uncovers as it slides. */
.teams-catch-up :is(.teams-catch-up__transcript, .teams-catch-up__empty) { position: relative; z-index: 1; touch-action: pan-y; }
/* Opaque, so the cue behind is only uncovered where the page has slid away. */
.teams-catch-up .teams-catch-up__empty { background: inherit; }
.teams-catch-up.is-swiping :is(.teams-catch-up__transcript, .teams-catch-up__empty),
.teams-catch-up.is-swipe-settling :is(.teams-catch-up__transcript, .teams-catch-up__empty),
.teams-catch-up.is-swipe-exiting :is(.teams-catch-up__transcript, .teams-catch-up__empty) {
    transform: translateX(var(--catch-up-swipe-x, 0px));
}
.teams-catch-up.is-swipe-settling :is(.teams-catch-up__transcript, .teams-catch-up__empty) { transition: transform .22s cubic-bezier(.2, .8, .2, 1); }
.teams-catch-up.is-swipe-exiting :is(.teams-catch-up__transcript, .teams-catch-up__empty) { transition: transform .2s ease-in, opacity .2s ease-in; opacity: 0; }
.teams-catch-up .teams-catch-up__swipe-cue {
    position: absolute;
    z-index: 0;
    top: 50%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    color: var(--tm-accent, #246b9b);
    font-size: 12px;
    font-weight: 600;
    opacity: calc(.35 + var(--catch-up-swipe-progress, 0) * .65);
    transform: translateY(-50%) scale(calc(.85 + var(--catch-up-swipe-progress, 0) * .15));
    pointer-events: none;
}
.teams-catch-up .teams-catch-up__swipe-cue i {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 2px solid currentColor;
    font-size: 15px;
    transition: background .15s ease, color .15s ease;
}
.teams-catch-up .teams-catch-up__swipe-cue.is-next { right: 18px; }
.teams-catch-up .teams-catch-up__swipe-cue.is-back { left: 18px; }
.teams-catch-up.is-swipe-armed .teams-catch-up__swipe-cue i { color: #fff; background: var(--tm-accent, #246b9b); border-color: var(--tm-accent, #246b9b); }
.teams-catch-up .teams-catch-up__transcript.is-entering { animation: teams-catch-up-slide-in .26s cubic-bezier(.2, .8, .2, 1); }
.teams-catch-up .teams-catch-up__transcript.is-entering-back { animation: teams-catch-up-slide-in-back .26s cubic-bezier(.2, .8, .2, 1); }
@keyframes teams-catch-up-slide-in {
    from { transform: translateX(40%); opacity: 0; }
    to   { transform: none; opacity: 1; }
}
@keyframes teams-catch-up-slide-in-back {
    from { transform: translateX(-40%); opacity: 0; }
    to   { transform: none; opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .teams-catch-up.is-swipe-settling :is(.teams-catch-up__transcript, .teams-catch-up__empty),
    .teams-catch-up.is-swipe-exiting :is(.teams-catch-up__transcript, .teams-catch-up__empty) { transition: none; }
    .teams-catch-up .teams-catch-up__transcript:is(.is-entering, .is-entering-back) { animation: none; }
    .teams-catch-up__empty.is-celebrating .teams-catch-up__badge,
    .teams-catch-up__empty.is-celebrating .teams-catch-up__badge::after,
    .teams-catch-up__empty.is-celebrating h2,
    .teams-catch-up__empty.is-celebrating p,
    .teams-catch-up__empty.is-celebrating button { animation: none; }
    .teams-catch-up__confetti { display: none; }
}
body.dark-theme .teams-catch-up, .dark-theme .teams-catch-up { color: var(--tm-text-1, #edf4fa); background: var(--tm-bg, #17212b); }
body.dark-theme .teams-catch-up__header, .dark-theme .teams-catch-up__header { background: var(--tm-bg-alt, #202c38); }
body.dark-theme .teams-catch-up__bubble, .dark-theme .teams-catch-up__bubble { background: var(--tm-bg-alt, #263440); }
body.dark-theme .teams-catch-up__reply textarea, .dark-theme .teams-catch-up__reply textarea { background: #17212b; }
body.dark-theme .teams-catch-up__empty.is-celebrating h2, .dark-theme .teams-catch-up__empty.is-celebrating h2 { color: var(--tm-text-1, #edf4fa); }
/* Phone layout: the page runs edge-to-edge, so the card's 10px margin put its
   header under the status bar / Dynamic Island. Clear the insets, and round and
   lift the card so it reads as a sheet floating over the page. */
body.mobile-standalone .teams-catch-up {
    margin: calc(var(--safe-top, 0px) + 8px) 8px max(10px, env(safe-area-inset-bottom, 0px));
    background: transparent;
    overflow: visible;
    /* Track the visible viewport so the keyboard cannot push the card away. */
    top: var(--catch-up-vv-top, 0px);
    bottom: auto;
    box-shadow: 0 14px 44px rgba(0, 0, 0, 0.34), 0 2px 8px rgba(0, 0, 0, 0.16);
    height: calc(var(--catch-up-vv-height, 100%) - var(--safe-top, 0px) - 8px - max(10px, env(safe-area-inset-bottom, 0px)));
}
/* The sheet is the card alone; the buttons float below it, as in MS Teams. */
body.mobile-standalone .teams-catch-up__card {
    border-radius: 20px;
    background: var(--tm-bg, #fff);
}

body.dark-theme.mobile-standalone .teams-catch-up__card { background: var(--tm-bg, #17212b); }
body.mobile-standalone .teams-catch-up__header { border-radius: 20px 20px 0 0; }
/* A dimmed backdrop makes the sheet and its buttons read as one modal. */
body.mobile-standalone .teams-catch-up::before { content: ''; position: fixed; inset: 0; z-index: -1; background: rgba(15, 23, 32, 0.45); }
/* The buttons are their own tray, styled like the card so the two belong together. */
body.mobile-standalone .teams-catch-up__actions {
    flex: 0 0 auto;
    margin-top: 10px;
    padding: 10px;
    border-radius: 20px;
    background: var(--tm-bg, #fff);
    box-shadow: 0 14px 44px rgba(0, 0, 0, 0.34), 0 2px 8px rgba(0, 0, 0, 0.16);
}
body.dark-theme.mobile-standalone .teams-catch-up__actions { background: var(--tm-bg, #17212b); }
body.mobile-standalone .teams-catch-up__actions button { padding: 11px 12px; border-radius: 14px; background: transparent; }
body.mobile-standalone .teams-catch-up__actions .is-primary { background: var(--tm-accent, #246b9b); }
/* A keyboard owns the bottom edge: no buttons, no bottom gap above it. */
body.mobile-standalone .teams-catch-up.is-keyboard-open { margin-bottom: 0; height: calc(var(--catch-up-vv-height, 100%) - var(--safe-top, 0px) - 8px); }
body.mobile-standalone .teams-catch-up.is-keyboard-open .teams-catch-up__actions { display: none; }

@media (max-width: 520px) { .teams-catch-up__message { max-width: 100%; } .teams-catch-up-trigger__label { display: none; } }

/* The Teams image gallery is opened from inside the widget, whose own layers sit
   above PhotoSwipe's default z-index (100000). */
body > .pswp { --pswp-root-z-index: 1000010; }

/* The page runs edge-to-edge (viewport-fit=cover), so PhotoSwipe's top bar would
   sit under the status bar / notch where its buttons cannot be tapped. Push the
   bar down by the top safe area; the bar's own 60px height is kept below it. */
body > .pswp .pswp__top-bar {
    top: env(safe-area-inset-top, 0px);
    padding-inline: env(safe-area-inset-left, 0px) env(safe-area-inset-right, 0px);
}

