/* BU-074 Compose Workbench. Light, sharp, minimal. Single accent: #DD5100. */
/* BU-186 bullet 67 (2026-05-18): panel resize via drag handles on grid gap. */

.compose-workbench-page {
    padding: 24px;
    /* Breathing room between the Scope filter row and the JARGAN main nav
       directly above it. 24px on the sides was fine but felt cramped at the top. */
    padding-top: 36px;
    background: #F8FAFC;
    color: #1F2937;
    font-feature-settings: "tnum" 1, "ss01" 1;
}

.compose-workbench-shell {
    max-width: 1600px;
    margin: 0 auto;
}

.compose-workbench-topbar {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 24px;
    margin-bottom: 16px;
}

.compose-workbench-title {
    margin: 0;
    font-size: 24px;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: #111827;
}

.compose-workbench-subtitle {
    margin-top: 4px;
    font-size: 14px;
    color: #6B7280;
    letter-spacing: -0.005em;
}

.compose-workbench-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
    min-width: 420px;
}

.compose-stat {
    min-width: 0;
    padding: 10px 12px;
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 10px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 1px 3px rgba(15, 23, 42, 0.06);
    transition: border-color 180ms ease-out, box-shadow 180ms ease-out;
}

.compose-stat:hover {
    border-color: #D1D5DB;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06), 0 2px 6px rgba(15, 23, 42, 0.07);
}

.compose-stat-label {
    font-size: 11px;
    line-height: 1;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #6B7280;
}

.compose-stat-value {
    margin-top: 6px;
    font-size: 18px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: #111827;
}

/* Engagement chip strip. Horizontal scroll, no scrollbar visible. */
.compose-workbench-engagements {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    padding: 2px 0 8px;
    margin-bottom: 16px;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.compose-workbench-engagements::-webkit-scrollbar {
    display: none;
}

.compose-workbench-empty-strip {
    padding: 8px 0;
    color: #6B7280;
    font-size: 13px;
}

.compose-workbench-scope {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    padding: 2px 0 4px;
    margin-bottom: 8px;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.compose-workbench-scope::-webkit-scrollbar {
    display: none;
}

.jgn-engagement-chip {
    padding: 6px 12px;
    border-radius: 999px;
    border: 1px solid #E5E7EB;
    background: #FFFFFF;
    color: #4B5563;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: border-color 180ms ease-out, background-color 180ms ease-out, color 180ms ease-out;
    white-space: nowrap;
}

.jgn-engagement-chip:hover {
    border-color: #9CA3AF;
    color: #1F2937;
}

.jgn-engagement-chip:focus-visible {
    outline: 2px solid #DD5100;
    outline-offset: 2px;
    border-color: #DD5100;
}

.jgn-engagement-chip.is-selected {
    background: #DD5100;
    color: #FFFFFF;
    border-color: #DD5100;
}

.jgn-engagement-chip.is-selected:hover {
    background: #C44900;
    border-color: #C44900;
}

.jgn-filter-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; padding: 10px 12px; border-bottom: 1px solid #E5E7EB; }
.jgn-filter-row__label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; color: #6B7280; font-weight: 600; }
.jgn-filter-chip { padding: 4px 10px; border-radius: 999px; border: 1px solid #E5E7EB; background: #FFFFFF; color: #4B5563; font-size: 11px; cursor: pointer; transition: all 180ms ease-out; }
.jgn-filter-chip:hover { border-color: #9CA3AF; }
.jgn-filter-chip--active { background: #DD5100; color: #FFFFFF; border-color: #DD5100; }
.jgn-filter-empty { padding: 16px; text-align: center; color: #9CA3AF; font-size: 12px; font-style: italic; }
.jgn-filter-empty a { color: #DD5100; cursor: pointer; text-decoration: underline; }

.jgn-platform-icon {
    display: inline-block;
    width: 18px;
    height: 18px;
    vertical-align: middle;
    color: #4B5563;
    text-align: center;
    line-height: 18px;
}

.jgn-platform-icon svg,
.jgn-platform-icon i {
    width: 16px;
    height: 16px;
    font-size: 16px;
    line-height: 1;
    vertical-align: middle;
}

.jgn-platform-icon svg {
    display: block;
    margin: 1px auto 0;
}

.jgn-platform-icon--unknown { color: #9CA3AF; opacity: 0.6; }

/* Voice multi-select dropdown menu */
.jgn-filter-voice-menu { position: absolute; z-index: 1050; top: 100%; left: 0; min-width: 220px; max-height: 320px; background: #FFFFFF; border: 1px solid #E5E7EB; border-radius: 8px; box-shadow: 0 8px 16px rgba(15,23,42,0.08); padding: 0; display: flex; flex-direction: column; }
.jgn-filter-voice-menu__search { padding: 8px 10px; border-bottom: 1px solid #E5E7EB; }
.jgn-filter-voice-menu__list { flex: 1; overflow-y: auto; padding: 4px 0; }
.jgn-filter-voice-menu__item { padding: 6px 12px; font-size: 12px; color: #1F2937; display: flex; align-items: center; gap: 6px; cursor: pointer; }
.jgn-filter-voice-menu__item:hover { background: #F9FAFB; }

.jgn-filter-chip--stage.jgn-stage--awareness { background: #FEF3C7; color: #92400E; border-color: #FDBA74; }
.jgn-filter-chip--stage.jgn-stage--consideration { background: #DBEAFE; color: #1E40AF; border-color: #93C5FD; }
.jgn-filter-chip--stage.jgn-stage--decision { background: #DCFCE7; color: #166534; border-color: #86EFAC; }
.jgn-filter-chip--stage.jgn-stage--retention { background: #F3E8FF; color: #6B21A8; border-color: #D8B4FE; }

.jgn-media-popover {
    position: absolute;
    z-index: 1050;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 4px;
    min-width: 240px;
    /* BU-186 bullet 77 (2026-05-18): bound height so the JS clamp
       always has room to shift the popover entirely into viewport. */
    max-height: min(320px, calc(100vh - 32px));
    max-width: min(420px, calc(100vw - 32px));
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 8px;
    box-shadow: 0 8px 16px rgba(15,23,42,0.08);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.jgn-media-popover__search { padding: 8px 10px; border-bottom: 1px solid #E5E7EB; }

/* BU-186 bullet 78 (2026-05-18): outlined-only voice + stage tag pills
   on each media option in the media-picker popover. Replaces the
   Bootstrap `text-bg-light border` which rendered nearly-invisible
   light text on a light background. */
.jgn-media-picker-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 4px;
}
.jgn-media-picker-tag {
    display: inline-block;
    padding: 2px 8px;
    font-size: 11px;
    font-weight: 400;
    color: #4B5563;
    background: transparent;
    border: 0.5px solid #E5E7EB;
    border-radius: 999px;
    line-height: 1.4;
}
.jgn-media-popover__toggle { padding: 6px 10px; font-size: 11px; color: #4B5563; border-bottom: 1px solid #E5E7EB; display: flex; align-items: center; gap: 6px; }
.jgn-media-popover__list { flex: 1; overflow-y: auto; padding: 4px 0; }
.jgn-media-popover__item { padding: 8px 12px; font-size: 12px; color: #1F2937; cursor: pointer; display: flex; flex-direction: column; gap: 2px; }
.jgn-media-popover__item:hover { background: #F9FAFB; }
.jgn-media-popover__item--selected { background: #FFEDD5; color: #9A3412; font-weight: 500; }
.jgn-media-popover__empty { padding: 16px; text-align: center; color: #9CA3AF; font-size: 12px; font-style: italic; }
.jgn-media-popover__backdrop { position: fixed; inset: 0; z-index: 1049; background: transparent; }

@media (prefers-reduced-motion: reduce) {
    .jgn-engagement-chip,
    .jgn-filter-chip,
    .compose-stat,
    .jgn-media-card {
        transition: none !important;
        animation: none !important;
    }
}

/* Panel inner layout. */
.compose-panel-inner {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-height: 0;
    height: 100%;
}

.compose-panel-inner--media {
    gap: 14px;
}

.compose-panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.compose-panel-head--sticky {
    position: sticky;
    top: 0;
    z-index: 3;
    padding-bottom: 8px;
    background: #FFFFFF;
}

.compose-panel-title {
    font-size: 14px;
    font-weight: 600;
    letter-spacing: -0.005em;
    color: #111827;
}

.compose-panel-badge {
    padding: 4px 8px;
    border-radius: 999px;
    background: #F3F4F6;
    color: #4B5563;
    font-size: 11px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* PanelHost bento layout. */
.jgn-bento-host {
    position: relative;
}

.panel-host-layout-surface,
.panel-host-split-node,
.panel-host-split-cell {
    min-width: 0;
    min-height: 0;
}

.panel-host-layout-surface {
    position: relative;
    /* 2026-05-08 audit: each .panel-host-splitter has an invisible
       ::after with `inset: -3px` providing a wider drag-hit target.
       That bleeds 3px past the surface and shows up as
       `scrollWidth > clientWidth` on every viewport. Clip the surface so
       the bleed doesn't fake horizontal overflow. The hit-area still
       works for the splitter inside the surface. */
    overflow: clip;
}

.panel-host-split-node {
    position: relative;
    display: grid;
    width: 100%;
    height: 100%;
    gap: 0;
}

.panel-host-split-cell {
    position: relative;
}

.panel-host-split-cell > .panel-host-panel,
.panel-host-split-cell > .panel-host-split-node {
    width: 100%;
    height: 100%;
}

.panel-host-panel {
    position: relative;
}

.panel-host-panel-header {
    justify-content: flex-start;
    gap: 10px;
}

.panel-host-panel-title {
    flex: 1 1 auto;
}

.jgn-bento-handle {
    cursor: grab;
    color: #9CA3AF;
    transition: color 180ms ease-out, background-color 180ms ease-out;
    padding: 0 6px;
    user-select: none;
    border: 0;
    background: transparent;
    border-radius: 6px;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.jgn-bento-handle:hover {
    color: #1F2937;
    background: rgba(229, 231, 235, 0.35);
}

.jgn-bento-handle:active {
    cursor: grabbing;
}

.jgn-bento-handle:focus-visible {
    outline: 2px solid rgba(221, 81, 0, 0.35);
    outline-offset: 1px;
}

.jgn-bento-drop-zones {
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0;
    z-index: 5;
    transition: opacity 120ms ease-out;
}

.jgn-bento-host.is-dragging .jgn-bento-drop-zones {
    pointer-events: auto;
    opacity: 1;
}

/* BU-097 v4: per-panel zones are now hit-test only (invisible). A SINGLE
   canvas-level preview rectangle shows where the dragged panel will land.
   Cleaner: user sees one orange rectangle previewing the final position
   instead of 12 zones (4 per panel × 3 panels) cluttering everything. */
.jgn-bento-drop-zone {
    position: absolute;
    background: transparent;
    border: 0;
    pointer-events: inherit;
    opacity: 0;
    /* Stay in DOM for hit-testing but never visible. */
}
.jgn-bento-host.is-dragging .jgn-bento-drop-zone { opacity: 0; }

.jgn-bento-drop-zone--top    { top: 0;    left: 0; right: 0; height: 35%; }
.jgn-bento-drop-zone--bottom { bottom: 0; left: 0; right: 0; height: 35%; }
.jgn-bento-drop-zone--left   { top: 35%;  bottom: 35%; left: 0; width: 35%; }
.jgn-bento-drop-zone--right  { top: 35%;  bottom: 35%; right: 0; width: 35%; }

/* BU-098: 8 fixed slot zones overlaid on the entire workbench canvas during a
   panel drag. Cursor proximity decides which is active. Active slot lights up
   solid orange. Other 7 stay subtle so user sees the available targets. */
.jgn-bento-canvas-slots {
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0;
    transition: opacity 120ms ease-out;
    z-index: 7;
}
.jgn-bento-host.is-dragging .jgn-bento-canvas-slots { opacity: 1; }

.jgn-bento-canvas-slot {
    position: absolute;
    background: rgba(15, 23, 42, 0.04);
    border: 2px dashed rgba(15, 23, 42, 0.14);
    border-radius: 10px;
    transition: background-color 120ms ease-out, border-color 120ms ease-out, box-shadow 120ms ease-out;
    display: flex;
    align-items: center;
    justify-content: center;
    color: rgba(15, 23, 42, 0.40);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.jgn-bento-canvas-slot.is-active {
    background: rgba(221, 81, 0, 0.22);
    border-color: #DD5100;
    border-style: solid;
    color: #DD5100;
    box-shadow: 0 8px 24px rgba(221, 81, 0, 0.22), inset 0 0 0 1px rgba(221, 81, 0, 0.30);
}
.jgn-bento-canvas-slot.is-occupied-by-source {
    /* Slot currently held by the dragged panel itself — show but unhighlight. */
    opacity: 0.30;
}


.jgn-bento-ghost {
    position: fixed;
    pointer-events: none;
    z-index: 9999;
    opacity: 0.85;
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.20);
    transform: translate(-9999px, -9999px);
    transition: none;
    border-radius: 8px;
    background: #FFFFFF;
    border: 2px solid #DD5100;
    overflow: hidden;
    box-sizing: border-box;
}

@media (prefers-reduced-motion: reduce) {
    .jgn-bento-drop-zone,
    .jgn-bento-ghost {
        transition: none !important;
    }
}

/* Sharp empty states. 48px gray-300 line illustration + tight copy. */
.compose-panel-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 32px 16px;
    color: #6B7280;
    font-size: 13px;
    text-align: center;
}

.compose-panel-empty__icon {
    width: 48px;
    height: 48px;
    color: #D1D5DB;
    flex: 0 0 auto;
}

.compose-panel-empty__title {
    font-size: 13px;
    font-weight: 600;
    color: #4B5563;
}

.compose-panel-empty__subtitle {
    font-size: 12px;
    /* 2026-05-08 audit: #9CA3AF on white = 2.54:1 (fail). #6B7280 = 4.83:1
       (pass) keeps the muted secondary feel while clearing AA. */
    color: #6B7280;
    max-width: 240px;
    line-height: 1.4;
}

/* Lazy-load notice in the Deliverables panel header (2026-05-09): explains
   why the user only sees a subset of engagements' deliverables when their
   scope is huge (admin "All" can be 1,000+ engagements). */
.compose-panel-recent-notice {
    margin: 8px 12px 4px;
    padding: 8px 12px;
    background: #FFF7ED;
    border: 1px solid #FED7AA;
    border-radius: 6px;
    font-size: 12px;
    color: #4B5563;
    line-height: 1.4;
}
.compose-panel-recent-notice strong {
    color: #9A3412;
    font-weight: 600;
}

/* BU-179: prevent the catch-all
       `.compose-panel-inner > *:not(.compose-panel-head) {
           overflow: auto; min-height: 0; flex: 1 1 auto;
       }`
   rule (defined later in this file at the internal-scroll section) from
   applying to the notice. The catch-all hands every direct child a flex
   grow + overflow:auto, which gave the notice a stretching height +
   internal scroll viewport. With small content that resulted in
   first-line clipping at the top edge (overflow:auto rounds the content
   box and crops the text's leading half-line) and an inconsistent
   visual height as the panel resized. Pin the notice to its natural
   intrinsic height with no internal overflow handling — the panel
   body's overflow:auto already handles the rare case where everything
   together is too tall. */
.compose-workbench-body .compose-panel-inner > .compose-panel-recent-notice {
    flex: 0 0 auto;
    overflow: visible;
    min-height: 0;
}

.compose-media-grid {
    display: grid;
    gap: 10px;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    align-content: start;
    overflow: auto;
    max-height: 100%;
    padding-right: 2px;
}

/* BU-104: invite-to-fill empty state for the Media panel. The panel
   surfaces a grid of dashed ghost cards (showing "lots of room is waiting
   for media"), with a CTA tile in the center prompting the user to compose
   their first media. When media exists, a single trailing ghost slot keeps
   the "more room available" energy alive. */
.compose-media-grid--empty {
    grid-auto-rows: minmax(110px, 1fr);
    align-content: start;
}

.compose-media-ghost {
    border-radius: 12px;
    border: 1.5px dashed rgba(221, 81, 0, 0.22);
    background: linear-gradient(180deg, rgba(221, 81, 0, 0.025) 0%, rgba(221, 81, 0, 0.06) 100%);
    min-height: 110px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: border-color 180ms ease-out, background 180ms ease-out;
}

/* 2026-05-08 audit: placeholder ghosts used the brand-orange dashed border
   (inherited from .compose-media-ghost), making them visually identical to
   the active "Compose your first media" CTA tile. Switch placeholders to a
   neutral 1px solid #EEE so the CTA stays the only orange-edged tile and
   the user's eye lands on the actionable target first. */
.compose-media-ghost--placeholder {
    opacity: 0.6;
    border: 1px solid #EEEEEE;
    background: #FAFAFA;
}

.compose-media-ghost--cta {
    flex-direction: column;
    gap: 8px;
    padding: 18px 20px;
    text-align: center;
    background: rgba(255, 255, 255, 0.95);
    border-color: rgba(221, 81, 0, 0.45);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
    grid-column: span 1;
    animation: compose-ghost-pulse 2.4s ease-in-out infinite;
}

.compose-media-ghost__icon {
    width: 32px;
    height: 32px;
    color: #DD5100;
    flex: 0 0 auto;
}

.compose-media-ghost__title {
    font-size: 13px;
    font-weight: 600;
    color: #111827;
    letter-spacing: -0.005em;
}

.compose-media-ghost__subtitle {
    font-size: 11px;
    color: #6B7280;
    line-height: 1.4;
    max-width: 220px;
}

.compose-media-ghost__subtitle a {
    color: #DD5100;
    font-weight: 600;
    text-decoration: none;
}

.compose-media-ghost__subtitle a:hover {
    text-decoration: underline;
}

.compose-media-ghost--trail {
    min-height: 90px;
    color: #9CA3AF;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.02em;
    border-color: #E5E7EB;
    background: transparent;
    opacity: 0.7;
}

.compose-media-ghost--trail:hover {
    border-color: rgba(221, 81, 0, 0.35);
    color: #DD5100;
    background: rgba(221, 81, 0, 0.03);
    opacity: 1;
}

@keyframes compose-ghost-pulse {
    0%, 100% {
        border-color: rgba(221, 81, 0, 0.45);
        box-shadow: 0 0 0 0 rgba(221, 81, 0, 0);
    }
    50% {
        border-color: rgba(221, 81, 0, 0.7);
        box-shadow: 0 0 0 4px rgba(221, 81, 0, 0.05);
    }
}

@media (prefers-reduced-motion: reduce) {
    .compose-media-ghost--cta { animation: none; }
}

/* BU-107: slim drop-zone composer. Replaces the bulky stacked card with a
   thin orange-accented zone that doubles as the compose form. Empty state
   = 48px dashed prompt. Filled state = single 44px row (count + name +
   ⚙ + Combine) with optional voice/stage/scope chips below the toggle. */
.jgn-compose-zone {
    position: sticky;
    top: 0;
    z-index: 4;
    display: flex;
    flex-direction: column;
    gap: 6px;
    /* 2026-05-08 audit: right padding cushioned to 96px so the floating
       "0 IN SCOPE" / "0 VISIBLE" pill doesn't render on top of the
       "Drop assets here to compose media" hint text. Same fix as
       .jgn-asset-picker__view padding-right. */
    padding: 8px 96px 8px 10px;
    border-radius: 10px;
    background: #FFFFFF;
    border: 1.5px dashed rgba(221, 81, 0, 0.32);
    transition: border-color 180ms ease-out, background-color 180ms ease-out, box-shadow 180ms ease-out;
}

.jgn-compose-zone--empty {
    border-style: dashed;
    background: rgba(221, 81, 0, 0.025);
    min-height: 48px;
    align-items: center;
    justify-content: center;
}

.jgn-compose-zone--active {
    border-style: solid;
    border-color: #DD5100;
    background: linear-gradient(180deg, rgba(221, 81, 0, 0.04) 0%, #FFFFFF 100%);
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}

.jgn-compose-zone--drag {
    border-style: solid;
    border-color: #DD5100;
    background: rgba(221, 81, 0, 0.10);
    box-shadow: 0 0 0 4px rgba(221, 81, 0, 0.15);
}

.jgn-compose-zone__hint {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    font-weight: 600;
    /* 2026-05-08 audit: brand orange #DD5100 on white = 4.00:1 (fail).
       The dark traffic-orange variant #B33D00 = 5.34:1 (pass) and is the
       documented brand value for small text needing AA contrast. */
    color: #B33D00;
    letter-spacing: 0.01em;
}

.jgn-compose-zone__hint-icon {
    width: 18px;
    height: 18px;
    /* Match the text color so the chevron-down isn't disconnected. */
    color: #B33D00;
    flex: 0 0 auto;
}

.jgn-compose-zone__row {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
}

.jgn-compose-zone__count {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 28px;
    padding: 0 10px;
    border-radius: 999px;
    background: #DD5100;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
}

.jgn-compose-zone__count i { font-size: 11px; }

.jgn-compose-zone__name {
    flex: 1 1 auto;
    min-width: 0;
    height: 28px;
    padding: 4px 10px;
    border: 1px solid #E5E7EB;
    border-radius: 8px;
    background: #FFFFFF;
    color: #1F2937;
    font-size: 12px;
    outline: none;
    transition: border-color 180ms ease;
}
.jgn-compose-zone__name:focus {
    border-color: #DD5100;
    box-shadow: 0 0 0 3px rgba(221, 81, 0, 0.12);
}

.jgn-compose-zone__more {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border: 1px solid #E5E7EB;
    border-radius: 8px;
    background: #FFFFFF;
    color: #6B7280;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0;
    transition: color 180ms ease, border-color 180ms ease, background-color 180ms ease;
}
.jgn-compose-zone__more:hover {
    color: #DD5100;
    border-color: rgba(221, 81, 0, 0.35);
}
.jgn-compose-zone__more.is-active {
    color: #fff;
    background: #DD5100;
    border-color: #DD5100;
}

.jgn-compose-zone__cta {
    flex: 0 0 auto;
    height: 28px;
    padding: 0 12px;
    border: 0;
    border-radius: 8px;
    background: #DD5100;
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    transition: background-color 180ms ease-out, transform 80ms ease-out;
}
.jgn-compose-zone__cta:hover { background: #C04600; }
.jgn-compose-zone__cta:active { transform: translateY(1px); }
.jgn-compose-zone__cta:disabled {
    background: #9CA3AF;
    cursor: not-allowed;
}

.jgn-compose-zone__options {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding-top: 4px;
    border-top: 1px solid rgba(221, 81, 0, 0.18);
}

.jgn-compose-zone__opt-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px;
}

.jgn-compose-zone__opt-label {
    flex: 0 0 44px;
    font-size: 9px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #9CA3AF;
    font-weight: 700;
}

.jgn-compose-zone__chip {
    height: 22px;
    padding: 0 9px;
    border: 1px solid #E5E7EB;
    border-radius: 999px;
    background: #FFFFFF;
    color: #1F2937;
    font-size: 10px;
    font-weight: 600;
    line-height: 20px;
    cursor: pointer;
    transition: background-color 180ms ease-out, border-color 180ms ease-out, color 180ms ease-out;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
}
.jgn-compose-zone__chip:hover {
    border-color: rgba(221, 81, 0, 0.35);
    color: #DD5100;
}
.jgn-compose-zone__chip--selected {
    background: #DD5100;
    border-color: #DD5100;
    color: #FFFFFF;
}
.jgn-compose-zone__chip--selected:hover {
    background: #C04600;
    border-color: #C04600;
    color: #FFFFFF;
}
.jgn-compose-zone__chip--add {
    border-style: dashed;
    color: #DD5100;
    border-color: rgba(221, 81, 0, 0.35);
}
.jgn-compose-zone__chip-x {
    color: rgba(255, 255, 255, 0.85);
    font-size: 12px;
    line-height: 1;
}
.jgn-compose-zone__inline-input {
    height: 22px;
    padding: 0 8px;
    border: 1px solid rgba(221, 81, 0, 0.35);
    border-radius: 999px;
    background: #FFFFFF;
    font-size: 10px;
    color: #1F2937;
    outline: none;
    width: 140px;
}

/* BU-108: staged-asset stack — wrapping chip list of items currently in the
   compose queue, each removable on click. */
.jgn-compose-zone__staged {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding: 0;
}
.jgn-compose-zone__staged-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 22px;
    padding: 0 6px 0 8px;
    border: 1px solid rgba(221, 81, 0, 0.30);
    border-radius: 999px;
    background: rgba(221, 81, 0, 0.06);
    color: #1F2937;
    font-size: 10px;
    font-weight: 500;
    line-height: 20px;
    cursor: pointer;
    max-width: 220px;
    transition: background-color 180ms ease-out, border-color 180ms ease-out;
}
.jgn-compose-zone__staged-chip:hover {
    background: rgba(221, 81, 0, 0.12);
    border-color: #DD5100;
}
.jgn-compose-zone__staged-icon {
    font-size: 11px;
    color: #DD5100;
    flex: 0 0 auto;
}
.jgn-compose-zone__staged-name {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.jgn-compose-zone__staged-x {
    font-size: 13px;
    color: #DD5100;
    line-height: 1;
    flex: 0 0 auto;
    font-weight: 700;
}
.jgn-compose-zone__staged-chip:hover .jgn-compose-zone__staged-x {
    color: #C04600;
}

/* BU-109: visible Options button — text label + chevron, not icon-only. */
.jgn-compose-zone__more {
    width: auto !important;
    padding: 0 10px !important;
    gap: 4px !important;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}
.jgn-compose-zone__more-chevron { font-size: 9px; }

/* BU-110: voice picker dropdown inside the compose zone. */
.jgn-compose-zone__voice-picker {
    position: relative;
    display: inline-flex;
}
.jgn-compose-zone__voice-menu {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: 50;
    width: 240px;
    max-height: 260px;
    overflow-y: auto;
    padding: 6px;
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 8px;
    box-shadow: 0 8px 20px rgba(15, 23, 42, 0.10), 0 2px 4px rgba(15, 23, 42, 0.06);
    display: flex;
    flex-direction: column;
    gap: 4px;
}
/* BU-122: "Within scope only" toggle row inside the voice menu, matches the
   asset library BU-065 pattern. */
.jgn-compose-zone__voice-strict {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 4px 4px 4px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
    font-size: 11px;
    color: #1F2937;
    cursor: pointer;
    user-select: none;
    margin: 0;
}
.jgn-compose-zone__voice-strict input[type="checkbox"] {
    width: 13px;
    height: 13px;
    margin: 0;
    cursor: pointer;
    accent-color: #DD5100;
}
.jgn-compose-zone__voice-strict-info {
    color: rgba(0, 0, 0, 0.45);
    font-size: 10px;
    cursor: help;
    margin-left: 4px;
}
.jgn-compose-zone__voice-search {
    width: 100%;
    height: 26px;
    padding: 4px 8px;
    border: 1px solid #E5E7EB;
    border-radius: 6px;
    font-size: 11px;
    outline: none;
}
.jgn-compose-zone__voice-search:focus {
    border-color: #DD5100;
    box-shadow: 0 0 0 2px rgba(221, 81, 0, 0.12);
}
.jgn-compose-zone__voice-option {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    border: 0;
    background: transparent;
    border-radius: 6px;
    text-align: left;
    cursor: pointer;
    font-size: 11px;
    color: #1F2937;
}
.jgn-compose-zone__voice-option:hover {
    background: rgba(221, 81, 0, 0.06);
    color: #DD5100;
}
.jgn-compose-zone__voice-option--empty {
    color: #9CA3AF;
    font-style: italic;
    cursor: default;
}
.jgn-compose-zone__voice-option--empty:hover {
    background: transparent;
    color: #9CA3AF;
}

/* BU-111 / BU-112: multi-column asset list inside the workbench. Default
   3 columns; user can toggle 1-6 + Auto via the control next to search.
   Each "row" is one grid cell — single-line still works, just laid out in
   N columns (or auto-fit). */
.compose-workbench-body .jgn-asset-picker__list {
    display: grid !important;
    grid-template-columns: var(--asset-grid-template, repeat(3, minmax(0, 1fr)));
    gap: 0 6px;
    align-content: start;
}
.compose-workbench-body .jgn-asset-picker__row {
    border-bottom: 1px solid #F3F4F6 !important;
    cursor: grab !important;
    gap: 6px !important;          /* tighten checkbox → name gap */
    padding: 4px 8px 4px 6px !important;
    transition: background-color 120ms ease-out, border-color 120ms ease-out, transform 120ms ease-out;
}
.compose-workbench-body .jgn-asset-picker__row:hover {
    background: rgba(221, 81, 0, 0.10) !important;
    border-bottom-color: rgba(221, 81, 0, 0.35) !important;
}
.compose-workbench-body .jgn-asset-picker__row:active {
    cursor: grabbing !important;
    background: rgba(221, 81, 0, 0.16) !important;
}
/* Hide the bi-images icon inside the row (Bootstrap Icons font may not be
   loaded; the type/meta line already conveys the asset type). The checkbox
   sits directly next to the asset name now. */
.compose-workbench-body .jgn-asset-picker__icon { display: none !important; }
.compose-workbench-body .jgn-asset-picker__check { display: none !important; }
.compose-workbench-body .jgn-asset-picker__row .form-check-input {
    margin-right: 0 !important;
}
/* BU-113: column-count toggle as a quiet sub-header. Right-aligned, ghost
   buttons (no border, no fill until hover/active), light lowercase
   "columns" label so the row reads as "view options" not "page numbers". */
.jgn-asset-picker__view {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 1px;
    margin: 0 0 4px 0;
    padding: 0;
    flex: 0 0 auto;
    height: 18px;
}
/* 2026-05-08 audit: #B0B6BE on white = 2.04:1 (fail). Bumped to #4B5563 =
   8.81:1. Inactive column buttons read clearly without competing visually
   with the active selection. */
.jgn-asset-picker__view-label {
    font-size: 9px;
    font-weight: 400;
    color: #4B5563;
    text-transform: lowercase;
    letter-spacing: 0;
    margin-right: 4px;
}
.jgn-asset-picker__view-btn {
    width: 18px;
    height: 18px;
    border: 0;
    border-radius: 4px;
    background: transparent;
    color: #4B5563;
    font-size: 10px;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0;
    transition: color 180ms ease-out, background-color 180ms ease-out;
}
.jgn-asset-picker__view-btn:hover {
    color: #B33D00;
    background: rgba(221, 81, 0, 0.08);
}
/* 2026-05-08: was color:#DD5100 on rgba(221,81,0,0.10) = orange-on-tinted-
   orange composite = ~4.0:1 (fail). #B33D00 (dark traffic-orange) on the
   same tint = 5.34:1 (pass). */
.jgn-asset-picker__view-btn.is-active {
    color: #B33D00;
    background: rgba(221, 81, 0, 0.10);
    font-weight: 600;
}
.jgn-asset-picker__view-btn--auto {
    width: auto !important;
    padding: 0 6px !important;
    font-size: 9px !important;
    letter-spacing: 0.02em;
    text-transform: lowercase;
}

@keyframes jgn-compose-zone-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}
.jgn-compose-zone__spin {
    animation: jgn-compose-zone-spin 0.9s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
    .jgn-compose-zone__spin { animation: none; }
}

/* Composer (sticky CTA panel above media grid). */
.jgn-compose-composer {
    position: sticky;
    top: 0;
    z-index: 4;
}

.jgn-compose-composer__empty,
.jgn-compose-composer__card {
    padding: 14px;
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 12px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 1px 3px rgba(15, 23, 42, 0.06);
}

.jgn-compose-composer__empty {
    display: flex;
    align-items: center;
    gap: 12px;
}

.jgn-compose-composer__empty-icon {
    width: 32px;
    height: 32px;
    color: #D1D5DB;
    flex: 0 0 auto;
}

.jgn-compose-composer__empty-text {
    min-width: 0;
}

.jgn-compose-composer__empty-title,
.jgn-compose-composer__title {
    font-size: 14px;
    font-weight: 600;
    letter-spacing: -0.005em;
    color: #111827;
}

.jgn-compose-composer__empty-subtitle {
    margin-top: 2px;
    color: #6B7280;
    font-size: 12px;
}

.jgn-compose-composer__label {
    font-size: 11px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #6B7280;
    margin-bottom: 4px;
}

.jgn-compose-composer__field {
    margin-top: 10px;
}

.jgn-compose-composer__field-label {
    display: block;
    margin-bottom: 6px;
    font-size: 12px;
    color: #4B5563;
}

.jgn-compose-composer__input {
    width: 100%;
    min-height: 38px;
    padding: 8px 10px;
    border: 1px solid #D1D5DB;
    border-radius: 8px;
    background: #FFFFFF;
    color: #1F2937;
    font-size: 14px;
    outline: none;
    transition: border-color 180ms ease-out, box-shadow 180ms ease-out;
}

.jgn-compose-composer__input:hover {
    border-color: #9CA3AF;
}

.jgn-compose-composer__input:focus {
    border-color: #DD5100;
    box-shadow: 0 0 0 3px rgba(221, 81, 0, 0.12);
}

.jgn-compose-composer__tag-group {
    margin-top: 12px;
}

.jgn-compose-composer__tag-heading {
    margin-bottom: 6px;
    font-size: 12px;
    font-weight: 600;
    color: #4B5563;
}

.jgn-compose-composer__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.jgn-compose-composer__chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    border-radius: 999px;
    border: 1px solid #E5E7EB;
    background: #F8FAFC;
    color: #1F2937;
    font-size: 11px;
    cursor: pointer;
    transition: border-color 180ms ease-out, background-color 180ms ease-out;
}

.jgn-compose-composer__chip:hover {
    border-color: #9CA3AF;
    background: #FFFFFF;
}

.jgn-compose-composer__chip--stage {
    background: #FFEDD5;
    color: #9A3412;
    border-color: #FDBA74;
}

.jgn-compose-composer__chip--stage:hover {
    border-color: #FB923C;
    background: #FED7AA;
}

.jgn-compose-composer__chip--muted {
    cursor: default;
    color: #9CA3AF;
    background: #FFFFFF;
}

.jgn-compose-composer__chip--muted:hover {
    border-color: #E5E7EB;
    background: #FFFFFF;
}

.jgn-compose-composer__chip-x {
    font-weight: 700;
    line-height: 1;
}

/* Media card. Class-based; reuse-heat tint via data-reuse-heat. */
.jgn-media-card {
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 10px;
    padding: 12px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 1px 3px rgba(15, 23, 42, 0.06);
    transition: transform 180ms ease-out, box-shadow 180ms ease-out, border-color 180ms ease-out;
    animation: jgn-media-card-enter 240ms ease-out both;
    position: relative;
}

@keyframes jgn-media-card-enter {
    from {
        opacity: 0;
        transform: translateY(4px) scale(0.98);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.jgn-media-card:hover {
    transform: translateY(-1px);
    box-shadow: 0 2px 4px rgba(15, 23, 42, 0.06), 0 4px 8px rgba(15, 23, 42, 0.08);
    border-color: #D1D5DB;
}

.jgn-media-card[draggable="true"] {
    cursor: grab;
}

.jgn-media-card.is-dragging {
    opacity: 0.85;
    transform: rotate(2deg) scale(1.02);
    box-shadow: 0 8px 16px rgba(15, 23, 42, 0.10), 0 4px 8px rgba(15, 23, 42, 0.08);
    cursor: grabbing;
}

/* Subtle reuse-heat tint: workhorse media show a barely-perceptible warm wash. */
.jgn-media-card[data-reuse-heat="1"] {
    background: linear-gradient(180deg, #FFFFFF 0%, #FFFAF5 100%);
}

.jgn-media-card[data-reuse-heat="2"] {
    background: linear-gradient(180deg, #FFFFFF 0%, #FFF4EA 100%);
}

.jgn-media-card[data-reuse-heat="3"] {
    background: linear-gradient(180deg, #FFFEFC 0%, #FFEED8 100%);
}

.jgn-media-card__title-row {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin-bottom: 6px;
}

.jgn-media-card__title {
    font-weight: 600;
    font-size: 14px;
    letter-spacing: -0.005em;
    color: #111827;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1 1 auto;
    min-width: 0;
}

/* BU-127: delete button on the media card. Subtle by default, red on hover
   so the destructive action is signaled before the user clicks. */
.jgn-media-card__delete {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    border: 0;
    background: transparent;
    color: #9CA3AF;
    border-radius: 6px;
    cursor: pointer;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: color 180ms ease-out, background-color 180ms ease-out;
}
.jgn-media-card__delete:hover {
    color: #DC2626;
    background: rgba(220, 38, 38, 0.10);
}
.jgn-media-card__delete:focus-visible {
    outline: 2px solid #DC2626;
    outline-offset: 2px;
}

/* BU-128: media-card selection state */
.jgn-media-card__select {
    width: 14px !important;
    height: 14px !important;
    margin: 2px 0 0 0 !important;
    flex: 0 0 auto;
    cursor: pointer;
    accent-color: #DD5100;
}
.jgn-media-card.is-selected {
    border-color: #DD5100 !important;
    box-shadow: 0 0 0 2px rgba(221, 81, 0, 0.18), 0 1px 2px rgba(15, 23, 42, 0.04) !important;
}

/* BU-133: deleting state — gray out the card, hide its content under a
   subtle overlay, and spin a marker to telegraph that the API call is in
   flight. Pointer events disabled so the user can't click delete twice. */
.jgn-media-card.is-deleting {
    opacity: 0.55;
    filter: grayscale(0.8);
    pointer-events: none;
    position: relative;
}
.jgn-media-card__deleting-overlay {
    position: absolute;
    inset: 0;
    background: rgba(255, 255, 255, 0.55);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border-radius: inherit;
    z-index: 5;
    backdrop-filter: blur(1px);
}
/* BU-133 followup: branded kinetic-grid 3-circle loader (ported from
   JarganApiDemo/renderer/styles/auth-modal.css). Three circles cycling
   through positions on a 3-cell grid — one orange #DD5100 + two black
   (admin variant) for contrast on the white deleting overlay. 3s cycle.
   Scaled to ~28px display via SVG width on MediaCard. */
.jgn-loader-kg {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.jgn-loader-kg svg {
    overflow: visible;
}
.jgn-loader-kg__c1 { animation: jgnLoaderKgC1 3s ease-in-out infinite; }
.jgn-loader-kg__c2 { animation: jgnLoaderKgC2 3s ease-in-out infinite; }
.jgn-loader-kg__c3 { animation: jgnLoaderKgC3 3s ease-in-out infinite; }

@keyframes jgnLoaderKgC1 {
    0%     { transform: translate(0, 0); }
    8.33%  { transform: translate(-60px, 0); }
    25%    { transform: translate(-60px, 0); }
    33.33% { transform: translate(-60px, 60px); }
    50%    { transform: translate(-60px, 60px); }
    58.33% { transform: translate(0, 60px); }
    75%    { transform: translate(0, 60px); }
    83.33% { transform: translate(0, 0); }
    100%   { transform: translate(0, 0); }
}
@keyframes jgnLoaderKgC2 {
    0%     { transform: translate(0, 0); }
    8.33%  { transform: translate(0, 0); }
    16.67% { transform: translate(0, -60px); }
    33.33% { transform: translate(0, -60px); }
    41.67% { transform: translate(-60px, -60px); }
    58.33% { transform: translate(-60px, -60px); }
    66.67% { transform: translate(-60px, 0); }
    83.33% { transform: translate(-60px, 0); }
    91.67% { transform: translate(0, 0); }
    100%   { transform: translate(0, 0); }
}
@keyframes jgnLoaderKgC3 {
    0%     { transform: translate(0, 0); }
    16.67% { transform: translate(0, 0); }
    25%    { transform: translate(60px, 0); }
    41.67% { transform: translate(60px, 0); }
    50%    { transform: translate(60px, -60px); }
    66.67% { transform: translate(60px, -60px); }
    75%    { transform: translate(0, -60px); }
    91.67% { transform: translate(0, -60px); }
    100%   { transform: translate(0, 0); }
}
/* Larger HTML-div variant of the brand loader — used in the page-load
   and panel-settle overlays where the SVG version was glitching during
   WASM bootstrap. HTML divs with `will-change: transform` get reliable
   compositor-layer promotion; SVG `<circle>` transforms aren't always
   GPU-accelerated and stutter when the main thread is busy.
   3-cell grid: 56px circles, 64px translate between adjacent cells. */
.jgn-loader-kg-xl {
    position: relative;
    width: 184px;
    height: 184px;
    flex: 0 0 auto;
}
.jgn-loader-kg-xl__cell {
    position: absolute;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    will-change: transform;
    transform: translateZ(0);
    backface-visibility: hidden;
}
/* Cycle: 6s, ease-in-out. Twelve sequential moves per cycle — only one
   circle moves at a time (sliding-puzzle pattern). c1 moves on beats
   0/3/6/9, c2 on 1/4/7/10, c3 on 2/5/8/11. Each move is ~500ms; rest
   between adjacent moves is ~500ms each. The previous 3s version felt
   rushed; doubling the cycle gives the easing room to breathe. */
/* L-shape spans 120x120 (cell 56 + gap 64). Container is 184x184.
   Offset each cell by +32 (= (184-120)/2) so the cluster is centered.
   Translate animations are relative, so they continue to work unchanged. */
.jgn-loader-kg-xl__c1 {
    top: 32px; left: 96px; background: #DD5100;
    animation: jgnLoaderKgXlC1 6s ease-in-out infinite;
}
.jgn-loader-kg-xl__c2 {
    top: 96px; left: 96px; background: #1F2937;
    animation: jgnLoaderKgXlC2 6s ease-in-out infinite;
}
.jgn-loader-kg-xl__c3 {
    top: 96px; left: 32px; background: #1F2937;
    animation: jgnLoaderKgXlC3 6s ease-in-out infinite;
}
@keyframes jgnLoaderKgXlC1 {
    0%     { transform: translate3d(0, 0, 0); }
    8.33%  { transform: translate3d(-64px, 0, 0); }
    25%    { transform: translate3d(-64px, 0, 0); }
    33.33% { transform: translate3d(-64px, 64px, 0); }
    50%    { transform: translate3d(-64px, 64px, 0); }
    58.33% { transform: translate3d(0, 64px, 0); }
    75%    { transform: translate3d(0, 64px, 0); }
    83.33% { transform: translate3d(0, 0, 0); }
    100%   { transform: translate3d(0, 0, 0); }
}
@keyframes jgnLoaderKgXlC2 {
    0%     { transform: translate3d(0, 0, 0); }
    8.33%  { transform: translate3d(0, 0, 0); }
    16.67% { transform: translate3d(0, -64px, 0); }
    33.33% { transform: translate3d(0, -64px, 0); }
    41.67% { transform: translate3d(-64px, -64px, 0); }
    58.33% { transform: translate3d(-64px, -64px, 0); }
    66.67% { transform: translate3d(-64px, 0, 0); }
    83.33% { transform: translate3d(-64px, 0, 0); }
    91.67% { transform: translate3d(0, 0, 0); }
    100%   { transform: translate3d(0, 0, 0); }
}
@keyframes jgnLoaderKgXlC3 {
    0%     { transform: translate3d(0, 0, 0); }
    16.67% { transform: translate3d(0, 0, 0); }
    25%    { transform: translate3d(64px, 0, 0); }
    41.67% { transform: translate3d(64px, 0, 0); }
    50%    { transform: translate3d(64px, -64px, 0); }
    66.67% { transform: translate3d(64px, -64px, 0); }
    75%    { transform: translate3d(0, -64px, 0); }
    91.67% { transform: translate3d(0, -64px, 0); }
    100%   { transform: translate3d(0, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
    .jgn-loader-kg-xl__c1,
    .jgn-loader-kg-xl__c2,
    .jgn-loader-kg-xl__c3 { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
    .jgn-loader-kg__c1,
    .jgn-loader-kg__c2,
    .jgn-loader-kg__c3 { animation: none; }
}
.jgn-media-card__deleting-label {
    font-size: 10px;
    color: #6B7280;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* BU-132: toolstrip above the media grid — Select-all + range-tip. */
.compose-media-toolstrip {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 4px 6px;
    flex: 0 0 auto;
}
.compose-media-toolstrip__btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 22px;
    padding: 0 8px;
    border: 1px solid #E5E7EB;
    background: #FFFFFF;
    color: #1F2937;
    border-radius: 6px;
    font-size: 11px;
    font-weight: 500;
    cursor: pointer;
    transition: color 180ms ease-out, border-color 180ms ease-out, background-color 180ms ease-out;
}
.compose-media-toolstrip__btn:hover {
    color: #DD5100;
    border-color: rgba(221, 81, 0, 0.40);
}
.compose-media-toolstrip__btn .form-check-input {
    width: 12px !important;
    height: 12px !important;
    margin: 0 !important;
    pointer-events: none;
    accent-color: #DD5100;
}
.compose-media-toolstrip__count {
    font-variant-numeric: tabular-nums;
    color: #9CA3AF;
    font-size: 10px;
}
.compose-media-toolstrip__hint {
    font-size: 10px;
    color: #9CA3AF;
}
.compose-media-toolstrip__hint kbd {
    display: inline-block;
    padding: 0 4px;
    border: 1px solid #E5E7EB;
    border-radius: 3px;
    background: #F9FAFB;
    font-size: 9px;
    font-family: inherit;
    color: #4B5563;
}

/* BU-128: bulk action bar — sits between the composer and the media grid
   inside Panel2 when one or more media are selected. */
.compose-media-bulkbar {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    background: linear-gradient(180deg, rgba(221, 81, 0, 0.10) 0%, rgba(221, 81, 0, 0.05) 100%);
    border: 1px solid rgba(221, 81, 0, 0.32);
    border-left: 4px solid #DD5100;
    border-radius: 8px;
    flex: 0 0 auto !important;
}
.compose-media-bulkbar__count {
    font-size: 11px;
    color: #1F2937;
    margin-right: 4px;
}
.compose-media-bulkbar__count strong {
    color: #DD5100;
    font-size: 13px;
    font-weight: 700;
    margin-right: 2px;
}
.compose-media-bulkbar__btn {
    height: 26px;
    padding: 0 10px;
    border: 1px solid rgba(221, 81, 0, 0.40);
    background: #FFFFFF;
    color: #DD5100;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    cursor: pointer;
    transition: background-color 180ms ease-out, color 180ms ease-out;
}
.compose-media-bulkbar__btn:hover {
    background: rgba(221, 81, 0, 0.10);
    color: #C04600;
}
.compose-media-bulkbar__btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}
.compose-media-bulkbar__btn--danger {
    border-color: rgba(220, 38, 38, 0.40);
    color: #DC2626;
}
.compose-media-bulkbar__btn--danger:hover {
    background: rgba(220, 38, 38, 0.10);
    color: #B91C1C;
}
.compose-media-bulkbar__btn--ghost {
    border-color: rgba(0, 0, 0, 0.10);
    color: #6B7280;
    background: transparent;
}
.compose-media-bulkbar__btn--ghost:hover {
    background: rgba(0, 0, 0, 0.04);
    color: #1F2937;
}

/* Inline menu that drops below the bulk bar */
/* BU-207: transparent click-away backdrop for the media bulkbar menus.
   Fixed full-viewport layer at z-index 1049 (same value the filter-dropdown
   .jgn-menu-backdrop uses) so an outside click — or a re-click on the
   Voice/Stage/Scope trigger — closes the open bulk menu. The menu below is
   raised to z-index 1050 so it stays above this layer. */
.compose-media-bulkbar__backdrop {
    position: fixed;
    inset: 0;
    z-index: 1049;
    background: transparent;
}

.compose-media-bulkbar__menu {
    position: relative;
    z-index: 1050;
    flex-basis: 100%;
    margin-top: 6px;
    padding: 8px;
    background: #FFFFFF;
    border: 1px solid rgba(221, 81, 0, 0.30);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.compose-media-bulkbar__menu-search {
    width: 100%;
    height: 26px;
    padding: 4px 10px;
    border: 1px solid #E5E7EB;
    border-radius: 6px;
    font-size: 11px;
    outline: none;
}
.compose-media-bulkbar__menu-search:focus {
    border-color: #DD5100;
    box-shadow: 0 0 0 2px rgba(221, 81, 0, 0.12);
}
.compose-media-bulkbar__menu-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    max-height: 120px;
    overflow-y: auto;
    align-content: flex-start;
}
.compose-media-bulkbar__menu-chips--scroll {
    max-height: 80px;
}
.compose-media-bulkbar__menu-actions {
    display: flex;
    gap: 6px;
    justify-content: flex-end;
}

.jgn-media-card__tags {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}

.jgn-media-card__tag {
    font-size: 10px;
    font-weight: 500;
    padding: 2px 8px;
    border-radius: 10px;
    line-height: 1.4;
}

.jgn-media-card__tag--voice {
    background: #F3F4F6;
    color: #4B5563;
}

.jgn-media-card__tag--stage {
    background: #FFEDD5;
    color: #9A3412;
}

.jgn-media-card__footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 11px;
    color: #6B7280;
    font-variant-numeric: tabular-nums;
}

.jgn-media-card__assign-status--assigned {
    color: #059669;
    font-weight: 500;
}

.jgn-media-card__assign-status--unassigned {
    color: #9CA3AF;
}

/* Combine CTA. Solid orange when active; dead gray when none. */
.jgn-compose-cta-primary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    background: #DD5100;
    color: #FFFFFF;
    font-weight: 600;
    font-size: 14px;
    letter-spacing: -0.005em;
    padding: 10px 16px;
    border-radius: 8px;
    border: none;
    cursor: pointer;
    transition: background-color 180ms ease-out, box-shadow 180ms ease-out;
    margin-top: 14px;
    width: 100%;
}

.jgn-compose-cta-primary:hover {
    background: #C44900;
    box-shadow: 0 1px 3px rgba(221, 81, 0, 0.20);
}

.jgn-compose-cta-primary:focus-visible {
    outline: 2px solid #DD5100;
    outline-offset: 2px;
}

.jgn-compose-cta-primary:active {
    background: #B14000;
}

.jgn-compose-cta-primary:disabled {
    background: #E5E7EB;
    color: #9CA3AF;
    cursor: not-allowed;
    box-shadow: none;
}

/* BU-166: calmer drag/drop visual language. Heavy green/amber outlines
   replaced with hairline border + leftbar accent + faint inset shadow so the
   drag-target hover reads as ambient context rather than a saturated control.
   Saturated color is reserved for the post-drop confirmation flash (240ms),
   not the merely-hovering state. Tween ease unified on
   cubic-bezier(0.22, 0.61, 0.36, 1) for layout, 180ms for color. */
.jgn-deliverable-media-list.is-media-drag-active .jgn-deliverable-drop-target {
    cursor: copy;
}

/* Active drop-target — UNASSIGNED row ("fresh assignment").
   Hairline 1px #d1d5db border via inset shadow + 3px neutral gray leftbar
   + faint outer halo. No background saturation. */
.jgn-deliverable-drop-target--active.jgn-deliverable-row-unassigned,
.jgn-deliverable-media-list.is-media-drag-active .jgn-deliverable-drop-target--active.jgn-deliverable-row-unassigned {
    background: transparent !important;
    outline: none !important;
    box-shadow:
        inset 3px 0 0 0 #9ca3af,
        inset 0 0 0 1px #d1d5db,
        0 0 0 4px rgba(17, 24, 39, 0.04) !important;
    position: relative;
    z-index: 2;
    transition: box-shadow 180ms ease-out;
}
.jgn-deliverable-drop-target--active.jgn-deliverable-row-unassigned td {
    background: transparent !important;
    color: inherit;
    font-weight: inherit;
}

/* Active drop-target — ASSIGNED row ("replace existing media").
   Same calm treatment as unassigned but with a quieter amber leftbar so the
   "replace" distinction is still readable without lighting the row up. */
.jgn-deliverable-drop-target--active.jgn-deliverable-row-assigned,
.jgn-deliverable-media-list.is-media-drag-active .jgn-deliverable-drop-target--active.jgn-deliverable-row-assigned {
    background: transparent !important;
    outline: none !important;
    box-shadow:
        inset 3px 0 0 0 #d97706,
        inset 0 0 0 1px #d1d5db,
        0 0 0 4px rgba(217, 119, 6, 0.06) !important;
    position: relative;
    z-index: 2;
    transition: box-shadow 180ms ease-out;
}
.jgn-deliverable-drop-target--active.jgn-deliverable-row-assigned td {
    background: transparent !important;
    color: inherit;
    font-weight: inherit;
}

/* Drop-confirm flash: 240ms fade from a soft tint back to transparent.
   Brief, delicate, non-blocking. Saturation here (not on hover) is what
   confirms the action landed. */
.jgn-deliverable-row-just-dropped {
    animation: jgn-deliverable-row-success 240ms ease-out;
}

@keyframes jgn-deliverable-row-success {
    0%   { background-color: rgba(34, 197, 94, 0.10); }
    100% { background-color: transparent; }
}

/* Failure flash: red ring pulse on drop error. */
.jgn-deliverable-row-failed {
    animation: jgn-deliverable-row-failure 600ms ease-out;
}

@keyframes jgn-deliverable-row-failure {
    0% { box-shadow: 0 0 0 2px #DC2626, 0 0 0 6px rgba(220, 38, 38, 0.18); background: #FEF2F2 !important; }
    60% { box-shadow: 0 0 0 2px rgba(220, 38, 38, 0.6), 0 0 0 4px rgba(220, 38, 38, 0.10); background: #FEF2F2 !important; }
    100% { box-shadow: none; background: #FFFFFF !important; }
}

/* "Just now" pill next to the media badge, shown for ~4s after a successful drop. */
.jgn-deliverable-just-now {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 1px 8px;
    border-radius: 999px;
    background: #DCFCE7;
    color: #166534;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    line-height: 1.5;
    white-space: nowrap;
    animation: jgn-just-now-fade-in 200ms ease-out;
}

@keyframes jgn-just-now-fade-in {
    from { opacity: 0; transform: translateY(2px); }
    to { opacity: 1; transform: translateY(0); }
}

.jgn-deliverable-row-selected { background: rgba(221,81,0,0.04) !important; }

/* Toast stack at viewport top-right. Stacks vertically when multiple. */
.jgn-toast-stack {
    position: fixed;
    top: 16px;
    right: 16px;
    z-index: 10500;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
    max-width: calc(100vw - 32px);
}

.jgn-toast {
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    min-width: 280px;
    max-width: 380px;
    padding: 12px 14px;
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 10px;
    box-shadow: 0 8px 20px rgba(15, 23, 42, 0.10), 0 2px 4px rgba(15, 23, 42, 0.06);
    color: #1F2937;
    font-size: 13px;
    line-height: 1.4;
    animation: jgn-toast-enter 200ms ease-out both;
}

.jgn-toast.is-leaving {
    animation: jgn-toast-leave 180ms ease-in both;
}

@keyframes jgn-toast-enter {
    from { opacity: 0; transform: translateX(12px); }
    to { opacity: 1; transform: translateX(0); }
}

@keyframes jgn-toast-leave {
    from { opacity: 1; transform: translateX(0); }
    to { opacity: 0; transform: translateX(12px); }
}

.jgn-toast--success { border-color: #BBF7D0; }
.jgn-toast--success .jgn-toast__icon { color: #166534; background: #DCFCE7; }

.jgn-toast--error { border-color: #FECACA; }
.jgn-toast--error .jgn-toast__icon { color: #991B1B; background: #FEE2E2; }

.jgn-toast__icon {
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.jgn-toast__icon svg {
    width: 14px;
    height: 14px;
}

.jgn-toast__body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.jgn-toast__message {
    color: #111827;
    font-weight: 500;
    word-break: break-word;
}

.jgn-toast__retry {
    align-self: flex-start;
    background: transparent;
    border: 0;
    padding: 0;
    color: #DD5100;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.jgn-toast__retry:hover { color: #B14000; }

.jgn-toast__close {
    flex: 0 0 auto;
    background: transparent;
    border: 0;
    padding: 2px;
    color: #9CA3AF;
    cursor: pointer;
    border-radius: 4px;
    line-height: 0;
    transition: color 120ms ease-out, background-color 120ms ease-out;
}

.jgn-toast__close:hover { color: #1F2937; background: #F3F4F6; }
.jgn-toast__close svg { width: 12px; height: 12px; }

.jgn-deliverable-multi-bar {
    position: sticky;
    top: 0;
    z-index: 5;
    background: #FEF3C7;
    color: #92400E;
    font-size: 12px;
    padding: 8px 12px;
    border-bottom: 1px solid #FDE68A;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.jgn-deliverable-multi-bar button {
    background: transparent;
    border: 1px solid #92400E;
    color: #92400E;
    border-radius: 999px;
    padding: 2px 10px;
    font-size: 11px;
    cursor: pointer;
}

/* BU-223 revision 2 (2026-05-23): trashcan no longer reserves layout space.
   At rest the picker button occupies the full cell width (the media name
   is no longer truncated by a hidden icon). On row hover the trashcan
   slides in from the right + scales up with a brand-flavored overshoot
   ease, while a white gradient mask fades the picker label beneath the
   icon so the name stays readable. */
.jgn-media-popover__host--with-clear {
    position: relative;
    display: block;
}
/* Picker fills the cell width so the media name reclaims the full ~190px
   that the old flex-sibling trashcan was reserving (and partially
   overflowing into). Combined with picker's overflow:hidden +
   text-truncate, this means the label takes the maximum space allowed
   by the BU-222 colgroup (200px cell minus 20px cell padding = ~180px). */
.jgn-media-popover__host--with-clear > .jgn-deliverable-media-list__assign-button {
    width: 100%;
}

.jgn-deliverable-row-clear {
    position: absolute;
    top: 50%;
    right: 4px;
    transform: translate3d(6px, -50%, 0) scale(0.85);
    transform-origin: 100% 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    background: #FFFFFF;
    border: 1px solid rgba(185, 28, 28, 0.22);
    border-radius: 6px;
    box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06),
                0 0 0 3px rgba(255, 255, 255, 0.7);
    color: #B91C1C;
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    /* Brand-flavored ease-out-back: subtle overshoot on scale so the icon
       feels like it pops into existence rather than merely appearing. */
    transition: opacity 160ms cubic-bezier(0.34, 1.56, 0.64, 1),
                transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1),
                background-color 140ms ease-out,
                box-shadow 160ms ease-out;
    z-index: 2;
}

/* The fade mask: a gradient at the picker's right edge that fades the
   media name to white so the trashcan never sits on top of legible text.
   Only paints when the row is hovered, so at rest the picker label is
   completely unobstructed. */
.jgn-media-popover__host--with-clear::after {
    content: "";
    position: absolute;
    top: 1px;
    right: 1px;
    bottom: 1px;
    width: 40px;
    border-radius: 0 6px 6px 0;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, #FFFFFF 60%);
    opacity: 0;
    pointer-events: none;
    transition: opacity 160ms ease-out;
    z-index: 1;
}

.jgn-deliverable-media-list tbody tr:hover .jgn-deliverable-row-clear,
.jgn-deliverable-media-list tbody tr:focus-within .jgn-deliverable-row-clear {
    opacity: 1;
    transform: translate3d(0, -50%, 0) scale(1);
    pointer-events: auto;
}
.jgn-deliverable-media-list tbody tr:hover .jgn-media-popover__host--with-clear::after,
.jgn-deliverable-media-list tbody tr:focus-within .jgn-media-popover__host--with-clear::after {
    opacity: 1;
}

.jgn-deliverable-row-clear:hover {
    background: #FEF2F2;
    border-color: #B91C1C;
    box-shadow: 0 2px 6px rgba(185, 28, 28, 0.18),
                0 0 0 3px rgba(255, 255, 255, 0.9);
}
.jgn-deliverable-row-clear:active {
    transform: translate3d(0, -50%, 0) scale(0.92);
}
.jgn-deliverable-row-clear:focus-visible {
    outline: 2px solid rgba(185, 28, 28, 0.35);
    outline-offset: 1px;
    opacity: 1;
    pointer-events: auto;
    transform: translate3d(0, -50%, 0) scale(1);
}

/* Reduced-motion: drop the scale+slide, keep the fade. */
@media (prefers-reduced-motion: reduce) {
    .jgn-deliverable-row-clear {
        transform: translate3d(0, -50%, 0) scale(1);
        transition: opacity 100ms ease-out, background-color 100ms ease-out;
    }
}

.jgn-deliverable-drop-target.is-incompatible {
    box-shadow: 0 0 0 2px #F59E0B, 0 0 0 6px rgba(245, 158, 11, 0.10) !important;
}

/* BU-221 extension 2 (2026-05-23): the prior 2px solid #DD5100 box-shadow
   ring painted a hard horizontal orange line at the row's top + bottom
   edges that the user explicitly flagged twice as ugly. Eradicate the
   ring entirely. The attention signal stays via the inline background
   tint (rgba 221,81,0,0.10) set in GetRowStyle, with a soft 1200ms
   background-color pulse to draw the eye on first highlight, without a
   hard chrome edge anywhere on the row. */
.jgn-deliverable-highlight {
    animation: jgn-deliverable-pulse 1200ms ease-out;
}

@keyframes jgn-deliverable-pulse {
    0%   { background-color: rgba(221, 81, 0, 0.28); }
    60%  { background-color: rgba(221, 81, 0, 0.18); }
    100% { background-color: rgba(221, 81, 0, 0.10); }
}

/* Asset picker focus enhancement on workbench surface. */
.jgn-asset-picker__input:focus {
    border-color: #DD5100 !important;
    box-shadow: 0 0 0 3px rgba(221, 81, 0, 0.12);
}

/* Responsive. */
@media (max-width: 1200px) {
    .compose-workbench-topbar {
        flex-direction: column;
    }

    .compose-workbench-stats {
        min-width: 0;
        width: 100%;
    }
}

@media (max-width: 900px) {
    .compose-workbench-page {
        padding: 16px;
    }

    .compose-workbench-stats {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Reduced motion: disable transforms but keep fades. */
@media (prefers-reduced-motion: reduce) {
    .jgn-media-card,
    .jgn-compose-cta-primary,
    .jgn-engagement-chip,
    .compose-stat,
    .jgn-compose-composer__chip,
    .jgn-compose-composer__input {
        transition: opacity 180ms ease-out, background-color 180ms ease-out, color 180ms ease-out;
    }

    .jgn-media-card:hover,
    .jgn-media-card.is-dragging {
        transform: none;
    }

    .jgn-media-card {
        animation: none;
    }

    .jgn-deliverable-highlight {
        animation: none;
    }

    .jgn-deliverable-drop-target {
        transform: none !important;
        transition: none !important;
    }

    .jgn-deliverable-row-just-dropped,
    .jgn-deliverable-row-failed,
    .jgn-deliverable-just-now {
        animation: none !important;
    }

    /* Keep success/failure visible without motion: hold a static color frame. */
    .jgn-deliverable-row-just-dropped { background: #DCFCE7 !important; }
    .jgn-deliverable-row-failed { background: #FEF2F2 !important; }

    .jgn-toast,
    .jgn-toast.is-leaving {
        animation: none !important;
        transition: opacity 180ms ease-out;
    }
}

/* BU-221 (2026-05-23): no chrome on assigned rows. The Media cell (BU-220)
   carries the assignment signal; per-row chrome is redundant. Orange
   semantic is now reserved for attention/action only (drag halos, drop
   targets, unassigned dogear, engagement-tab active underline, multilink). */
.jgn-deliverable-row-assigned {
    background: transparent;
    box-shadow: none;
}
/* BU-186 bullet 82 (2026-05-18): dogear FLIPPED to UNASSIGNED rows.
   The orange triangular dogear is a 'this row needs attention' flag,
   not a 'this row is done' badge — more useful highlighting the
   unfinished work than the finished work. Assigned rows keep the
   warm peach tint + orange left-edge bar (their existing BU-093
   visual identity) without the corner glyph. */
.jgn-deliverable-row-unassigned td:first-child {
    position: relative;
}
.jgn-deliverable-row-unassigned td:first-child::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 0;
    height: 0;
    border-top: 12px solid #DD5100;
    border-right: 12px solid transparent;
    pointer-events: none;
    z-index: 2;
}
.jgn-deliverable-row-unassigned {
    background: #FFFFFF;
}

/* BU-221: drop-target tint still warranted (it is the drag-affordance state,
   not the assigned state). Keep. */
.jgn-deliverable-row-assigned.jgn-deliverable-drop-target,
.jgn-deliverable-row-assigned.jgn-deliverable-drop-target td {
    background: rgba(221, 81, 0, 0.06) !important;
    box-shadow: none;
}

/* BU-094: cross-engagement assignment cluster on the Media card footer. */
.jgn-media-card__assign-cluster {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.jgn-media-card__assign-status--assigned-other {
    color: #DD5100;
    font-weight: 500;
    font-size: 11px;
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.jgn-media-card__detach {
    width: 18px;
    height: 18px;
    padding: 0;
    border: 1px solid #E5E7EB;
    background: #FFFFFF;
    color: #6B7280;
    font-size: 14px;
    line-height: 14px;
    border-radius: 999px;
    cursor: pointer;
    transition: background 120ms ease-out, border-color 120ms ease-out, color 120ms ease-out;
}
.jgn-media-card__detach:hover {
    background: #FEF2F2;
    border-color: #DC2626;
    color: #DC2626;
}

/* BA-019: Move affordance. Surfaced when a media's DeliverableIds.Count >= 2
   (WF-192 many-to-many). Visually distinct from detach (×) — pill, not round;
   on-brand orange family (#DD5100 + WF-167 popover vocabulary), not red. */
.jgn-media-card__move {
    padding: 2px 9px;
    border: 1px solid #E5E7EB;
    background: #FFFFFF;
    color: #4B5563;
    font-size: 11px;
    font-weight: 500;
    line-height: 14px;
    border-radius: 999px;
    cursor: pointer;
    letter-spacing: 0.02em;
    transition: background 120ms ease-out, border-color 120ms ease-out,
                color 120ms ease-out, box-shadow 120ms ease-out;
}
.jgn-media-card__move:hover {
    background: #FFF6EE;
    border-color: #DD5100;
    color: #DD5100;
}
.jgn-media-card__move:focus-visible {
    outline: none;
    border-color: #DD5100;
    box-shadow: 0 0 0 3px rgba(221, 81, 0, 0.22);
}
.jgn-media-card__move:active {
    background: #DD5100;
    color: #FFFFFF;
    border-color: #DD5100;
}

/* BA-019: multi-link "Linked × N" pill replaces the plain "Assigned" pill when
   a media is on 2+ deliverables. Same shape vocabulary as the assigned pill
   but with the count surfaced and a soft orange accent to signal sharing. */
.jgn-media-card__assign-status--multilink {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 9px;
    background: #FFF6EE;
    color: #B14200;
    border: 1px solid #FAD5B8;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    line-height: 14px;
}
.jgn-media-card__assign-status--multilink svg {
    color: #DD5100;
    flex-shrink: 0;
}
.jgn-media-card__assign-status--multilink__count {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
}

/* BA-019 bullet 8 (2026-05-23): the "Linked × N" pill is a clickable button.
   Reset default button chrome so it visually matches the prior <span> pill,
   while gaining a clear hover state to signal interactivity. */
button.jgn-media-card__assign-status--multilink {
    cursor: pointer;
    font-family: inherit;
}
.jgn-media-card__assign-status--multilink:hover {
    background: #FFEDD8;
    border-color: #DD5100;
}
.jgn-media-card__assign-status--multilink--open {
    background: #FFEDD8;
    border-color: #DD5100;
}
.jgn-media-card__assign-status--multilink:focus-visible {
    outline: none;
    border-color: #DD5100;
    box-shadow: 0 0 0 3px rgba(221, 81, 0, 0.22);
}

/* BA-019 bullet 8: popover anchor + popover.
   Anchor = positioned wrapper so the absolute-positioned popover docks below
   the pill. Popover = card with internal scroll, max visible rows (~6 at
   ~28px per row + padding), brand-vocabulary borders/shadows, rows are real
   <button>s with hover + focus-visible states + active selection. */
.jgn-media-card__multilink-anchor {
    position: relative;
    display: inline-flex;
    align-items: center;
}
/* BA-019 bullet 9 (2026-05-23): popover z-index bumped to 1200 so it wins
   against the sticky topbar (~100) and panel-host (~30). Row layout switched
   to a 4-column grid that mirrors the deliverable-table vocabulary
   (date · platform icon · channel pill · stage letter). */
.jgn-media-card__multilink-popover {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 1200;
    min-width: 280px;
    max-width: 360px;
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 10px;
    box-shadow: 0 12px 28px rgba(15, 23, 42, 0.20),
                0 2px 6px rgba(15, 23, 42, 0.08);
    overflow: hidden;
    animation: jgn-multilink-popover-in 100ms ease-out;
}
@keyframes jgn-multilink-popover-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}
.jgn-media-card__multilink-popover__header {
    padding: 8px 12px 6px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #6B7280;
    border-bottom: 1px solid #F1F1F1;
    background: #FAFAFA;
}
.jgn-media-card__multilink-popover__list {
    max-height: 260px;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 4px 0;
    scrollbar-width: thin;
}
.jgn-media-card__multilink-popover__list::-webkit-scrollbar {
    width: 6px;
}
.jgn-media-card__multilink-popover__list::-webkit-scrollbar-thumb {
    background: #D1D5DB;
    border-radius: 3px;
}

/* Per-row grid: date · platform icon · channel pill · stage letter.
   Tabular-nums on the date column keeps dates column-true across rows. */
.jgn-multilink-row {
    display: grid;
    grid-template-columns: 44px 18px 1fr 22px;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 7px 10px 7px 13px;
    text-align: left;
    background: transparent;
    border: none;
    border-left: 3px solid transparent;
    color: #1F2937;
    font-size: 12px;
    line-height: 1.2;
    font-family: inherit;
    cursor: pointer;
    transition: background 80ms ease-out, border-color 80ms ease-out;
}
.jgn-multilink-row:hover {
    background: #FFF6EE;
    border-left-color: #DD5100;
}
.jgn-multilink-row:focus-visible {
    outline: none;
    background: #FFF6EE;
    border-left-color: #DD5100;
    box-shadow: inset 0 0 0 1px rgba(221, 81, 0, 0.20);
}
.jgn-multilink-row__date {
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    color: #6B7280;
    letter-spacing: 0.01em;
    white-space: nowrap;
}
.jgn-multilink-row__platform { display: inline-flex; align-items: center; justify-content: center; }
.jgn-multilink-row__channel { min-width: 0; overflow: hidden; }
.jgn-multilink-row__channel .jgn-deliverable-pill {
    font-size: 11px;
    padding: 1px 7px;
}
.jgn-multilink-row__stage { display: inline-flex; align-items: center; justify-content: center; }
.jgn-multilink-row__stage .jgn-deliverable-stage-token {
    width: 18px;
    height: 18px;
    font-size: 10px;
}

/* BA-019 bullet 10 (2026-05-23): row pulse after popover-click navigation.
   Animates `box-shadow: inset 0 0 0 9999px rgba(...)` on each <td>. This is
   Bootstrap's own table-overlay slot — Bootstrap already paints
   `box-shadow: inset 0 0 0 9999px var(--bs-table-bg-state, transparent)` on
   every td, so we can override THAT slot during the pulse without fighting
   the `background: #FFF8F0 !important` on assigned rows (which would block a
   background-color animation per Chrome's cascade).
   Two gentle peaks for a delicate double-pulse rhythm, then a long fade
   over 2s ease-out. Composes harmlessly with the row's inset 6px orange
   left bar (that lives on the <tr>, not the td). */
@keyframes jgn-deliverable-row-link-pulse {
    0%   { box-shadow: inset 0 0 0 9999px rgba(221, 81, 0, 0.00); }
    18%  { box-shadow: inset 0 0 0 9999px rgba(221, 81, 0, 0.34); }
    35%  { box-shadow: inset 0 0 0 9999px rgba(221, 81, 0, 0.18); }
    55%  { box-shadow: inset 0 0 0 9999px rgba(221, 81, 0, 0.28); }
    100% { box-shadow: inset 0 0 0 9999px rgba(221, 81, 0, 0.00); }
}
.jgn-deliverable-row-link-pulse > td {
    animation: jgn-deliverable-row-link-pulse 2s ease-out;
}

@media (prefers-reduced-motion: reduce) {
    .jgn-media-card__multilink-popover { animation: none; }
    .jgn-multilink-row { transition: none; }
    .jgn-deliverable-row-link-pulse { animation: none; }
}

/* WF-192b — sharing-row coupling. When the user hovers/focuses a deliverable
   row whose media is linked to 2+ deliverables, the OTHER rows holding the
   same media get [data-sharing-with-active="true"] via the
   sharing-row-coupling.js event-delegation script. Paint a subtle left-edge
   accent strip in the WF-167 brand vocabulary (#DD5100). Source row itself
   does NOT carry the attribute, so the user keeps a single primary hover
   focus while the siblings show the share. Implemented as ::after pseudo
   element (not box-shadow) to sidestep Bootstrap's table-cell shadow that
   competes for the same slot. */
tr[data-sharing-with-active="true"] td:first-child {
    position: relative;
}
tr[data-sharing-with-active="true"] td:first-child::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 3px;
    background: #DD5100;
    pointer-events: none;
    z-index: 3;
    opacity: 1;
    transition: opacity 120ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
    tr[data-sharing-with-active="true"] td:first-child::after {
        transition: none;
    }
}

/* WF-192c — from/to move picker. Modal-style overlay. Two columns of
   deliverable buttons (linked = From, unlinked in-scope = To). Brand
   vocabulary: hairline border, soft shadow, Traffic Orange accents on the
   selected option and the primary action. Backdrop click + Escape cancel. */
.jgn-move-picker-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1100;
    background: rgba(15, 23, 42, 0.42);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 32px;
    animation: jgn-move-picker-fade-in 120ms ease-out;
}
@keyframes jgn-move-picker-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}
.jgn-move-picker {
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, 0.18);
    width: min(720px, 100%);
    max-height: calc(100vh - 64px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.jgn-move-picker__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 18px;
    border-bottom: 1px solid #F1F1F1;
}
.jgn-move-picker__title {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: #111827;
    letter-spacing: 0.01em;
}
.jgn-move-picker__close {
    border: none;
    background: transparent;
    color: #6B7280;
    font-size: 22px;
    line-height: 1;
    padding: 0 4px;
    cursor: pointer;
    border-radius: 6px;
}
.jgn-move-picker__close:hover {
    color: #DD5100;
    background: #FFF6EE;
}
.jgn-move-picker__body {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    padding: 14px 18px;
    overflow: auto;
    flex: 1;
}
.jgn-move-picker__column {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}
.jgn-move-picker__column-label {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #6B7280;
    padding-bottom: 4px;
    border-bottom: 1px solid #F1F1F1;
    margin-bottom: 2px;
}
.jgn-move-picker__option {
    text-align: left;
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 8px;
    padding: 8px 10px;
    font-size: 12px;
    color: #1F2937;
    cursor: pointer;
    transition: background 100ms ease-out, border-color 100ms ease-out, color 100ms ease-out;
    font-variant-numeric: tabular-nums;
}
.jgn-move-picker__option:hover {
    background: #FFF6EE;
    border-color: #FAD5B8;
}
.jgn-move-picker__option:focus-visible {
    outline: none;
    border-color: #DD5100;
    box-shadow: 0 0 0 3px rgba(221, 81, 0, 0.22);
}
.jgn-move-picker__option--selected {
    background: #FFF6EE;
    border-color: #DD5100;
    color: #B14200;
    font-weight: 600;
}
.jgn-move-picker__option--selected:hover {
    background: #FFEDD8;
}
.jgn-move-picker__empty {
    font-size: 12px;
    color: #6B7280;
    font-style: italic;
    padding: 8px 10px;
}
.jgn-move-picker__error {
    background: #FEF2F2;
    border-top: 1px solid #FECACA;
    color: #B91C1C;
    padding: 10px 18px;
    font-size: 12px;
}
.jgn-move-picker__footer {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 12px 18px;
    border-top: 1px solid #F1F1F1;
    background: #FAFAFA;
}
.jgn-move-picker__btn {
    padding: 6px 14px;
    font-size: 12px;
    font-weight: 600;
    border-radius: 8px;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background 100ms ease-out, border-color 100ms ease-out, color 100ms ease-out;
}
.jgn-move-picker__btn--secondary {
    background: #FFFFFF;
    border-color: #E5E7EB;
    color: #4B5563;
}
.jgn-move-picker__btn--secondary:hover {
    border-color: #9CA3AF;
    color: #1F2937;
}
.jgn-move-picker__btn--primary {
    background: #DD5100;
    border-color: #DD5100;
    color: #FFFFFF;
}
.jgn-move-picker__btn--primary:hover {
    background: #B14200;
    border-color: #B14200;
}
.jgn-move-picker__btn--primary:disabled,
.jgn-move-picker__btn--primary[disabled] {
    background: #E5E7EB;
    border-color: #E5E7EB;
    color: #9CA3AF;
    cursor: not-allowed;
}
@media (prefers-reduced-motion: reduce) {
    .jgn-move-picker-backdrop { animation: none; }
    .jgn-move-picker__option,
    .jgn-move-picker__btn,
    .jgn-move-picker__close { transition: none; }
}

/* BU-096: Dashboard layout. Page is a fixed-height workbench, not a scrolling
   document. Uses position: fixed to escape MainLayout's Bootstrap .container
   max-width constraint (which clamps page content to ~1296px). */
.compose-workbench-dashboard {
    /* Sits below the sticky top-bar (Row1 52px + Row2 44px = 96px), with a
       12px gap so the Scope filter row doesn't crowd the primary nav.
       Was top: 56px (only cleared Row1) — pre-dated the F-041 sticky fix
       that pinned both rows; with sticky on, the Scope row was tucked
       directly under Row2 with no breathing room. */
    position: fixed;
    top: 108px;
    left: 0;
    right: 0;
    bottom: 0;
    height: auto;
    width: auto;
    max-width: none !important;
    padding: 0 !important;
    margin: 0 !important;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: #F8FAFC;
    z-index: 10;
}

/* When /compose is mounted, the workbench is position:fixed and fills the
   viewport below the sticky top-bar. The MainLayout's d-flex+min-vh-100
   wrapper + footer otherwise add ~250px of empty document below it that
   the user could scroll into. ComposeWorkbenchPage adds this class to
   <body> on mount and removes it on dispose. */
body.compose-fullscreen {
    overflow: hidden;
}
body.compose-fullscreen .footer {
    display: none;
}

/* Initial page-load overlay — branded 3-circle loader. Sits above the
   workbench surface until ComposeWorkbenchPage's first LoadPageAsync
   round-trip completes. Removes the cold-start flash where empty panels
   render briefly before data arrives. */
.compose-workbench-loading {
    position: absolute;
    inset: 0;
    z-index: 50;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 18px;
    background: #FFFFFF;
}
.compose-workbench-loading__label {
    font-size: 13px;
    font-weight: 600;
    color: #4B5563;
    letter-spacing: 0.02em;
}

.compose-workbench-header {
    /* BU-103: header now allowed to grow when scope sub-pickers + engagement
       chips + summary all want room. Wraps to multiple rows; constituent
       chip strips internal-scroll if their row is still too narrow. Header
       also gains its own scroll when content exceeds 35vh. */
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 4px 16px;
    background: #FFFFFF;
    border-bottom: 1px solid #E5E7EB;
    min-height: 40px;
    max-height: 35vh;
    overflow-y: auto;
    flex-wrap: wrap;
    align-content: flex-start;
}

.compose-workbench-title-compact {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: #111827;
    white-space: nowrap;
    flex: 0 0 auto;
}

.compose-workbench-header-bar {
    /* BU-103: wrap chips onto a second/third row when scope sub-picker
       expands the toolbar. */
    display: flex;
    align-items: center;
    gap: 8px 12px;
    flex: 1 1 100%;
    min-width: 0;
    flex-wrap: wrap;
    row-gap: 4px;
}

.compose-workbench-header-chips {
    flex-wrap: wrap;
    row-gap: 4px;
}

/* Each chip strip can horizontally scroll when its single row is the wrong
   size — engagement strip already had this; sub-pickers inherit it. */
.compose-workbench-header-bar .jgn-scope-subpicker {
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: thin;
    flex-wrap: nowrap;
}

.compose-workbench-header-label {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #9CA3AF;
    font-weight: 600;
    white-space: nowrap;
    flex: 0 0 auto;
}

.compose-workbench-header-chips {
    display: flex;
    gap: 4px;
    align-items: center;
    flex: 0 0 auto;
}

.compose-workbench-header-chips--scroll {
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.compose-workbench-header-chips--scroll::-webkit-scrollbar { display: none; }

.compose-workbench-header-divider {
    width: 1px;
    height: 18px;
    background: #E5E7EB;
    flex: 0 0 auto;
}

.compose-workbench-header-summary {
    display: flex;
    gap: 12px;
    align-items: center;
    flex: 0 0 auto;
    margin-left: auto;
    color: #6B7280;
    font-size: 11px;
    white-space: nowrap;
}

.compose-workbench-stat-inline strong {
    color: #111827;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    margin-right: 2px;
}

/* BU-240: demoted treatment for the four-stat strip when the workbench is
   empty (0 assets AND 0 media). Without this, "0 / 0 / 0 / 0%" reads as a
   failing scorecard the moment the page loads; the --quiet modifier thins
   the stats down to a subtle inventory chip until real numbers exist. */
.compose-workbench-header-summary--quiet { opacity: 0.55; font-size: 10px; }
.compose-workbench-header-summary--quiet .compose-workbench-stat-inline strong { font-weight: 500; }

.compose-workbench-empty-inline {
    color: #9CA3AF;
    font-size: 11px;
    font-style: italic;
}

.jgn-engagement-chip--compact {
    padding: 4px 10px;
    font-size: 11px;
    font-weight: 500;
    border-radius: 999px;
}

.compose-workbench-body {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    overflow: hidden;
    padding: 12px;
}

.compose-workbench-body > * {
    flex: 1 1 auto;
    min-height: 0;
    min-width: 0;
}

/* BU-096 follow-up: PanelHost has min-height: 720px / 640px hardcoded in its
   own <style> block. Inside the dashboard body those minimums clip the
   bottom row (Deliverables) since the dashboard container is overflow:hidden
   at exactly 100vh - header. Override to fill whatever height we have. */
.compose-workbench-body .panel-host-shell {
    min-height: 0 !important;
    height: 100% !important;
    padding: 0 !important;
    background: transparent !important;
}
.compose-workbench-body .panel-host-layout-surface {
    min-height: 0 !important;
    height: 100% !important;
}
.compose-workbench-body .panel-host-shell > * {
    min-height: 0;
}

/* BU-097: bento drag handle must look grabbable. Inline SVG grip means we
   need explicit padding + non-zero line-height. Override button defaults. */
.jgn-bento-handle {
    cursor: grab !important;
    background: transparent;
    border: 1px solid transparent;
    padding: 6px 8px;
    color: #9CA3AF;
    border-radius: 6px;
    transition: color 180ms ease-out, background-color 180ms ease-out, border-color 180ms ease-out;
    line-height: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.jgn-bento-handle:hover {
    color: #DD5100;
    background: rgba(221, 81, 0, 0.06);
    border-color: rgba(221, 81, 0, 0.18);
}
.jgn-bento-handle:active {
    cursor: grabbing !important;
    color: #DD5100;
    background: rgba(221, 81, 0, 0.10);
}
.jgn-bento-handle:focus-visible {
    outline: 2px solid #DD5100;
    outline-offset: 2px;
}
.jgn-bento-handle svg {
    display: block;
    pointer-events: none;
}

/* BU-099: panel space-efficiency pass */

/* Tighter type inside panels — one step down across the board */
.panel-host-panel { font-size: 12px; }
.panel-host-panel-title { font-size: 13px !important; font-weight: 600; }
.panel-host-panel-body { font-size: 12px; }

/* Compose-panel head: badge-only flavor (no duplicate title) */
.compose-panel-head--badge-only {
    justify-content: flex-end;
    padding: 4px 8px;
    min-height: 0;
}
.compose-panel-badge {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #6B7280;
    font-weight: 600;
    background: #F3F4F6;
    padding: 2px 8px;
    border-radius: 999px;
}

/* Asset picker tightening */
.jgn-asset-picker { font-size: 12px; }
.jgn-asset-picker__row { padding: 4px 8px !important; }
.jgn-asset-picker__row-title { font-size: 12px !important; }
.jgn-asset-picker__row-meta { font-size: 10px !important; }

/* Filter row inside panels (assets + media) — collapsed by default,
   expand-on-click via [open] details */
.jgn-asset-picker__filters,
.compose-panel-filters {
    font-size: 11px;
}

/* Make filter rows compact dropdown-style anchors instead of inline pill walls */
.jgn-filter-row { padding: 6px 8px !important; gap: 4px !important; }
.jgn-filter-row__label { font-size: 9px !important; }
.jgn-filter-chip { padding: 2px 8px !important; font-size: 10px !important; }

/* Deliverable filter grid: tighter labels + smaller controls */
.jgn-deliverable-filter-grid { padding: 6px 10px !important; gap: 6px !important; }
.jgn-deliverable-filter-label { font-size: 9px !important; }

/* BU-186 Stage 5 (2026-05-17): Deliverable table methodology treatment.
   Column headers in neutral tertiary, row cells in primary dark, hairline
   row separators. Overrides the prior 10px/!important rules with the same
   selector + !important so cascade-order wins, since both are at the
   same specificity.
   BU-222 (2026-05-23): flipped from auto to fixed so the colgroup widths
   declared inside the Razor component actually bind. Brief absorbs slack
   instead of Voice. */
.jgn-deliverable-media-list table { table-layout: fixed !important; }
.jgn-deliverable-media-list thead th {
    font-size: 11px !important;
    font-weight: 400 !important;
    color: #6B7280 !important;
    text-transform: none !important;
    letter-spacing: 0 !important;
    padding: 6px 10px !important;
    border-bottom: 0.5px solid #E5E7EB !important;
}
.jgn-deliverable-cell { padding: 7px 10px !important; font-size: 13px !important; font-weight: 400 !important; }
.jgn-deliverable-cell--date { font-size: 12px !important; color: #6B7280 !important; }
.jgn-deliverable-cell--brief { font-size: 12px !important; color: #6B7280 !important; }
.jgn-deliverable-pill { font-size: 11px !important; font-weight: 400 !important; padding: 2px 8px !important; }
.jgn-deliverable-stage-pill { font-size: 11px !important; font-weight: 400 !important; padding: 2px 8px !important; }

/* Internal scrolls — confirm each panel scrolls inside itself */
.panel-host-panel-body { overflow: auto; }
.compose-panel-inner { overflow: hidden; }
.compose-panel-inner > *:not(.compose-panel-head) { overflow: auto; min-height: 0; flex: 1 1 auto; }

/* Floating panel badge — absolute-positioned at top-right corner of the panel,
   overlaid on the panel-host header so it doesn't claim its own row.
   2026-05-08 audit: pair with `.jgn-asset-picker__view { padding-right: ... }`
   below so the columns 1-6 / auto controls don't extend behind the badge.
   Without that pairing the "0 SELECTED" pill sat on top of "auto". */
.compose-panel-inner { position: relative; }
.compose-panel-badge--floating {
    position: absolute;
    top: 8px;
    right: 12px;
    z-index: 4;
    pointer-events: none;
    font-size: 9px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    /* 2026-05-08 audit: #6B7280 on #F3F4F6 = 4.39:1 (just under 4.5).
       #4B5563 = 7.45:1, comfortably above WCAG AA. */
    color: #4B5563;
    font-weight: 600;
    background: rgba(243, 244, 246, 0.92);
    padding: 2px 8px;
    border-radius: 999px;
    backdrop-filter: blur(4px);
}

/* 2026-05-08 audit: reserve room for the floating "0 SELECTED" badge so the
   asset-picker column-count buttons don't render underneath it. The badge
   width is roughly 80px including padding+blur — give the row a 96px
   right-padding cushion. */
.compose-workbench-body .jgn-asset-picker__view {
    padding-right: 96px !important;
}

/* BU-099 follow-up: kill the wasted gap between panel-host header and the
   first child of the panel body. PanelHost ships with padding: 24px on the
   body and the AssetPicker carries its own padding: 12px + 1px border, which
   compounded into ~36px of dead space. Inside the workbench dashboard scope
   we tighten both. */
.compose-workbench-body .panel-host-panel-body {
    padding: 6px 10px 10px 10px !important;
}
.compose-workbench-body .compose-panel-inner {
    gap: 6px;
}
.compose-workbench-body .compose-panel-inner--media {
    gap: 4px;     /* BU-116: was 8px — kill the huge gap between composer and Voice filter row */
}
.compose-workbench-body .jgn-compose-zone--active {
    margin-bottom: 0;
}

/* BU-117: composer "Which X?" entity sub-picker. Same height-bounded
   chip layout as the workbench-header / panel-level subpickers so a long
   list of partners or workspaces can't burst out of the composer card. */
.jgn-compose-zone__owner {
    margin-top: 4px;
    padding: 6px 0 0 0;
    border-top: 1px dashed rgba(221, 81, 0, 0.25);
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}
.jgn-compose-zone__owner-top {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.jgn-compose-zone__owner-top .jgn-compose-zone__opt-label {
    color: #DD5100;
    font-weight: 700;
    text-transform: none;
    letter-spacing: 0;
    font-size: 10px;
    flex: 0 0 auto;
}
.jgn-compose-zone__owner-search {
    flex: 1 1 160px;
    min-width: 110px;
    height: 22px;
    padding: 2px 8px;
    border: 1px solid rgba(221, 81, 0, 0.30);
    border-radius: 999px;
    background: #FFFFFF;
    font-size: 10px;
    color: #1F2937;
    outline: none;
}
.jgn-compose-zone__owner-search:focus {
    border-color: #DD5100;
    box-shadow: 0 0 0 2px rgba(221, 81, 0, 0.12);
}
.jgn-compose-zone__owner-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    max-height: 80px;
    overflow-y: auto;
    align-content: flex-start;
    padding: 0 2px;
}
.jgn-compose-zone__owner-chips::-webkit-scrollbar { width: 6px; }
.jgn-compose-zone__owner-chips::-webkit-scrollbar-thumb {
    background: rgba(221, 81, 0, 0.25);
    border-radius: 999px;
}
.jgn-compose-zone__owner-empty {
    font-size: 10px;
    color: #9CA3AF;
    font-style: italic;
}
.compose-workbench-body .jgn-asset-picker {
    padding: 0 !important;
    border: 0 !important;
    background: transparent !important;
    border-radius: 0 !important;
}
.compose-workbench-body .jgn-asset-picker__search { margin-bottom: 6px; }
.compose-workbench-body .jgn-asset-picker__chips { margin-bottom: 6px; }
.compose-workbench-body .jgn-asset-picker__filters { margin-bottom: 6px; gap: 4px; }

/* BU-100 / BU-105: scope sub-picker — when a user selects
   Workspace/Partner/Engagement chip, a connected drawer drops down with
   "Which X?" + entity chips. Visual through-line: matching orange tint,
   solid 4px left accent (signals "you're inside Workspace scope"), and a
   small upward notch on top that visually hooks the drawer to the chip row
   above. Same pattern at workbench-header (larger) and panel (smaller). */
.jgn-scope-subpicker {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    padding: 8px 12px 8px 16px;
    margin: 4px 0 6px 0;
    border-radius: 0 10px 10px 10px;
    background: rgba(221, 81, 0, 0.06);
    border: 1px solid rgba(221, 81, 0, 0.22);
    border-left: 4px solid #DD5100;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4);
}
.jgn-scope-subpicker::before {
    /* upward notch — "this drawer comes from the chip row above" */
    content: '';
    position: absolute;
    top: -6px;
    left: 12px;
    width: 10px;
    height: 10px;
    background: rgba(221, 81, 0, 0.06);
    border-top: 1px solid rgba(221, 81, 0, 0.22);
    border-left: 1px solid rgba(221, 81, 0, 0.22);
    transform: rotate(45deg);
}
.jgn-scope-subpicker__label {
    font-size: 11px !important;
    font-weight: 700;
    color: #DD5100;
    text-transform: none;
    letter-spacing: 0;
    margin-right: 6px;
    flex: 0 0 auto;
}
.jgn-scope-subpicker .jgn-filter-chip {
    background: #fff;
    color: #DD5100;
    border: 1px solid rgba(221, 81, 0, 0.40);
    font-weight: 600;
}
.jgn-scope-subpicker .jgn-filter-chip:hover {
    background: rgba(221, 81, 0, 0.06);
    border-color: #DD5100;
}
.jgn-scope-subpicker .jgn-filter-chip--active {
    background: #DD5100 !important;
    color: #fff !important;
    border-color: #DD5100 !important;
}
.jgn-scope-subpicker__empty {
    font-size: 10px;
    color: #9CA3AF;
    font-style: italic;
    flex: 0 0 auto;
}

/* Workbench header version: same visual language, sized for toolbar scale
   (slightly stronger tint and bigger chips). */
.compose-workbench-header-bar .jgn-scope-subpicker,
.jgn-scope-subpicker--header {
    margin: 4px 0 4px 0;
    padding: 8px 12px 8px 16px;
    background: rgba(221, 81, 0, 0.08);
    border: 1px solid rgba(221, 81, 0, 0.28);
    border-left: 4px solid #DD5100;
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
}
.compose-workbench-header-bar .jgn-scope-subpicker::before,
.jgn-scope-subpicker--header::before {
    background: rgba(221, 81, 0, 0.08);
    border-top-color: rgba(221, 81, 0, 0.28);
    border-left-color: rgba(221, 81, 0, 0.28);
}
.compose-workbench-header-bar .jgn-scope-subpicker__label,
.jgn-scope-subpicker--header .jgn-scope-subpicker__label {
    font-size: 12px !important;
    font-weight: 700;
}

/* BU-106: subpicker layout. Top row = label + search + (optional) "All"
   chip. Below it, the entity chips wrap. Chips fit content (no fixed
   height) so multi-word entity names like "Circuit Breaker Properties"
   don't get clipped. The chips area itself is height-bounded with internal
   scroll so it can't push the rest of the workbench off-screen. */
.jgn-scope-subpicker__top {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.jgn-scope-subpicker__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    max-height: 22vh;
    overflow-y: auto;
    align-content: flex-start;
    padding: 2px 0;
}
.jgn-scope-subpicker__chips::-webkit-scrollbar { width: 8px; }
.jgn-scope-subpicker__chips::-webkit-scrollbar-thumb {
    background: rgba(221, 81, 0, 0.25);
    border-radius: 999px;
}
.jgn-scope-subpicker__search {
    flex: 1 1 180px;
    min-width: 120px;
    height: 26px;
    padding: 4px 10px;
    border: 1px solid rgba(221, 81, 0, 0.30);
    border-radius: 999px;
    background: #fff;
    font-size: 11px;
    color: #1F2937;
    outline: none;
}
.jgn-scope-subpicker__search:focus {
    border-color: #DD5100;
    box-shadow: 0 0 0 3px rgba(221, 81, 0, 0.15);
}
.jgn-scope-subpicker__all {
    margin-left: auto;
    flex: 0 0 auto;
}

/* BU-106: chip text-clip fix. Let chips grow to fit multi-word entity
   names; never clip lines. */
.jgn-scope-subpicker .jgn-filter-chip {
    height: auto !important;
    min-height: 22px;
    padding: 3px 10px !important;
    line-height: 1.25 !important;
    white-space: nowrap;
    max-width: 240px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.compose-workbench-header-bar .jgn-scope-subpicker .jgn-filter-chip,
.jgn-scope-subpicker--header .jgn-filter-chip {
    min-height: 26px;
    padding: 4px 12px !important;
    font-size: 11px !important;
    line-height: 1.25 !important;
    max-width: 280px;
}

/* BU-101: density pass on the workbench panels.
   Goals: assets/media take ≥50% of panel height; filter sections collapse to
   a single inline toolbar; rows become single-line with name + meta inline +
   right-aligned reuse badge; chips shrink ~25%; redundant labels go. */

/* 1. Filters fold into a single horizontal toolbar (Voice / Stage / Scope on
   one wrapping row). Each row label is small caps and inline. */
.compose-workbench-body .jgn-asset-picker__filters,
.compose-workbench-body .compose-panel-inner--media > .jgn-filter-row {
    flex-direction: row !important;
    flex-wrap: wrap !important;
    align-items: center;
    gap: 4px 10px !important;
    margin-bottom: 4px !important;
    padding: 2px 4px !important;
}
.compose-workbench-body .jgn-asset-picker__filters > .jgn-filter-row {
    padding: 0 !important;
    margin: 0 !important;
    /* 2026-05-08 audit: was `flex: 0 0 auto` which let the row size to its
       intrinsic content width, ignoring the parent. When a row's chips
       summed wider than the asset panel (e.g. tablet @ 260px panel width vs
       Stage row's 319px chip total), the row overflowed instead of wrapping
       its chips. `max-width: 100%` caps the row at parent width so chips
       wrap into multiple lines. */
    flex: 0 1 auto;
    max-width: 100%;
    gap: 4px !important;
}
.compose-workbench-body .jgn-filter-row__label {
    font-size: 9px !important;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    /* 2026-05-08 audit: was #9CA3AF (2.54:1 fail). #6B7280 = 4.83:1 pass.
       Higher-specificity rule than the base .jgn-filter-row__label so this
       wins inside the workbench body. */
    color: #6B7280;
    margin-right: 2px;
}

/* 2. Chip compression — 24px chip height (was ~32px), tighter padding. */
.compose-workbench-body .jgn-filter-chip {
    height: 22px;
    padding: 0 8px !important;
    font-size: 10px !important;
    line-height: 22px;
    border-radius: 999px;
}
/* BU-186 Stage 4 (2026-05-17): Compose Assets panel — methodology token
   treatment overriding the prior compact-but-heavy chrome. Object (asset
   name) is the figure, all else is ground. Hairline 0.5px borders, 400/500
   weights only, neutral chrome, no orange ambient color. These rules win
   specificity over the AssetPicker inline <style> block via the
   .compose-workbench-body parent prefix. */
.compose-workbench-body .jgn-asset-picker__chips {
    gap: 6px !important;
    margin-bottom: 8px !important;
}
.compose-workbench-body .jgn-asset-picker__chip {
    height: auto;
    padding: 3px 10px !important;
    font-size: 11px !important;
    font-weight: 400;
    line-height: 1.4;
    background: transparent !important;
    border: 0.5px solid #E5E7EB !important;
    color: #4B5563 !important;
    border-radius: 999px !important;
    transition: background-color 120ms ease-out, border-color 120ms ease-out, color 120ms ease-out;
}
.compose-workbench-body .jgn-asset-picker__chip:hover {
    background: #F9FAFB !important;
    color: #111827 !important;
}
.compose-workbench-body .jgn-asset-picker__chip.is-active,
.compose-workbench-body .jgn-asset-picker__chip[aria-pressed="true"] {
    background: #F3F4F6 !important;
    border-color: #6B7280 !important;
    color: #111827 !important;
    font-weight: 500;
}

/* Asset rows — hairline separator, neutral hover. */
.compose-workbench-body .jgn-asset-picker__list {
    gap: 0 !important;
    padding: 0;
    max-height: none !important;
}
.compose-workbench-body .jgn-asset-picker__row {
    padding: 6px 10px !important;
    border: 0 !important;
    border-radius: 0 !important;
    border-bottom: 0.5px solid #E5E7EB !important;
    background: transparent !important;
    gap: 10px !important;
    min-height: 30px;
    transition: background-color 120ms ease-out;
}
.compose-workbench-body .jgn-asset-picker__row:last-child {
    border-bottom: 0 !important;
}
.compose-workbench-body .jgn-asset-picker__row:hover {
    background: #F9FAFB !important;
}
.compose-workbench-body .jgn-asset-picker__icon {
    font-size: 12px !important;
    color: #9CA3AF;
    width: 14px !important;
}
.compose-workbench-body .jgn-asset-picker__content {
    display: flex !important;
    flex-direction: row !important;
    align-items: baseline;
    gap: 6px;
    min-width: 0;
    flex: 1 1 auto;
}
.compose-workbench-body .jgn-asset-picker__name {
    font-weight: 500;
    font-size: 13px;
    color: #111827;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin: 0 !important;
}
.compose-workbench-body .jgn-asset-picker__meta {
    font-size: 11px !important;
    font-weight: 400;
    color: #6B7280;
    margin: 0 !important;
    flex: 0 0 auto;
    white-space: nowrap;
}
.compose-workbench-body .jgn-asset-picker__meta::before {
    content: "·";
    margin-right: 4px;
    color: #D1D5DB;
}
/* Reuse badge — outlined-only hairline, neutral. No orange. */
.compose-workbench-body .jgn-asset-picker__badge {
    font-size: 10px !important;
    font-weight: 400;
    padding: 1px 8px !important;
    background: transparent !important;
    border: 0.5px solid #E5E7EB !important;
    color: #6B7280 !important;
    border-radius: 999px !important;
    flex: 0 0 auto;
}
.compose-workbench-body .jgn-asset-picker__check {
    display: none !important;  /* checkbox already shows selection */
}

/* Compact form-check checkbox — 13px square, neutral accent. */
.compose-workbench-body .jgn-asset-picker__row .form-check-input {
    width: 13px !important;
    height: 13px !important;
    margin-top: 0 !important;
    accent-color: #6B7280;
}

/* Search input — hairline border, neutral. */
.compose-workbench-body .jgn-asset-picker__input {
    min-height: 30px !important;
    font-size: 12px !important;
    font-weight: 400;
    padding: 4px 10px !important;
    border: 0.5px solid #E5E7EB !important;
    border-radius: 8px !important;
    color: #111827 !important;
    background: #FFFFFF !important;
}
.compose-workbench-body .jgn-asset-picker__input:focus {
    border-color: #6B7280 !important;
    outline: none !important;
}
.compose-workbench-body .jgn-asset-picker__search {
    margin-bottom: 8px !important;
}

/* 6. Sub-picker chip row inside panels — keep the connected-drawer visual
   from .jgn-scope-subpicker but compress slightly for panel scale. */
.compose-workbench-body .jgn-scope-subpicker {
    padding: 6px 10px 6px 14px !important;
    margin: 4px 0 6px 0 !important;
    gap: 6px !important;
}
.compose-workbench-body .jgn-scope-subpicker__label {
    font-size: 10px !important;
}
.compose-workbench-body .jgn-scope-subpicker .jgn-filter-chip {
    height: 22px;
    padding: 0 9px !important;
    line-height: 20px;
}

/* BU-105 / BU-125: panel scroll model — replaces the broken blanket
   rules from BU-099 and the original BU-105. The principle: in each
   panel one child is the SCROLLABLE BODY (asset picker / media grid /
   deliverable list) — everything else is FROZEN CHROME (composer,
   filter rows, scope sub-picker, search input).

   Frozen chrome fits content and doesn't scroll. Scrollable body takes
   remaining flex space and scrolls internally. */

/* Frozen panel chrome */
/* BU-225 (2026-05-23): added .compose-media-toolstrip + .compose-media-bulkbar
   so the Select-all hint row and the bulk-action bar stop stretching to fill
   panel height. Line 2993's broadly applied `flex: 1 1 auto` was inflating
   them to ~109px tall when their natural content height is ~22-30px, which
   read as ~200px of dead vertical space between the drop zone and the card
   grid. The grid's own `flex: 1 1 auto` rule (line 3514 area) keeps it the
   sole growing container as intended. */
.compose-workbench-body .compose-panel-inner > .jgn-compose-composer,
.compose-workbench-body .compose-panel-inner > .jgn-compose-zone,
.compose-workbench-body .compose-panel-inner > .jgn-filter-row,
.compose-workbench-body .compose-panel-inner > .jgn-scope-subpicker,
.compose-workbench-body .compose-panel-inner > .jgn-deliverable-engagement-tabs,
.compose-workbench-body .compose-panel-inner > .compose-media-toolstrip,
.compose-workbench-body .compose-panel-inner > .compose-media-bulkbar {
    flex: 0 0 auto !important;
    overflow: visible !important;
}

/* Scrollable panel body — Assets / Media / Deliverables */
.compose-workbench-body .compose-panel-inner > .jgn-asset-picker {
    display: flex !important;
    flex-direction: column !important;
    flex: 1 1 auto !important;
    min-height: 0 !important;
    height: auto !important;
    overflow: hidden !important;
}
.compose-workbench-body .jgn-asset-picker > .jgn-asset-picker__search,
.compose-workbench-body .jgn-asset-picker > .jgn-asset-picker__chips,
.compose-workbench-body .jgn-asset-picker > .jgn-asset-picker__filters,
.compose-workbench-body .jgn-asset-picker > .jgn-asset-picker__view,
.compose-workbench-body .jgn-asset-picker > .jgn-scope-subpicker {
    flex: 0 0 auto !important;
    overflow: visible !important;
}
.compose-workbench-body .jgn-asset-picker__list {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    max-height: none !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
}
.compose-workbench-body .compose-panel-inner > .compose-media-grid {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    max-height: none !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
}
.compose-workbench-body .compose-panel-inner > .jgn-deliverable-media-list {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    max-height: 100%;
    /* BU-126: filter row stays pinned, only the table scrolls. The list
       itself becomes a flex column; .__filters is frozen, .table-responsive
       is the scroll container. */
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
}
.compose-workbench-body .jgn-deliverable-media-list > .jgn-deliverable-media-list__filters,
.compose-workbench-body .jgn-deliverable-media-list > .jgn-deliverable-multi-bar {
    flex: 0 0 auto !important;
    overflow: visible !important;
}
.compose-workbench-body .jgn-deliverable-media-list > .table-responsive {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow-y: auto !important;
    overflow-x: auto !important;
}

/* BU-130: clickable column headers — sort affordance. */
.jgn-deliverable-header {
    cursor: pointer;
    user-select: none;
    transition: background-color 120ms ease, color 120ms ease;
}
/* BU-227 bullet 6: pin the column-headers <thead><tr> row to the top of the
   table's scroll container (.table-responsive) so headers stay visible while
   the table scrolls. Targets every <th> in the deliverable table thead — the
   sortable headers (.jgn-deliverable-header) AND the bookends (the select-all
   checkbox <th> and the Media <th>) which are plain <th>s without that class.
   z-index 4 sits BELOW the engagement-tabs row (z-index 5 on
   .jgn-deliverable-engagement-tabs-row) so the tabs always win on overlap.
   Inline `background:#fff` on each <th> keeps body rows from showing through. */
.jgn-deliverable-media-list table thead th {
    position: sticky;
    top: 0;
    z-index: 4;
    background: #fff;
}
.jgn-deliverable-header:hover {
    background-color: rgba(221, 81, 0, 0.05);
    color: #DD5100;
}
.jgn-deliverable-header.is-active {
    color: #DD5100;
}
.jgn-deliverable-header__caret {
    margin-left: 4px;
    font-size: 9px;
    color: #DD5100;
    display: inline-block;
}
.compose-workbench-body .compose-media-grid {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow-y: auto !important;
    max-height: none !important;
}

/* 7. Floating panel badge — keep visible but lower z to not steal click. */
.compose-workbench-body .compose-panel-badge--floating {
    font-size: 9px !important;
    padding: 1px 6px !important;
}

/* 8. Media composer card — tighter padding when shown. */
.compose-workbench-body .jgn-compose-composer__card {
    padding: 8px 12px !important;
    gap: 6px !important;
}
.compose-workbench-body .jgn-compose-composer__title {
    font-size: 13px !important;
}
.compose-workbench-body .jgn-compose-composer__tag-group {
    gap: 4px !important;
}

/* ---------------------------------------------------------------------------
   BU-148: Scope owner picker (table variant). Shared by:
     - Compose Workbench global header sub-picker (Which Workspace/Partner/Engagement?)
     - Media panel sub-picker
     - AssetPicker sub-picker
   Replaces the .jgn-scope-subpicker pill-blob pattern with a sortable,
   searchable, scroll-bounded table. Same shape as .channel-picker on
   /template/list — kept distinct here so the two evolve independently.
   --------------------------------------------------------------------------- */
.scope-owner-picker {
    border: 1px solid #E5E7EB;
    border-radius: 6px;
    background: #FFFFFF;
    margin-top: 6px;
    max-width: 560px;
}

.scope-owner-picker__toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-bottom: 1px solid #E5E7EB;
}

.scope-owner-picker__label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: #6B7280;
    font-weight: 600;
    white-space: nowrap;
}

.scope-owner-picker__search { flex: 1 1 auto; min-width: 0; }
.scope-owner-picker__count { font-size: 11px; color: #6B7280; white-space: nowrap; }

.scope-owner-picker__bulk { font-size: 11px !important; padding: 2px 8px !important; }

.scope-owner-picker__scroll {
    max-height: 240px;
    overflow-y: auto;
}

.scope-owner-picker__table { font-size: 12px; }

.scope-owner-picker__table thead th {
    position: sticky;
    top: 0;
    background: #F9FAFB;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: #6B7280;
    font-weight: 600;
    border-bottom: 1px solid #E5E7EB;
    z-index: 1;
}

.scope-owner-picker__check-col { width: 32px; text-align: center; }
/* 2026-05-07 brand audit: Bootstrap 5's .table paints cells via
   box-shadow: inset 0 0 0 9999px var(--bs-table-bg-state, ...), and the
   .table-info modifier sets --bs-table-bg to a blue (#cff4fc). Without
   overriding that variable AND the td background, the cell-level blue
   wins over any row-level background. Drive the override at both layers
   so hover and selected register cleanly on every consumer. */
.scope-owner-picker__table tbody tr:hover {
    --bs-table-bg-state: #FEE6D6;
    background: #FEE6D6;
}
.scope-owner-picker__table tbody tr:hover td {
    background-color: #FEE6D6;
}

.scope-owner-picker__table tbody tr.table-info {
    --bs-table-bg-state: #FEE6D6;
    background: #FEE6D6;
    color: #DD5100;
    font-weight: 600;
    box-shadow: inset 3px 0 0 0 #DD5100;
}
.scope-owner-picker__table tbody tr.table-info td {
    background-color: #FEE6D6;
    color: #DD5100;
}

.scope-owner-picker__table tbody tr.table-info:hover {
    --bs-table-bg-state: #FCC9A4;
    background: #FCC9A4;
}
.scope-owner-picker__table tbody tr.table-info:hover td {
    background-color: #FCC9A4;
    color: #B33D00;
}

.scope-owner-picker__table input[type=checkbox],
.scope-owner-picker__table input[type=radio] { pointer-events: none; }

/* ---------------------------------------------------------------------------
   BU-148: Cascading scope picker — chip row (level 1) + scope-owner-picker
   table (level 2) read as a single cascade. Top-of-page horizontal layout on
   wide viewports; vertical stack on mobile via the existing flex-wrap on
   .compose-workbench-header-bar. The leaf level inherits the .scope-owner-picker
   styles above; this layer adds the connecting rail and chip-row affordance.
   BU-152: neomorphic depth — soft outer shadow + subtle inset on root, active
   chip lifted with a richer shadow, filter trail visible whenever any
   ancestor is set so the user always knows what's filtering.
   --------------------------------------------------------------------------- */
.compose-workbench-cascade {
    align-items: flex-start;
    background: linear-gradient(180deg, #FBFCFD 0%, #F6F8FA 100%);
    border-radius: 10px;
    padding: 6px 8px;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.9),
        inset 0 -1px 0 rgba(0, 0, 0, 0.04),
        0 1px 2px rgba(0, 0, 0, 0.04);
}

/* BU-152: depth on the chip row. Active chip lifts; inactive chips sit flush. */
.compose-workbench-cascade__chips .jgn-filter-chip--active {
    box-shadow: 0 1px 2px rgba(221, 81, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}

.compose-workbench-cascade__chips .jgn-filter-chip:not(.jgn-filter-chip--active):not(.jgn-filter-chip--disabled) {
    background: #FFFFFF;
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
}

/* BU-152: filter trail. Sits below the chip row, summarizes the ancestor
   chain. Always-on when any selection exists, even Personal/Org. */
.compose-workbench-cascade__trail {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: 6px;
    padding: 4px 8px;
    background: rgba(221, 81, 0, 0.06);
    border-radius: 999px;
    font-size: 11px;
    color: #4B5563;
    flex: 0 0 100%;
}

.compose-workbench-cascade__trail-label {
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #9CA3AF;
    font-weight: 600;
    font-size: 10px;
    margin-right: 4px;
}

.compose-workbench-cascade__trail-value {
    color: #111827;
    font-weight: 600;
}

.compose-workbench-cascade__trail-sep {
    color: #9CA3AF;
    font-size: 14px;
    line-height: 1;
}

.compose-workbench-cascade__trail-part {
    display: inline-flex;
    align-items: baseline;
    gap: 2px;
    white-space: nowrap;
}

.compose-workbench-cascade__level {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    flex: 0 1 auto;
    min-width: 0;
}

.compose-workbench-cascade__level--root {
    flex: 0 0 auto;
}

.compose-workbench-cascade__level--leaf {
    flex: 1 1 auto;
    min-width: 0;
    position: relative;
    padding-left: 16px;
}

.compose-workbench-cascade__level--leaf::before {
    content: "›";
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    color: #9CA3AF;
    font-size: 18px;
    font-weight: 600;
    line-height: 1;
}

.compose-workbench-cascade__chips {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
}

.compose-workbench-cascade__clear {
    appearance: none;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 999px;
    width: 22px;
    height: 22px;
    line-height: 1;
    color: #9CA3AF;
    cursor: pointer;
    font-size: 16px;
    padding: 0;
    margin-left: 4px;
    transition: all 180ms ease-out;
}

.compose-workbench-cascade__clear:hover {
    color: #111827;
    border-color: #E5E7EB;
}

/* BU-157: chips for levels the tenant policy doesn't permit.
   Rendered disabled rather than hidden so the user sees their cap. */
.jgn-filter-chip--disabled,
.jgn-filter-chip--disabled:hover {
    opacity: 0.45;
    cursor: not-allowed;
    background: #F3F4F6;
    color: #9CA3AF;
    border-color: #E5E7EB;
}

/* ---------------------------------------------------------------------------
   BU-163: Scope tab strip per UI designer mock. Replaces BU-162's pill-bar
   visual with a horizontal tab system. Selected values REPLACE the level
   label inline (e.g. "Bella Tavola" replaces "Partner") with a chevron;
   level name surfaces via tooltip on hover. Active tab gets a green
   underline. White/gray base with green accent — no more glass/neomorphic.
   --------------------------------------------------------------------------- */
.compose-workbench-scopebar-host {
    background: transparent;
    border-radius: 0;
    padding: 0;
    box-shadow: none;
    display: flex;
    flex-direction: column;
    gap: 0;
    flex: 1 1 100%;
    min-width: 0;
}

.compose-workbench-scopetabs {
    display: flex;
    align-items: stretch;
    gap: 0;
    flex-wrap: wrap;
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 12px 12px 0 0;
    border-bottom: none;
    padding: 0 4px;
    flex: 0 0 100%;
}

.compose-workbench-scopetabs__heading {
    display: inline-flex;
    align-items: center;
    padding: 0 14px;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 600;
    color: #94A3B8;
    border-right: 1px solid #E5E7EB;
    margin-right: 4px;
}

.compose-workbench-scopetab {
    appearance: none;
    border: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    font-size: 13px;
    color: #475569;
    background: transparent;
    border-bottom: 2px solid transparent;
    transition: all 180ms ease-out;
    white-space: nowrap;
    max-width: 240px;
    font-weight: 500;
    margin-bottom: -1px;
}

.compose-workbench-scopetab:hover:not(:disabled):not(.compose-workbench-scopetab--active) {
    color: #111827;
    background: #F9FAFB;
}

.compose-workbench-scopetab__icon {
    display: inline-flex;
    color: #6B7280;
    flex: 0 0 auto;
}

.compose-workbench-scopetab--active .compose-workbench-scopetab__icon,
.compose-workbench-scopetab--filled .compose-workbench-scopetab__icon {
    color: #DD5100;
}

.compose-workbench-scopetab__text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.compose-workbench-scopetab__chevron {
    color: #94A3B8;
    font-size: 10px;
    margin-left: 2px;
}

.compose-workbench-scopetab--filled {
    color: #111827;
    font-weight: 600;
}

.compose-workbench-scopetab.compose-workbench-scopetab--active {
    color: #DD5100;
    border-bottom-color: #DD5100;
    background: #FFFFFF;
}

.compose-workbench-scopetab--active .compose-workbench-scopetab__chevron {
    color: #DD5100;
}

.compose-workbench-scopetab--disabled,
.compose-workbench-scopetab--disabled:hover {
    opacity: 0.45;
    cursor: not-allowed;
    background: transparent;
    color: #94A3B8;
}

.compose-workbench-scopetabs__clear {
    appearance: none;
    border: none;
    background: transparent;
    color: #94A3B8;
    cursor: pointer;
    font-size: 16px;
    line-height: 1;
    padding: 0 14px;
    margin-left: auto;
    border-radius: 0;
    transition: color 180ms ease-out;
}

.compose-workbench-scopetabs__clear:hover {
    color: #DC2626;
}

/* BU-163: drawer below the tab strip. Continuous border with the tabs so
   the two read as one container. */
.compose-workbench-drawer {
    flex: 0 0 100%;
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 0 0 12px 12px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
    padding: 16px 18px 14px;
    animation: compose-workbench-drawer-in 180ms ease-out;
}

@keyframes compose-workbench-drawer-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}

/* BU-163 + 2026-05-07 brand audit M-04: respect prefers-reduced-motion. */
@media (prefers-reduced-motion: reduce) {
    .compose-workbench-drawer {
        animation: none;
    }
}

.compose-workbench-drawer__head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}

.compose-workbench-drawer__head-left {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1 1 auto;
}

.compose-workbench-drawer__title {
    font-size: 16px;
    font-weight: 600;
    color: #111827;
    line-height: 1.3;
}

.compose-workbench-drawer__subtitle {
    font-size: 12px;
    color: #6B7280;
}

.compose-workbench-drawer__actions {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    flex: 0 0 auto;
}

.compose-workbench-drawer__searchwrap {
    position: relative;
    display: inline-flex;
    align-items: center;
}

.compose-workbench-drawer__search-icon {
    position: absolute;
    left: 10px;
    color: #94A3B8;
    pointer-events: none;
    font-size: 14px;
}

.compose-workbench-drawer__search {
    appearance: none;
    border: 1px solid #E5E7EB;
    border-radius: 8px;
    padding: 7px 12px 7px 28px;
    background: #FFFFFF;
    min-width: 240px;
    font-size: 13px;
    color: #111827;
    transition: border-color 180ms ease-out, box-shadow 180ms ease-out;
}

.compose-workbench-drawer__search::placeholder {
    color: #94A3B8;
}

.compose-workbench-drawer__search:focus {
    outline: none;
    border-color: #DD5100;
    box-shadow: 0 0 0 3px rgba(221, 81, 0, 0.12);
}

.compose-workbench-drawer__action {
    appearance: none;
    border: none;
    cursor: pointer;
    padding: 7px 14px;
    font-size: 12px;
    font-weight: 600;
    border-radius: 8px;
    background: #DD5100;
    color: #FFFFFF;
    box-shadow: 0 1px 2px rgba(221, 81, 0, 0.20);
    transition: all 180ms ease-out;
}

.compose-workbench-drawer__action:hover {
    background: #B33D00;
}

.compose-workbench-drawer__action--ghost {
    background: #FFFFFF;
    color: #475569;
    border: 1px solid #E5E7EB;
    box-shadow: none;
}

.compose-workbench-drawer__action--ghost:hover {
    background: #F9FAFB;
    color: #111827;
}

.compose-workbench-drawer__chip-btn {
    appearance: none;
    border: 1px solid #E5E7EB;
    background: #FFFFFF;
    color: #475569;
    cursor: pointer;
    padding: 7px 14px;
    font-size: 12px;
    font-weight: 600;
    border-radius: 8px;
    transition: all 180ms ease-out;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.compose-workbench-drawer__chip-btn:hover {
    background: #F9FAFB;
    color: #111827;
    border-color: #D1D5DB;
}

.compose-workbench-drawer__list {
    border: 1px solid #E5E7EB;
    border-radius: 10px;
    background: #FFFFFF;
    max-height: 320px;
    overflow-y: auto;
}

.compose-workbench-drawer__list .scope-owner-picker__table {
    background: transparent;
    margin-bottom: 0;
}

.compose-workbench-drawer__list .scope-owner-picker__table thead th {
    background: #F9FAFB;
    color: #374151;
    font-size: 12px;
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0;
    border-bottom: 1px solid #E5E7EB;
    padding: 10px 14px;
    position: sticky;
    top: 0;
}

.compose-workbench-drawer__col-title {
    flex: 1 1 auto;
}

.compose-workbench-drawer__col-count {
    color: #6B7280;
    font-size: 11px;
    font-weight: 500;
    margin-left: auto;
}

.compose-workbench-drawer__list .scope-owner-picker__table thead th[role="button"] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.compose-workbench-drawer__list .scope-owner-picker__table tbody tr {
    border-bottom: 1px solid #F3F4F6;
}

.compose-workbench-drawer__list .scope-owner-picker__table tbody tr:last-child {
    border-bottom: none;
}

.compose-workbench-drawer__list .scope-owner-picker__table tbody tr:hover {
    --bs-table-bg-state: #FEE6D6;
    background: #FEE6D6;
}
.compose-workbench-drawer__list .scope-owner-picker__table tbody tr:hover td {
    background-color: #FEE6D6;
}

.compose-workbench-drawer__list .scope-owner-picker__table tbody tr.table-info {
    --bs-table-bg-state: #FEE6D6;
    background: #FEE6D6;
    border-color: #FCC9A4;
    color: #DD5100;
    font-weight: 600;
    box-shadow: inset 3px 0 0 0 #DD5100;
}
.compose-workbench-drawer__list .scope-owner-picker__table tbody tr.table-info td {
    background-color: #FEE6D6;
    color: #DD5100;
    font-weight: 600;
}

.compose-workbench-drawer__list .scope-owner-picker__table tbody tr.table-info:hover {
    --bs-table-bg-state: #FCC9A4;
    background: #FCC9A4;
}
.compose-workbench-drawer__list .scope-owner-picker__table tbody tr.table-info:hover td {
    background-color: #FCC9A4;
    color: #B33D00;
}

.compose-workbench-drawer__list .scope-owner-picker__table tbody td {
    padding: 11px 14px;
    font-size: 13px;
    color: #111827;
}

.compose-workbench-drawer__list .scope-owner-picker__table input[type=radio]:checked,
.compose-workbench-drawer__list .scope-owner-picker__table input[type=checkbox]:checked {
    accent-color: #DD5100;
}

.compose-workbench-drawer__simple {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 6px 4px;
}

.compose-workbench-drawer__copy {
    margin: 0;
    font-size: 13px;
    color: #1F2937;
}

.compose-workbench-drawer__copy--muted {
    color: #64748B;
    font-style: italic;
}

.compose-workbench-drawer__done {
    appearance: none;
    border: 1px solid #E5E7EB;
    cursor: pointer;
    padding: 7px 14px;
    font-size: 12px;
    font-weight: 600;
    border-radius: 8px;
    background: #FFFFFF;
    color: #475569;
    transition: all 180ms ease-out;
}

.compose-workbench-drawer__done:hover {
    background: #F9FAFB;
    color: #111827;
}

/* BU-153: per-engagement tabs in the Deliverables panel. Tab strip sits
   between the filter row and the deliverable table; visible only when
   Rows contains >1 distinct EngagementId. "All" tab restores the flat view. */
.jgn-deliverable-engagement-tabs {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    padding: 6px 12px 0;
    border-bottom: 1px solid #E5E7EB;
    background: #F9FAFB;
    /* BU-154: parent compose-panel-inner--media is a flex column with a
       fixed height (resizable bento). Without flex: 0 0 auto the strip
       gets compressed to 7px. Same protection applies to BU-153 use. */
    flex: 0 0 auto;
}

.jgn-deliverable-engagement-tab {
    appearance: none;
    background: transparent;
    border: 1px solid transparent;
    border-bottom: none;
    border-radius: 6px 6px 0 0;
    padding: 6px 12px;
    font-size: 12px;
    color: #4B5563;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: all 180ms ease-out;
    margin-bottom: -1px;
    white-space: nowrap;
    max-width: 240px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.jgn-deliverable-engagement-tab:hover {
    background: #F3F4F6;
    color: #111827;
}

.jgn-deliverable-engagement-tab--active {
    background: #FFFFFF;
    color: #DD5100;
    border-color: #E5E7EB;
    font-weight: 600;
}

.jgn-deliverable-engagement-tab__count {
    background: #E5E7EB;
    color: #4B5563;
    font-size: 10px;
    padding: 1px 6px;
    border-radius: 999px;
    font-variant-numeric: tabular-nums;
}

.jgn-deliverable-engagement-tab--active .jgn-deliverable-engagement-tab__count {
    background: #FEE6D6;
    color: #DD5100;
}

/* BU-074 #10 (2026-05-09): engagement chip strip + sort dropdown row.
   Row wraps the strip and the sort control. Sort hugs the right edge,
   the strip flex-grows. */
.jgn-deliverable-engagement-tabs-row {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    flex: 0 0 auto;
    background: #F9FAFB;
    border-bottom: 1px solid #E5E7EB;
    padding-right: 12px;
    /* BU-227: pin the tabs row to the top of the panel scroll container so the
       user can always switch engagement without scrolling back up.
       z-index keeps the row above the table header and the link-popover/pulse
       rows when the table scrolls underneath. */
    position: sticky;
    top: 0;
    z-index: 5;
}

.jgn-deliverable-engagement-tabs-row > .jgn-deliverable-engagement-tabs {
    flex: 1 1 auto;
    border-bottom: none;
    padding-bottom: 6px;
    background: transparent;
}

/* BU-196: single-engagement row — no tablist, just the View Plan pill. */
.jgn-deliverable-engagement-tabs-row--single-engagement {
    padding: 6px 12px;
    align-items: center;
}

/* BU-196: View Plan pill in the deliverables engagement-tabs row.
   Shape + dimensions mirror .compose-panel-filter-drawer__pill so the
   navigation chrome reads as part of the same panel-header vocabulary.
   Distinguished from the (gray) filter pill by:
   - the brand-orange calendar icon (always visible — signals plan surface)
   - the trailing chevron (signals navigation, not a toggle)
   - the orange-on-hover treatment (filter pills hover to neutral gray) */
.jgn-deliverable-plan-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    align-self: center;
    height: 24px;
    padding: 0 10px;
    border: 0.5px solid #E5E7EB;
    border-radius: 999px;
    background: transparent;
    color: #4B5563;
    font-size: 12px;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color 120ms ease-out, border-color 120ms ease-out, color 120ms ease-out;
    flex-shrink: 0;
    margin-left: 4px;
    margin-bottom: 5px;
}

.jgn-deliverable-plan-link:hover {
    /* Orange lives in the border + icon + chevron (graphical, 3:1 threshold).
       The label text stays dark (#111827) to clear WCAG AA 4.5:1 — brand
       orange #DD5100 as a text color is only ~3.8:1 on this tint. Mirrors
       the .compose-panel-filter-drawer__pill hover (text → #111827). */
    background: #FFF7F4;
    border-color: #DD5100;
    color: #111827;
    text-decoration: none;
}

.jgn-deliverable-plan-link:focus-visible {
    outline: 1px solid #DD5100;
    outline-offset: 1px;
}

.jgn-deliverable-plan-link__icon {
    /* Brand orange calendar — always visible, signals the link's identity
       as a plan-surface navigation. */
    color: #DD5100;
    flex-shrink: 0;
}

.jgn-deliverable-plan-link__label {
    line-height: 1;
}

.jgn-deliverable-plan-link__chevron {
    color: #9CA3AF;
    flex-shrink: 0;
    transition: transform 180ms ease-out, color 120ms ease-out;
}

.jgn-deliverable-plan-link:hover .jgn-deliverable-plan-link__chevron {
    color: #DD5100;
    transform: translateX(2px);
}

@media (prefers-reduced-motion: reduce) {
    .jgn-deliverable-plan-link__chevron {
        transition: none;
    }
}

/* In the single-engagement row, lift the pill margin reset so the row's own
   padding (6px 12px) does the work — avoids double-stacking margins. */
.jgn-deliverable-engagement-tabs-row--single-engagement .jgn-deliverable-plan-link {
    margin-left: 0;
    margin-bottom: 0;
}

.jgn-deliverable-engagement-tabs__sort {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 0 6px 0;
    flex: 0 0 auto;
    align-self: center;
}

.jgn-deliverable-engagement-tabs__sort-label {
    font-size: 11px;
    color: #6B7280;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
}

.jgn-deliverable-engagement-tabs__sort-select {
    appearance: none;
    background: #FFFFFF;
    border: 1px solid #D1D5DB;
    border-radius: 6px;
    padding: 4px 24px 4px 8px;
    font-size: 12px;
    color: #1F2937;
    cursor: pointer;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='none' stroke='%236B7280' stroke-width='1.5' d='M1 1l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 6px center;
    transition: border-color 180ms ease-out, box-shadow 180ms ease-out;
}

.jgn-deliverable-engagement-tabs__sort-select:hover {
    border-color: #9CA3AF;
}

.jgn-deliverable-engagement-tabs__sort-select:focus {
    outline: none;
    border-color: #DD5100;
    box-shadow: 0 0 0 2px rgba(221, 81, 0, 0.12);
}

/* BU-174: deliverable-panel variant of the BU-148 scope-owner-picker. Sits
   flush at the top of the Deliverables panel inner. Slightly narrower
   max-height so the deliverables table below stays the dominant surface. */
.scope-owner-picker--deliverable {
    margin-top: 4px;
    margin-bottom: 4px;
    max-width: none;
}

.scope-owner-picker--deliverable .scope-owner-picker__scroll {
    max-height: 180px;
}

.scope-owner-picker__clear {
    appearance: none;
    background: transparent;
    border: 0;
    padding: 2px 8px;
    font-size: 11px;
    color: #6b7280;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.scope-owner-picker__clear:hover {
    color: #DD5100;
}

.scope-owner-picker__caret {
    font-size: 9px;
    margin-left: 2px;
    color: #DD5100;
}

/* BU-174 hover + selected + click motion. Bootstrap 5's .table paints
   var(--bs-table-bg-state) on every cell via an inset box-shadow trick,
   which would otherwise hide a row-level background. Drive the hover
   state through that variable AND set the cell background explicitly so
   the rule wins regardless of which Bootstrap mode the consumer is in.
   140ms ease-out matches the rest of the compose-workbench motion set.
   Palette uses the single brand accent #DD5100 — no off-brand blues. */
.scope-owner-picker--deliverable .scope-owner-picker__table tbody tr {
    transition: background-color 140ms ease-out, transform 90ms ease-out;
}

.scope-owner-picker--deliverable .scope-owner-picker__table tbody tr td {
    transition: background-color 140ms ease-out, color 140ms ease-out;
}

.scope-owner-picker--deliverable .scope-owner-picker__table tbody tr:hover {
    --bs-table-bg-state: #FEE6D6; /* 10% traffic-orange tint, clearly visible */
    background: #FEE6D6;
}

.scope-owner-picker--deliverable .scope-owner-picker__table tbody tr:hover td {
    background-color: #FEE6D6;
}

.scope-owner-picker--deliverable .scope-owner-picker__table tbody tr:active {
    transform: scale(0.997);
}

.scope-owner-picker--deliverable .scope-owner-picker__table tbody tr:active td {
    --bs-table-bg-state: #FCC9A4; /* mid-tone traffic-orange under press */
    background-color: #FCC9A4;
}

.scope-owner-picker--deliverable .scope-owner-picker__table tbody tr.table-info {
    --bs-table-bg-state: #FEE6D6;
    background: #FEE6D6;
    color: #DD5100;
    font-weight: 600;
    box-shadow: inset 3px 0 0 0 #DD5100;
}

.scope-owner-picker--deliverable .scope-owner-picker__table tbody tr.table-info td {
    --bs-table-bg-state: #FEE6D6;
    background-color: #FEE6D6;
    color: #DD5100;
    font-weight: 600;
}

.scope-owner-picker--deliverable .scope-owner-picker__table tbody tr.table-info:hover {
    --bs-table-bg-state: #FCC9A4;
    background: #FCC9A4;
}

.scope-owner-picker--deliverable .scope-owner-picker__table tbody tr.table-info:hover td {
    background-color: #FCC9A4;
    color: #B33D00;
}

/* Brief flash when the user picks a row, so the selection registers as a
   tactile event instead of a silent color swap. Brighter traffic-orange
   ramping down to the resting tint. */
@keyframes scope-owner-picker-pick-flash {
    0%   { background-color: #FCAA70; }
    100% { background-color: #FEE6D6; }
}

.scope-owner-picker--deliverable .scope-owner-picker__table tbody tr.table-info td {
    animation: scope-owner-picker-pick-flash 320ms ease-out;
}

/* BU-175 part 2: panel-local scope row. Sits inline with the panel title
   inside PanelHost's panel-host-panel-header-extra slot. Reads as a quieter
   version of the global scope row (12px / muted gray) so it stays visually
   subordinate to the panel name. */
.panel-scope-row {
    display: flex;
    align-items: baseline;
    gap: 6px;
    flex: 1 1 auto;
    min-width: 0;
}

.panel-scope-row .scope-row {
    font-size: 12px;
    color: #6b7280;
    margin-top: 0;
    margin-bottom: 0;
    line-height: 1.4;
    flex: 1 1 auto;
    min-width: 0;
}

.panel-scope-row .scope-label {
    font-size: 12px;
}

.panel-scope-row .scope-segment {
    font-size: 12px;
    font-weight: 500;
}

.panel-scope-row .scope-segment__value {
    color: #111827;
}

/* "Match global" reset link — small text affordance that clears the
   panel-local override so the panel re-mirrors the global scope. */
.panel-scope-match-global {
    appearance: none;
    background: transparent;
    border: 0;
    padding: 0;
    font-size: 11px;
    color: #6b7280;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
    flex: 0 0 auto;
}

.panel-scope-match-global:hover {
    color: #DD5100;
}

.panel-scope-match-global:focus-visible {
    outline: 2px solid #DD5100;
    outline-offset: 2px;
    border-radius: 2px;
}

@media (max-width: 720px) {
    .compose-workbench-cascade__level--leaf {
        padding-left: 0;
        flex: 1 1 100%;
    }
    .compose-workbench-cascade__level--leaf::before {
        display: none;
    }
}


/* ============================================================================
   BU-165: text-first inline scope breadcrumb (supersedes BU-164's button).
   Plain inline text reading "Scope · A / B / C" placed under the page title.
   Click anywhere on the row opens a 260px neutral-gray cascading menu (no
   green branding, no chevrons, no icons). Hovering a segment underlines just
   that segment. Menu uses position:fixed at z-index 10600 so it escapes the
   compose page's overflow:hidden ancestor (.compose-workbench-page) and sits
   above the toast stack (z 10500); spec mentions z 1000 conceptually but the
   running app's stacking context requires more.
   ============================================================================ */

.scope-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    font-size: 13px;
    line-height: 20px;
    color: #111827;
    margin-top: 4px;
    margin-bottom: 4px;
    position: relative; /* for the absolute hit-area child */
}

.scope-label {
    color: #6b7280;
    font-weight: 400;
    cursor: pointer;
    border-radius: 2px;
    /* 2026-05-10 bug: z-index is ignored on static-positioned elements, so
       the absolute .scope-row__hitarea (z-index:0) was painting on top of
       these spans and intercepting all real-user clicks. Adding
       position:relative makes z-index:1 actually apply. */
    position: relative;
    z-index: 1;
}

.scope-label:focus-visible {
    outline: 2px solid #DD5100;
    outline-offset: 2px;
}

.scope-segment {
    color: #111827;
    font-weight: 500;
    cursor: pointer;
    border-radius: 2px;
    /* 2026-05-10 bug: see .scope-label note above. position:relative makes
       z-index:1 actually apply, lifting visible segments above the
       absolute .scope-row__hitarea (z-index:0). */
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* BU-175 part 1: leading muted-gray icon. Default color matches the level
   label (#6b7280) so an "unset"-style segment reads quietly; promoted to
   #111827 alongside the value when the segment is filled. .scope-segment is
   only rendered for filled levels, so the default is mostly defensive. */
.scope-segment__icon {
    color: #6b7280;
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    line-height: 0;
}

.scope-segment .scope-segment__icon {
    color: #111827; /* segment is filled → match the value */
}

/* The level label sits inside the segment so the user can tell which
   scope a value belongs to even when two adjacent segments have the
   same display name (e.g. workspace + partner both = "Miss Wildermuth
   LLC"). Muted-gray + lighter weight keeps the value the reading
   anchor while the label disambiguates. */
.scope-segment__level {
    color: #6b7280;
    font-weight: 400;
}

.scope-segment__value {
    color: #111827;
    font-weight: 500;
}

.scope-segment:hover .scope-segment__value {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.scope-segment:focus-visible {
    outline: 2px solid #DD5100;
    outline-offset: 2px;
}

.scope-segment--all {
    color: #111827;
}

.scope-segment--all:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.scope-separator {
    /* 2026-05-08 audit: was #d1d5db on white = 1.47:1, well below WCAG AA.
       #6b7280 = 4.83:1 still reads as a soft separator without disappearing
       for any reader with diminished contrast sensitivity. */
    color: #6b7280;
    user-select: none;
}

/* Invisible button covering the row's slack area so clicking the gap
   between segments still opens the menu. Sits below the segment spans
   (z-index:1) so segment-specific clicks fire instead of the row click. */
.scope-row__hitarea {
    position: absolute;
    inset: 0;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
    z-index: 0;
}

/* BU-178: trailing slot inside .scope-row for controls anchored to the
   far-right (currently the reset-layout icon button on the global
   workbench-header scope row only — panel-local rows do not pass
   TrailingChildren). margin-left:auto floats it to the right of the
   flex row; position:relative + z-index:2 lifts it above the absolute
   .scope-row__hitarea (z-index:0) so clicks reach the button, not the
   row hitarea. When the row wraps on narrow viewports, the trailing
   slot lands at the right of whatever line it ends up on. */
.scope-row__trailing {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    position: relative;
    z-index: 2;
    flex: 0 0 auto;
}

.scope-row__reset-btn {
    width: 28px;
    height: 28px;
    min-width: 28px;
    border: 1px solid #E5E7EB;
    border-radius: 6px;
    background: #FFFFFF;
    color: #6B7280;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    cursor: pointer;
    transition: color 180ms ease-out, border-color 180ms ease-out, background-color 180ms ease-out;
}
.scope-row__reset-btn:hover {
    color: #1F2937;
    border-color: #D1D5DB;
    background: #F9FAFB;
}
.scope-row__reset-btn:focus-visible {
    outline: 2px solid rgba(221, 81, 0, 0.55);
    outline-offset: 2px;
}

/* Mobile / narrow viewport: bump the touch target to >=32x32 while
   keeping the visual icon size the same. The button itself stays 28x28
   visually; an outer hit-zone padding extends the click area. */
@media (max-width: 639px) {
    .scope-row__reset-btn {
        width: 32px;
        height: 32px;
        min-width: 32px;
    }
}

.scope-row--open .scope-label,
.scope-row--open .scope-segment {
    /* While the menu is open, the active segment stays underlined so the
       user can see which level they're editing. */
    text-decoration: none;
}

/* ---------------------------------------------------------------------------
   Cascading menu chrome
   --------------------------------------------------------------------------- */

.scope-menu-backdrop {
    position: fixed;
    inset: 0;
    background: transparent;
    z-index: 10599;
    cursor: default;
}

.scope-menu {
    position: fixed;
    z-index: 10600;
    background: #ffffff;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(17, 24, 39, 0.08);
    padding: 8px;
    display: flex;
    flex-direction: row;
    align-items: stretch;
    gap: 0;
}

.scope-menu__rootlist {
    width: 260px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.scope-menu-row {
    appearance: none;
    background: transparent;
    border: 1px solid transparent;
    cursor: pointer;
    display: grid;
    grid-template-columns: 16px 1fr;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 6px;
    text-align: left;
    color: #111827;
    transition: background-color 140ms ease-out, border-color 140ms ease-out;
    width: 100%;
}

.scope-menu-row__icon {
    color: #6b7280;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 16px;
}

.scope-menu-row__text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.scope-menu-row--filled .scope-menu-row__icon {
    color: #111827;
}

.scope-menu-row:hover {
    background: #f9fafb;
}

.scope-menu-row--active {
    background: #f3f4f6;
}

.scope-menu-row:focus-visible {
    outline: none;
    border-color: #DD5100;
    box-shadow: 0 0 0 3px rgba(221, 81, 0, 0.20);
}

.scope-menu-title {
    font-size: 13px;
    font-weight: 600;
    color: #111827;
}

.scope-menu-value {
    font-size: 12px;
    color: #6b7280;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.scope-menu-row--filled .scope-menu-value {
    color: #111827;
    font-weight: 500;
}

.scope-menu__clear {
    appearance: none;
    border: none;
    background: transparent;
    color: #6b7280;
    cursor: pointer;
    font-size: 12px;
    font-weight: 400;
    padding: 8px 12px;
    border-radius: 6px;
    margin-top: 4px;
    text-align: left;
    transition: background-color 140ms ease-out, color 140ms ease-out;
}

.scope-menu__clear:hover {
    background: #f3f4f6;
    color: #111827;
}

/* ---------------------------------------------------------------------------
   Flyout panel — sibling panel to the rootlist, opens to the right
   --------------------------------------------------------------------------- */

.scope-menu__flyout {
    margin-left: 8px;
    background: #ffffff;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(17, 24, 39, 0.08);
    padding: 8px;
    width: 320px;
    max-height: 360px;
    display: flex;
    flex-direction: column;
    animation: scope-menu-flyout-in 160ms ease-out;
}

@keyframes scope-menu-flyout-in {
    from { opacity: 0; transform: translateX(-4px); }
    to   { opacity: 1; transform: translateX(0); }
}

/* BU-165 + 2026-05-07 brand audit M-05: respect prefers-reduced-motion. */
@media (prefers-reduced-motion: reduce) {
    .scope-menu__flyout {
        animation: none;
    }
}

.scope-menu__flyout-head {
    padding: 4px 4px 8px 4px;
    border-bottom: 1px solid #f3f4f6;
}

.scope-menu__flyout-title {
    font-size: 13px;
    font-weight: 600;
    color: #111827;
}

.scope-menu__flyout-breadcrumb {
    font-size: 11px;
    color: #6b7280;
    margin-top: 2px;
}

.scope-menu__flyout-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 6px;
}

.scope-menu__search {
    flex: 1 1 auto;
    appearance: none;
    border: 1px solid #e5e7eb;
    background: #ffffff;
    border-radius: 6px;
    padding: 6px 8px;
    font-size: 12px;
    color: #111827;
    min-width: 0;
}

.scope-menu__search:focus {
    outline: none;
    border-color: #9ca3af;
    box-shadow: 0 0 0 3px rgba(156, 163, 175, 0.18);
}

.scope-menu__chipbtn {
    appearance: none;
    border: 1px solid #e5e7eb;
    background: #ffffff;
    color: #6b7280;
    cursor: pointer;
    border-radius: 6px;
    padding: 5px 8px;
    font-size: 11px;
    font-weight: 500;
    flex: 0 0 auto;
    transition: background-color 140ms ease-out, color 140ms ease-out;
}

.scope-menu__chipbtn:hover {
    background: #f9fafb;
    color: #111827;
}

.scope-menu__bulk-actions {
    display: flex;
    gap: 6px;
    margin: 4px 4px 6px 4px;
}

.scope-menu__bulk-btn {
    appearance: none;
    border: 1px solid #e5e7eb;
    background: #ffffff;
    cursor: pointer;
    color: #111827;
    font-size: 11px;
    font-weight: 500;
    padding: 4px 8px;
    border-radius: 6px;
    transition: background-color 140ms ease-out;
}

.scope-menu__bulk-btn:hover {
    background: #f9fafb;
}

.scope-menu__bulk-btn--ghost {
    color: #6b7280;
}

.scope-menu__bulk-btn--ghost:hover {
    color: #111827;
}

.scope-menu__flyout-list {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 2px 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-height: 0;
}

.scope-menu__listrow {
    appearance: none;
    background: transparent;
    border: 1px solid transparent;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 10px;
    border-radius: 6px;
    text-align: left;
    color: #111827;
    transition: background-color 140ms ease-out;
    width: 100%;
}

.scope-menu__listrow:hover {
    background: #f9fafb;
}

.scope-menu__listrow--selected {
    background: #f3f4f6;
}

.scope-menu__listrow--selected:hover {
    background: #e5e7eb;
}

.scope-menu__listrow:focus-visible {
    outline: none;
    border-color: #9ca3af;
    box-shadow: 0 0 0 3px rgba(156, 163, 175, 0.18);
}

.scope-menu__listrow-label {
    font-size: 12px;
    color: #111827;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1 1 auto;
}

.scope-menu__listrow-text {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
    overflow: hidden;
}

.scope-menu__listrow-subtitle {
    font-size: 11px;
    color: #6b7280;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.scope-menu__empty {
    padding: 16px 12px;
    text-align: center;
    font-size: 12px;
    color: #6b7280;
}

.scope-menu__flyout-foot {
    border-top: 1px solid #f3f4f6;
    padding: 6px 4px 2px 4px;
}

.scope-menu__count {
    font-size: 11px;
    color: #6b7280;
}

@media (max-width: 720px) {
    .scope-menu {
        flex-direction: column;
    }
    .scope-menu__rootlist {
        width: 100%;
    }
    .scope-menu__flyout {
        margin-left: 0;
        margin-top: 6px;
        width: 100%;
        max-height: 280px;
    }
}

/* ---------------------------------------------------------------------------
   Page title row — keeps inventory snapshot on the right of "Compose Workbench"
   while the scope row sits on its own line below. Both rows take full header
   width so they stack vertically inside .compose-workbench-header (which uses
   flex-wrap to support multi-row content per BU-103).
   --------------------------------------------------------------------------- */
.compose-workbench-title-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    flex: 1 1 100%;
}

.compose-workbench-header > .scope-row {
    flex: 1 1 100%;
    margin-top: 2px;
}

/* BU-186 bullet 68 (2026-05-18): consolidated single-row workbench header.
   Title + ScopeSelector + stats + reset all live on ONE horizontal strip.
   Overrides the .compose-workbench-header > .scope-row { flex: 1 1 100% }
   rule above (which would otherwise force the scope onto its own row).
   No more .compose-workbench-title-row wrapper — title is a direct child. */
.compose-workbench-header.compose-workbench-header--single-row {
    flex-wrap: nowrap;
    padding: 6px 16px;
    min-height: 44px;
    gap: 14px;
}
.compose-workbench-header.compose-workbench-header--single-row > .compose-workbench-title-compact {
    flex: 0 0 auto;
    align-self: center;
}
.compose-workbench-header.compose-workbench-header--single-row > .scope-row {
    flex: 0 1 auto;
    margin-top: 0;
    align-self: center;
    min-width: 0;
}
.compose-workbench-header.compose-workbench-header--single-row > .compose-workbench-header-summary {
    flex: 0 0 auto;
    margin-left: auto;
    align-self: center;
}
.compose-workbench-header.compose-workbench-header--single-row > .compose-workbench-header-reset {
    flex: 0 0 auto;
    align-self: center;
    margin-left: 4px;
}

/* ============================================================================
   BU-166: motion-language pass. Unifies layout transitions on
   cubic-bezier(0.22, 0.61, 0.36, 1) at 220ms for "feels gentle" easing on
   panel preset switches, drawer toggles, and splitter snap. Color/opacity
   stays at 180ms. Reserves saturated color for confirmed-action moments
   (the 240ms drop flash). Honors prefers-reduced-motion.
   ============================================================================ */

:root {
    --bu166-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
    --bu166-layout-ms: 220ms;
    --bu166-color-ms: 180ms;
    --bu166-snap-ms: 140ms;
}

/* PanelHost cells: width/height/flex-basis transitions for preset switches
   and drawer open/close. During an active splitter drag the splitter writes
   inline flex-basis at pointer rate — we exclude .is-resizing from the tween
   so the splitter follows pointer 1:1, then re-arms on release. */
.panel-host-split-cell {
    transition:
        flex-basis var(--bu166-layout-ms) var(--bu166-ease),
        height var(--bu166-layout-ms) var(--bu166-ease),
        width var(--bu166-layout-ms) var(--bu166-ease),
        opacity var(--bu166-color-ms) var(--bu166-ease);
}

/* Suppress the layout tween while the user is actively dragging a splitter
   so the splitter follows pointer 1:1; re-arms on pointerup so a snap-near
   point glides into place over var(--bu166-snap-ms). Uses :has() so we
   don't have to hook a Blazor state class onto every sibling cell. */
.panel-host-split-node:has(> .panel-host-splitter[data-active="true"])
    > .panel-host-split-cell {
    transition: none;
}

.panel-host-panel {
    transition:
        opacity var(--bu166-color-ms) var(--bu166-ease),
        transform var(--bu166-layout-ms) var(--bu166-ease);
}

.panel-host-panel-body {
    transition: opacity var(--bu166-color-ms) var(--bu166-ease);
}

/* Drawer (Panel3 collapse) — height grows/shrinks with the eased curve.
   overflow:hidden during the tween prevents content pop; existing rule
   already sets it. */
.panel-host-tray-collapsed,
.panel-host-tray-host {
    transition:
        height var(--bu166-layout-ms) var(--bu166-ease),
        max-height var(--bu166-layout-ms) var(--bu166-ease),
        opacity var(--bu166-color-ms) var(--bu166-ease);
}

/* Honor prefers-reduced-motion globally for all BU-166-tweened surfaces.
   Drop tween durations to 0ms while keeping final state values intact, so
   layout still snaps but doesn't animate. The drop-confirm flash collapses
   to opacity-only so the user still sees it landed without motion. */
@media (prefers-reduced-motion: reduce) {
    .panel-host-split-cell,
    .panel-host-panel,
    .panel-host-panel-body,
    .panel-host-tray-collapsed,
    .panel-host-tray-host,
    .jgn-deliverable-drop-target--active.jgn-deliverable-row-unassigned,
    .jgn-deliverable-drop-target--active.jgn-deliverable-row-assigned {
        transition: none !important;
    }

    .jgn-deliverable-row-just-dropped {
        animation: none !important;
        background-color: rgba(221, 81, 0, 0.10) !important;
    }
}

/* ============================================================================
   2026-05-08: responsive fixes from /audit-responsive run.
   Three issues caught at ≤720px (mobile):
     1. The bento split nodes kept rendering Assets+Media side-by-side at
        390px wide because the grid template comes from the saved layout JSON
        and never collapsed. Force a single-column stack at mobile.
     2. .jgn-asset-picker__filters had inner `.jgn-filter-row { flex: 0 0 auto }`
        which prevented chip wrapping and produced a +203px horizontal overflow
        on mobile (DOM scan finding).
     3. .panel-host-panel-title was a single flex row with text + scope-row
        squeezed onto one baseline; on narrow panels the title was clipped
        (DOM scan: `panel-host-panel-title` content=57x66 container=49x66).
        Allow it to stack vertically when space is tight.
   ============================================================================ */

@media (max-width: 720px) {
    /* Mobile bento collapse.
       Tried `display: grid` first — ran into a chicken-and-egg:
       the outer split-node had `grid-template-rows: auto`, the auto
       track sized to the inner split-node's height, and the inner split-
       node sized to its parent track height. They settled at 324px even
       though the inner split contained two 320px cells (640px total),
       and the inner content overflowed visually onto the next outer
       panel. Switched to `display: flex` so cells size to their content
       additively without the grid sizing cycle. */
    .panel-host-split-node {
        display: flex !important;
        flex-direction: column !important;
        gap: 12px !important;
        grid-template-rows: none !important;
        grid-template-columns: none !important;
        grid-template-areas: none !important;
        height: auto !important;
    }

    .panel-host-split-cell {
        flex: 0 0 auto !important;
        grid-area: auto !important;
        grid-row: auto !important;
        grid-column: auto !important;
        min-height: 320px;
    }

    /* Leaf cells (those holding a single panel) cap at 70vh so their
       inner panel scroll engages instead of expanding to scrollHeight.
       Branch cells (those holding a nested split-node) use auto height
       so they grow to fit ALL the leaves inside. Without distinguishing
       these two cases, a branch cell either clips its child split (when
       capped) or balloons to 40k+ pixels (when uncapped). */
    .panel-host-split-cell:has(> .panel-host-panel) {
        height: 70vh;
        max-height: 70vh;
    }
    .panel-host-split-cell:has(> .panel-host-split-node) {
        height: auto !important;
        max-height: none !important;
    }

    .panel-host-splitter {
        display: none !important;
    }

    /* Force each filter row to its own line at mobile widths.
       The earlier "flex: 1 1 100% / flex-direction: column" combination DID
       compute as column on the parent but the rows still rendered side by
       side because they retained their natural inline widths inside the
       column. Setting width:100% on the row itself is the authoritative
       fix — each row is now its own block-level stripe. */
    .compose-workbench-body .jgn-asset-picker__filters > .jgn-filter-row {
        width: 100% !important;
        flex-basis: 100% !important;
        flex-grow: 0 !important;
    }

    .compose-workbench-body .jgn-asset-picker__filters,
    .compose-workbench-body .compose-panel-inner--media > .jgn-filter-row {
        flex-direction: column !important;
        align-items: stretch !important;
        /* CRITICAL: with flex-wrap:wrap inherited from the existing rule at
           line 2602, each row's flex-basis:100% in column direction
           overflowed the parent's main axis (height) and wrapped to a new
           COLUMN — placing rows side-by-side instead of stacking. Forcing
           nowrap keeps everything on a single column track. */
        flex-wrap: nowrap !important;
    }

    /* Chips inside any filter row must wrap and shrink at narrow widths.
       Bootstrap-ish .jgn-filter-chip has implicit flex-shrink:0 which
       prevented Stage/Voice chips from wrapping at 390px even though the
       parent had flex-wrap:wrap. */
    .compose-workbench-body .jgn-filter-row,
    .compose-workbench-body .jgn-asset-picker__chips {
        flex-wrap: wrap !important;
        max-width: 100%;
    }
    .compose-workbench-body .jgn-filter-chip,
    .compose-workbench-body .jgn-asset-picker__chip {
        flex-shrink: 1 !important;
        min-width: 0;
    }

    .panel-host-panel-title {
        flex-direction: column !important;
        align-items: flex-start !important;
        gap: 2px !important;
    }

    .panel-host-panel-header-extra {
        width: auto !important;
    }
}

/* ────────────────────────────────────────────────────────────────────
   WF-167: Assignment warning modal (Voice / Stage / User-scope warns)
   ──────────────────────────────────────────────────────────────────── */
.wf167-modal {
    background: transparent;
    z-index: 1060;
}
.wf167-modal-backdrop {
    z-index: 1055;
    opacity: 0.5;
}
.wf167-modal .modal-content {
    border: 1px solid #d4a72c;
    border-top: 4px solid #f0ad4e;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.wf167-modal .modal-header {
    background: #fff8e1;
    color: #5a4a14;
}
.wf167-modal-lead {
    color: #5a4a14;
    margin-bottom: 0.75rem;
}
.wf167-warning-list {
    list-style: none;
    padding: 0;
    margin: 0;
}
.wf167-warning-row {
    border-left: 3px solid #f0ad4e;
    background: #fffaf0;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.5rem;
    border-radius: 2px;
}
.wf167-warning-dim {
    font-weight: 600;
    color: #5a4a14;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 0.15rem;
}
.wf167-warning-msg {
    color: #333;
    margin-bottom: 0.35rem;
    font-size: 0.95rem;
}
.wf167-warning-vals {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    font-size: 0.85rem;
    color: #666;
}
.wf167-warning-val-label {
    font-weight: 600;
    color: #555;
}
/* WF-167: modal title icon — Traffic Orange ties to JARGAN brand. */
.wf167-modal-title-icon {
    color: #DD5100;
    vertical-align: -3px;
    margin-right: 0.4rem;
}

/* WF-167: Assign-anyway button — brand Traffic Orange + WCAG AA contrast.
   White on #DD5100 = 4.95:1 (passes AA). Replaces the Bootstrap amber that
   was below threshold (4.45:1 fg, 3.72:1 hover). */
.wf167-assign-anyway {
    background: #DD5100;
    border-color: #B83F00;
    color: #FFFFFF;
    font-weight: 600;
}
.wf167-assign-anyway:hover {
    background: #B83F00;
    border-color: #8C2F00;
    color: #FFFFFF;
}
.wf167-assign-anyway:focus-visible {
    outline: 2px solid #DD5100;
    outline-offset: 2px;
}

/* WF-167: modal + backdrop entry motion — parity with .jgn-toast 200ms slide.
   Respects prefers-reduced-motion. */
@keyframes wf167-modal-enter {
    from { opacity: 0; transform: translateY(-8px) scale(0.98); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes wf167-backdrop-enter {
    from { opacity: 0; }
    to   { opacity: 0.5; }
}
.wf167-modal .modal-dialog { animation: wf167-modal-enter 180ms ease-out both; }
.wf167-modal-backdrop      { animation: wf167-backdrop-enter 180ms ease-out both; }
@media (prefers-reduced-motion: reduce) {
    .wf167-modal .modal-dialog, .wf167-modal-backdrop { animation: none; }
}

/* WF-167: warning badge on assigned-media row after override.
   #FFFFFF on #DD5100 = 4.95:1 (passes AA). Replaces the unreadable #fff on
   #f0ad4e (1.95:1) that hid the badge glyph. */
.wf167-warning-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #DD5100;
    color: #FFFFFF;
    font-size: 0.7rem;
    font-weight: 700;
    margin-left: 0.35rem;
    cursor: help;
    flex-shrink: 0;
    animation: wf167-badge-pop 260ms cubic-bezier(.34,1.56,.64,1) both;
}
@keyframes wf167-badge-pop {
    from { transform: scale(0); opacity: 0; }
    60%  { transform: scale(1.2); opacity: 1; }
    to   { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
    .wf167-warning-badge { animation: none; }
}

/* WF-171: click-toggle warning popover. Badge wrap is relatively-positioned
   so the popover can absolute-anchor below it. Cursor goes from 'help' to
   'pointer' since the badge is now interactive (button role). */
.wf167-warning-badge-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
    flex-shrink: 0; /* WF-173: badge is now a flex-sibling of .jgn-media-card__title; never let it collapse in tight rows. */
}
.wf167-warning-badge-wrap .wf167-warning-badge {
    cursor: pointer;
}
.wf167-warning-badge-wrap .wf167-warning-badge[aria-expanded="true"] {
    background: #B83F00;
    box-shadow: 0 0 0 2px rgba(221, 81, 0, 0.25);
}
.wf167-warning-badge-wrap .wf167-warning-badge:focus-visible {
    outline: 2px solid #DD5100;
    outline-offset: 2px;
}

/* Backdrop catches click-away. Transparent, full-viewport, behind the
   popover but above everything else so clicks outside dismiss. */
.wf167-warning-backdrop {
    position: fixed;
    inset: 0;
    z-index: 10500;
    background: transparent;
    cursor: default;
}

/* Popover floats over the page, anchored above the badge wrap. Traffic-Orange
   accent border, dark text on light card. */
.wf167-warning-popover {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 10501;
    min-width: 280px;
    max-width: 360px;
    padding: 10px 12px;
    background: #FFFFFF;
    border: 1px solid #DD5100;
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(15, 23, 42, 0.16);
    color: #1F2937;
    font-size: 0.825rem;
    line-height: 1.4;
    text-align: left;
    cursor: default;
    animation: wf167-popover-enter 140ms ease-out both;
}
@keyframes wf167-popover-enter {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    .wf167-warning-popover { animation: none; }
}
.wf167-warning-popover-title {
    display: block;
    font-weight: 600;
    color: #B83F00;
    margin-bottom: 6px;
}
.wf167-warning-popover-list {
    margin: 0;
    padding-left: 18px;
}
.wf167-warning-popover-list li {
    margin-bottom: 4px;
}
.wf167-warning-popover-list li:last-child {
    margin-bottom: 0;
}
.wf167-warning-popover-list strong {
    color: #DD5100;
}

/* BU-218 extension 19 (2026-05-23): clickable warning-row button. Reset
   default button chrome so it looks like the prior bulleted text, then add
   pointer + subtle hover to signal interactivity. Click navigates parent
   to the deliverable this warning is about. */
.wf167-warning-popover-item {
    display: block;
    width: 100%;
    text-align: left;
    background: transparent;
    border: 0;
    padding: 2px 6px;
    margin: 0 -6px;
    border-radius: 4px;
    color: inherit;
    font: inherit;
    cursor: pointer;
    transition: background-color 120ms ease-out;
}
.wf167-warning-popover-item:hover {
    background: rgba(221, 81, 0, 0.08);
}
.wf167-warning-popover-item:focus-visible {
    outline: 2px solid rgba(221, 81, 0, 0.35);
    outline-offset: 1px;
}

/* ──────────────────────────────────────────────────────────────────────
   BU-186: Compose panel filter drawer + chevron pill.

   Pattern: each Compose panel header carries a single chevron pill on
   the right reading e.g. "⏷ 2 filters · 18 items". Click toggles a
   drawer that slides down between the panel header and the items grid,
   holding what used to be inline filter chrome (voice/stage chips, sort
   dropdown, search input, channel/date filters in Deliverables).

   Pill is rendered inline by the parent (PanelXHeader fragments in
   ComposeWorkbenchPage); drawer body is the new <PanelFilterDrawer>
   shared component.

   Open/closed state is owned + persisted by ComposeWorkbenchPage to
   localStorage under key `compose-panel-filter-drawer:{PanelId}`.
   This block is pure presentation; no state lives here.

   Walkthrough bullets covered: 2 (collapsed by default), 3 (pill text),
   4 (slide-down animation), 8 (multi-drawer non-overlap), 11 (empty
   state), 14 (body retention), 15 (Deliverables height budget).
   ────────────────────────────────────────────────────────────────────── */

.compose-panel-filter-drawer__body {
    /* Collapsed default. ComposeWorkbenchPage's localStorage read in
       OnAfterRenderAsync flips IsOpen back to true for any panel the
       user had open previously — but the FIRST paint of every panel
       is collapsed regardless of stored state (avoids a layout flash). */
    overflow: hidden;
    max-height: 0;
    transition: max-height 220ms cubic-bezier(.4, 0, .2, 1);
    background: rgba(255, 255, 255, 0.85);
    border-bottom: 1px solid transparent;
}

/* The drawer is a direct child of .compose-panel-inner, which has a
   pre-existing universal rule (compose-workbench.css line 2510):
       .compose-panel-inner > *:not(.compose-panel-head) {
         overflow: auto;
         min-height: 0;
         flex: 1 1 auto;
       }
   That makes every body child a flex-grower with auto overflow — which
   defeats our max-height: 0 → 380px transition (the drawer ends up
   8px tall because it competes with MediaComposer + grid + bulkbar
   for vertical share) AND replaces our overflow: hidden with auto
   (showing internal scrollbars on a closed drawer). The drawer needs
   to NOT flex-grow and MUST keep overflow: hidden so the slide-down
   transition reads cleanly. */
.compose-panel-inner > .compose-panel-filter-drawer__body {
    flex: 0 0 auto;
    overflow: hidden;
}

.compose-panel-filter-drawer__body--open {
    /* Max-height generous enough for the Deliverables drawer at its
       tallest (6 filter groups + sort + multi-bar). Walkthrough bullet
       15 requires the drawer to leave >=50% of the panel for the items
       below — that's a panel-layout concern, but capping the drawer
       gives the items room to breathe even at the tallest scenario. */
    max-height: 380px;
    border-bottom-color: #E5E7EB;
}

.compose-panel-filter-drawer__content {
    padding: 10px 12px 12px 12px;
}

@media (prefers-reduced-motion: reduce) {
    .compose-panel-filter-drawer__body {
        transition: none;
    }
}

.compose-panel-filter-drawer__pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 24px;
    padding: 0 10px;
    border: 0.5px solid #E5E7EB;
    border-radius: 999px;
    background: transparent;
    color: #4B5563;
    font-size: 12px;
    font-weight: 400;
    cursor: pointer;
    transition: background-color 120ms ease-out, border-color 120ms ease-out, color 120ms ease-out;
    /* Don't let the pill collapse in tight panel headers. */
    flex-shrink: 0;
}

.compose-panel-filter-drawer__pill:hover {
    background: #F9FAFB;
    border-color: #D1D5DB;
    color: #111827;
}

.compose-panel-filter-drawer__pill[aria-expanded="true"] {
    background: #F3F4F6;
    border-color: #6B7280;
    color: #111827;
}

.compose-panel-filter-drawer__pill:focus-visible {
    outline: 1px solid #6B7280;
    outline-offset: 1px;
}

.compose-panel-filter-drawer__pill-count {
    /* "2" or "5" badge — only rendered when ActiveFilterCount > 0.
       BU-186 bullet 20 (restraint with orange): neutral gray pill,
       no Traffic Orange disc here. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 16px;
    height: 14px;
    padding: 0 4px;
    border-radius: 999px;
    background: #6B7280;
    color: #FFFFFF;
    font-size: 10px;
    font-weight: 500;
    line-height: 1;
}

.compose-panel-filter-drawer__pill-divider {
    /* The "·" between filters and item count. Decorative. */
    color: #9CA3AF;
    font-weight: 400;
}

.compose-panel-filter-drawer__pill-chevron {
    width: 10px;
    height: 10px;
    transition: transform 180ms ease-out;
}

.compose-panel-filter-drawer__pill[aria-expanded="true"]
.compose-panel-filter-drawer__pill-chevron {
    transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
    .compose-panel-filter-drawer__pill-chevron {
        transition: none;
    }
}

/* Deliverables drawer is the tallest because of the 6 filter groups
   (Search / Voice / Stage / Media-assignment / Channel / Date) + sort
   + multi-bar. Walkthrough bullet 15 calls for a multi-row layout so
   it doesn't overflow horizontally at 1280px. Hint to the drawer
   content via a CSS grid when this class is set by the parent. */
.compose-panel-filter-drawer__content--deliverables {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 8px 12px;
}

/* ──────────────────────────────────────────────────────────────────────
   BU-186 stage 2.2: minimalist drawer chrome.

   Walkthrough bullets 17-19 (appended 2026-05-15): drawer contents fit
   on a SINGLE row; values come from compact dropdown triggers (not pill
   strips); stages render as colored circles, one per stage, instead of
   word-chips. Selected stages fill with their brand color, unselected
   are outlined. The existing per-stage palette (jgn-stage--awareness
   / --consideration / --decision / --retention) supplies the colors;
   the circle pulls its border + active-fill from currentColor.
   ────────────────────────────────────────────────────────────────────── */

.jgn-filter-row--inline {
    display: flex;
    align-items: center;
    gap: 18px;
    flex-wrap: nowrap;
    margin: 0;
}

/* Multi-select dropdown anchor — hoisted into the global stylesheet so
   ComposeWorkbenchPage can use it independently of DeliverableMediaList's
   <style> block. Same visual pattern as DMList uses. BU-186 stage 2.2
   bullet 18 ("Filter values are multi-select dropdowns, not pill rows"). */
.jgn-filter-anchor {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    border: 1px solid #D1D5DB;
    background: #FFFFFF;
    border-radius: 8px;
    font-size: 12px;
    color: #4B5563;
    cursor: pointer;
    transition: border-color 180ms ease-out, background-color 180ms ease-out, color 180ms ease-out;
    text-align: left;
    flex-shrink: 0;
}

.jgn-filter-anchor:hover {
    border-color: #9CA3AF;
    color: #1F2937;
}

.jgn-filter-anchor:focus-visible {
    outline: 2px solid rgba(221, 81, 0, 0.35);
    outline-offset: 1px;
    border-color: #DD5100;
}

.jgn-filter-anchor--active {
    border-color: #DD5100;
    background: #FFF7ED;
    color: #9A3412;
}

.jgn-filter-anchor__text {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.jgn-filter-anchor__count {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    background: #DD5100;
    color: #FFFFFF;
    border-radius: 999px;
    font-size: 10px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.jgn-filter-anchor__caret {
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    opacity: 0.7;
}

/* Compose drawer filter group — explicit horizontal row layout. The bare
   .jgn-filter-group selector is also defined inside DeliverableMediaList's
   inline <style> block (flex-direction: column + min-width: 240px), which
   would otherwise stack the stage circles vertically. Scoping to the
   --inline parent wins specificity without disturbing DMList's layout. */
.jgn-filter-row--inline .jgn-filter-group {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 6px;
    min-width: 0;
    flex: 0 0 auto;
}

.jgn-filter-row--inline .jgn-filter-group--stage {
    /* The 4 stage circles + small inter-circle gap. Compact. */
    gap: 8px;
}

/* Stage circle — 16px disc with per-stage color. Outlined when
   unselected, filled-with-color when selected. Hover gets a subtle
   ring; focus-visible gets a stronger one. Tooltip via title attr
   surfaces the stage name on hover. */
.jgn-stage-circle {
    width: 16px;
    height: 16px;
    padding: 0;
    border-radius: 50%;
    background: transparent;
    border: 2px solid currentColor;
    cursor: pointer;
    transition: background-color 120ms ease-out, transform 120ms ease-out, box-shadow 120ms ease-out;
    /* color comes from the per-stage class below; the circle uses
       currentColor for both border and active-fill so we don't have
       to duplicate the palette here. */
    color: #9CA3AF; /* fallback if no stage class wins */
}

.jgn-stage-circle:hover {
    transform: scale(1.12);
}

.jgn-stage-circle:focus-visible {
    outline: 2px solid #DD5100;
    outline-offset: 2px;
}

.jgn-stage-circle.is-active {
    background: currentColor;
}

/* Per-stage color resolves currentColor for both the border and the
   active fill. Palette matches the existing .jgn-filter-chip--stage
   variants in compose-workbench.css line 190-193: amber for Awareness,
   blue for Consideration, green for Decision, purple for Retention.
   IMPORTANT: there is a separate global rule `.jgn-stage--{name} {
   background: #FEF3C7 ... }` (pastel-fill chip variant) that would
   otherwise paint these circles with a light pastel background even
   when unselected. We override background: transparent here so the
   outline-when-unselected / filled-when-active treatment reads cleanly. */
.jgn-stage-circle.jgn-stage--awareness {
    color: #F59E0B; /* amber-500 */
    background: transparent;
}
.jgn-stage-circle.jgn-stage--consideration {
    color: #3B82F6; /* blue-500 */
    background: transparent;
}
.jgn-stage-circle.jgn-stage--decision {
    color: #22C55E; /* green-500 */
    background: transparent;
}
.jgn-stage-circle.jgn-stage--retention {
    color: #A855F7; /* purple-500 */
    background: transparent;
}

/* Active = filled disc. Re-state per-stage color here so the more-
   specific selector wins over the .jgn-stage-circle.is-active base. */
.jgn-stage-circle.jgn-stage--awareness.is-active    { background: #F59E0B; }
.jgn-stage-circle.jgn-stage--consideration.is-active { background: #3B82F6; }
.jgn-stage-circle.jgn-stage--decision.is-active     { background: #22C55E; }
.jgn-stage-circle.jgn-stage--retention.is-active    { background: #A855F7; }

@media (prefers-reduced-motion: reduce) {
    .jgn-stage-circle:hover {
        transform: none;
    }
    .jgn-stage-circle {
        transition: none;
    }
}

/* =====================================================================
   BU-186 stage 3 (2026-05-15) — outside-developer Media panel redesign
   ---------------------------------------------------------------------
   Walkthrough bullets 20-30. Treat orange as accent (drop zone download
   glyph, active engagement-tab underline, warning icon — nowhere else).
   Hairline 0.5px borders. Sentence case + 400/500 weights only.
   Three-zone card: title row / voices-scroll (max-height 48px, 4px
   hairline scrollbar) / margin-top:auto bottom block (4×18px fixed-slot
   stage scaffold + footer row). Card grid stretches with fixed 3 cols.
   ===================================================================== */

/* Card surface — quiet, hairline-bordered. Overrides 1287..1336 family. */
.jgn-media-card {
    background: #FFFFFF;
    border: 0.5px solid #E5E7EB;
    border-radius: 8px;
    padding: 11px 12px;
    box-shadow: none;
    animation: none;
    transition: border-color 180ms ease-out;
    display: flex;
    flex-direction: column;
    gap: 9px;
    position: relative;
}
.jgn-media-card:hover {
    transform: none;
    box-shadow: none;
    border-color: #D1D5DB;
}
.jgn-media-card[draggable="true"] { cursor: grab; }
.jgn-media-card.is-dragging {
    opacity: 0.85;
    transform: rotate(1deg) scale(1.01);
    box-shadow: 0 4px 10px rgba(15, 23, 42, 0.08);
    cursor: grabbing;
}
/* Drop the reuse-heat warm-wash gradient — also part of orange restraint. */
.jgn-media-card[data-reuse-heat="1"],
.jgn-media-card[data-reuse-heat="2"],
.jgn-media-card[data-reuse-heat="3"] {
    background: #FFFFFF;
}
.jgn-media-card.is-selected {
    border-color: #6B7280 !important;
    box-shadow: none !important;
}

/* Title row */
.jgn-media-card .jgn-media-card__title-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 0;
}
.jgn-media-card .jgn-media-card__title {
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0;
    color: #111827;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1 1 auto;
    min-width: 0;
}

/* Warning badge — single amber alert icon, no orange disc background.
   Scoped to MediaCard usage; ProductionStacks + MediaLibrary keep their
   own orange-disc treatment unchanged. */
.jgn-media-card .wf167-warning-badge {
    width: auto;
    height: auto;
    border-radius: 0;
    background: transparent;
    color: #BA7517;
    margin-left: 0;
    animation: none;
    cursor: pointer;
}
.jgn-media-card .wf167-warning-badge-wrap .wf167-warning-badge[aria-expanded="true"] {
    background: transparent;
    box-shadow: none;
    color: #854F0B;
}
.jgn-media-card .wf167-warning-badge-wrap .wf167-warning-badge:focus-visible {
    outline: 2px solid #BA7517;
    outline-offset: 2px;
}

/* Faux-checkbox visual on the bulk-select input. accent-color shows
   through native checkmark to keep the box behavior; tone it neutral. */
.jgn-media-card .jgn-media-card__select {
    width: 13px !important;
    height: 13px !important;
    accent-color: #6B7280;
}

/* Delete (trash) button — quiet tertiary, no red hover wash. */
.jgn-media-card .jgn-media-card__delete {
    width: 16px;
    height: 16px;
    color: #9CA3AF;
    background: transparent;
    border-radius: 4px;
}
.jgn-media-card .jgn-media-card__delete:hover {
    color: #6B7280;
    background: transparent;
}
.jgn-media-card .jgn-media-card__delete:focus-visible {
    outline: 1px solid #9CA3AF;
    outline-offset: 1px;
}

/* Voices zone — bounded scrolling, hairline 4px scrollbar. */
.jgn-media-card__voices {
    max-height: 48px;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: #E5E7EB transparent;
}
.jgn-media-card__voices::-webkit-scrollbar { width: 4px; }
.jgn-media-card__voices::-webkit-scrollbar-track { background: transparent; }
.jgn-media-card__voices::-webkit-scrollbar-thumb {
    background: #E5E7EB;
    border-radius: 2px;
}
.jgn-media-card__voices::-webkit-scrollbar-thumb:hover {
    background: #D1D5DB;
}
.jgn-media-card__voices-wrap {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding-right: 4px;
}
.jgn-media-card__voice-pill {
    font-size: 11px;
    line-height: 1.4;
    padding: 2px 8px;
    border-radius: 999px;
    border: 0.5px solid #E5E7EB;
    background: transparent;
    color: #4B5563;
    white-space: nowrap;
}

/* Bottom block — pinned to card floor via margin-top: auto, so every
   card in a row lands its stage scaffold + footer at the same Y. */
.jgn-media-card__bottom {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    gap: 9px;
}

/* Stage scaffold — 4-column fixed-width grid. X position locked per stage
   regardless of which are assigned. Active = colored letter token,
   inactive = 0.5px dashed circle ghost. */
.jgn-media-card__stages {
    display: grid;
    grid-template-columns: repeat(4, 18px);
    gap: 6px;
    align-items: center;
}
.jgn-media-card__stage-slot {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 500;
    line-height: 1;
    box-sizing: border-box;
}
.jgn-media-card__stage-slot--ghost {
    background: transparent;
    border: 0.5px dashed #E5E7EB;
    color: transparent;
}
.jgn-media-card__stage-slot--awareness {
    background: #FDF6E9;
    border: 0.5px solid #FAC775;
    color: #854F0B;
}
.jgn-media-card__stage-slot--consideration {
    background: #F2F8FD;
    border: 0.5px solid #B5D4F4;
    color: #0C447C;
}
.jgn-media-card__stage-slot--decision {
    background: #F5FAEC;
    border: 0.5px solid #C0DD97;
    color: #27500A;
}
.jgn-media-card__stage-slot--retention {
    background: #EEEDFE;
    border: 0.5px solid #CECBF6;
    color: #3C3489;
}

/* Footer row — photo icon + count left; assigned cluster right (when
   assigned only; unassigned omits the right cluster entirely). */
.jgn-media-card .jgn-media-card__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 11px;
    color: #6B7280;
    font-variant-numeric: tabular-nums;
}
.jgn-media-card__asset-count {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: #6B7280;
}
.jgn-media-card .jgn-media-card__assign-cluster {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.jgn-media-card .jgn-media-card__assign-status--assigned {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: #3B6D11;
    font-weight: 400;
}
.jgn-media-card .jgn-media-card__assign-status--assigned-other {
    color: #6B7280;
    font-weight: 400;
}
.jgn-media-card .jgn-media-card__detach {
    width: 14px;
    height: 14px;
    line-height: 1;
    font-size: 12px;
    color: #9CA3AF;
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
    margin-left: 2px;
}
.jgn-media-card .jgn-media-card__detach:hover { color: #6B7280; }

/* Grid stretch — every card in a row matches the tallest card's height
   so the margin-top:auto bottom block lands at the same Y. */
.compose-workbench-body .compose-panel-inner > .compose-media-grid,
.compose-media-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
    align-items: stretch;
    align-content: start;
}

/* Engagement tabs (Media panel variant) — flatten the strip. Hairline
   bottom border; active tab gets a 1.5px solid #BA7517 underline that
   overlays the strip's hairline via margin-bottom: -0.5px. Neutral tab
   labels; counts as small tertiary.
   BU-186 bullet 31 (2026-05-15): single-row with horizontal scroll,
   tightened vertical padding — previous flex-wrap caused 90px strip
   from 2 wrapped rows. The user called out: "All this vertical space
   between the deliverable engagement tabs and the media are is
   unnecessary." */
.jgn-deliverable-engagement-tabs--media {
    padding: 0 0 0 0;
    border-bottom: 0.5px solid #E5E7EB;
    background: transparent;
    gap: 22px;
    flex-wrap: nowrap;
    overflow-x: auto !important;
    overflow-y: visible !important;
    scrollbar-width: none;
    -ms-overflow-style: none;
    min-height: 0;
    max-width: 100%;
}
/* Override the base universal rule at line 2962 which forces overflow:
   visible !important on every panel-inner child. The media-variant tabs
   need horizontal scroll behavior, not visible. */
.compose-workbench-body .compose-panel-inner > .jgn-deliverable-engagement-tabs--media {
    overflow-x: auto !important;
    overflow-y: visible !important;
}
.jgn-deliverable-engagement-tabs--media::-webkit-scrollbar { display: none; }
.jgn-deliverable-engagement-tabs--media .jgn-deliverable-engagement-tab {
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 4px 0 5px;
    font-size: 13px;
    font-weight: 400;
    color: #6B7280;
    margin-bottom: -0.5px;
    flex-shrink: 0;
    white-space: nowrap;
    max-width: none;
}
.jgn-deliverable-engagement-tabs--media .jgn-deliverable-engagement-tab:hover {
    background: transparent;
    color: #111827;
}
.jgn-deliverable-engagement-tabs--media .jgn-deliverable-engagement-tab--active {
    background: transparent;
    color: #111827;
    font-weight: 500;
    border-bottom: 1.5px solid #BA7517;
}
.jgn-deliverable-engagement-tabs--media .jgn-deliverable-engagement-tab__count {
    background: transparent;
    color: #9CA3AF;
    font-size: 11px;
    font-weight: 400;
    padding: 0;
    border-radius: 0;
}
.jgn-deliverable-engagement-tabs--media .jgn-deliverable-engagement-tab--active .jgn-deliverable-engagement-tab__count {
    background: transparent;
    color: #9CA3AF;
}

/* BU-186 bullet 32 (2026-05-15): popover overflow escape. When a Voice
   filter popover (.jgn-filter-voice-menu) or a WF-171 warning popover
   (.wf167-warning-popover) is open, force overflow: visible on each of
   the clipping ancestors so the popover renders above panel/drawer/
   grid boundaries. Uses :has() — supported in Chrome 105+ / Safari 15.4+
   / Firefox 121+ (all current local browsers).
   Verbatim user direction: "the Z values for the popouts on Voice
   selection and warning detail are wrong- popouts are hidden. Both
   can extend beyond the panel itself/ontop of other panels if needed."
   z-index bumped to 20000+ so popovers float above any other panel chrome. */
.jgn-filter-voice-menu { z-index: 20001; }
.wf167-warning-popover { z-index: 20001; }
.wf167-warning-backdrop { z-index: 20000; }

.compose-panel-filter-drawer__body:has(.jgn-filter-voice-menu),
.compose-panel-inner > .compose-panel-filter-drawer__body:has(.jgn-filter-voice-menu) {
    overflow: visible;
}
.compose-panel-filter-drawer__content:has(.jgn-filter-voice-menu) {
    overflow: visible;
}
.jgn-filter-row--inline:has(.jgn-filter-voice-menu) {
    overflow: visible;
}

.compose-media-grid:has(.wf167-warning-popover),
.compose-workbench-body .compose-panel-inner > .compose-media-grid:has(.wf167-warning-popover) {
    overflow: visible;
}
.jgn-media-card:has(.wf167-warning-popover) {
    overflow: visible;
    z-index: 20002;
}
.compose-panel-inner:has(.wf167-warning-popover),
.compose-panel-inner:has(.jgn-filter-voice-menu) {
    overflow: visible;
}
.panel-host-panel:has(.wf167-warning-popover),
.panel-host-panel:has(.jgn-filter-voice-menu) {
    overflow: visible;
    z-index: 20003;
}
.panel-host-panel-body:has(.wf167-warning-popover),
.panel-host-panel-body:has(.jgn-filter-voice-menu) {
    overflow: visible;
}

/* BU-186 bullets 35 + 36 (2026-05-15): drawer stage filter circles
   match the media card stage scaffold (token-driven, not saturated
   single-color fills). And drawer row gains clear horizontal grouping
   hierarchy via 24px between-group gap + a 0.5px hairline left-border
   on the 2nd and 3rd groups. Verbatim user directions:
   - "style the control draer stage filter pills in the same way as the media cards."
   - "can you maggage the horizontal spacing? No clear hierarchy" */

/* Bump row gap so groups read as distinct. */
.jgn-filter-row--inline {
    gap: 24px;
}
/* Hairline vertical divider between groups — pushes each non-first group
   away from its predecessor with a visible separator. Padding-left
   creates breathing room inside the group after the divider. */
.jgn-filter-row--inline > .jgn-filter-group + .jgn-filter-group {
    border-left: 0.5px solid #E5E7EB;
    padding-left: 24px;
    margin-left: 0;
}
/* Intra-group: Stage circles tight at 6px (matches card stage-grid gap). */
.jgn-filter-row--inline .jgn-filter-group--stage {
    gap: 6px;
}

/* Drawer stage filter circles re-styled to the card's token system.
   Overrides the .jgn-stage-circle base + per-stage saturated rules
   in the section above (lines 5246-5305). Scoped to the inline
   filter row so other usages of .jgn-stage-circle (if any) remain
   untouched. */
.jgn-filter-row--inline .jgn-stage-circle {
    /* BU-186 bullet 37 (2026-05-15): added weight so the user can see
       the circle is selectable. 0.5px dashed reads as decoration; 1px
       solid + #F9FAFB tint reads as a button. Inactive letter remains
       hidden (color: transparent) so the inert state is the empty
       circle, not a labeled token. */
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #F9FAFB;
    border: 1px solid #D1D5DB;
    color: transparent;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 500;
    line-height: 1;
    padding: 0;
    box-sizing: border-box;
    transition: background-color 120ms ease-out, color 120ms ease-out, border-color 120ms ease-out, transform 120ms ease-out;
}
.jgn-filter-row--inline .jgn-stage-circle:hover {
    transform: scale(1.08);
    border-color: #9CA3AF;
    background: #F3F4F6;
    /* On hover, reveal the letter in a quiet neutral so the user
       gets a hint of what the circle represents before clicking. */
    color: #6B7280;
}
.jgn-filter-row--inline .jgn-stage-circle:focus-visible {
    outline: 1.5px solid #6B7280;
    outline-offset: 2px;
}
/* The letter is injected via ::after rather than as inline content
   because the existing Razor button is intentionally empty (the title
   attr carries the stage name). content-via-class keeps Razor untouched. */
.jgn-filter-row--inline .jgn-stage-circle.jgn-stage--awareness::after { content: "A"; }
.jgn-filter-row--inline .jgn-stage-circle.jgn-stage--consideration::after { content: "C"; }
.jgn-filter-row--inline .jgn-stage-circle.jgn-stage--decision::after { content: "D"; }
.jgn-filter-row--inline .jgn-stage-circle.jgn-stage--retention::after { content: "R"; }

/* Voice trigger softened to match the minimalist token system —
   hairline border, neutral active state, no orange. */
.jgn-filter-row--inline .jgn-filter-anchor {
    border: 0.5px solid #E5E7EB;
    background: transparent;
    color: #4B5563;
    padding: 4px 8px;
    font-size: 12px;
    font-weight: 400;
    border-radius: 999px;
}
.jgn-filter-row--inline .jgn-filter-anchor:hover {
    border-color: #D1D5DB;
    background: #F9FAFB;
    color: #111827;
}
.jgn-filter-row--inline .jgn-filter-anchor:focus-visible {
    outline: 1px solid #6B7280;
    outline-offset: 1px;
    border-color: #D1D5DB;
}
.jgn-filter-row--inline .jgn-filter-anchor--active {
    border-color: #6B7280;
    background: #F3F4F6;
    color: #111827;
}
.jgn-filter-row--inline .jgn-filter-anchor__count {
    background: #6B7280;
    color: #FFFFFF;
    font-weight: 500;
}

/* Active state: card-token palette (fill / border / text). Override
   the prior `.jgn-stage-circle.jgn-stage--{name}.is-active` rules with
   the inline-row prefix for higher specificity. BU-186 bullet 37:
   border weight bumped to 1px to match the new inactive-state weight,
   so all 4 circles read with consistent visual weight regardless of
   their selection state. */
.jgn-filter-row--inline .jgn-stage-circle.jgn-stage--awareness.is-active {
    background: #FDF6E9;
    border: 1px solid #F0B65A;
    color: #854F0B;
}
.jgn-filter-row--inline .jgn-stage-circle.jgn-stage--consideration.is-active {
    background: #F2F8FD;
    border: 1px solid #A5C8EE;
    color: #0C447C;
}
.jgn-filter-row--inline .jgn-stage-circle.jgn-stage--decision.is-active {
    background: #F5FAEC;
    border: 1px solid #B0D183;
    color: #27500A;
}
.jgn-filter-row--inline .jgn-stage-circle.jgn-stage--retention.is-active {
    background: #EEEDFE;
    border: 1px solid #BFBCF1;
    color: #3C3489;
}

/* BU-186 bullet 38 (2026-05-15): EXCLUDED state — red ring + diagonal
   strikethrough line through the circle. Reads like a "forbidden /
   no-entry" symbol. Letter inside flips to red so the stage is still
   identifiable. The diagonal line is a ::before pseudo-element rotated
   -45deg; ::after is reserved for the letter.
   Verbatim user direction: "the second click of a stage chip should
   exclude that stage. Indicatee excuded stage by changing stroke to
   red and adding diagonal line through circle" */
.jgn-filter-row--inline .jgn-stage-circle.is-excluded {
    background: #FEF2F2;
    border: 1px solid #DC2626;
    color: #B91C1C;
    position: relative;
    overflow: visible;
}
.jgn-filter-row--inline .jgn-stage-circle.is-excluded::before {
    /* Diagonal strike line through the circle. 1.5px solid red,
       sized slightly wider than the circle so it reads as a banner
       cut, not a tiny scribble. */
    content: '';
    position: absolute;
    top: 50%;
    left: -2px;
    right: -2px;
    height: 1.5px;
    background: #DC2626;
    transform: rotate(-45deg);
    transform-origin: center center;
    pointer-events: none;
    border-radius: 1px;
}
/* When excluded, the per-stage `.is-active` rules above must NOT
   re-apply the colored palette. The toggle never sets both classes
   simultaneously (include and exclude are mutually disjoint in the
   state model), but defend explicitly for safety in case external
   code stuffs both classes on. */
.jgn-filter-row--inline .jgn-stage-circle.is-excluded.is-active {
    background: #FEF2F2 !important;
    border-color: #DC2626 !important;
    color: #B91C1C !important;
}

/* BU-186 bullet 39 (2026-05-15): Reset filters button at the right
   edge of the drawer row. Subtle text link with a small refresh
   icon; only renders when HasMediaFilters is true (Razor-side gate).
   Visually subordinate to the filter controls — small font, neutral
   color, no orange. */
.jgn-filter-reset {
    appearance: none;
    background: transparent;
    border: 0;
    padding: 4px 8px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    font-size: 11px;
    font-weight: 400;
    color: #6B7280;
    cursor: pointer;
    border-radius: 4px;
    transition: background-color 120ms ease-out, color 120ms ease-out;
    flex-shrink: 0;
}
/* BU-186 bullet 74 (2026-05-18): leading icon-only Reset variant —
   sits at the start of the drawer filter strip. No margin auto. */
.jgn-filter-reset--leading {
    margin-left: 0;
    padding: 4px 6px;
    align-self: center;
    order: -1;
}
.jgn-filter-reset--leading svg { opacity: 0.65; }
.jgn-filter-reset--leading:hover svg { opacity: 1; }
/* BU-186 bullet 72 (2026-05-18): click-away backdrop for filter
   dropdowns (Voice + Channel menus). Transparent layer just below
   the menu's z-index that catches outside-click and trigger-re-click. */
.jgn-menu-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1049;
    background: transparent;
}
.jgn-filter-reset:hover {
    color: #111827;
    background: #F3F4F6;
}
.jgn-filter-reset:focus-visible {
    outline: 1px solid #6B7280;
    outline-offset: 1px;
}
.jgn-filter-reset svg {
    flex-shrink: 0;
    opacity: 0.7;
}
.jgn-filter-reset:hover svg {
    opacity: 1;
}
/* When the Reset button is present (HasMediaFilters), don't let the
   prior group's hairline divider attach to it — Reset stands alone
   on the right, not visually grouped with the filter clusters. */
.jgn-filter-row--inline > .jgn-filter-group + .jgn-filter-reset {
    border-left: none;
    padding-left: 8px;
}

/* BU-186 bullet 57 (2026-05-17): drawer-hosted Search input + Columns
   button group. Same minimalist token treatment as the rest of the
   drawer chrome — hairline borders, neutral colors, 400 weight, no
   orange. Search input flex-grows to take horizontal slack. */
.jgn-drawer-search {
    width: 100%;
    min-height: 26px;
    padding: 3px 10px;
    border: 0.5px solid #E5E7EB;
    border-radius: 999px;
    background: transparent;
    color: #111827;
    font-size: 12px;
    font-weight: 400;
    outline: none;
    transition: border-color 120ms ease-out, background-color 120ms ease-out;
}
.jgn-drawer-search:hover {
    background: #F9FAFB;
}
.jgn-drawer-search:focus {
    border-color: #6B7280;
    background: #FFFFFF;
}
.jgn-drawer-search::placeholder {
    color: #9CA3AF;
}

.jgn-columns-group {
    display: inline-flex;
    align-items: center;
    gap: 0;
    border: 0.5px solid #E5E7EB;
    border-radius: 999px;
    overflow: hidden;
    background: transparent;
}
.jgn-columns-group__label {
    font-size: 11px;
    font-weight: 400;
    color: #9CA3AF;
    padding: 0 8px 0 10px;
    white-space: nowrap;
    line-height: 1.4;
}
.jgn-columns-btn {
    appearance: none;
    background: transparent;
    border: 0;
    border-left: 0.5px solid #E5E7EB;
    padding: 3px 8px;
    font-size: 11px;
    font-weight: 400;
    color: #6B7280;
    cursor: pointer;
    line-height: 1.4;
    transition: background-color 120ms ease-out, color 120ms ease-out;
}
.jgn-columns-btn:hover {
    background: #F9FAFB;
    color: #111827;
}
.jgn-columns-btn.is-active {
    background: #F3F4F6;
    color: #111827;
    font-weight: 500;
}
.jgn-columns-btn--auto {
    padding: 3px 10px;
    font-style: italic;
}

/* BU-186 bullet 59 (2026-05-17): bar-glyph column cycle button. 1-4
   vertical bars rendered inside a pill-shaped button. Click cycles
   the count; visual reflects the active count. */
.jgn-columns-cycle {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 0 12px;
    height: 26px;
    min-width: 52px;
    border: 0.5px solid #E5E7EB;
    border-radius: 999px;
    background: transparent;
    color: #6B7280;
    cursor: pointer;
    transition: background-color 120ms ease-out, border-color 120ms ease-out, color 120ms ease-out;
    line-height: 1;
    flex-shrink: 0;
    justify-content: center;
}
.jgn-columns-cycle:hover {
    background: #F9FAFB;
    border-color: #D1D5DB;
    color: #111827;
}
.jgn-columns-cycle:focus-visible {
    outline: 1px solid #6B7280;
    outline-offset: 1px;
}
.jgn-columns-cycle__bar {
    display: inline-block;
    width: 2px;
    height: 12px;
    background: currentColor;
    border-radius: 1px;
}

/* BU-186 bullet 58 (2026-05-17): Deliverables drawer controls — date
   range, sort dropdown, sort direction. Same minimalist tokens as the
   rest of the drawer chrome. The drawer row uses flex-wrap so the 8
   controls + reset wrap to multiple rows when the panel is narrow. */
.jgn-filter-row--wrap {
    flex-wrap: wrap !important;
    row-gap: 8px !important;
}
.jgn-drawer-date {
    min-height: 26px;
    padding: 3px 8px;
    border: 0.5px solid #E5E7EB;
    border-radius: 8px;
    background: transparent;
    color: #111827;
    font-size: 12px;
    font-weight: 400;
    font-variant-numeric: tabular-nums;
    outline: none;
    transition: border-color 120ms ease-out, background-color 120ms ease-out;
    flex: 0 0 auto;
    width: 130px;
}
.jgn-drawer-date:hover {
    background: #F9FAFB;
}
.jgn-drawer-date:focus {
    border-color: #6B7280;
    background: #FFFFFF;
}
.jgn-date-range {
    display: inline-flex !important;
    align-items: center;
    gap: 6px !important;
}
.jgn-date-range__sep {
    font-size: 12px;
    color: #9CA3AF;
    line-height: 1;
}
.jgn-drawer-sort {
    appearance: none;
    -webkit-appearance: none;
    min-height: 26px;
    padding: 3px 24px 3px 10px;
    border: 0.5px solid #E5E7EB;
    border-radius: 8px;
    background: transparent;
    color: #4B5563;
    font-size: 12px;
    font-weight: 400;
    cursor: pointer;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'><path d='M3 4.5l3 3 3-3' fill='none' stroke='%236B7280' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat: no-repeat;
    background-position: right 8px center;
    transition: background-color 120ms ease-out, border-color 120ms ease-out;
}
.jgn-drawer-sort:hover { background-color: #F9FAFB; }
.jgn-drawer-sort:focus { outline: none; border-color: #6B7280; }
/* BU-186 bullet 65 (2026-05-18): center-justified header-placed selection badge
   for the Assets panel. Sits inline in the panel-scope-row between the scope
   chrome (left) and the drawer pill (right). The wrapper .panel-header-center
   takes the flex slack so the badge appears centered. */
.panel-header-center {
    flex: 1 1 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
}
.compose-panel-badge--header {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: 999px;
    border: 0.5px solid #E5E7EB;
    background: #F9FAFB;
    color: #4B5563;
    font-size: 11px;
    font-weight: 500;
    line-height: 1.4;
    letter-spacing: 0;
    text-transform: none;
    white-space: nowrap;
}

/* BU-186 bullet 62 (2026-05-18): hide-engagement-tabs eye-icon toggle in
   the Deliverables panel header. Sits next to the drawer chevron pill —
   neutral hairline button when tabs visible, slightly emphasized when
   tabs are currently hidden (slash icon). */
.jgn-engagement-tabs-toggle {
    appearance: none;
    background: transparent;
    border: 0.5px solid #E5E7EB;
    width: 24px;
    height: 24px;
    border-radius: 999px;
    color: #6B7280;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background-color 120ms ease-out, color 120ms ease-out, border-color 120ms ease-out;
    flex-shrink: 0;
}
.jgn-engagement-tabs-toggle:hover {
    background: #F9FAFB;
    color: #111827;
    border-color: #D1D5DB;
}
.jgn-engagement-tabs-toggle.is-hidden {
    background: #F3F4F6;
    color: #111827;
}
/* BU-229 (2026-05-23): inline variant lives INSIDE the engagement-tabs
   tablist (immediately right of the last tab). align-self centers it on
   the tab strip's baseline regardless of tab height, and a slim left
   margin gives a comfortable gap from the last tab without disconnecting. */
.jgn-deliverable-engagement-tabs > .jgn-engagement-tabs-toggle--inline {
    align-self: center;
    margin-left: 6px;
}

/* BU-186 bullet 61 (2026-05-18): compact the engagement-tabs row — no
   excess vertical band above or below. The row sits flush against the
   header strip and the table. */
.jgn-deliverable-engagement-tabs,
.jgn-deliverable-engagement-tabs-row {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
    padding-top: 0 !important;
}
.jgn-deliverable-engagement-tabs-row {
    min-height: auto !important;
}

.jgn-sort-direction {
    min-width: 26px;
    height: 26px;
    border: 0.5px solid #E5E7EB;
    border-radius: 999px;
    background: transparent;
    color: #6B7280;
    cursor: pointer;
    font-size: 12px;
    line-height: 1;
    transition: background-color 120ms ease-out, color 120ms ease-out, border-color 120ms ease-out;
    margin-left: 4px;
}
.jgn-sort-direction:hover {
    background: #F9FAFB;
    color: #111827;
    border-color: #D1D5DB;
}

/* BU-186 bullet 33 (2026-05-15): Assigned/Unassigned segmented control.
   Hairline rounded pill containing 3 radio-style segment buttons. Active
   segment carries a quiet neutral fill; unselected segments are
   transparent. Matches the minimalist token system used by the cards. */
.jgn-segmented {
    display: inline-flex;
    align-items: stretch;
    border: 0.5px solid #E5E7EB;
    border-radius: 999px;
    overflow: hidden;
    background: transparent;
}
.jgn-segment {
    appearance: none;
    background: transparent;
    border: 0;
    border-left: 0.5px solid #E5E7EB;
    padding: 3px 10px;
    font-size: 11px;
    font-weight: 400;
    color: #6B7280;
    cursor: pointer;
    white-space: nowrap;
    transition: background-color 120ms ease-out, color 120ms ease-out;
    line-height: 1.4;
}
.jgn-segment:first-child { border-left: 0; }
.jgn-segment:hover {
    background: #F9FAFB;
    color: #111827;
}
.jgn-segment.is-active {
    background: #F3F4F6;
    color: #111827;
    font-weight: 500;
}
.jgn-segment:focus-visible {
    outline: 1px solid #6B7280;
    outline-offset: -1px;
}

/* MediaComposer drop zone (empty state only) — amber tokens. Active /
   drag-over states keep the original orange treatment so the user sees
   a clear visual transition when something is dropped. */
.compose-panel-inner--media .jgn-compose-zone--empty {
    border: 1px dashed #F0D9B5;
    background: #FEFAF2;
    border-radius: 8px;
    padding: 14px 16px;
    min-height: auto;
}
.compose-panel-inner--media .jgn-compose-zone--empty .jgn-compose-zone__hint {
    color: #854F0B;
    font-size: 13px;
    font-weight: 400;
    letter-spacing: 0;
}
.compose-panel-inner--media .jgn-compose-zone--empty .jgn-compose-zone__hint-icon {
    color: #BA7517;
    width: 15px;
    height: 15px;
}

/* ============================================================
   BU-218 (2026-05-23) — Media panel compactness refinement.
   Card height drops ~45%, four-state color encoding (open / sage /
   parchment / brand-orange), options drawer restructured with paired
   Voice+Stage line + reused ScopeSelector Lucide icons +
   permission-aware chip filtering. Spec: docs/media-card-compact-mockup.html
   ============================================================ */

.jgn-media-card {
    padding: 8px 10px 9px;
    gap: 6px;
    border-left: 2.5px solid transparent;
}

.jgn-media-card__meta {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: auto;
}

.jgn-media-card__counts {
    display: flex;
    align-items: center;
    gap: 5px;
    margin-left: auto;
    min-width: 0;
    overflow: hidden;
}

/* BU-218 extension 2 (2026-05-23): __status visually matches the existing
   .jgn-media-card__assign-status--multilink pill exactly so all three
   assignment states share one pill vocabulary. Only the label text +
   palette color differ across (--assigned / --assigned-other /
   --multilink). Same shape (11px / weight 600 / Title-case, NOT
   uppercase white-on-saturated), same padding, same border, same radius. */
.jgn-media-card__status {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 9px;
    border: 1px solid transparent;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    line-height: 14px;
    white-space: nowrap;
}
.jgn-media-card__status svg { flex-shrink: 0; }

.jgn-media-card__pill {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 11px;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    color: #4B5563;
    padding: 1.5px 7px 1.5px 5px;
    border: 0.5px solid #E5E7EB;
    border-radius: 999px;
    background: rgba(255,255,255,0.7);
    white-space: nowrap;
    line-height: 1.4;
}
.jgn-media-card__pill svg { flex-shrink: 0; color: #9CA3AF; }
.jgn-media-card__pill--voices { cursor: pointer; }
.jgn-media-card__pill--voices:hover { border-color: #D1D5DB; background: #FFFFFF; }

.jgn-media-card__engagement {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 10.5px;
    font-weight: 500;
    color: #854F0B;
    padding: 1.5px 7px;
    border: 0.5px solid #FAC775;
    background: rgba(250, 199, 117, 0.10);
    border-radius: 999px;
    min-width: 0;
    flex: 0 99 110px;
    overflow: hidden;
    white-space: nowrap;
    cursor: pointer;
}
.jgn-media-card__engagement svg { flex-shrink: 0; color: #854F0B; opacity: 0.7; }
.jgn-media-card__engagement-name { overflow: hidden; text-overflow: ellipsis; min-width: 0; }

/* BU-218 extension (2026-05-23): the prior pill text colors were too dark
   (#27500A / #5B3705 / #82310C) and read as olive/brown/rust instead of
   the intended sage/amber/orange. Brightened to the palette mid-tones so
   the state reads unambiguously at a glance. Left bar also bumped from
   2.5px to 3.5px for a stronger assignment edge. New __status pill carries
   an explicit text label (Assigned / Elsewhere / Linked x N) so state is
   readable without relying on color alone (accessibility + clarity). */

/* State 1: Assigned in-scope (sage).
   BU-218 extension 3 (2026-05-23): chained-class selector (.jgn-media-card.
   jgn-media-card--assigned) bumps specificity to (0,2,0) so the assignment
   state outweighs the `.jgn-media-card[data-reuse-heat="1|2|3"]` reuse-heat
   rules (also 0,2,0 but earlier in the cascade). Assigned state is a HARD
   semantic and must always win over the reuse-heat SOFT background tint. */
.jgn-media-card.jgn-media-card--assigned {
    background: #ECF7E0;
    border-color: #A8CF7A;
    border-left: 3.5px solid #3B6D11;
}
.jgn-media-card--assigned .jgn-media-card__pill {
    border-color: rgba(168, 207, 122, 0.7);
    background: rgba(255,255,255,0.7);
    color: #3B6D11;
}
.jgn-media-card--assigned .jgn-media-card__pill svg { color: #3B6D11; opacity: 0.95; }
.jgn-media-card--assigned .jgn-media-card__status {
    color: #3B6D11;
    background: #ECF7E0;
    border-color: #A8CF7A;
}
.jgn-media-card--assigned .jgn-media-card__status svg { color: #3B6D11; }

/* State 2: Assigned out-of-scope (parchment + amber).
   See BU-218 extension 3 note above for the chained-class specificity bump. */
.jgn-media-card.jgn-media-card--assigned-other {
    background: #FBEFD3;
    border-color: #F0B850;
    border-left: 3.5px solid #854F0B;
}
.jgn-media-card--assigned-other .jgn-media-card__pill {
    border-color: rgba(240, 184, 80, 0.7);
    background: rgba(255,255,255,0.65);
    color: #854F0B;
}
.jgn-media-card--assigned-other .jgn-media-card__pill svg { color: #854F0B; opacity: 0.95; }
.jgn-media-card--assigned-other .jgn-media-card__status {
    color: #854F0B;
    background: #FBEFD3;
    border-color: #F0B850;
}
.jgn-media-card--assigned-other .jgn-media-card__status svg { color: #854F0B; }

/* State 3: Multi-linked (WF-192 brand-orange wash).
   See BU-218 extension 3 note above for the chained-class specificity bump. */
.jgn-media-card.jgn-media-card--multilink {
    background: #FFEAD6;
    border-color: #F4A26B;
    border-left: 3.5px solid #DD5100;
}
.jgn-media-card--multilink .jgn-media-card__pill {
    border-color: rgba(244, 162, 107, 0.75);
    background: rgba(255,255,255,0.7);
    color: #DD5100;
}
.jgn-media-card--multilink .jgn-media-card__pill svg { color: #DD5100; opacity: 0.95; }

/* Hover-only delete + detach */
.jgn-media-card__delete, .jgn-media-card__detach {
    opacity: 0;
    transition: opacity 140ms ease-out;
}
.jgn-media-card:hover .jgn-media-card__delete,
.jgn-media-card:hover .jgn-media-card__detach,
.jgn-media-card:focus-within .jgn-media-card__delete,
.jgn-media-card:focus-within .jgn-media-card__detach {
    opacity: 1;
}

/* Detach in title-row variant */
.jgn-media-card__title-row .jgn-media-card__detach {
    width: 16px; height: 16px;
    border-radius: 4px;
    font-size: 13px;
    color: #9CA3AF;
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
    line-height: 1;
}
.jgn-media-card__title-row .jgn-media-card__detach:hover { color: #6B7280; }

/* Suppress legacy stacked blocks */
.jgn-media-card .jgn-media-card__voices { display: none; }
.jgn-media-card .jgn-media-card__footer { display: none; }

/* Just-composed pulse */
@keyframes jgn-card-just-composed {
    0%   { box-shadow: 0 0 0 0 rgba(59, 109, 17, 0); }
    18%  { box-shadow: 0 0 0 4px rgba(59, 109, 17, 0.20); }
    55%  { box-shadow: 0 0 0 5px rgba(59, 109, 17, 0.06); }
    100% { box-shadow: 0 0 0 0 rgba(59, 109, 17, 0); }
}
.jgn-media-card.is-just-composed { animation: jgn-card-just-composed 1.6s ease-out; }

/* Compose-zone polish */
.jgn-compose-zone {
    border-width: 1px;
    padding: 8px 12px 8px 12px;
}
.jgn-compose-zone--empty {
    border-color: rgba(221, 81, 0, 0.28);
    min-height: 42px;
}
.jgn-compose-zone--drag {
    box-shadow: 0 0 0 4px rgba(221, 81, 0, 0.12), 0 6px 14px rgba(221, 81, 0, 0.10);
}
.jgn-compose-zone--active {
    background: linear-gradient(180deg, rgba(221, 81, 0, 0.035) 0%, #FFFFFF 70%);
}
.jgn-compose-zone__more.is-active {
    background: #DD5100;
    border-color: #DD5100;
    color: #FFFFFF;
}

/* Options drawer restructure */
.jgn-compose-zone__options {
    border-top: 0.5px solid rgba(221, 81, 0, 0.22);
    margin-top: 10px;
    padding: 10px 2px 4px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    background: linear-gradient(180deg, rgba(221, 81, 0, 0.012) 0%, transparent 100%);
    border-radius: 0 0 6px 6px;
}
.jgn-compose-zone__opt-line {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 5px 20px;
    min-height: 24px;
}
.jgn-compose-zone__opt-line--owner {
    padding-top: 6px;
    margin-top: 2px;
    padding-left: 18px;
    border-top: 0.5px dashed #E5E7EB;
}
.jgn-compose-zone__opt-group {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    min-width: 0;
}
.jgn-compose-zone__opt-label {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 9.5px;
    font-weight: 500;
    letter-spacing: 0.1em;
    color: #9CA3AF;
    text-transform: uppercase;
    margin-right: 4px;
    white-space: nowrap;
    flex: none;
}
.jgn-compose-zone__opt-line--owner .jgn-compose-zone__opt-label {
    color: #B14200;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* Refined chip rules (override existing) */
.jgn-compose-zone__chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 22px;
    padding: 0 9px;
    border: 0.5px solid #E5E7EB;
    border-radius: 999px;
    background: #FFFFFF;
    color: #4B5563;
    font-size: 10.5px;
    font-weight: 500;
    line-height: 20px;
    cursor: pointer;
    white-space: nowrap;
    transition: border-color 140ms ease-out, background-color 140ms ease-out, color 140ms ease-out;
}
.jgn-compose-zone__chip:hover { border-color: #9CA3AF; color: #1F2937; }
.jgn-compose-zone__chip--selected {
    background: #B14200;
    border-color: #B14200;
    color: #FFFFFF;
}
.jgn-compose-zone__chip--selected:hover {
    background: #95370A;
    border-color: #95370A;
}
.jgn-compose-zone__chip--add {
    border-style: dashed;
    border-color: #D1D5DB;
    color: #6B7280;
}
.jgn-compose-zone__chip--add:hover {
    border-style: dashed;
    border-color: #DD5100;
    color: #DD5100;
    background: rgba(221, 81, 0, 0.04);
}
.jgn-compose-zone__chip-x {
    color: rgba(255, 255, 255, 0.78);
    font-size: 11px;
    margin-left: 2px;
}

/* Stage chips: per-palette via data-stage attr */
.jgn-compose-zone__chip--stage {
    width: 22px;
    height: 22px;
    padding: 0;
    justify-content: center;
    border-radius: 50%;
    font-size: 10px;
    font-weight: 500;
    border: 0.5px dashed #D1D5DB;
    background: transparent;
    color: #9CA3AF;
    line-height: 1;
}
.jgn-compose-zone__chip--stage:hover {
    border-style: solid;
    border-color: #6B7280;
    color: #4B5563;
}
.jgn-compose-zone__chip--stage[data-stage='awareness'].is-on {
    background: #FDF6E9; border: 0.5px solid #FAC775; color: #854F0B;
}
.jgn-compose-zone__chip--stage[data-stage='consideration'].is-on {
    background: #F2F8FD; border: 0.5px solid #B5D4F4; color: #0C447C;
}
.jgn-compose-zone__chip--stage[data-stage='decision'].is-on {
    background: #F5FAEC; border: 0.5px solid #C0DD97; color: #27500A;
}
.jgn-compose-zone__chip--stage[data-stage='retention'].is-on {
    background: #EEEDFE; border: 0.5px solid #CECBF6; color: #3C3489;
}

/* Scope chips: with reused ScopeSelector Lucide icon */
.jgn-compose-zone__chip--scope {
    padding-left: 7px;
    padding-right: 9px;
    gap: 5px;
}
.jgn-compose-zone__chip-icon {
    display: inline-flex;
    color: currentColor;
    flex-shrink: 0;
    opacity: 0.75;
}
.jgn-compose-zone__chip--selected .jgn-compose-zone__chip-icon { opacity: 1; }

/* Affirmation pill for single-scope-allowed degenerate case */
.jgn-compose-zone__scope-affirm {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 22px;
    padding: 0 10px 0 8px;
    font-size: 10.5px;
    font-weight: 500;
    color: #6B7280;
    background: rgba(0,0,0,0.025);
    border: 0.5px solid #E5E7EB;
    border-radius: 999px;
    white-space: nowrap;
}
.jgn-compose-zone__scope-affirm-icon { color: #9CA3AF; }
.jgn-compose-zone__scope-affirm-target { color: #1F2937; font-weight: 500; }
.jgn-compose-zone__scope-affirm-hint {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 9px;
    color: #9CA3AF;
    letter-spacing: 0.06em;
    margin-left: 4px;
}

/* Owner sub-picker (replaces legacy __owner block) */
.jgn-compose-zone__owner { display: none; } /* legacy block suppressed; replaced by __opt-line--owner */
.jgn-compose-zone__owner-connector { color: #C0C4C9; font-size: 11px; line-height: 1; }
.jgn-compose-zone__owner-search {
    height: 22px;
    padding: 0 9px;
    border: 0.5px solid #E5E7EB;
    border-radius: 999px;
    background: #FFFFFF;
    font-size: 10.5px;
    color: #1F2937;
    font-family: inherit;
    outline: none;
    width: 150px;
}
.jgn-compose-zone__owner-search:focus {
    border-color: #DD5100;
    box-shadow: 0 0 0 2px rgba(221, 81, 0, 0.10);
}

/* BU-218: ghost-card heights need to match the new compact-card baseline
   so grid rows do not stretch real cards via align-items: stretch. The
   trailing 'Combine more' ghost was 90px (sized for the old 110px cards);
   the placeholder/empty-state ghosts were 110px. All reduced to ~70px to
   match the new ~63-70px card range. The CTA empty-state ghost keeps its
   own larger min-height since it carries its own headline + icon. */
.compose-media-ghost--trail { min-height: 70px; }
.compose-media-ghost--placeholder { min-height: 70px; }
.compose-media-grid--empty { grid-auto-rows: minmax(70px, 1fr); }

/* ────────────────────────────────────────────────────────────────────────
   BU-228 (2026-05-23): click-to-expand Media card inline editor.
   When the user clicks a compact card it gains the .jgn-media-card--editing
   class and reveals a Voice + Stage editor surface inside the card. A Save
   button (Lucide unlock icon) sits top-right of the editor panel with a
   guaranteed >=32x32 hit area. Outside-click is captured by a transparent
   full-viewport backdrop (.jgn-media-card-edit-backdrop) using the same
   pattern as wf167-warning-backdrop.
   ──────────────────────────────────────────────────────────────────────── */

.jgn-media-card-edit-backdrop {
    position: fixed;
    inset: 0;
    z-index: 10400;
    background: rgba(15, 23, 42, 0.04);
    cursor: default;
}

.jgn-media-card--editing {
    /* Outline the editing card so it floats above the panel chrome and the
       backdrop's slight tint. Keep the orange accent already used for
       BU-128 selection so the affordance reads as "active surface". */
    position: relative;
    z-index: 10401;
    border-color: #DD5100 !important;
    box-shadow: 0 0 0 2px rgba(221, 81, 0, 0.18),
                0 10px 24px rgba(15, 23, 42, 0.12) !important;
    cursor: default;
}

.jgn-media-card--editing:hover {
    /* Suppress the lift-on-hover translate while editing so the editor
       surface stays still under the cursor. */
    transform: none;
}

/* BU-228 bullet 12 (2026-05-23): editor padding + gap tightened; header row
   removed entirely (was a wasted line for an unnecessary "EDIT VOICE & STAGE"
   title). Editor is now Voice row + Stage row, with the Save button absolutely
   pinned to the top-right of the panel via .jgn-media-card__editor-save.
   position: relative so the absolute child anchors inside. */
.jgn-media-card__editor {
    position: relative;
    margin-top: 6px;
    padding: 6px 36px 4px 0;
    border-top: 1px dashed #E5E7EB;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* BU-228 bullet 13 (2026-05-23): Save button collapsed to an icon-only 32x32
   square pinned absolute top-right. Drops the label + the wide rectangular
   shape — the unlocked-padlock affordance carries the meaning. Hit area
   stays >=32x32 per the walkthrough's tap-target rule. */
.jgn-media-card__editor-save {
    position: absolute;
    top: 4px;
    right: 0;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid #DD5100;
    background: #DD5100;
    color: #FFFFFF;
    border-radius: 8px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    transition: background-color 160ms ease-out, transform 160ms ease-out, box-shadow 160ms ease-out;
}
.jgn-media-card__editor-save:hover {
    background: #B84300;
    border-color: #B84300;
    box-shadow: 0 2px 8px rgba(221, 81, 0, 0.30);
}
.jgn-media-card__editor-save:focus-visible {
    outline: 2px solid #FFFFFF;
    outline-offset: 2px;
    box-shadow: 0 0 0 4px rgba(221, 81, 0, 0.45);
}
.jgn-media-card__editor-save:disabled {
    background: #F3F4F6;
    color: #9CA3AF;
    border-color: #E5E7EB;
    cursor: progress;
    box-shadow: none;
}
.jgn-media-card__editor-save .lucide {
    flex: 0 0 auto;
}

.jgn-media-card__editor-section {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.jgn-media-card__editor-label {
    font-size: 10px;
    font-weight: 600;
    color: #6B7280;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.jgn-media-card__editor-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    position: relative;
}

.jgn-media-card__voice-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    min-height: 26px;
    padding: 0 10px;
    border: 1px solid #E5E7EB;
    background: #FFFFFF;
    color: #111827;
    border-radius: 999px;
    cursor: pointer;
    font-size: 12px;
    font-weight: 500;
    transition: background-color 140ms ease-out, border-color 140ms ease-out, color 140ms ease-out;
}
.jgn-media-card__voice-chip:hover {
    background: #F9FAFB;
    border-color: #D1D5DB;
}
.jgn-media-card__voice-chip--selected {
    background: #FFF7F4;
    border-color: #FCD9C7;
    color: #B84300;
}
.jgn-media-card__voice-chip--selected:hover {
    background: #FFEEDF;
    border-color: #DD5100;
}
.jgn-media-card__voice-chip--add {
    color: #6B7280;
    border-style: dashed;
}
.jgn-media-card__voice-chip--add:hover {
    color: #DD5100;
    border-color: #DD5100;
    background: #FFF7F4;
}

.jgn-media-card__voice-picker {
    position: relative;
    display: inline-flex;
    flex-direction: column;
    gap: 0;
    min-width: 160px;
}

.jgn-media-card__voice-input {
    min-height: 28px;
    padding: 0 10px;
    border: 1px solid #DD5100;
    background: #FFFFFF;
    color: #111827;
    border-radius: 6px;
    font-size: 12px;
    width: 100%;
    box-shadow: 0 0 0 3px rgba(221, 81, 0, 0.12);
}
.jgn-media-card__voice-input:focus {
    outline: none;
    border-color: #DD5100;
    box-shadow: 0 0 0 3px rgba(221, 81, 0, 0.25);
}

.jgn-media-card__voice-menu {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 10402;
    max-height: 180px;
    overflow-y: auto;
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 6px;
    box-shadow: 0 6px 18px rgba(15, 23, 42, 0.12);
    display: flex;
    flex-direction: column;
    padding: 4px 0;
}

.jgn-media-card__voice-menu-item {
    text-align: left;
    padding: 6px 10px;
    border: 0;
    background: transparent;
    color: #111827;
    font-size: 12px;
    cursor: pointer;
}
.jgn-media-card__voice-menu-item:hover {
    background: #FFF7F4;
    color: #B84300;
}

.jgn-media-card__editor-stages {
    display: flex;
    gap: 6px;
}

/* BU-228 bullet 14 (2026-05-23): editor stage toggles are bigger than the
   compact card's 18px slots (24px) so they're easier to tap. Always render
   in their per-stage palette — .is-on shows filled (bg + border + colored
   letter); .is-off overrides background to transparent so the circle reads
   as outline-only with the palette-colored border + letter still visible. */
.jgn-media-card__stage-toggle {
    width: 24px;
    height: 24px;
    font-size: 12px;
    border-width: 1.25px;
    cursor: pointer;
    transition: transform 140ms ease-out, box-shadow 140ms ease-out;
}
.jgn-media-card__stage-toggle:hover {
    transform: translateY(-1px);
    box-shadow: 0 2px 6px rgba(15, 23, 42, 0.12);
}
.jgn-media-card__stage-toggle.is-on {
    border-color: rgba(15, 23, 42, 0.24);
}
.jgn-media-card__stage-toggle.is-off {
    background: transparent;
}
.jgn-media-card__stage-toggle:focus-visible {
    outline: 2px solid #DD5100;
    outline-offset: 2px;
}

.jgn-media-card__editor-error {
    margin-top: 4px;
    padding: 6px 8px;
    background: #FEF2F2;
    border: 1px solid #FCA5A5;
    color: #991B1B;
    border-radius: 6px;
    font-size: 12px;
}

