:root {
    --kcpc-ink: #1a1a2e;
    --kcpc-accent: #e94560;
    --kcpc-surface: #ffffff;
    --kcpc-bg: #f4f5f7;
    --kcpc-border: #dcdfe4;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
    background: var(--kcpc-bg);
    color: var(--kcpc-ink);
}

.auth-page {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
}

.auth-card {
    background: var(--kcpc-surface);
    border: 1px solid var(--kcpc-border);
    border-radius: 8px;
    padding: 2.5rem;
    width: 100%;
    max-width: 360px;
}

.auth-card h1 { margin: 0 0 0.25rem; font-size: 1.5rem; }
/* Logo/subtitle are centered above the form (their own thing, read top-down) while every form
   control below keeps the existing full-width/edge-to-edge behavior (form input {width:100%},
   .auth-card button[type="submit"] {width:100%}, .auth-forgot-row {justify-content:flex-end}) -
   all of them already share the form's own left/right edges via ordinary block flow, so centering
   the logo/subtitle needs no change to that layout, just to these two rules. */
.subtitle { margin: 0 0 1.5rem; color: #6b7280; font-size: 0.9rem; text-align: center; }

form label { display: block; margin-top: 1rem; font-size: 0.85rem; font-weight: 600; }
form input {
    width: 100%;
    padding: 0.55rem 0.6rem;
    margin-top: 0.25rem;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    font-size: 1rem;
}

button[type="submit"] {
    margin-top: 1.5rem;
    padding: 0.6rem;
    background: var(--kcpc-accent);
    color: #fff;
    border: none;
    border-radius: 6px;
    font-size: 1rem;
    cursor: pointer;
}
/* The login card is the one deliberate full-width button in the app - everywhere else (every
   authenticated page lives inside .app-main) gets compact + right-aligned instead, since a plain
   width:100% here used to silently stretch every submit button across the whole app to fill
   whatever container it sat in (.panel, .form-card, a bare <form>, ...). margin-left: auto on a
   width:auto block element is the standard CSS technique for right-aligning without a wrapper. */
.auth-card button[type="submit"] { width: 100%; }
.app-main button[type="submit"] {
    display: block;
    width: auto;
    margin-left: auto;
}

.alert-error {
    background: #fdecea;
    color: #b3261e;
    border: 1px solid #f5c2c0;
    border-radius: 6px;
    padding: 0.6rem 0.75rem;
    font-size: 0.85rem;
}

.admin-temp-password-box { display: flex; flex-direction: column; gap: 0.4rem; }
.admin-temp-password-label { font-weight: 600; font-size: 0.85rem; }
.admin-temp-password-row { display: flex; align-items: center; gap: 0.6rem; }
.admin-temp-password-value {
    font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
    font-size: 1.05rem; font-weight: 700; letter-spacing: 0.02em;
    background: rgba(0, 0, 0, 0.06); padding: 0.3rem 0.6rem; border-radius: 6px;
}

.auth-forgot-row { display: flex; justify-content: flex-end; margin-top: 0.5rem; }
.auth-forgot-link { font-size: 0.8rem; color: var(--kcpc-accent); text-decoration: none; }
.auth-forgot-link:hover { text-decoration: underline; }
.auth-back-link { display: block; margin-top: 1.25rem; font-size: 0.85rem; text-align: center; color: var(--kcpc-accent); text-decoration: none; }
.auth-back-link:hover { text-decoration: underline; }

/* Header refinement: logo + primary nav + notification/profile actions all now live in ONE row
   (nav.jsp nests <nav class="app-nav"> directly inside <header class="app-header">, in between
   the brand and the actions, instead of a separate nav strip below) so the whole header reads as
   one cohesive unit rather than two stacked bars. No space-between here on purpose: .app-nav is
   flex:1 (see below) and consumes exactly the remaining width between the logo and the actions,
   which is what naturally left-aligns the nav right after the logo and pins the actions to the
   far right - everything positioned by flex layout alone, no absolute positioning/offsets. */
.app-header {
    display: flex;
    align-items: center;
    gap: 1.75rem;
    padding: 0.7rem 1.5rem;
    background: var(--kcpc-ink);
    color: #fff;
}

.app-header .brand { font-weight: 700; display: flex; align-items: center; flex-shrink: 0; }
/* KCPC logo: a genuinely transparent-background asset (the original supplied artwork had an
   opaque white background, so an earlier revision wrapped it in a white "badge" chip to avoid a
   stray white rectangle on the dark header - now replaced by a transparent-background version of
   the same logo, supplied directly by the user, so it sits straight on the dark navy header with
   no chip needed; original KCPC brand colors/typography/"bandhani" script/"Since 1978" caption are
   unchanged). Fixed width + height:auto preserves the source's native aspect ratio at every
   viewport. Sized up from the old 28px-tall icon-in-the-corner treatment to give the logo real
   visual presence as the anchor of the single-row header. */
.brand-logo { display: block; width: 128px; height: auto; }
@media (max-width: 700px) {
    .brand-logo { width: 84px; }
}
/* Login screen: the login card's own background is already white, so the logo sits directly on
   it with no badge needed - just sized/spaced in the same slot the "KCPC Bandhani" heading used
   to occupy. Height stays comfortably under the source image's native 87px (no upscaling/blur). */
/* The current logo artwork is wide (2:1), so it is sized by WIDTH to fit the login card's content
   area (card max-width 360px minus its 2.5rem padding) - a fixed 200px height would make it 400px
   wide and overflow the card. */
.auth-logo { display: block; width: 100%; max-width: 280px; height: auto; margin: 0 auto 0.85rem; }

/* Header profile menu (replaces the old always-visible Sign out pill): notification bell +
   divider + avatar/name/chevron trigger, pinned to the far right because .app-nav (its flex:1
   sibling) consumes all the remaining space between the logo and this block - see .app-header's
   own comment above. */
.app-header-actions { display: flex; align-items: center; gap: 0.75rem; flex-shrink: 0; }
.app-header-notification { position: relative; }
.app-header-notification-btn {
    position: relative; display: inline-flex; align-items: center; justify-content: center;
    width: 2rem; height: 2rem; border-radius: 999px; font-size: 1rem; color: #fff; opacity: 0.85;
    background: none; border: none; cursor: pointer;
}
.app-header-notification-btn:hover, .app-header-notification-btn[aria-expanded="true"] { background: rgba(255, 255, 255, 0.1); opacity: 1; }
/* Only rendered when unreadNotificationCount > 0 (see nav.jsp) - no empty/zero badge ever shows. */
.app-header-notification-badge {
    position: absolute; top: -2px; right: -2px; min-width: 14px; height: 14px; border-radius: 999px;
    background: var(--kcpc-accent); color: #fff; font-size: 0.6rem; font-weight: 700; line-height: 14px;
    text-align: center; padding: 0 3px;
}
/* Dropdown: same shape/z-index as .app-header-profile-menu (both live in .app-header-actions,
   so they share the exact same "not inside a scrolling ancestor" reasoning - see that rule's own
   comment). Fixed width (not just max-width) since, unlike the profile menu, this one has real
   internal content (title/message/time) that needs consistent wrapping. */
.app-header-notification-menu {
    /* right:0 (not left:0) - the bell sits well to the LEFT of the header's own right edge (the
       profile trigger/divider are further right still), so a left-anchored dropdown would extend
       rightward off the edge of the viewport, exactly like the profile menu's own dropdown avoids
       by anchoring the same way. */
    position: absolute; top: 100%; right: 0; margin-top: 0.5rem; background: #fff; color: var(--kcpc-ink);
    border: 1px solid var(--kcpc-border); border-radius: 10px; box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);
    width: min(340px, calc(100vw - 2rem)); z-index: 1100; overflow: hidden;
}
.app-header-notification-menu-header {
    display: flex; align-items: center; justify-content: space-between; padding: 0.65rem 0.85rem;
    border-bottom: 1px solid var(--kcpc-border); font-weight: 700; font-size: 0.85rem;
}
.app-header-notification-mark-all {
    background: none; border: none; color: var(--kcpc-accent); font-size: 0.78rem; font-weight: 600;
    cursor: pointer; padding: 0; height: auto; width: auto;
}
.app-header-notification-list { max-height: 360px; overflow-y: auto; }
.app-header-notification-empty { padding: 1rem 0.85rem; margin: 0; }
.app-header-notification-item {
    display: flex; gap: 0.6rem; padding: 0.65rem 0.85rem; text-decoration: none; color: inherit;
    border-bottom: 1px solid var(--kcpc-border);
}
.app-header-notification-item:last-child { border-bottom: none; }
.app-header-notification-item:hover { background: #f9fafb; }
.app-header-notification-item-unread { background: #fef6f7; }
.app-header-notification-item-unread:hover { background: #fdecea; }
.app-header-notification-dot {
    flex-shrink: 0; width: 8px; height: 8px; border-radius: 999px; margin-top: 0.35rem;
    background: var(--kcpc-accent); visibility: hidden;
}
.app-header-notification-item-unread .app-header-notification-dot { visibility: visible; }
.app-header-notification-body { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.app-header-notification-title { font-weight: 700; font-size: 0.82rem; }
.app-header-notification-message { font-size: 0.8rem; color: var(--kcpc-ink); }
.app-header-notification-time { font-size: 0.72rem; color: #9ca3af; }
.app-header-notification-view-all {
    display: block; text-align: center; padding: 0.6rem; font-size: 0.82rem; font-weight: 600;
    color: var(--kcpc-accent); text-decoration: none; border-top: 1px solid var(--kcpc-border);
}
.app-header-notification-view-all:hover { background: #f9fafb; }
@media (max-width: 700px) {
    .app-header-notification-menu { width: calc(100vw - 2rem); }
}
.app-header-divider { width: 1px; height: 1.4rem; background: rgba(255, 255, 255, 0.2); }
.app-header-profile { position: relative; }
.app-header-profile-trigger {
    display: inline-flex; align-items: center; gap: 0.55rem; background: none; border: none;
    color: #fff; cursor: pointer; padding: 0.3rem 0.6rem; border-radius: 999px; font-size: 0.85rem;
    font-weight: 600; width: auto; height: auto;
}
.app-header-profile-trigger:hover, .app-header-profile-trigger[aria-expanded="true"] { background: rgba(255, 255, 255, 0.1); }
.app-header-avatar {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 1.9rem; height: 1.9rem; border-radius: 999px; background: var(--kcpc-accent); color: #fff;
    font-weight: 700; font-size: 0.7rem;
}
/* Name + Business Role stacked (e.g. "KCPC CEO" / "CEO") - businessRoleName is an existing
   MvcNavigationAdvice attribute already used elsewhere for nav visibility, reused here purely for
   display; not a new backend field. */
.app-header-profile-text { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.2; }
.app-header-profile-name { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-header-profile-role { font-size: 0.68rem; font-weight: 500; opacity: 0.75; }
.app-header-profile-chevron { font-size: 0.65rem; opacity: 0.85; }
/* Dropdown: same visual language as .stage-comment-menu-dropdown elsewhere (white surface, subtle
   border+shadow, high z-index) - simpler here since .app-header is never inside a scrolling/
   overflow-clipped ancestor, so no "portal" reparenting trick is needed the way that one requires.
   max-width caps against the viewport (not just a fixed width) so it can never overflow on a
   narrow screen even though it's right-anchored to a trigger that stays near the edge. */
.app-header-profile-menu {
    position: absolute; top: 100%; right: 0; margin-top: 0.5rem; background: #fff; color: var(--kcpc-ink);
    border: 1px solid var(--kcpc-border); border-radius: 10px; box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);
    min-width: 220px; max-width: min(280px, calc(100vw - 2rem)); z-index: 1100; padding: 0.5rem;
}
.app-header-profile-menu-identity { display: flex; align-items: center; gap: 0.65rem; padding: 0.4rem; }
.app-header-profile-menu-details { display: flex; flex-direction: column; min-width: 0; }
.app-header-profile-menu-name { font-weight: 700; font-size: 0.88rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.app-header-profile-menu-email { font-size: 0.78rem; color: #6b7280; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.app-header-profile-menu-divider { height: 1px; background: var(--kcpc-border); margin: 0.4rem 0; }
.app-header-profile-menu-signout {
    display: flex; align-items: center; gap: 0.4rem; width: 100%; background: none; border: none;
    text-align: left; padding: 0.5rem 0.4rem; font-size: 0.85rem; font-weight: 600; color: var(--kcpc-accent);
    cursor: pointer; border-radius: 6px; height: auto;
}
.app-header-profile-menu-signout:hover { background: #fdecea; }
.app-header-profile-menu-help {
    display: flex; align-items: center; gap: 0.4rem; padding: 0.5rem 0.4rem; font-size: 0.85rem; font-weight: 600;
    color: var(--kcpc-ink); text-decoration: none; border-radius: 6px;
}
.app-header-profile-menu-help:hover { background: var(--kcpc-bg); }
/* Smaller screens: drop the name text (avatar+chevron alone stay clickable/identifiable) so the
   trigger can never force .app-header-actions wider than the viewport - the dropdown itself
   already caps its own width above regardless of breakpoint. */
@media (max-width: 700px) {
    .app-header-profile-text { display: none; }
}

/* ENG-057: Sign out - red is otherwise reserved for primary/destructive workflow actions in this
   app, and ending your session is thematically a fit; a compact pill instead of the old underlined
   text link. */
.link-button {
    background: var(--kcpc-accent);
    border: none;
    color: #fff;
    border-radius: 999px;
    padding: 0.4rem 1rem;
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 600;
    width: auto;
}
.link-button:hover { opacity: 0.92; }

.app-main { padding: 2rem; }
.muted { color: #6b7280; }

.header-link {
    color: #fff;
    text-decoration: none;
    margin-right: 1rem;
    font-size: 0.9rem;
}
.header-link:hover { text-decoration: underline; }
.logout-form { margin-left: auto; }

.form-card {
    background: var(--kcpc-surface);
    border: 1px solid var(--kcpc-border);
    border-radius: 8px;
    padding: 1.5rem;
    max-width: 480px;
}
.form-card label { display: block; margin-top: 1rem; font-weight: 600; font-size: 0.85rem; }
.form-card input, .form-card textarea {
    width: 100%;
    padding: 0.5rem;
    margin-top: 0.25rem;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    font-size: 0.95rem;
}
.form-card button {
    margin-top: 1.25rem;
    padding: 0.5rem 1.25rem;
    background: var(--kcpc-accent);
    color: #fff;
    border: none;
    border-radius: 6px;
    cursor: pointer;
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--kcpc-surface);
    border: 1px solid var(--kcpc-border);
}
/* Planned Outputs table sits directly under the Planning Details form (no heading between them
   anymore) - a little breathing room so the two don't visually run together. */
#planned-outputs-table { margin-top: 1.5rem; }
.data-table th, .data-table td {
    text-align: left;
    padding: 0.6rem 0.75rem;
    border-bottom: 1px solid var(--kcpc-border);
    font-size: 0.9rem;
}
.data-table th { background: #f9fafb; }

.hidden { display: none !important; }

.status-badge {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background: #eef2ff;
    color: #3730a3;
    font-size: 0.75rem;
    font-weight: 600;
}

/* ENG-055: Publishing execution checklist status pills - same shape as .status-badge, own colors. */
.status-pill {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
}
.status-pill.status-pending { background: #fef3c7; color: #92400e; }
.status-pill.status-completed { background: #dcfce7; color: #166534; }
/* ENG-090: Skip Stage - a distinct, muted/neutral outcome (neither Approved-green nor
   Rework-red), same gray already used by .status-pill.status-neutral below. */
.status-pill.status-skipped { background: #e5e7eb; color: #374151; }
#publishing-checklist-table .publishing-checklist-evidence { width: 100%; min-width: 160px; }
#publishing-checklist-table td, #publishing-checklist-table th { vertical-align: middle; }

/* ENG-057: My Work page - status/priority pills, the employee summary card, the count badge next
   to each section heading, and the outline "View Details" action link (blue, not red - red on
   this app is reserved for primary/destructive workflow actions, and View Details is neither). */
.status-pill.status-assigned { background: #dbeafe; color: #1d4ed8; }
.status-pill.status-inprogress { background: #d1fae5; color: #047857; }
.status-pill.status-inreview { background: #ffedd5; color: #c2410c; }
.status-pill.status-needschanges { background: #fee2e2; color: #b91c1c; }
/* ENG-059: My Ideas - "Under Review" gets its own purple (distinct from the blue "Assigned"/
   "In Review" pills above, which mean something different on My Work). ENG-088's Idea Queue asks
   for "Under Review -> blue" specifically, which would contradict that deliberate distinction if
   changed globally - .idea-queue-table below scopes the blue override to just that table instead
   of touching My Ideas' own established purple. */
.status-pill.status-underreview { background: #ede9fe; color: #6d28d9; }
/* ENG-088: Idea Queue - "Reopened" gets its own purple (the same shade "Under Review" used to be
   the sole owner of), now distinguishing it from Under Review's blue in that table. */
.status-pill.status-reopened { background: #ede9fe; color: #6d28d9; }
.status-pill.status-rejected { background: #fee2e2; color: #991b1b; }
/* ENG-061: My Ideas - "Retained" gets its own soft amber, distinct from Rejected's red. */
.status-pill.status-retained { background: #fef3c7; color: #92400e; }
/* ENG-067: My Shoots shows the raw WorkflowStatus name (not a per-stage friendly relabel, since a
   Model isn't executing a specific stage) - a single neutral gray pill covers every status value. */
.status-pill.status-neutral { background: #e5e7eb; color: #374151; }
/* BR-063 Hold/Resume: same amber used by .flag-hold (Pipeline/Content Detail's own On Hold badge)
   - a supplementary badge alongside the real status pill, never replacing it. */
.status-pill.status-onhold { background: #fff4e5; color: #92400e; margin-left: 0.3rem; }

/* BR-063 Hold/Resume: the prominent on-hold information block on Shoot/Edit/Publish Task Detail
   (request section 9) - same amber family as .flag-hold/.status-onhold, just a full block instead
   of a small pill, since this is the primary thing the page needs to communicate while held. */
.hold-info-block {
    background: #fff8ec; border: 1px solid #fde3b8; border-radius: 8px;
    padding: 0.9rem 1.1rem; margin: 0.5rem 0;
}
.hold-info-block p { margin: 0.3rem 0; font-size: 0.88rem; color: #78350f; }
.hold-info-title { font-weight: 700; font-size: 0.95rem; margin-bottom: 0.5rem; }

.priority-pill { display: inline-block; padding: 0.15rem 0.5rem; border-radius: 999px; font-size: 0.72rem; font-weight: 700; }
.priority-pill.priority-high { background: #fee2e2; color: #b91c1c; }
.priority-pill.priority-medium { background: #ffedd5; color: #c2410c; }
.priority-pill.priority-low { background: #dbeafe; color: #1d4ed8; }

/* Permission-driven My Work: stage badges, independent of the row's own Business Role/executor
   label - distinguishes SHOOT/EDIT/PUBLISHING/REPOST rows in the combined "All" view. */
.stage-badge { display: inline-block; padding: 0.15rem 0.55rem; border-radius: 999px; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.02em; margin-right: 0.4rem; }
.stage-badge.stage-shoot { background: #dbeafe; color: #1d4ed8; }
.stage-badge.stage-edit { background: #ede9fe; color: #6d28d9; }
.stage-badge.stage-publish { background: #dcfce7; color: #166534; }
.stage-badge.stage-repost { background: #ffedd5; color: #c2410c; }

.my-work-stage-tabs { display: flex; gap: 0.5rem; margin: 1rem 0; border-bottom: 1px solid #e5e7eb; }
/* .my-work-stage-tab-link is the same tab, as a navigation link: an Execution tab whose target is
   another page (Publication Links & Performance) rather than a panel on this one. Same typography,
   padding and active underline - it only adds the anchor resets a <button> does not need. */
.my-work-stage-tab,
.my-work-stage-tab-link { background: none; border: none; padding: 0.55rem 1rem; font-weight: 600; font-size: 0.9rem; color: #6b7280; cursor: pointer; border-bottom: 2px solid transparent; }
.my-work-stage-tab-link { text-decoration: none; display: inline-block; }
.my-work-stage-tab.active,
.my-work-stage-tab-link.active { color: #111827; border-bottom-color: #2563eb; }
.my-work-stage-panel.hidden { display: none; }

.execution-blocked-note { display: inline-block; padding: 0.3rem 0.6rem; border-radius: 6px; background: #fee2e2; color: #991b1b; font-size: 0.78rem; font-weight: 600; }

.my-work-mode-tabs { display: flex; gap: 0.5rem; margin: 1rem 0 0.25rem; border-bottom: 2px solid #e5e7eb; }
.my-work-mode-tab { background: none; border: none; padding: 0.6rem 1.1rem; font-weight: 700; font-size: 0.95rem; color: #6b7280; cursor: pointer; border-bottom: 3px solid transparent; }
.my-work-mode-tab.active { color: #111827; border-bottom-color: #2563eb; }
.my-work-mode-panel.hidden { display: none; }
.assignment-mgmt-tab { background: none; border: none; padding: 0.55rem 1rem; font-weight: 600; font-size: 0.9rem; color: #6b7280; cursor: pointer; border-bottom: 2px solid transparent; }
.assignment-mgmt-tab.active { color: #111827; border-bottom-color: #2563eb; }
.assignment-mgmt-panel.hidden { display: none; }

.lead-badge {
    display: inline-block;
    margin-left: 0.35rem;
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    background: #d1fae5;
    color: #047857;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
}

.count-badge {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05rem 0.5rem;
    border-radius: 999px;
    background: #eef2ff;
    color: #3730a3;
    font-size: 0.78rem;
    font-weight: 700;
    vertical-align: middle;
}

.drive-link { color: #1d4ed8; text-decoration: none; font-size: 0.85rem; white-space: nowrap; }
.drive-link:hover { text-decoration: underline; }

.btn-outline {
    display: inline-block;
    background: transparent;
    color: #1d4ed8;
    border: 1px solid #93c5fd;
    border-radius: 6px;
    padding: 0.35rem 0.8rem;
    font-size: 0.8rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    width: auto;
}
.btn-outline:hover { background: #eff6ff; }

.page-header-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.5rem;
}
.page-header-row h1 { margin-bottom: 0.2rem; }
.page-header-row-actions { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }

/* "View all notifications" page - same unread dot/highlight language as the header dropdown
   (.app-header-notification-item*), just full-width rows inside a plain .panel instead of a
   fixed-width dropdown list. */
.notification-row {
    display: flex; gap: 0.75rem; align-items: flex-start; padding: 0.85rem 0;
    border-bottom: 1px solid var(--kcpc-border);
}
.notification-row:last-child { border-bottom: none; }
.notification-row-unread { background: #fef6f7; margin: 0 -1rem; padding: 0.85rem 1rem; }
.notification-row-dot {
    flex-shrink: 0; width: 9px; height: 9px; border-radius: 999px; margin-top: 0.4rem;
    background: var(--kcpc-accent); visibility: hidden;
}
.notification-row-unread .notification-row-dot { visibility: visible; }
.notification-row-body { flex: 1; min-width: 0; }
.notification-row-title { font-weight: 700; font-size: 0.92rem; color: var(--kcpc-ink); text-decoration: none; }
.notification-row-title:hover { text-decoration: underline; }
.notification-row-message { margin: 0.2rem 0 0; font-size: 0.85rem; color: var(--kcpc-ink); }
.notification-row-time { margin: 0.25rem 0 0; font-size: 0.75rem; }
.notification-row-mark-read {
    background: none; border: none; color: var(--kcpc-accent); font-size: 0.78rem; font-weight: 600;
    cursor: pointer; padding: 0; height: auto; width: auto; white-space: nowrap;
}

.employee-summary-card {
    display: flex;
    gap: 1.5rem;
    align-items: center;
    background: var(--kcpc-surface);
    border: 1px solid var(--kcpc-border);
    border-radius: 8px;
    padding: 0.75rem 1.25rem;
}
/* Shared label/value pair styling - the employee-summary-card (My Work) and the Shoot panel's
   Content Summary block (deliverable-detail.jsp, ENG-058) both use this same small-caps-label +
   bold-value pattern. */
.summary-field-label { font-size: 0.72rem; color: #6b7280; text-transform: uppercase; letter-spacing: 0.02em; }
.summary-field-value { font-size: 0.95rem; font-weight: 700; color: var(--kcpc-ink); }

/* ENG-058: Shoot panel's read-only Content Summary - Content ID/Name/Priority/Planned Shoot Date/
   Model(s)/Shoot Lead/Drive Link/My Status, all sourced from data already on the page, laid out as
   a compact grid instead of a form (nothing here is editable). */
.content-summary-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.9rem 1.5rem;
    margin: 0.75rem 0 1.25rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--kcpc-border);
}
@media (max-width: 900px) {
    .content-summary-grid { grid-template-columns: repeat(2, 1fr); }
}
.content-summary-grid .summary-field-value { display: block; margin-top: 0.15rem; }

.my-work-table-wrapper .view-all-link { display: block; text-align: center; padding: 0.75rem; font-size: 0.85rem; }

/* ENG-058: Cameraperson KPI cards, tabs, and the "delayed" status pill variant (own color, not
   reused from Needs Changes - a delayed-but-otherwise-fine task and a rework request are different
   problems and shouldn't look identical). */
.kpi-cards {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
    margin-bottom: 1.5rem;
}
@media (max-width: 900px) {
    .kpi-cards { grid-template-columns: repeat(2, 1fr); }
}
/* ENG-059: My Ideas has 5 KPI cards, not 4 - its own column count rather than overloading .kpi-cards. */
.kpi-cards.kpi-cards-5 { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 1100px) {
    .kpi-cards.kpi-cards-5 { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 700px) {
    .kpi-cards.kpi-cards-5 { grid-template-columns: repeat(2, 1fr); }
}
/* ENG-067: My Shoots has only 2 KPI cards (Upcoming Shoots, Next Shoot). */
.kpi-cards.kpi-cards-2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 600px) {
    .kpi-cards.kpi-cards-2 { grid-template-columns: 1fr; }
}
/* KPI Dashboard -> Performance: the Publication Links & Performance task group has 6 cards. */
.kpi-cards.kpi-cards-6 { grid-template-columns: repeat(6, 1fr); }
@media (max-width: 1200px) {
    .kpi-cards.kpi-cards-6 { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 700px) {
    .kpi-cards.kpi-cards-6 { grid-template-columns: repeat(2, 1fr); }
}
/* The counting UNIT under each of those cards - content items, links and obligations are different
   entities, so every card says which one it counts and they are never read as one total. */
.kpi-card-unit { font-size: 0.72rem; color: #6b7280; letter-spacing: 0.02em; }
/* ENG-068: Publisher's My Work has 3 KPI cards, not 4 (no Rework KPI - Publishing has no review gate). */
.kpi-cards.kpi-cards-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 700px) {
    .kpi-cards.kpi-cards-3 { grid-template-columns: 1fr; }
}
.kpi-card {
    display: flex;
    gap: 0.85rem;
    align-items: flex-start;
    background: var(--kcpc-surface);
    border: 1px solid var(--kcpc-border);
    border-radius: 8px;
    padding: 1rem 1.1rem;
}
/* A KPI card that is itself a link (Publication Links & Performance -> Completed, which opens the
   Completed Tasks sub-tab). Keeps the card's own typography instead of inheriting anchor styling,
   and shows it is interactive on hover/focus - only used where the click actually goes somewhere. */
.kpi-card-link { text-decoration: none; color: inherit; cursor: pointer; transition: border-color 0.15s ease; }
.kpi-card-link:hover { border-color: var(--kcpc-accent); }
.kpi-card-link:focus-visible { outline: 2px solid var(--kcpc-accent); outline-offset: 2px; }
.kpi-card-icon {
    flex-shrink: 0;
    width: 2.4rem;
    height: 2.4rem;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
}
.kpi-card.kpi-active .kpi-card-icon { background: #dbeafe; }
.kpi-card.kpi-rework .kpi-card-icon { background: #ffedd5; }
.kpi-card.kpi-delayed .kpi-card-icon { background: #fee2e2; }
.kpi-card.kpi-completed .kpi-card-icon { background: #d1fae5; }
.kpi-card.kpi-underreview .kpi-card-icon { background: #ede9fe; }
.kpi-card.kpi-rejected .kpi-card-icon { background: #fee2e2; }
.kpi-card.kpi-retained .kpi-card-icon { background: #fef3c7; }
.kpi-card-body { display: flex; flex-direction: column; }
.kpi-card-title-row { display: flex; align-items: baseline; gap: 0.5rem; }
.kpi-card-title { font-weight: 700; font-size: 0.9rem; color: var(--kcpc-ink); }
.kpi-card-count { font-size: 1.3rem; font-weight: 800; }
.kpi-card.kpi-active .kpi-card-count { color: #1d4ed8; }
.kpi-card.kpi-rework .kpi-card-count { color: #c2410c; }
.kpi-card.kpi-delayed .kpi-card-count { color: #b91c1c; }
.kpi-card.kpi-completed .kpi-card-count { color: #047857; }
.kpi-card.kpi-underreview .kpi-card-count { color: #6d28d9; }
.kpi-card.kpi-rejected .kpi-card-count { color: #991b1b; }
.kpi-card.kpi-retained .kpi-card-count { color: #92400e; }
.kpi-card-subtitle { font-size: 0.78rem; color: #6b7280; margin-top: 0.1rem; }
/* My Performance: "6.5 / 8.0" style KPI cards - the "/ max" suffix is de-emphasized so the earned
   value (already colored/sized by .kpi-card-count above) stays the visual focus. */
.kpi-card-count-max { font-size: 0.9rem; font-weight: 600; color: #6b7280; }

.my-work-tabs {
    display: flex;
    gap: 1.5rem;
    border-bottom: 1px solid var(--kcpc-border);
    margin-bottom: 1.25rem;
}
button.my-work-tab {
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    padding: 0.6rem 0.1rem;
    font-size: 0.9rem;
    font-weight: 600;
    color: #6b7280;
    cursor: pointer;
    width: auto;
}
button.my-work-tab.active { color: #1d4ed8; border-bottom-color: #1d4ed8; }
.my-work-tab-panel.hidden { display: none; }

.status-pill.status-delayed { background: #fee2e2; color: #b91c1c; }

/* My Work stage tabs (Shoot/Edit/Publishing only): Planned Date cell highlight for an
   already-delayed task (item.delayed) - same light red/pink as .status-delayed, but scoped to
   just the date cell, never the whole row. */
.planned-date-delayed { background: #fee2e2; }

/* ENG-059: My Ideas - search/filter bar (plain GET query params, full-page reload - no client-side
   table-filtering pattern exists anywhere else in this app to reuse) and pagination. */
.my-ideas-filters {
    display: flex;
    align-items: end;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}
.my-ideas-filters .filter-field { display: flex; flex-direction: column; gap: 0.3rem; flex: 0 0 auto; }
.my-ideas-filters .filter-field.filter-field-search { flex: 1 1 220px; }
.my-ideas-filters label { font-size: 0.78rem; font-weight: 600; color: #6b7280; }
.my-ideas-search-input {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    font-size: 0.9rem;
}
.my-ideas-filters select {
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    font-size: 0.9rem;
    min-width: 150px;
}
.my-ideas-filters .btn-outline { height: 2.35rem; display: inline-flex; align-items: center; }

.idea-description-hint { font-size: 0.8rem; color: #6b7280; margin-top: 0.1rem; }

.pagination {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 1rem;
    font-size: 0.85rem;
    color: #6b7280;
}
.pagination-controls { display: flex; gap: 0.35rem; }
.pagination-controls a, .pagination-controls span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    height: 2rem;
    padding: 0 0.4rem;
    border-radius: 6px;
    border: 1px solid var(--kcpc-border);
    text-decoration: none;
    color: var(--kcpc-ink);
    font-size: 0.85rem;
}
.pagination-controls a:hover { background: #f4f5f7; }
.pagination-controls .page-current { background: #1d4ed8; color: #fff; border-color: #1d4ed8; font-weight: 700; }
.pagination-controls .page-disabled { color: #d1d5db; }

.inline-decision-form {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin-top: 0.5rem;
    padding: 0.75rem;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    max-width: 320px;
}
.inline-decision-form label { font-size: 0.8rem; font-weight: 600; }
.inline-decision-form select, .inline-decision-form input {
    width: 100%;
    padding: 0.35rem;
    margin-top: 0.15rem;
}
.inline-decision-form button {
    margin-top: 0.4rem;
    padding: 0.4rem 0.9rem;
    background: var(--kcpc-accent);
    color: #fff;
    border: none;
    border-radius: 6px;
    cursor: pointer;
}

.alert-success {
    background: #eafaf0;
    color: #14633d;
    border: 1px solid #b7e4c7;
    border-radius: 6px;
    padding: 0.6rem 0.75rem;
    font-size: 0.85rem;
    margin-bottom: 1rem;
}
.alert-error { margin-bottom: 1rem; }

/* Neutral/informational flash (e.g. "retry accepted" - distinct from a success/failure outcome,
   which is not yet known at the moment the request was accepted). */
.alert-info {
    background: #eff6ff;
    color: #1d4ed8;
    border: 1px solid #bfdbfe;
    border-radius: 6px;
    padding: 0.6rem 0.75rem;
    font-size: 0.85rem;
    margin-bottom: 1rem;
}

/* ENG-082 (visual polish pass): a full CEO/CEO_OWNER nav can carry 12 links (Content Pipeline
   through Publishing Catalogue) - flex-wrap used to drop the tail end (e.g. "Publishing Catalogue")
   onto a visually broken second row once the window narrowed even slightly. Kept as one compact,
   horizontally-scrollable row instead: every role-authorized link stays reachable (none hidden),
   tighter gap/padding buys back some room before scrolling is ever needed, and the scrollbar itself
   is unobtrusive (thin, only appears on the nav's own strip) rather than removed outright.
   Header refinement: nav now lives inside .app-header itself (see nav.jsp) rather than a separate
   bar below it, so it no longer carries its own background/vertical padding - flex:1 + min-width:0
   makes it consume exactly the space left over between the logo and the notification/profile
   actions, shrinking (and internally scrolling) before it can ever force the header to overflow
   horizontally. */
.app-nav {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    flex: 1 1 auto;
    min-width: 0;
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: thin;
}
.app-nav a {
    display: inline-flex;
    align-items: center;
    color: #cbd5e1;
    text-decoration: none;
    font-size: 0.85rem;
    font-weight: 500;
    padding: 0.45rem 0.7rem;
    border-radius: 6px;
    white-space: nowrap;
    flex: none;
    border-bottom: 2px solid transparent;
}
.app-nav a:hover { background: rgba(255,255,255,0.1); color: #fff; }
/* Active-state VISUAL treatment only (a red underline instead of the old solid pill) - the
   underlying "which link is active" logic in nav.jsp (currentPath-driven, per link) is completely
   unchanged, still the same .active class on the same conditions. */
.app-nav a.active { background: none; color: #fff; border-bottom-color: var(--kcpc-accent); }

.flag-chip {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    margin-left: 0.35rem;
}
.flag-delayed { background: #fdecea; color: #b3261e; }
.flag-hold { background: #fff4e5; color: #92400e; }
/* Repost: a parallel-state chip like .flag-hold, in a violet nobody else uses, so "reposting"
   reads as clearly distinct from the amber hold state and from every stage colour. */
.flag-repost { background: #ede9fe; color: #5b21b6; }
/* Content Pipeline: active rework cycle (PipelineRow#inRework), shown under the real status. */
.flag-rework { background: #ffedd5; color: #9a3412; }

.status-strip { display: flex; align-items: center; gap: 0.4rem; margin: 0.25rem 0 1.25rem; }

.panel {
    background: var(--kcpc-surface);
    border: 1px solid var(--kcpc-border);
    border-radius: 8px;
    padding: 1.25rem 1.5rem;
    margin-bottom: 1.25rem;
    max-width: 760px;
}
/* Deliverable Detail: use the full available width instead of a narrow fixed column, while
   keeping individual fields a readable size rather than stretching a single input full-screen. */
.app-main-wide .panel { max-width: none; }
.app-main-wide .kpi-grid { max-width: none; }
.app-main-wide .panel .field-row { max-width: 900px; }
.app-main-wide .panel > form > label:not(.form-grid label) > input:not([type="checkbox"]),
.app-main-wide .panel > form > label:not(.form-grid label) > select,
.app-main-wide .panel > form > label:not(.form-grid label) > textarea { max-width: 500px; }

/* Multi-column field grid (Planning Workspace etc.): 3 columns on desktop, 2 on tablet, 1 on
   mobile, instead of every field stacking one-per-row down a long narrow column. */
.form-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem 1.25rem;
    margin-top: 0.75rem;
}
.form-grid label { margin-top: 0; }
.form-grid .grid-span-all { grid-column: 1 / -1; }
.form-grid .checkbox-inline { display: inline-flex; align-items: center; gap: 0.3rem; font-weight: 400; margin-left: 0.75rem; }
.form-grid .checkbox-inline input { width: auto; }
@media (max-width: 900px) {
    .form-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
    .form-grid { grid-template-columns: 1fr; }
}

/* ENG-051: inline validation - a missing/invalid field gets a red outline and a message right
   under it instead of a full-page redirect that discards the rest of the form (planning-submit.js). */
.field-error { margin-top: 4px; font-size: 12px; color: #dc2626; }
.input-error { border-color: #dc2626; }

/* Overview panel: read-only fields (Priority, Dates, Drive Link, Cameraperson(s)/Editor(s), ...)
   in the same 3-column grid as the Planning forms, instead of one field per stacked line. */
.overview-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem 1.25rem;
}
.overview-grid p { margin: 0; }
@media (max-width: 900px) {
    .overview-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
    .overview-grid { grid-template-columns: 1fr; }
}

/* Compact, right-aligned action button (Save Plan, Submit for Planning Review) instead of a
   full-width bar. */
.btn-row { margin-top: 1rem; text-align: right; }
.btn-row button[type="submit"] { width: auto; margin-top: 0; padding: 0.6rem 1.75rem; }

/* Inline dropdown + action button (Cameraperson Assignment etc.) instead of the select taking a
   full row on its own with the button stacked below it. */
.assign-row { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; max-width: 500px; }
.assign-row select { width: auto; flex: 1; min-width: 220px; }
.assign-row button { width: auto; margin-top: 0; }
.panel h2 { margin-top: 0; font-size: 1.05rem; }
.panel h3 { font-size: 0.95rem; margin-bottom: 0.4rem; }
.panel label { font-weight: 600; font-size: 0.85rem; }
.panel input, .panel select, .panel textarea {
    width: 100%;
    padding: 0.45rem;
    margin-top: 0.25rem;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    font-size: 0.9rem;
}
.panel button, .action-form button {
    padding: 0.5rem 1.1rem;
    background: var(--kcpc-accent);
    color: #fff;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.9rem;
}
.panel button.secondary, .action-form button.secondary { background: #4b5563; }
.panel button:disabled, .action-form button:disabled { background: #9ca3af; cursor: not-allowed; }
button[type="submit"].success { background: #1a7f4b; }
.field-row { display: flex; gap: 1rem; }
.field-row > div { flex: 1; }
.checklist-item { font-size: 0.85rem; margin: 0.15rem 0; }
.checklist-ok { color: #14633d; }
.checklist-missing { color: #b3261e; }

.actions-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.25rem;
}
.actions-bar details {
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    background: var(--kcpc-surface);
}
.actions-bar summary {
    padding: 0.4rem 0.8rem;
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 600;
}
.actions-bar .action-form {
    padding: 0.75rem 0.9rem 0.9rem;
    min-width: 260px;
}

.note-box {
    background: #eef2ff;
    border: 1px solid #c7d2fe;
    color: #3730a3;
    border-radius: 6px;
    padding: 0.6rem 0.75rem;
    font-size: 0.82rem;
    margin: 0.6rem 0;
}

/* ENG-058: Rework Feedback - distinct from .note-box (informational, blue) since this is corrective
   guidance the employee actually needs to act on, matching the Needs Changes/rework color used
   elsewhere on this page. */
.rework-feedback-box {
    background: #fff7ed;
    border: 1px solid #fed7aa;
    color: #9a3412;
    border-radius: 6px;
    padding: 0.75rem 1rem;
    margin: 0.75rem 0 1.25rem;
}
.rework-feedback-box strong { display: block; font-size: 0.85rem; margin-bottom: 0.3rem; }
.rework-feedback-box p { margin: 0; font-size: 0.9rem; white-space: pre-wrap; }

.timeline { list-style: none; margin: 0; padding: 0; max-width: 760px; }
.timeline li {
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--kcpc-border);
    font-size: 0.85rem;
}
.timeline .ts { color: #6b7280; margin-right: 0.5rem; }
/* ENG-091: a stage excluded at Idea Review planning time - a plain note, not a real transition. */
.timeline li.timeline-skipped { color: #6b7280; font-style: italic; }

.filter-bar { margin-bottom: 1rem; font-size: 0.85rem; }
.filter-bar select, .filter-bar input { margin-right: 0.75rem; padding: 0.3rem; }

.kpi-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0.9rem; max-width: 1100px; }
.kpi-tile {
    background: var(--kcpc-surface);
    border: 1px solid var(--kcpc-border);
    border-radius: 8px;
    padding: 1rem;
}
.kpi-tile .kpi-value { font-size: 1.6rem; font-weight: 700; }
.kpi-tile .kpi-label { font-size: 0.78rem; color: #6b7280; }
.kpi-tile .kpi-na { color: #9ca3af; font-style: italic; }

/* CEO Content Pipeline 18-column dashboard */
/* ENG-079: no max-height/vertical overflow here on purpose - a capped height + overflow:auto
   would create an INTERNAL vertical scrollbar for the table once 10 rows exceed that height,
   which is exactly what this table must never do. Only overflow-x is scrollable (for the wide
   lifecycle columns); the table's own height is left to flow naturally in the page, so 10 compact
   rows fit on one normal viewport without a nested scrollbar - if content ever does exceed the
   viewport, the PAGE scrolls, not this box. */
.pipeline-scroll {
    position: relative;
    overflow-x: auto;
    overflow-y: visible;
    border: 1px solid var(--kcpc-border);
    border-radius: 8px;
}
/* ENG-081: AJAX loading state - keeps the current table visible (just dimmed) instead of ever
   flashing blank while pipeline-dashboard.js's fetch() is in flight, plus a small spinner in the
   table's own corner. pointer-events:none also blocks a second click on the (still-visible, about
   to be replaced) old content while a request is already in progress. */
.pipeline-scroll.pipeline-loading .pipeline-table {
    opacity: 0.5;
    pointer-events: none;
    transition: opacity 0.15s ease;
}
.pipeline-scroll.pipeline-loading::after {
    content: '';
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    width: 18px;
    height: 18px;
    border: 2px solid var(--kcpc-border);
    border-top-color: var(--kcpc-accent);
    border-radius: 50%;
    animation: pipeline-spin 0.6s linear infinite;
    z-index: 5;
}
@keyframes pipeline-spin {
    to { transform: rotate(360deg); }
}
.pipeline-table {
    width: max-content;
    min-width: 100%;
    /* border-collapse: collapse breaks position:sticky for a cell that must stick in BOTH
       directions at once (this table's Content ID header needs sticky-top, as part of the
       header row, AND sticky-left, as the pinned column) - a well-known Chromium/WebKit bug.
       Plain data cells only need one sticky axis so they were unaffected; separate + zero
       spacing keeps the same collapsed visual look while fixing the header cell. */
    border-collapse: separate;
    border-spacing: 0;
    background: var(--kcpc-surface);
}
.pipeline-table th, .pipeline-table td {
    text-align: left;
    padding: 0.35rem 0.65rem;
    border-bottom: 1px solid var(--kcpc-border);
    font-size: 0.85rem;
    line-height: 1.3;
    vertical-align: middle;
    white-space: nowrap;
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pipeline-table th {
    background: #f9fafb;
    position: sticky;
    top: 0;
    z-index: 2;
    font-weight: 700;
    font-size: 0.76rem;
    line-height: 1.3;
    color: #475569;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
/* ENG-074: single flat header row (no grouped pastel header row above it), so Content ID only
   ever needs to stick on ONE axis at a time relative to any OTHER rule (top from the generic
   th rule above, left from this one) - a simpler, more reliable combination than the two-tier
   grouped-header layout ENG-069/071 had, where the header cell needed both axes from competing
   selectors at once. */
.pipeline-table td.pipeline-col-id, .pipeline-table th.pipeline-col-id {
    position: sticky;
    left: 0;
    background: var(--kcpc-surface);
    z-index: 1;
    font-weight: 600;
}
.pipeline-table th.pipeline-col-id { background: #f9fafb; z-index: 3; font-weight: 700; }

/* SKU: pinned immediately after Content ID (same sticky-left region). Content ID's column width
   is intentionally left auto/content-driven (unchanged from before), so `left` here is not a
   hardcoded guess - it's set from --pipeline-sku-left, a custom property pipeline-dashboard.js
   computes from Content ID's actual rendered width on load (and on resize), which is what keeps
   SKU flush against Content ID without overlapping it. The `120px` fallback only applies with JS
   disabled. Same z-index tiering as Content ID (1 for data cells, 3 for the header cell so it
   wins over the generic sticky-top th at z-index 2). Background matches ordinary cells exactly
   (same var(--kcpc-surface)/#f9fafb as ordinary td/th) - sticky needs an opaque background so
   scrolled-under columns don't show through, not a distinct color. */
.pipeline-table td.pipeline-col-sku, .pipeline-table th.pipeline-col-sku {
    position: sticky;
    left: var(--pipeline-sku-left, 120px);
    background: var(--kcpc-surface);
    z-index: 1;
}
.pipeline-table th.pipeline-col-sku { background: #f9fafb; z-index: 3; }

/* Status: pinned to the far right (mirrors Content ID/SKU's pinned-left treatment). `right: 0` is
   exact regardless of any other column's width, so no computed offset is needed here. */
.pipeline-table td.pipeline-col-status, .pipeline-table th.pipeline-col-status {
    position: sticky;
    right: 0;
    background: var(--kcpc-surface);
    z-index: 1;
}
.pipeline-table th.pipeline-col-status { background: #f9fafb; z-index: 3; }

.pipeline-table td.pipeline-col-wrap { white-space: normal; }
.pipeline-table tbody tr:hover td { background: #fafbfc; }
.pipeline-table tbody tr:hover td.pipeline-col-id,
.pipeline-table tbody tr:hover td.pipeline-col-sku,
.pipeline-table tbody tr:hover td.pipeline-col-status {
    background: #f5f6f8;
}

.pipeline-link-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 6px;
    color: var(--kcpc-accent);
}
.pipeline-link-icon:hover { background: rgba(233, 69, 96, 0.1); }
.pipeline-link-icon svg { width: 16px; height: 16px; }
.pipeline-link-muted { color: #c1c5cc; }

.performance-cell.clickable {
    color: var(--kcpc-accent);
    text-decoration: underline;
    cursor: pointer;
}

/* ENG-074: Content Pipeline - premium admin-dashboard redesign (stage tabs, compact filter bar,
   Columns/Export toolbar, flat sortable 20-column table, soft pill status badges). Pure
   presentation - the underlying data source (PipelineDashboardService/PipelineRow), route, and
   every workflow/permission/business rule are unchanged. */
/* ENG-079: page heading ("Content Pipeline" / "... view — complete end-to-end visibility...")
   removed entirely (not just hidden) so the stage tabs sit right under the nav with no leftover
   margin from the old heading block. */

/* Stage filter tabs - the at-a-glance summary (replacing the standalone KPI cards), a coarse
   status-group quick filter per tab with its own count badge. */
.pipeline-stage-tabs {
    display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.6rem;
}
.pipeline-stage-tab {
    display: inline-flex; align-items: center; gap: 0.35rem;
    padding: 0.3rem 0.75rem; border-radius: 8px; border: 1px solid var(--kcpc-border);
    background: var(--kcpc-surface); color: #475569; font-size: 0.85rem; font-weight: 600;
    text-decoration: none; white-space: nowrap; line-height: 1.3;
}
.pipeline-stage-tab:hover { border-color: #cbd5e1; background: #f8fafc; }
.pipeline-stage-tab.active {
    background: var(--kcpc-accent); border-color: var(--kcpc-accent); color: #fff;
    box-shadow: 0 2px 8px rgba(233, 69, 96, 0.25);
}
.pipeline-stage-tab.active .pipeline-stage-count { background: rgba(255,255,255,0.25); color: #fff; }
.pipeline-stage-tab.attention:not(.active) { color: #b91c1c; border-color: #fecaca; background: #fef2f2; }
/* Cancelled: a terminal, negative state - the same muted-red treatment as Needs Attention,
   deliberately one step calmer (slate-tinted border) so an alert and an archive state do not
   read as equally urgent. Active state is the shared accent pill, unchanged. */
.pipeline-stage-tab.cancelled:not(.active) { color: #9f1239; border-color: #e5c3cb; background: #fdf5f6; }
.pipeline-stage-icon { font-size: 0.85rem; }
.pipeline-stage-count {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 1.4rem; height: 1.4rem; padding: 0 0.35rem; border-radius: 999px;
    background: #eef2f7; color: #475569; font-size: 0.72rem; font-weight: 700;
}

/* ENG-080: Compact filter bar - Search + Priority + Platform + Date Range + Delayed only +
   Apply/Clear, all on one shared visual baseline. The bar itself is `align-items: flex-end`, and
   every group's actual CONTROL (input/select/date-row/checkbox-row/button) shares one fixed
   height (--pipeline-filter-control-h) - so regardless of whether a group has a label above it
   (Priority/Platform/Date Range) or not (Search/Delayed only/buttons), each group's own box bottom
   lines up on the exact same pixel: flex-end aligns bottoms, and equal control height means equal
   total group height too, which is what also keeps the three labeled groups' LABELS starting at
   the same top position. This replaces the previous `align-items: center`, which centered each
   group on the row's cross-axis independently by its own (differing) total height - the actual
   cause of Search/Delayed-only/the buttons appearing to float at inconsistent vertical positions. */
.pipeline-filter-bar {
    /* Corrected from an arbitrary 42px to the .pipeline-stage-tab pill's own actual computed
       height, so the filter row is genuinely equal to the pills above it instead of merely
       internally consistent with itself: a pill has no explicit height - it's sized by
       padding (0.3rem top+bottom = 9.6px) + border (2px) + its tallest inline child, which is
       .pipeline-stage-count's own explicit height:1.4rem (22.4px), taller than the pill's own
       text line-height. 22.4 + 9.6 + 2 = 34px. */
    --pipeline-filter-control-h: 34px;
    display: flex; align-items: flex-end; gap: 0.9rem; flex-wrap: wrap;
    background: var(--kcpc-surface); border: 1px solid var(--kcpc-border); border-radius: 10px;
    padding: 0.5rem 0.85rem; margin-bottom: 0.55rem; box-shadow: 0 1px 2px rgba(15, 23, 42, 0.03);
}
/* box-sizing:border-box already applies globally (see the top-of-file `* {}` rule), so height
   alone is enough - min-height + box-sizing are still declared explicitly here too (scoped to
   this filter bar only, not a global input/select/button change) purely as a defensive pin
   against exactly this class of bug recurring silently in the future. */
.pipeline-filter-bar select, .pipeline-filter-bar input[type="date"], .pipeline-filter-bar input[type="text"] {
    height: var(--pipeline-filter-control-h);
    min-height: var(--pipeline-filter-control-h);
    box-sizing: border-box;
    padding: 0 0.65rem;
    border: 1px solid var(--kcpc-border);
    border-radius: 7px;
    font-size: 0.85rem;
    line-height: normal;
    background: var(--kcpc-surface);
    color: var(--kcpc-ink);
}
.pipeline-search-field { position: relative; }
.pipeline-search-field input[type="text"] { padding-right: 2rem; min-width: 260px; }
.pipeline-search-icon {
    position: absolute; right: 0.6rem; top: 50%; transform: translateY(-50%);
    color: #9ca3af; pointer-events: none; font-size: 0.85rem;
}
.pipeline-filter-inline {
    display: flex; flex-direction: column; gap: 0.3rem;
    font-size: 0.72rem; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.03em;
    line-height: 1;
}
.pipeline-date-range-inputs { display: flex; align-items: center; gap: 0.35rem; }
.pipeline-date-range-inputs input[type="date"] { width: 8.75rem; }
.pipeline-date-range-inputs span { color: #9ca3af; font-weight: 400; }
/* Delayed only: no label row above it (like Search and the buttons), so it needs the same fixed
   control height to land on the shared bottom baseline instead of the row's old center-line;
   internal align-items:center keeps the checkbox + its text vertically centered as one group
   within that height, and white-space:nowrap keeps "Delayed only" on one line whenever the bar
   has room (it wraps naturally with the rest of the bar on narrow viewports instead). */
.pipeline-filter-checkbox {
    display: flex; align-items: center; gap: 0.4rem;
    height: var(--pipeline-filter-control-h);
    min-height: var(--pipeline-filter-control-h);
    box-sizing: border-box;
    font-size: 0.82rem; font-weight: 600; color: var(--kcpc-ink); white-space: nowrap;
}
.btn-primary {
    display: inline-flex; align-items: center; justify-content: center; gap: 0.35rem;
    height: var(--pipeline-filter-control-h);
    padding: 0 1rem; border-radius: 7px; border: 1px solid var(--kcpc-accent);
    background: var(--kcpc-accent); color: #fff; font-size: 0.85rem; font-weight: 700;
    cursor: pointer; white-space: nowrap;
}
/* min-height/box-sizing pinned explicitly here (scoped to this filter bar, not a global .btn-primary
   change - other pages using .btn-primary, e.g. Export's Generate Export, are untouched). */
.pipeline-filter-bar .btn-primary {
    min-height: var(--pipeline-filter-control-h);
    box-sizing: border-box;
}
/* Clear reuses the shared .btn-outline look - scoped here (not on the shared rule) so its height
   only changes inside this filter bar, not on every other page that uses .btn-outline. */
.pipeline-filter-bar .btn-outline {
    display: inline-flex; align-items: center; justify-content: center;
    height: var(--pipeline-filter-control-h);
    min-height: var(--pipeline-filter-control-h);
    box-sizing: border-box;
}
.btn-primary:hover { background: #d63852; border-color: #d63852; }

/* My Work -> Dashboard (Publisher) filter panel. Reuses .pipeline-filter-bar wholesale so the
   controls, spacing and baseline are identical to the Content Pipeline filter bar - these two
   rules only cover the one control that bar has never had to render: a MULTI-select.
   Both are scoped under .my-work-dashboard-filters, so the Content Pipeline's own filter bar
   (single-selects only) is not touched at all. */
/* The hint line under the bar - pulled up against the bar's own 0.55rem bottom margin so the
   filter panel reads as one block rather than a bar with a detached stray sentence. */
.my-work-dashboard-filters > .muted {
    margin: -0.15rem 0 0.85rem;
    font-size: 0.78rem;
}

/* Today / Tomorrow / Select Date quick-pick pills. EVERY control in this bar - both pills, the
   date picker, and the Channel/Platform dropdowns - is pinned to the shared
   --pipeline-filter-control-h, so the row is one clean horizontal band with a single baseline
   rather than controls of three different heights. The pills are single-line for that reason:
   the date itself is exposed via title/aria-label instead of a second visible line. */
.my-work-dashboard-filters .mw-date-quickpick { display: flex; align-items: center; gap: 0.4rem; }
.my-work-dashboard-filters .mw-date-card {
    display: inline-flex; align-items: center; gap: 0.4rem;
    height: var(--pipeline-filter-control-h);
    min-height: var(--pipeline-filter-control-h);
    box-sizing: border-box;
    padding: 0 0.7rem;
    border: 1px solid var(--kcpc-border); border-radius: 7px;
    background: var(--kcpc-surface); color: var(--kcpc-ink);
    text-decoration: none; cursor: pointer; white-space: nowrap;
    /* .pipeline-filter-inline (the label wrapper) uppercases and letter-spaces its text for the
       field label; the pill's own contents opt back out so they read normally. */
    text-transform: none; letter-spacing: normal;
}
.my-work-dashboard-filters a.mw-date-card:hover { border-color: var(--kcpc-accent); }
.my-work-dashboard-filters .mw-date-card-label {
    font-size: 0.8rem; font-weight: 600; color: var(--kcpc-ink);
}
/* Count badge - same pill treatment as .pipeline-stage-count, so a filter-bar count and a tab
   count read as the same kind of thing. */
.my-work-dashboard-filters .mw-date-card-count {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 1.4rem; height: 1.4rem; padding: 0 0.35rem;
    border-radius: 999px; background: #eef0f4; color: #6b7280;
    font-size: 0.72rem; font-weight: 700;
}
.my-work-dashboard-filters .mw-date-card.active .mw-date-card-count {
    background: var(--kcpc-accent); color: #fff;
}
/* Selected state: accent border + tint, and the label/count promoted to the accent colour so the
   active card is unmistakable at a glance rather than relying on the border alone. */
.my-work-dashboard-filters .mw-date-card.active {
    border-color: var(--kcpc-accent);
    background: rgba(233, 69, 96, 0.07); /* --kcpc-accent #e94560 at 7% */
    box-shadow: inset 0 0 0 1px var(--kcpc-accent);
}
.my-work-dashboard-filters .mw-date-card.active .mw-date-card-label { color: var(--kcpc-accent); }
/* The picker pill wraps a real <input type="date">, which the shared .pipeline-filter-bar rule
   would otherwise size to the full control height inside an already-bordered pill. */
.my-work-dashboard-filters .mw-date-card-picker { cursor: default; }
.my-work-dashboard-filters .mw-date-card-picker input[type="date"] {
    height: auto; min-height: 0;
    padding: 0; border: 0; background: transparent;
    font-size: 0.8rem; color: var(--kcpc-ink);
}

/* Platforms dropdown: a <details>/<summary> multi-select, deliberately built to look exactly like
   the Channel <select> beside it (same height, border, radius, padding and type scale) so the two
   filters read as one pair. Same component pattern as .kcpc-stages-picker; no JavaScript. */
.my-work-dashboard-filters .mw-platform-picker { position: relative; }
.my-work-dashboard-filters .mw-platform-picker-toggle {
    display: inline-flex; align-items: center; justify-content: space-between; gap: 0.5rem;
    height: var(--pipeline-filter-control-h);
    min-height: var(--pipeline-filter-control-h);
    box-sizing: border-box;
    padding: 0 0.65rem;
    border: 1px solid var(--kcpc-border); border-radius: 7px;
    background: var(--kcpc-surface); color: var(--kcpc-ink);
    font-size: 0.85rem; font-weight: 400;
    text-transform: none; letter-spacing: normal; white-space: nowrap;
    list-style: none; cursor: pointer;
}
/* Both are needed to suppress the native disclosure triangle across browsers - the ::marker form
   for standards-compliant engines, the -webkit- form for Safari. */
.my-work-dashboard-filters .mw-platform-picker-toggle::-webkit-details-marker { display: none; }
.my-work-dashboard-filters .mw-platform-picker-toggle::marker { content: ""; }
.my-work-dashboard-filters .mw-platform-picker-value {
    display: inline-flex; align-items: center; gap: 0.25rem; overflow: hidden;
}
.my-work-dashboard-filters .mw-platform-picker-caret { color: #6b7280; font-size: 0.7rem; }
.my-work-dashboard-filters .mw-platform-picker[open] .mw-platform-picker-toggle {
    border-color: var(--kcpc-accent);
}
.my-work-dashboard-filters .mw-platform-chip {
    display: inline-flex; align-items: center;
    padding: 2px 8px; border-radius: 14px;
    background: #f1f3ff; color: var(--kcpc-ink);
    font-size: 0.72rem; font-weight: 600;
}
/* Absolutely positioned so opening the dropdown overlays the content below instead of pushing the
   whole filter bar (and the table under it) downwards. */
.my-work-dashboard-filters .mw-platform-checklist {
    position: absolute; z-index: 30; top: calc(100% + 4px); left: 0;
    display: flex; flex-direction: column; gap: 0.3rem;
    min-width: 100%; max-height: 14rem; overflow-y: auto;
    padding: 0.5rem;
    border: 1px solid var(--kcpc-border); border-radius: 7px;
    background: var(--kcpc-surface);
    box-shadow: 0 6px 16px rgba(15, 23, 42, 0.12);
}
.my-work-dashboard-filters .mw-platform-checklist .platform-check-item {
    display: flex; align-items: center; gap: 0.4rem; margin: 0;
    font-size: 0.82rem; font-weight: 400; color: var(--kcpc-ink);
    text-transform: none; letter-spacing: normal; white-space: nowrap; cursor: pointer;
}
.my-work-dashboard-filters .mw-platform-checklist .platform-check-item input { width: auto; margin: 0; }

/* Apply/Clear pushed to the far right of the row, so the three filter fields group together on
   the left and the actions read as a separate cluster. */
.my-work-dashboard-filters .mw-filter-actions {
    display: inline-flex; align-items: flex-end; gap: 0.5rem; margin-left: auto;
}

.pipeline-status-cell { display: flex; flex-direction: column; gap: 0.15rem; align-items: flex-start; }
.pipeline-status-badge {
    display: inline-block; padding: 0.12rem 0.55rem; border-radius: 999px;
    font-size: 0.72rem; font-weight: 700; line-height: 1.4; white-space: nowrap;
}
.pipeline-status-badge.stage-planning { background: #dbeafe; color: #1d4ed8; }
.pipeline-status-badge.stage-shoot { background: #dcfce7; color: #166534; }
.pipeline-status-badge.stage-edit { background: #ede9fe; color: #6d28d9; }
.pipeline-status-badge.stage-publishing { background: #ffedd5; color: #c2410c; }
.pipeline-status-badge.stage-performance { background: #fef9c3; color: #854d0e; }
.pipeline-status-badge.stage-completed { background: #dcfce7; color: #166534; }
.pipeline-status-badge.stage-cancelled { background: #f3f4f6; color: #6b7280; }
.pipeline-status-badge.stage-delayed { background: #fee2e2; color: #b91c1c; }

.pipeline-sort-link {
    display: inline-flex; align-items: center; gap: 0.3rem;
    color: inherit; text-decoration: none; font-weight: inherit;
}
.pipeline-sort-link:hover { color: var(--kcpc-accent); }
.pipeline-sort-indicator { font-size: 0.6rem; color: #b6bcc7; }
.pipeline-sort-indicator.active { color: var(--kcpc-accent); }

/* ENG-076 (defect fix): Platforms column - one icon+count chip per planned Platform. Every chip is
   a real, always-clickable <button> that opens a popover listing every real (Planned Output,
   Publication Target) publishing task's status - "active"/"muted" is a purely cosmetic color cue
   (any published vs all still pending), never a click-eligibility gate. The popover is for viewing
   task status, not only for opening live links, so a fully-pending platform must be just as
   clickable as a fully/partially published one. */
.pipeline-platform-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.pipeline-platform-chip-wrap { position: relative; }
.pipeline-platform-chip {
    display: inline-flex; align-items: center; gap: 0.3rem;
    padding: 0.16rem 0.5rem; border-radius: 999px; font-size: 0.78rem; font-weight: 600;
    line-height: 1.3; white-space: nowrap; border: 1px solid transparent; cursor: pointer;
}
.pipeline-platform-chip.active {
    background: #dcfce7; color: #166534; border-color: #bbf7d0;
}
.pipeline-platform-chip.active:hover { background: #bbf7d0; }
.pipeline-platform-chip.muted {
    background: #f1f5f9; color: #94a3b8;
}
.pipeline-platform-chip.muted:hover { background: #e2e8f0; }
.pipeline-platform-chip:focus-visible { outline: 2px solid var(--kcpc-accent); outline-offset: 1px; }
/* ENG-076: icons are local, full-color brand-badge SVGs (static/icons/platforms/ - own artwork
   using each platform's real brand colors, not emoji, not a CDN icon font, and not the exact
   copyrighted official logo files), rendered via <img>. Muted/planned-only state only reduces
   opacity - it must NOT desaturate/grey the icon, so brand identity stays visible even though the
   chip is still fully clickable. */
.pipeline-platform-icon { width: 18px; height: 18px; display: block; flex: none; border-radius: 5px; }
.pipeline-platform-chip.muted .pipeline-platform-icon { opacity: 0.5; }
.pipeline-platform-count { font-size: 0.76rem; font-weight: 700; }

/* ENG-076: the popover is a <body>-level fixed-position overlay (moved there once by
   pipeline-dashboard.js on first open, positioned via getBoundingClientRect() of the clicked
   chip) instead of being positioned relative to its own table cell - a wide table's own
   .pipeline-scroll overflow:auto container (and any stacking context sticky cells create) would
   otherwise clip it or bury it behind later rows/cells. z-index is deliberately way above
   anything else on this page (sticky headers/cells top out at z-index 4). */
.pipeline-platform-popover {
    position: fixed; top: -9999px; left: -9999px; z-index: 1000;
    background: var(--kcpc-surface); border: 1px solid var(--kcpc-border); border-radius: 10px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, 0.22); padding: 0.7rem;
    /* Clamped to the viewport: the popover is position:fixed, so on a narrow screen an
       unclamped 340px minimum would run off the edge. */
    min-width: min(340px, calc(100vw - 12px)); max-width: min(460px, calc(100vw - 12px));
    white-space: normal;
}
.pipeline-platform-popover-header {
    display: flex; align-items: center; gap: 0.4rem;
    padding-bottom: 0.5rem; margin-bottom: 0.4rem; border-bottom: 1px solid var(--kcpc-border);
}
.pipeline-platform-popover-title { font-weight: 700; font-size: 0.85rem; color: var(--kcpc-ink); }
.pipeline-platform-progress { margin-left: auto; font-size: 0.72rem; font-weight: 700; color: #166534; }
/* ENG-076 (defect fix): the popover is a real table (one row per Planned Output x Publication
   Target task, never deduplicated by channel) so Main Channel/Collab With/Status/Link each get their own
   column - a flex row couldn't align independent columns across rows whose channel handle
   length varies. No Output Type or Output column here - both live on the Planning tab. */
.pipeline-platform-popover-table { width: 100%; border-collapse: collapse; font-size: 0.78rem; }
.pipeline-platform-popover-table th {
    text-align: left; font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em;
    color: #94a3b8; padding: 0 0.5rem 0.35rem 0;
}
.pipeline-channel-row td { padding: 0.3rem 0.5rem 0.3rem 0; vertical-align: middle; white-space: nowrap; }
.pipeline-channel-handle { color: var(--kcpc-ink); font-weight: 600; }
.pipeline-channel-row.pending .pipeline-channel-handle { color: #94a3b8; font-weight: 500; }
.pipeline-channel-status { font-size: 0.74rem; font-weight: 600; color: #166534; }
.pipeline-channel-status.muted { color: #94a3b8; font-weight: 500; }
.pipeline-channel-open {
    font-size: 0.74rem; font-weight: 700; color: var(--kcpc-accent); text-decoration: none;
}
.pipeline-channel-open:hover { text-decoration: underline; }

/* ENG-079: pagination/footer area tightened - scoped to .pipeline-pagination (an extra class
   alongside the shared .pagination) so my-ideas.jsp/my-work.jsp's own pagination footers, which
   reuse the same base .pagination class, are left exactly as they were. */
.pipeline-pagination { margin-top: 0.5rem; }
.pipeline-footer-note {
    margin-top: 0.5rem; padding: 0.4rem 0.85rem; border-radius: 8px;
    background: #f8fafc; color: #64748b; font-size: 0.78rem; display: flex; gap: 0.5rem; align-items: flex-start;
}
.pipeline-per-page { display: flex; align-items: center; gap: 0.4rem; font-size: 0.85rem; color: #6b7280; }
.pipeline-per-page select { padding: 0.25rem 0.5rem; border: 1px solid var(--kcpc-border); border-radius: 6px; }

/* Publication Targets: one row per Platform, channels as chips on the same line - "Platform :
   Channel Channel" - instead of a flat comma list or a count-labelled block per platform. */
.target-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 6px;
}
.target-platform {
    min-width: 90px;
    font-weight: 600;
    font-size: 0.82rem;
}
.target-channels {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.channel-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 5px 6px 5px 10px;
    border-radius: 14px;
    background: #f1f3ff;
    color: #3730a3;
    font-size: 0.75rem;
    white-space: nowrap;
}
.channel-chip form { display: inline-flex; margin: 0; }
.chip-remove {
    background: none;
    border: none;
    color: inherit;
    cursor: pointer;
    font-size: 0.85rem;
    line-height: 1;
    padding: 0 0.15rem;
    width: auto;
    margin: 0;
}
.muted-summary { color: #6b7280; font-size: 0.82rem; }
.ajax-error { color: #b91c1c; font-size: 0.78rem; margin-top: 4px; }

/* Planned Outputs "Type" cell: one chip per Reel Type in a REEL group (e.g. SHORT + LONG created
   together), since the row is now one per reelGroupId rather than one per PlannedOutput. */
.reeltype-chip {
    display: inline-block;
    margin-left: 0.35rem;
    padding: 2px 8px;
    border-radius: 10px;
    background: #ecfdf5;
    color: #065f46;
    font-size: 0.72rem;
    font-weight: 600;
    white-space: nowrap;
}

/* Publishing Scope (read-only table) - output type badges and scope chips */
.scope-target-icon { border-radius: 3px; flex: none; }
.badge-type {
    display: inline-block; padding: 2px 9px; border-radius: 10px; font-size: 0.72rem; font-weight: 700;
    white-space: nowrap; text-transform: uppercase; letter-spacing: 0.02em;
}
.badge-type-REEL { background: #ede9fe; color: #6d28d9; }
.badge-type-VIDEO { background: #dbeafe; color: #1d4ed8; }
.badge-type-PHOTOGRAPHY { background: #dcfce7; color: #166534; }
.scope-target-chip {
    display: inline-flex; align-items: center; gap: 0.3rem; padding: 4px 8px; margin: 0 4px 4px 0;
    border-radius: 12px; font-size: 0.75rem; white-space: nowrap;
}
.scope-target-chip.planned { background: #f1f3ff; color: #3730a3; }
.scope-target-chip.published { background: #dcfce7; color: #166534; }
.scope-locked {
    display: inline-flex; align-items: center; gap: 0.2rem; color: #6b7280; font-size: 0.7rem;
    font-weight: 600; white-space: nowrap; margin-left: 0.3rem;
}
.content-detail-scope-table { margin-top: 0.75rem; }
.scope-add-target-details summary { cursor: pointer; font-size: 0.82rem; color: var(--kcpc-accent); }
.scope-add-target-details[open] summary { margin-bottom: 0.5rem; }

.kcpc-modal-overlay {
    position: fixed; inset: 0; background: rgba(15, 23, 42, 0.55); z-index: 1000;
    display: flex; align-items: flex-start; justify-content: center; padding: 3.5rem 1.5rem;
    overflow-y: auto;
}
.kcpc-modal {
    background: var(--kcpc-surface); border-radius: 12px; width: 100%; max-width: 900px;
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.25); display: flex; flex-direction: column; max-height: 100%;
}
.kcpc-modal-header {
    display: flex; align-items: center; justify-content: space-between; padding: 1.1rem 1.4rem;
    border-bottom: 1px solid var(--kcpc-border);
}
.kcpc-modal-header h3 { margin: 0; font-size: 1.05rem; }
.kcpc-modal-close {
    background: none; border: none; font-size: 1.4rem; line-height: 1; cursor: pointer; color: #6b7280;
    padding: 0.2rem 0.5rem;
}
.kcpc-modal-close:hover { color: var(--kcpc-ink); }
.kcpc-modal-body { padding: 1.2rem 1.4rem; overflow-y: auto; }
.kcpc-modal-footer {
    display: flex; justify-content: flex-end; gap: 0.6rem; padding: 1rem 1.4rem;
    border-top: 1px solid var(--kcpc-border);
    align-items: baseline;
}

/* Script Description viewer (Content Detail -> Overview): note-icon trigger + read-only modal
   body. The description itself may be unlimited-length (a full script) - pre-wrap preserves the
   author's line breaks/spacing while still wrapping long lines, and the modal body's own
   overflow-y:auto (above) provides scrolling for long text without growing the page layout. */
.script-description-icon-btn {
    background: none; border: none; cursor: pointer; font-size: 1.15rem; line-height: 1;
    padding: 0.15rem 0.3rem; border-radius: 6px;
}
.script-description-icon-btn:hover { background: var(--kcpc-surface-muted, #f1f5f9); }
.script-description-text {
    white-space: pre-wrap; word-wrap: break-word; font-family: inherit; font-size: 0.9rem;
    line-height: 1.5; margin: 0;
}

/* Idea Description edit mode (CEO/Marketing Manager only) - Description + mandatory Update
   Reason, swapped in over the read-only view within the same modal body. */
.script-description-modal-actions { display: flex; align-items: center; gap: 0.2rem; flex: none; }
.script-description-edit-form {
    margin-top: 0.9rem; padding-top: 0.9rem; border-top: 1px solid var(--kcpc-border);
}
.script-description-edit-form label { display: block; margin-top: 0.9rem; font-weight: 600; font-size: 0.85rem; }
.script-description-edit-form label:first-child { margin-top: 0; }
.script-description-edit-form textarea {
    width: 100%; margin-top: 0.3rem; padding: 0.5rem 0.6rem; border: 1px solid var(--kcpc-border);
    border-radius: 6px; font-size: 0.88rem; font-family: inherit; resize: vertical;
}
.script-description-edit-form textarea#scriptDescriptionEditTextarea { min-height: 130px; }
.script-description-edit-form textarea#scriptDescriptionReasonTextarea { min-height: 60px; }
.script-description-edit-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 0.9rem; }
.script-description-edit-actions button[type="submit"] {
    padding: 0.5rem 1.1rem; border-radius: 7px; font-weight: 700; font-size: 0.85rem;
    border: 1px solid #1d4ed8; background: #1d4ed8; color: #fff; cursor: pointer;
}
.script-description-edit-actions button[type="submit"]:hover:not(:disabled) { background: #1e40af; }
.script-description-edit-actions button[type="submit"]:disabled { opacity: 0.6; cursor: not-allowed; }

/* Reference Link inline edit widget (CEO/Marketing Manager only) - idea-detail.jsp's own field row
   and the Reviews Workspace's "Reviewing Idea" panel both include fragments/
   idea-reference-link-edit.jspf as-is, so this is the one place its look lives. */
.ref-link-view { display: inline-flex; align-items: center; gap: 0.3rem; flex-wrap: wrap; }
.ref-link-edit-form { margin-top: 0.4rem; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.ref-link-edit-input {
    flex: 1 1 260px; min-width: 200px; padding: 0.4rem 0.6rem; border: 1px solid var(--kcpc-border);
    border-radius: 6px; font-size: 0.88rem; font-family: inherit;
}
.ref-link-edit-actions { display: flex; gap: 0.4rem; flex: none; }
.ref-link-edit-actions button[type="submit"] {
    padding: 0.4rem 0.9rem; border-radius: 7px; font-weight: 700; font-size: 0.82rem;
    border: 1px solid #1d4ed8; background: #1d4ed8; color: #fff; cursor: pointer;
}
.ref-link-edit-actions button[type="submit"]:hover:not(:disabled) { background: #1e40af; }
/* Cancel and Save share one box: identical padding, font, line-height and 1px border, so their
   heights are exactly equal. Two inherited rules used to break that - the global
   `button[type="submit"]` 1.5rem margin-top pushed Save down while the flex row's default
   stretch grew Cancel to that taller row, and inside a .panel `.panel button` (0.5rem 1.1rem /
   0.9rem, no border) out-specified .btn-outline. Sizing and alignment only - colours stay with
   the existing rules above. */
.ref-link-edit-actions { align-items: center; }
.ref-link-edit-actions button[type="submit"],
.ref-link-edit-actions button.btn-outline {
    margin: 0; padding: 0.4rem 0.9rem; border-radius: 7px; font-weight: 700; font-size: 0.82rem;
    line-height: 1.2; border-width: 1px; border-style: solid; box-sizing: border-box;
}
.ref-link-edit-form .reviews-decision-error { flex-basis: 100%; margin: 0; }
/* The same widget extracted for the other content-metadata fields (fragments/inline-field-edit.jspf)
   on the role Task Detail screens: multi-line values (Publishing Instructions) take the full
   row, and the form reads left-aligned at normal weight even inside a
   right-aligned, bold .summary-field-value. */
.ref-link-edit-form .ife-textarea { flex-basis: 100%; resize: vertical; }
.summary-field-value .ref-link-edit-form { justify-content: flex-end; text-align: left; font-weight: 400; }

.action-stack { display: flex; flex-direction: column; gap: 0.4rem; align-items: flex-start; min-width: 140px; }
.action-stack .action-form { margin: 0; }
.action-stack button.secondary { background: #4b5563; }

/* Add Target: Platform -> Channel checklist (publication-scope.js narrows it by Platform once
   JavaScript has run; without JS every Channel checkbox stays visible and the form still works). */
.kcpc-channel-checklist {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin: 0.4rem 0;
    max-height: 180px;
    overflow-y: auto;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    padding: 0.5rem;
}
.kcpc-channel-checklist .channel-check-item {
    font-weight: 400;
    margin: 0;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.kcpc-channel-checklist .channel-check-item.hidden { display: none; }
.kcpc-channel-checklist .channel-check-item input { width: auto; }

/* ENG-091: Stages picker (Idea Review Planning Basics) - a fixed 3-option <details>/<summary>
   dropdown, same visual language as .reviews-platform-picker below (toggle chrome) and
   .kcpc-channel-checklist above (checklist chrome) plus the shared .model-chip chip style, rather
   than inventing a new one. */
.kcpc-stages-picker { min-width: 220px; }
.kcpc-stages-picker-toggle {
    display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; min-height: 2.2rem;
    list-style: none; cursor: pointer; background: var(--kcpc-surface);
    border: 1px solid var(--kcpc-border); border-radius: 6px; padding: 0.3rem 0.55rem; font-size: 0.8rem;
}
.kcpc-stages-picker-toggle::-webkit-details-marker { display: none; }
.kcpc-stages-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.kcpc-stages-checklist {
    display: flex; flex-direction: column; gap: 0.3rem; margin: 0.4rem 0;
    border: 1px solid var(--kcpc-border); border-radius: 6px; padding: 0.5rem;
}
.kcpc-stages-checklist .stage-check-item { font-weight: 400; margin: 0; display: flex; align-items: center; gap: 0.4rem; }
.kcpc-stages-checklist .stage-check-item input { width: auto; }

/* Add Output / Edit: Reel Type field (label + checklist + hint), hidden while Output Type isn't
   REEL (publication-scope.js also disables and clears its checkboxes then; without JS it stays
   visible/enabled and the server ignores any Reel Type submitted against a non-REEL Output Type). */
.kcpc-reeltype-group.hidden { display: none; }
.kcpc-reeltype-checklist {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin: 0.4rem 0;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
}
.kcpc-reeltype-checklist .reeltype-check-item {
    font-weight: 400;
    margin: 0;
    display: flex;
    align-items: center;
    gap: 0.3rem;
}
.kcpc-reeltype-checklist .reeltype-check-item input { width: auto; }

/* Model(s): searchable checkbox-backed multi-select shown as chips (model-picker.js). Without
   JS this is just the plain .kcpc-model-checklist below, always visible - .kcpc-model-input (the
   chip/search box) stays hidden until the script reveals it, and the checklist only collapses
   into a toggleable dropdown once tagged .kcpc-model-checklist-js.
   .kcpc-assignment-picker (Shoot/Edit/Publishing Assignment, assignment-picker.js) reuses every
   rule below via the shared inner class names (kcpc-model-input/-chips/-search/-checklist,
   model-chip, model-check-item) but is deliberately its OWN root class, never kcpc-model-picker -
   model-picker.js selects `.kcpc-model-picker` globally, and giving an assignment picker that
   class would make model-picker.js ALSO initialize on it (a real bug found in review: it built a
   second, non-AJAX "ghost" chip alongside the real one, and removing the ghost never touched the
   actual assignment). */
.kcpc-model-picker, .kcpc-assignment-picker { display: flex; flex-direction: column; }
/* Shoot/Edit/Publishing Assignment picker sits directly under whatever came before it (no heading
   anymore) - a little breathing room so it doesn't visually run into e.g. "+ Add Output" above it.
   Scoped to .kcpc-assignment-picker only, not the shared .kcpc-model-picker rule above, so the
   Planning Details "Model(s)" field (a .form-grid item, never had a heading of its own) is untouched. */
.kcpc-assignment-picker { margin-top: 1.5rem; }
/* ENG-042: Assignee(s) chip-picker and the Team Lead dropdown side by side in one 2-column grid row,
   collapsing to 1 column on narrow screens. The checklist dropdown and the single "Assign ...(s)"
   button both span the full width on the row(s) below. .assignment-add-form (ENG-041's single-button
   merge - the checklist and Lead <select> submit together) is a *direct* grid item's sibling here:
   it gets `display: contents` so IT doesn't occupy a grid cell of its own - its children (the Lead
   field, checklist, and button) become grid items in their own right, while the chip/search field
   stays a real, un-nested sibling <div> (chips are each their own small <form>, and HTML forms can't
   nest, so they can never live inside .assignment-add-form). */
.assignment-picker-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.5rem 1.25rem;
    align-items: start;
}
.assignment-picker-grid > .assignment-add-form { display: contents; }
.assignment-picker-field label { margin-top: 0; }
.assignment-picker-grid .kcpc-model-checklist,
.assignment-picker-grid .assignment-add-submit { grid-column: 1 / -1; }
@media (max-width: 700px) {
    .assignment-picker-grid { grid-template-columns: 1fr; }
}

/* Planning/Shoot/Edit Review Decision: Decision + Reason (or, ENG-052, Decision + the Qualifying
   Cameraperson(s)/Editor(s) chip picker) side by side instead of stacked, and the "Submit Decision"
   button pulled out of the global `button[type="submit"] { width: 100% }` rule (meant for the
   narrow auth-card login form, but unscoped so it leaks everywhere) - compact and right-aligned
   instead of a full-width bar. Top-aligned (not `end`) so "Decision" and the second column's own
   heading sit on the same line - the qualifying-picker column is taller than a plain Reason input. */
.review-decision-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    align-items: start;
}
.review-decision-grid label { margin-top: 0; }
@media (max-width: 700px) {
    .review-decision-grid { grid-template-columns: 1fr; }
}
/* Final Submit: a two-column action row inside Publication Targets - the go-live date, its input
   and its helper text on the left; the action and its own status message on the right. Deliberately
   a grid rather than free-floating flex children, so the button lines up with the date field and the
   two messages can never end up beside each other. Stacks to one column (date first) on a narrow
   viewport. Typography, borders and button colour are the app's existing ones. */
/* The form lives inside .review-actions, which is a flex row with justify-content: flex-end. A flex
   item sizes to its content, so the form shrank and was pushed right - that, not a margin, is what
   left the wide empty gutter before "Final Publishing Date". Spanning the row puts the date column
   back on the card's normal content edge; .review-actions keeps right-aligning every other form. */
/* Publication Targets, inline performance: the four metric columns under one PERFORMANCE UPDATE
   group header, with compact inputs so the row stays readable. The table keeps .data-table's own
   styling; only the inputs and the group header are new, and the panel scrolls horizontally on a
   narrow viewport rather than the columns collapsing. */
.performance-group-head { text-align: center; }
.performance-metric-input { width: 100%; min-width: 88px; padding: 0.35rem 0.4rem; border: 1px solid var(--kcpc-border); border-radius: 6px; font-size: 0.85rem; }
.performance-state-cell { vertical-align: middle; }
/* The four metric inputs are the widest thing in this row now that the N/A checkboxes are gone,
   so the table needs less forced width before it starts scrolling - the metric columns share the
   space naturally instead of being stretched across a gap the checkboxes used to fill. */
#publication-links-table { min-width: 940px; }
#publication-targets { overflow-x: auto; }

#publishing-final-submit-form { flex: 1 1 100%; width: 100%; }

.final-submit-row {
    display: grid;
    grid-template-columns: minmax(0, 65%) minmax(0, 35%);
    gap: 1.25rem;
    align-items: start;
    width: 100%;
}
.final-submit-date { display: flex; flex-direction: column; gap: 0.35rem; min-width: 0; }
.final-publishing-date-field { display: flex; flex-direction: column; align-items: flex-start; gap: 0.3rem; font-weight: 600; font-size: 0.9rem; }
.final-publishing-date-field input[type="date"] {
    padding: 0.55rem 0.6rem;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    font-size: 0.95rem;
    max-width: 220px;
}
.final-publishing-date-help { margin: 0; font-size: 0.8rem; max-width: 54ch; }
.final-submit-action { display: flex; flex-direction: column; align-items: flex-end; gap: 0.4rem; text-align: right; }
/* The app-wide submit-button rule carries margin-top: 1.5rem for form footers, which is exactly
   what pushed this button out of line with the date field beside it. */
.final-submit-action button[type="submit"] { margin-top: 0; min-width: 170px; padding: 0.55rem 1rem; }
.final-submit-action .muted { font-size: 0.8rem; max-width: 32ch; }
@media (max-width: 760px) {
    .final-submit-row { grid-template-columns: 1fr; }
    .final-submit-action { align-items: stretch; text-align: left; }
    .final-submit-action button[type="submit"] { width: 100%; min-width: 0; }
}

.review-actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 16px;
}
.review-actions button {
    width: auto;
    min-width: 160px;
}

.kcpc-model-input {
    display: none;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    min-height: 2.2rem;
    padding: 0.3rem 0.5rem;
    margin-top: 0.3rem;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    cursor: text;
}
.kcpc-model-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.kcpc-model-chips form { display: inline-flex; margin: 0; }
.model-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 3px 6px 3px 10px;
    border-radius: 14px;
    background: #f1f3ff;
    color: #3730a3;
    font-size: 0.78rem;
    white-space: nowrap;
}
.model-chip .chip-remove {
    background: none;
    border: none;
    color: inherit;
    cursor: pointer;
    font-size: 0.85rem;
    line-height: 1;
    padding: 0 0.15rem;
    width: auto;
    margin: 0;
}
.kcpc-model-search {
    display: none;
    flex: 1 1 120px;
    min-width: 100px;
    border: none;
    outline: none;
    padding: 2px 0;
}
.kcpc-model-checklist {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    margin-top: 0.3rem;
    max-height: 180px;
    overflow-y: auto;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    padding: 0.5rem;
}
.kcpc-model-checklist.kcpc-model-checklist-js:not(.open) { display: none; }
.model-check-item { font-weight: 400; margin: 0; display: flex; align-items: center; gap: 0.4rem; }
.model-check-item input { width: auto; }
.model-check-item.hidden { display: none; }
.assignee-task-count { font-size: 0.82rem; }

/* Initial Shoot Assignment (Reviews -> Ideas -> Approve, and idea-detail.jsp's own Review Decision
   form): Cameraperson(s) / Shoot Lead / Model(s)/Talent side by side in ONE CSS grid row, exactly
   3 equal-width columns. Every column is the SAME structural unit - a .reviews-shoot-assignment-col
   whose first child is a <label>, immediately followed by its control - so all three sit as plain,
   uniform grid items with align-items:start; there is no per-field row-spanning or independent
   positioning that could push one column's controls out of line with the others.
   .reviews-shoot-assignment-camera (the Cameraperson .kcpc-model-picker) is display:contents purely
   so its TWO .reviews-shoot-assignment-col children (Cameraperson's own column, Shoot Lead's own
   column) become the actual grid items in columns 1-2, while the Lead <select> stays a real DOM
   descendant of that picker the whole time - model-picker.js's refreshLeadOptions finds it via
   picker.querySelector('.kcpc-lead-select'), scoped to that one picker instance, so it can never be
   moved into a separate, unrelated container. Model(s)/Talent (column 3) is a true sibling
   .kcpc-model-picker carrying the same .reviews-shoot-assignment-col class directly - a
   self-contained instance model-picker.js wires independently, structurally identical to the other
   two columns (never boxed differently, never given extra margin/padding of its own). */
.reviews-shoot-assignment-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 24px;
    align-items: start;
}
.reviews-shoot-assignment-camera { display: contents; }
.reviews-shoot-assignment-col {
    display: flex;
    flex-direction: column;
    min-width: 0;
    margin: 0;
}
.reviews-shoot-assignment-col > label { display: block; margin: 0; }
.reviews-shoot-assignment-col > .kcpc-model-input { margin-top: 0.3rem; }
.reviews-shoot-assignment-col > .kcpc-lead-select { margin-top: 0.3rem; }
.reviews-shoot-assignment-grid > .reviews-field-hint { grid-column: 1 / -1; margin-top: 0.5rem; }
.reviews-shoot-assignment-grid .kcpc-model-checklist {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.3rem;
    max-height: 220px;
    margin-top: 0.3rem;
}
.reviews-shoot-assignment-grid .model-check-item { margin: 0; }
@media (max-width: 900px) {
    .reviews-shoot-assignment-grid { grid-template-columns: 1fr; }
}

/* Editor Assignment / Publisher Assignment (Reviews -> Shoot/Edit -> Approve): same 2-column
   variant of the Initial Shoot Assignment pattern above - Editor(s)/Editor Lead, or Publisher(s)/
   Publisher Lead, side by side in one CSS grid row. Reuses .reviews-shoot-assignment-col for the
   uniform label+control column structure; .reviews-next-team-picker plays the exact same
   display:contents role as .reviews-shoot-assignment-camera (its two columns become real grid
   items while the Lead <select> stays a DOM descendant of the picker for model-picker.js). */
.reviews-next-team-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 24px;
    align-items: start;
}
.reviews-next-team-picker { display: contents; }
@media (max-width: 900px) {
    .reviews-next-team-grid { grid-template-columns: 1fr; }
}

/* Shoot Review -> Edit Planning (Planned Edit Date | Edit Lead), Edit Review -> Publishing Planning
   (Planned Live Date | Publisher) and Content Detail -> Edit Planning (.stage-planning-two-col): one
   full-width row, two equal columns, each control filling its column. Stacks on small screens. */
.reviews-next-stage-grid,
.stage-planning-two-col {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.5rem 1.25rem;
    width: 100%;
    margin-top: 0.75rem;
    align-items: start;
}
.reviews-next-stage-grid > label,
.stage-planning-two-col > label { display: block; margin: 0; min-width: 0; }
.reviews-next-stage-grid > label > input,
.reviews-next-stage-grid > label > select,
.stage-planning-two-col > label > input,
.stage-planning-two-col > label > select {
    display: block;
    width: 100%;
    max-width: none;
    box-sizing: border-box;
}
@media (max-width: 600px) {
    .reviews-next-stage-grid,
    .stage-planning-two-col { grid-template-columns: 1fr; }
}
/* Read-only Editor Mark below that row: one full-width line, "Editor Mark  0.5", value never wraps. */
.reviews-next-stage-mark { width: 100%; margin-top: 0.75rem; flex-wrap: nowrap; }
.reviews-next-stage-mark .reviews-field-label { width: auto; white-space: nowrap; }
.reviews-next-stage-mark .reviews-field-value { white-space: nowrap; word-break: normal; }

/* ENG-049: Review Decision / Shoot Instructions / Comments read as three distinct blocks, not one
   flat run of fields - a heading with a bottom rule per block, sized to match the Decision label
   above it (form label's 0.85rem/600) instead of the browser's larger default h3 styling, so the
   three block headings read as one consistent hierarchy. */
.stage-block-heading {
    margin-top: 2rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px solid var(--kcpc-border);
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.3;
}
/* ENG-049.1: Shoot/Edit/Publishing Description's heading now lives inside .stage-description-header
   alongside the Edit button (see below) instead of standing alone, so it's no longer the first
   .stage-block-heading sibling on the panel - Comments (still standalone) keeps the default 2rem
   gap, and the header takes the tighter "first block" spacing directly. */
.stage-description-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-top: 1.25rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px solid var(--kcpc-border);
}
.stage-description-header .stage-block-heading {
    margin: 0;
    padding-bottom: 0;
    border-bottom: none;
}

/* ENG-046: Shoot/Edit/Publishing Description + Jira-style Comments thread. */
.stage-description-form textarea,
.stage-comment-form textarea {
    width: 100%;
    padding: 0.5rem 0.6rem;
    margin-top: 0.25rem;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    font-size: 0.9rem;
    font-family: inherit;
    resize: vertical;
}
.stage-save-flash { margin-left: 0.75rem; color: #1a7f4b; font-size: 0.85rem; font-weight: 600; }

/* ENG-049: Description defaults to a clean read view (heading + a small "Edit" button on one row,
   text below) instead of an always-open textarea; the edit form (textarea + Cancel/Save) only
   appears once "Edit" is clicked, replacing the text rather than sitting under it. */
.stage-description-text { margin: 0.5rem 0 0; font-size: 0.9rem; white-space: pre-wrap; }
/* ENG-049.2: Edit as a subtle text-link (pencil icon + "Edit"), not a bordered button - it's a
   minor secondary action next to the heading, so it should read even quieter than Cancel/Save/
   Comment. Faded by default, darker + underlined on hover. Selector is `button.stage-description-
   edit-btn` (not just the bare class) purely for specificity - `.panel button`/`.action-form button`
   (an element+class selector) would otherwise win over a single-class selector and repaint it red.
   `margin: 0`/`min-height: 0` reset `.panel button`'s `margin-top: 1rem`, which would otherwise
   inflate `.stage-description-header`'s row height the same way it did on the Comments "..." menu
   (ENG-050) - fixed here proactively for the same reason. */
button.stage-description-edit-btn {
    flex-shrink: 0;
    width: auto;
    min-width: 0;
    height: auto;
    min-height: 0;
    margin: 0;
    background: transparent;
    border: none;
    padding: 0.2rem 0.35rem;
    border-radius: 4px;
    font-size: 0.85rem;
    color: #6b7280;
    text-decoration: none;
    cursor: pointer;
}
button.stage-description-edit-btn:hover {
    color: var(--kcpc-ink);
    text-decoration: underline;
    background: #f4f5f7;
}

.stage-comments { margin-top: 0.5rem; }
.stage-comments-list {
    display: flex;
    flex-direction: column;
    max-height: 320px;
    overflow-y: auto;
    margin-bottom: 0.75rem;
}
/* ENG-049/050: a flat, divided thread (Jira-style) instead of a boxed card per comment - compact
   ~8px top/bottom padding per comment, no extra margin. */
.stage-comment { position: relative; padding: 8px 0; margin: 0; border-bottom: 1px solid var(--kcpc-border); }
.stage-comment:last-child { border-bottom: none; }
.stage-comment:hover { background: #fafafa; }
.stage-comment-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    font-size: 0.8rem;
    line-height: 1.25;
    color: #6b7280;
    margin-bottom: 3px;
    min-height: 0;
}
.stage-comment-meta-text { flex: 1 1 auto; min-width: 0; }
.stage-comment-meta strong { color: var(--kcpc-ink); }
.stage-comment-edited { font-style: italic; }
.stage-comment-text { margin: 0; font-size: 0.9rem; line-height: 1.35; white-space: pre-wrap; }
.stage-comment-form { margin-top: 0.5rem; }

/* ENG-050: "..." menu on your own comment (Edit/Delete) - Jira-style, kept out of the flow so it
   doesn't push the timestamp around. Deliberately colorless/borderless (not the app's red action
   button) so it stays a quiet affordance and the comment text keeps the visual focus. Selector is
   `button.stage-comment-menu-btn` (not just the bare class) purely for specificity - `.panel
   button`/`.action-form button` (an existing element+class rule) would otherwise outrank a bare
   class selector and repaint it button-red, same issue the standalone Edit link already hit.
   `margin: 0` is likewise required, not cosmetic: `.panel button`'s `margin-top: 1rem` was never
   overridden here, so it was inflating the whole `.stage-comment-meta` flex row's rendered height
   to ~42px (confirmed live via devtools) even though the button's own content is tiny - the actual
   root cause of the "too much gap" report, not the comment/meta padding values themselves. */
.stage-comment-menu { position: relative; flex-shrink: 0; margin-left: auto; }
button.stage-comment-menu-btn {
    background: transparent;
    border: 0;
    width: auto;
    min-width: 0;
    height: auto;
    min-height: 0;
    margin: 0;
    padding: 0 4px;
    border-radius: 5px;
    cursor: pointer;
    font-size: 18px;
    line-height: 1;
    color: #6b7280;
}
button.stage-comment-menu-btn:hover, button.stage-comment-menu-btn.open { background: #f3f4f6; color: #111827; }
.stage-comment-menu-dropdown {
    position: absolute;
    right: 0;
    top: 100%;
    margin-top: 2px;
    background: #fff;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    box-shadow: 0 4px 14px rgba(15, 23, 42, 0.12);
    min-width: 96px;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    padding: 0.25rem;
}
/* ENG-050.1: .stage-comments-list scrolls (overflow-y: auto; max-height: 320px) - an
   overflow:auto/hidden ancestor clips any position:absolute descendant that extends past its
   bounds, so no z-index fixes a dropdown opened on the last visible comment (it just gets cut off,
   z-index or not). stage-discussion.js reparents the opened dropdown straight into <body> and
   switches it to position:fixed (a JS "portal"), which escapes that clip entirely; this class is
   what that reparenting applies - the coordinates themselves are computed/positioned in JS from the
   trigger button's on-screen rect. */
.stage-comment-menu-dropdown.portal {
    position: fixed;
    top: auto;
    margin-top: 0;
}
.stage-comment-menu-dropdown button {
    background: transparent;
    border: none;
    text-align: left;
    padding: 0.35rem 0.6rem;
    font-size: 0.85rem;
    color: var(--kcpc-ink);
    border-radius: 4px;
    cursor: pointer;
    width: 100%;
}
.stage-comment-menu-dropdown button:hover { background: #f4f5f7; }
.stage-comment-delete-trigger { color: #b42318; }
.stage-comment-delete-confirm-text { display: block; font-size: 0.85rem; margin-top: 0.4rem; }
.stage-comment-edit-form, .stage-comment-delete-form { margin-top: 0.4rem; }

/* ENG-049: button hierarchy - Submit Decision (default, primary red) stays the one prominent
   action; Cancel/Save/Comment (and now the comment Edit/Delete inline forms) are visually
   secondary and more compact so they don't compete with it. The "..." trigger and its dropdown are
   styled separately above (quieter than a bordered button, matching the standalone Edit link). */
.stage-description-cancel-btn,
.stage-description-form .review-actions button,
.stage-comment-form button,
.stage-comment-edit-form .review-actions button,
.stage-comment-delete-form .review-actions button {
    background: transparent;
    color: var(--kcpc-ink);
    border: 1px solid var(--kcpc-border);
    padding: 0.4rem 0.9rem;
    font-size: 0.85rem;
}
.stage-description-form .review-actions button:hover,
.stage-comment-form button:hover,
.stage-description-cancel-btn:hover,
.stage-comment-edit-form .review-actions button:hover,
.stage-comment-delete-form .review-actions button:hover { background: #f4f5f7; }
.stage-comment-delete-form .stage-comment-delete-confirm-btn {
    background: #b42318;
    color: #fff;
    border-color: #b42318;
}
.stage-comment-delete-form .stage-comment-delete-confirm-btn:hover { background: #932016; }
/* Cancel + Save (and the delete confirm's Cancel/Yes) sit side by side (unlike every other lone
   .review-actions button on this page) - `gap` spaces them instead of each self-pushing via
   margin-left:auto, which would fly them apart to opposite edges instead of pairing them up. */
.stage-description-form .review-actions {
    gap: 0.5rem;
}
.stage-comment-edit-form .review-actions,
.stage-comment-delete-form .review-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 0.4rem;
}
.stage-description-form .review-actions button,
.stage-comment-edit-form .review-actions button,
.stage-comment-delete-form .review-actions button {
    width: auto;
    min-width: 0;
    margin-left: 0;
}

/* My Work: Description column shouldn't stretch the whole table for a couple of long instructions. */
.my-work-description { max-width: 280px; white-space: pre-wrap; }

/* ENG-062: My Work - Content ID as a clear, clickable link. */
.content-id-link { color: #1d4ed8; font-weight: 700; text-decoration: none; }
.content-id-link:hover { text-decoration: underline; }

.filter-pills { display: flex; gap: 0.4rem; }
.filter-pill {
    display: inline-flex;
    align-items: center;
    padding: 0.4rem 0.85rem;
    border-radius: 999px;
    border: 1px solid var(--kcpc-border);
    background: transparent;
    color: #4b5563;
    font-size: 0.8rem;
    font-weight: 600;
    text-decoration: none;
}
.filter-pill:hover { background: #f3f4f6; }
.filter-pill.active { background: #1d4ed8; border-color: #1d4ed8; color: #fff; }

/* ENG-062: feedback cards - clean horizontal rows, not an audit-log table. */
.feedback-card {
    border: 1px solid var(--kcpc-border);
    border-radius: 8px;
    padding: 1rem 1.25rem;
}
.feedback-card-main {
    display: grid;
    grid-template-columns: 1.1fr 1fr 2fr 1fr auto;
    gap: 1.25rem;
    align-items: start;
}
.feedback-field-label { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; color: #9ca3af; margin-bottom: 0.15rem; }
.feedback-stage-value { font-size: 0.8rem; font-weight: 600; color: #4b5563; }
.feedback-reviewer { margin-top: 0.35rem; font-size: 0.78rem; color: #6b7280; }
.feedback-reviewer::before { content: "\1F464\00A0"; }
.feedback-date-col { font-size: 0.85rem; white-space: nowrap; margin-top: 1.2rem; }

.feedback-history { margin-top: 0.75rem; padding-top: 0.6rem; border-top: 1px solid var(--kcpc-border); }
.feedback-history summary { cursor: pointer; font-size: 0.8rem; font-weight: 600; color: #1d4ed8; }
.feedback-history-list { list-style: none; margin: 0.6rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.feedback-history-list li { display: flex; align-items: center; gap: 0.6rem; font-size: 0.82rem; color: #4b5563; }
.feedback-history-list .ts { color: #9ca3af; min-width: 150px; }

@media (max-width: 900px) {
    .feedback-card-main { grid-template-columns: 1fr; gap: 0.6rem; }
}

/* ENG-064: Camera Person Shoot Task Detail page. */
.breadcrumb { font-size: 0.82rem; color: #6b7280; margin-bottom: 1rem; }
.breadcrumb a { color: #1d4ed8; text-decoration: none; }
.breadcrumb a:hover { text-decoration: underline; }

.shoot-task-header-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}
.shoot-task-header-row h1 { margin-bottom: 0.15rem; }
.shoot-status-card {
    background: var(--kcpc-surface);
    border: 1px solid var(--kcpc-border);
    border-radius: 8px;
    padding: 0.9rem 1.25rem;
    min-width: 200px;
}
.shoot-status-value { margin-top: 0.35rem; }
.shoot-status-value .status-pill { font-size: 0.85rem; padding: 0.25rem 0.7rem; }
.shoot-delay-note { margin: 0.5rem 0 0; font-size: 0.78rem; color: #b91c1c; }

.shoot-progress-panel { margin-bottom: 1.25rem; }
.progress-tracker { display: flex; align-items: flex-start; }
.progress-step { display: flex; flex-direction: column; align-items: center; text-align: center; flex: 0 0 auto; min-width: 108px; }
.progress-step-marker {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.95rem;
    border: 2px solid var(--kcpc-border);
    color: #9ca3af;
    background: #fff;
}
.progress-step-done .progress-step-marker { background: #1d4ed8; border-color: #1d4ed8; color: #fff; }
.progress-step-current .progress-step-marker { background: #eff6ff; border-color: #1d4ed8; color: #1d4ed8; }
.progress-step-rework.progress-step-current .progress-step-marker { background: #fff7ed; border-color: #ea580c; color: #ea580c; }
.progress-step-label { margin-top: 0.5rem; font-size: 0.82rem; font-weight: 600; color: #4b5563; }
.progress-step-current .progress-step-label { color: #1d4ed8; }
.progress-step-rework.progress-step-current .progress-step-label { color: #ea580c; }
.progress-step-date { margin-top: 0.15rem; font-size: 0.72rem; color: #9ca3af; }
.progress-step-connector { flex: 1 1 auto; height: 2px; background: var(--kcpc-border); margin-top: 17px; min-width: 24px; }

/* Publication Links detail (the PERM_09 employee's own task screen): the SAME Publisher task-detail
   language, using the full content width. Width itself comes from the existing .app-main-wide rule
   above (.panel max-width: none) - the only thing that needs saying here is that this screen's
   progress tracker spreads its five steps across that width instead of clumping them at the left,
   which is what .progress-step's flex: 0 0 auto does by default. Scoped to this page so the
   Publisher's own tracker keeps its existing appearance exactly. */
.publication-links-detail .progress-tracker { justify-content: space-between; }
.publication-links-detail .progress-step { flex: 1 1 0; }

.shoot-task-columns { display: grid; grid-template-columns: 65% 35%; gap: 1.25rem; align-items: start; }
.shoot-task-col-main, .shoot-task-col-side { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; }
@media (max-width: 1000px) {
    .shoot-task-columns { grid-template-columns: 1fr; }
}

/* ENG-065: Content & Shoot Information as a clean label|value list instead of a grid. */
.info-list { display: flex; flex-direction: column; }
.info-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    padding: 0.65rem 0;
    border-bottom: 1px solid var(--kcpc-border);
}
.info-row:last-child { border-bottom: none; }
.info-row .summary-field-label { flex: 0 0 auto; white-space: nowrap; }
.info-row .summary-field-value { flex: 1 1 auto; text-align: right; margin-top: 0; word-break: break-word; }

.shoot-info-sections { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
@media (max-width: 700px) {
    .shoot-info-sections { grid-template-columns: 1fr; }
}
.info-strip {
    margin-top: 1rem;
    padding: 0.6rem 0.85rem;
    background: #eff6ff;
    border: 1px solid #bfdbfe;
    border-radius: 6px;
    color: #1e40af;
    font-size: 0.85rem;
}

.shoot-latest-feedback { border-color: var(--kcpc-border); }
.shoot-feedback-warning { background: #fff7ed; border-color: #fdba74; }
.shoot-feedback-card-main { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; margin-bottom: 0.75rem; }
.shoot-feedback-reason { margin: 0.2rem 0 0.9rem; font-size: 0.9rem; }
.feedback-reviewer-name { font-size: 0.85rem; font-weight: 600; }

.shoot-action-panel { display: flex; flex-direction: column; gap: 0.6rem; }
/* Beats the generic .app-main button[type="submit"] rule (element+class+attribute specificity)
   so this stays a full-width primary action instead of the app-wide compact/right-aligned default. */
.shoot-action-panel button[type="submit"].shoot-primary-action {
    display: block;
    width: 100%;
    min-width: 0;
    margin: 0;
    padding: 0.75rem;
    background: var(--kcpc-accent);
    color: #fff;
    border: none;
    border-radius: 8px;
    font-size: 0.95rem;
    font-weight: 700;
    cursor: pointer;
}
.shoot-action-panel button[type="submit"].shoot-primary-action:hover { opacity: 0.92; }
.shoot-action-panel form { margin: 0; }
.shoot-drive-action { width: 100%; text-align: center; }
.shoot-status-compact {
    margin: 0;
    padding: 0.6rem 0.85rem;
    background: #f3f4f6;
    border-radius: 6px;
    text-align: center;
    font-weight: 600;
    color: #4b5563;
    font-size: 0.85rem;
}

/* ENG-060: Submit Idea screen - centered card, narrower than the full page width. */
.idea-submit-card { max-width: 640px; margin: 0 auto; }
.idea-submit-form.form-card { max-width: none; }
.required-mark { color: #dc2626; }
.optional-mark { color: #6b7280; font-weight: 400; font-size: 0.8rem; }

.field-hint-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.75rem;
    margin-top: 0.3rem;
}
.field-hint { color: #6b7280; font-size: 0.78rem; }
.char-counter { color: #9ca3af; font-size: 0.78rem; white-space: nowrap; }
.char-counter.char-counter-near-limit { color: #b45309; }
.char-counter.char-counter-at-limit { color: #dc2626; }

.input-with-icon { position: relative; margin-top: 0.25rem; }
.input-with-icon .input-icon {
    position: absolute;
    left: 0.6rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.85rem;
    opacity: 0.6;
}
.input-with-icon input { margin-top: 0; padding-left: 2rem; }

.idea-submit-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.75rem;
    margin-top: 1.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--kcpc-border);
}
/* Beats the generic .form-card button / .app-main button[type="submit"] rules (element+class /
   class+element+attr specificity) so Reset stays an outline button and Submit stays compact and
   grouped with it, not stretched full-width by the app-wide submit-button rule. */
.idea-submit-form .idea-submit-actions button.btn-outline {
    background: transparent;
    color: #1d4ed8;
    border: 1px solid #93c5fd;
    margin-top: 0;
    padding: 0.5rem 1.1rem;
}
.idea-submit-form .idea-submit-actions button.btn-outline:hover { background: #eff6ff; }
.idea-submit-form .idea-submit-actions button[type="submit"] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    width: auto;
    min-width: 0;
    margin-left: 0;
    margin-top: 0;
}

.idea-submit-footer-hint { text-align: center; color: #6b7280; font-size: 0.85rem; margin-top: 1.25rem; }

/* ENG-061: My Ideas - Submitted On shows date/time on two lines. */
.submitted-on-cell { white-space: nowrap; }
.submitted-on-time { font-size: 0.78rem; }

/* ENG-082: CEO/MM Content Detail redesign - top bar, lifecycle stepper, summary bar, two-column
   tabs+sidebar layout. Reuses existing tokens/classes (.panel, .status-badge, .status-pill,
   .priority-pill, .flag-chip, .data-table, .kcpc-model-picker*, .stage-comment*, .my-work-tabs*,
   .pipeline-platform-*) wherever content is unchanged - only genuinely new layout gets new classes. */
.content-detail-topbar { margin-bottom: 0.75rem; }
.content-detail-topbar-row { display: flex; justify-content: space-between; align-items: flex-start; gap: 2rem; flex-wrap: wrap; }
.content-detail-topbar-text { flex: 1; min-width: 260px; }
.content-detail-back-link { display: inline-block; margin-bottom: 0.4rem; color: var(--kcpc-accent); font-weight: 600; font-size: 0.85rem; text-decoration: none; }
.content-detail-back-link:hover { text-decoration: underline; }
.content-detail-topbar h1 { margin: 0 0 0.25rem; font-size: 1.5rem; }
.content-detail-title-row { display: flex; align-items: baseline; gap: 0.4rem; font-size: 0.95rem; }
.content-detail-id { font-weight: 700; }
.content-detail-sep { color: #9ca3af; }
.content-detail-idea-title { color: #475569; }

/* ENG-082 (visual polish pass): stepper sits beside the title block (not stacked below it), sized
   and spaced to match the reference layout - bigger dots (2.5rem) with small decorative SVG icons
   (stroke="currentColor", so they inherit the done/current/pending color automatically) instead of
   plain numbers. The connecting line is a single ::before spanning the row edge-to-edge BEHIND the
   dots (z-index), not per-node <span> connectors - this guarantees every gap between nodes is
   exactly equal (flex justify-content:space-between distributes the 6 nodes evenly across the
   stepper's own width) regardless of label text length, and the line reads as one continuous,
   longer connector rather than 5 short segments. The stepper gets a fixed flex-basis so it always
   gets the same generous width next to the title block instead of shrinking to fit whatever's left. */
.content-detail-stepper { position: relative; display: flex; justify-content: space-between; flex: 0 1 460px; min-width: 380px; }
.content-detail-stepper::before {
    content: ''; position: absolute; top: 1.25rem; left: 2.75rem; right: 2.75rem; height: 2px;
    background: #e5e7eb; z-index: 0;
}
.content-detail-step { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 0.4rem; }
.content-detail-step-dot {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.5rem; height: 2.5rem; border-radius: 50%;
    background: var(--kcpc-surface); color: #9ca3af; border: 2px solid #e5e7eb;
}
.content-detail-step-dot svg { width: 18px; height: 18px; }
.content-detail-step-current .content-detail-step-dot { background: var(--kcpc-accent); border-color: var(--kcpc-accent); color: #fff; }
.content-detail-step-done .content-detail-step-dot { background: #dcfce7; border-color: #bbf7d0; color: #166534; }
.content-detail-step-label { font-size: 0.76rem; color: #6b7280; font-weight: 600; text-align: center; white-space: nowrap; }
.content-detail-step-current .content-detail-step-label { color: var(--kcpc-ink); }
@media (max-width: 1100px) { .content-detail-stepper { flex-basis: 100%; min-width: 0; } }

.content-detail-summary-bar {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr)); gap: 1rem; align-items: start;
    background: var(--kcpc-surface); border: 1px solid var(--kcpc-border); border-radius: 10px;
    padding: 0.7rem 1.1rem; margin: 1rem 0 1.25rem;
}
.content-detail-summary-cell { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.9rem; min-width: 0; }
.content-detail-summary-label { font-size: 0.7rem; font-weight: 700; color: #9ca3af; text-transform: uppercase; letter-spacing: 0.03em; }
/* Every cell's value sits in its own fixed-height flex row (regardless of whether it's a plain
   text date, a link, a pill badge, or a badge + flag-chips) so all 6 cells' values start at the
   same visual baseline instead of drifting depending on each value type's own natural line-height. */
.content-detail-summary-value { display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem; min-height: 1.6rem; line-height: 1.4; }

/* Automatic Drive folder provisioning status - only shown while not yet SUCCEEDED (the normal
   case, auto-provisioned and working, adds nothing extra here). */
.drive-provisioning-status { font-size: 0.78rem; }
.drive-provisioning-failed { color: #b91c1c; }
.drive-provisioning-in_progress, .drive-provisioning-not_started { color: #9ca3af; }
.drive-provisioning-retry-form { display: inline; margin: 0; }
.drive-provisioning-retry-form .link-button { padding: 0.2rem 0.65rem; font-size: 0.76rem; }

/* Folder Link Management (PERM_13) admin override - collapsed by default, matches the
   .actions-bar details/summary convention used elsewhere in this app. */
.drive-relink-details {
    margin: 0 0 1.25rem; border: 1px solid var(--kcpc-border); border-radius: 8px; background: var(--kcpc-surface);
}
.drive-relink-details summary { padding: 0.55rem 0.9rem; cursor: pointer; font-size: 0.82rem; font-weight: 600; color: var(--kcpc-accent); }
.drive-relink-form { padding: 0 0.9rem 0.9rem; }

/* Main:sidebar ratio ~73%/27% (close to the reference's wider sidebar column while staying within
   the 74-76%/24-26% range), sidebar top-aligned with main's tab row via align-items:flex-start so
   Action Center's card top lines up with the Overview tabs, not the summary strip above them. */
.content-detail-body { display: flex; gap: 1.5rem; align-items: flex-start; }
.content-detail-main { flex: 1 1 73%; min-width: 0; }
.content-detail-sidebar { flex: 0 1 27%; min-width: 320px; display: flex; flex-direction: column; gap: 1.25rem; }
@media (max-width: 1100px) {
    .content-detail-body { flex-direction: column; }
    .content-detail-sidebar { min-width: 0; flex-basis: auto; width: 100%; }
}

.content-detail-tabs { margin-bottom: 1rem; }

/* Overview card - definition-list-style field rows (fixed-width label + value) so values line up
   vertically down each column, matching the reference's aligned two-column summary look. Padding/
   row spacing tightened (visual polish pass) so the card's height tracks its actual content
   instead of leaving a visibly empty band under the shorter column. */
.content-detail-overview-card { padding: 1.1rem 1.4rem; }
.content-detail-card-title { margin: 0 0 0.75rem; font-size: 1rem; font-weight: 700; }
.content-detail-overview-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 2.5rem; align-items: start; }
@media (max-width: 800px) { .content-detail-overview-grid { grid-template-columns: 1fr; } }
.content-detail-section-heading { margin: 0.85rem 0 0.35rem; font-size: 0.7rem; font-weight: 600; color: #9ca3af; text-transform: uppercase; letter-spacing: 0.03em; }
.content-detail-overview-grid > div > .content-detail-section-heading:first-child { margin-top: 0; }
.content-detail-field-row { display: flex; align-items: baseline; gap: 0.75rem; padding: 0.3rem 0; font-size: 0.85rem; }
.content-detail-field-row-divider { border-bottom: 1px solid var(--kcpc-border); margin-bottom: 0.4rem; padding-bottom: 0.5rem; }
.content-detail-field-label { width: 148px; flex: none; color: #6b7280; }
.content-detail-field-value { color: var(--kcpc-ink); font-weight: 600; }
/* Overview -> People: each contributor's own decided mark for this content, shown as a raw value
   only (never "/10" or a total) - visually offset from the name, same row. */
.content-detail-people-mark { margin-left: 0.5rem; color: #6b7280; font-weight: 600; }
.content-detail-platform-chips { margin: 0.4rem 0 1rem; }
/* Summary strip's Platform/Channel cell reuses the same chip fragment inline, just without the
   block-level top/bottom margin the Publishing tab's own copy has. */
.content-detail-platform-chips-inline { margin: 0; }

/* Timeline/Activity preview (Overview tab) - compact rows: icon, title+badge+description, then
   timestamp/actor on the right. Same real `timeline` data as the Timeline tab, just the first few
   rows - "View full timeline" below switches tabs via content-detail.js (my-work-tabs.js's own
   click-driven show/hide, not a duplicated tab mechanism). */
.content-detail-timeline-preview { margin-top: 1rem; padding: 1.1rem 1.4rem; }
.content-detail-stage-comments-block { margin-top: 1rem; padding: 1.1rem 1.4rem; }

/* Performance tab - each obligation is its own compact card (sibling .panel, matching the Shoot/
   Edit tabs' own comments-block convention) led by a publication identity block, so the manager
   never enters metrics against the wrong REEL variation/Platform/Channel. */
.performance-obligation-card { margin-bottom: 1rem; }
.performance-obligation-card:last-child { margin-bottom: 0; }
.performance-obligation-identity { padding-bottom: 0.75rem; margin-bottom: 0.75rem; border-bottom: 1px solid var(--kcpc-border); }
.performance-obligation-identity-row { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.performance-obligation-content-type { font-weight: 700; font-size: 0.95rem; color: var(--kcpc-ink); }
.performance-obligation-event-type-badge {
    font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
    color: #6b7280; background: #f3f4f6; padding: 0.15rem 0.55rem; border-radius: 999px; white-space: nowrap;
}
.performance-obligation-target { font-size: 0.85rem; color: #475569; margin-top: 0.25rem; }
.performance-obligation-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; font-size: 0.8rem; color: #6b7280; margin-top: 0.35rem; }
.performance-obligation-due { font-size: 0.8rem; font-weight: 600; color: var(--kcpc-ink); margin-top: 0.35rem; }

/* Draft status + Correct-a-Metric (metric picker reveals exactly one Corrected Value field at a
   time, scoped per-card via .closest('form') in performance-metric-correction.js - never a
   page-wide selector, so multiple obligation cards on one page can never cross-read each other's
   values) and Correction History, all still inside the same compact card. */
.performance-draft-status { font-size: 0.8rem; font-weight: 600; color: #15803d; margin: 0.5rem 0; }
.performance-metric-correction-field { margin-top: 0.5rem; }
.performance-metric-correction-current { font-size: 0.85rem; color: #475569; margin: 0.15rem 0 0.35rem; }
.correction-history-entry { padding: 0.6rem 0; border-bottom: 1px solid var(--kcpc-border); font-size: 0.85rem; }
.correction-history-entry:last-child { border-bottom: none; }
.correction-history-entry p { margin: 0.15rem 0; }

/* Reopen-for-Publishing / repost cycle indicator - a compact badge (never a relabel of the
   original ORIGINAL records), shown next to Assign Publisher, the checklist heading, and the
   Publisher's own status pill whenever PublishingService#currentPublishingCycleStart is non-null. */
.repost-cycle-badge {
    display: inline-block; font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
    color: #9a3412; background: #ffedd5; padding: 0.15rem 0.55rem; border-radius: 999px; white-space: nowrap;
    margin-left: 0.5rem; vertical-align: middle;
}
.content-detail-timeline-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.content-detail-timeline-item {
    display: flex; align-items: flex-start; gap: 0.75rem;
    padding: 0.7rem 0; border-bottom: 1px solid var(--kcpc-border);
}
.content-detail-timeline-item:last-child { border-bottom: none; padding-bottom: 0.2rem; }
.content-detail-timeline-item:first-child { padding-top: 0.2rem; }
.content-detail-timeline-icon {
    flex: none; width: 2rem; height: 2rem; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: #ede9fe; color: #6d28d9;
}
.content-detail-timeline-icon svg { width: 16px; height: 16px; }
.content-detail-timeline-body { flex: 1; min-width: 0; }
.content-detail-timeline-title-row { display: flex; align-items: center; gap: 0.5rem; }
.content-detail-timeline-title { font-weight: 700; font-size: 0.88rem; color: var(--kcpc-ink); }
.content-detail-timeline-badge {
    font-size: 0.68rem; font-weight: 700; color: #6d28d9; background: #ede9fe;
    padding: 0.1rem 0.5rem; border-radius: 999px;
}
.content-detail-timeline-desc { margin: 0.2rem 0 0; font-size: 0.82rem; color: #6b7280; }
.content-detail-timeline-meta { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 0.2rem; font-size: 0.78rem; color: #6b7280; text-align: right; }
.content-detail-timeline-time { white-space: nowrap; }
.content-detail-timeline-actor { font-weight: 600; color: var(--kcpc-ink); }
.content-detail-view-full-timeline {
    display: block; margin: 0.85rem auto 0; background: none; border: none; cursor: pointer;
    color: var(--kcpc-accent); font-weight: 600; font-size: 0.85rem;
}
.content-detail-view-full-timeline:hover { text-decoration: underline; }

.content-detail-current-stage { font-size: 0.85rem; color: #6b7280; margin: 0.2rem 0 0.65rem; }
.content-detail-action-center h4 { font-size: 0.74rem; font-weight: 700; color: #9ca3af; text-transform: uppercase; letter-spacing: 0.03em; margin: 0.75rem 0 0.45rem; }
.content-detail-action-helper { font-size: 0.78rem; color: #9ca3af; margin: -0.25rem 0 0.5rem; }
.content-detail-action-row { display: flex; flex-wrap: wrap; gap: 0.5rem; }
/* Both Primary Actions and Other Actions are clean 2-column grids in the reference (Approve/Reject
   side by side, then Hold/Resume, Reschedule/Reassign, Cancel/Reopen) - every button in either
   group shares the same fixed height/width convention via .content-detail-action-btn below. */
.content-detail-action-row-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
.content-detail-action-btn {
    height: 2.3rem; padding: 0 0.85rem; border-radius: 7px; font-size: 0.8rem; font-weight: 700; cursor: pointer;
    border: 1px solid var(--kcpc-border); background: var(--kcpc-surface); color: var(--kcpc-ink);
    text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    display: inline-flex; align-items: center; justify-content: center;
}
.content-detail-action-row-grid .content-detail-action-btn { width: 100%; }
.content-detail-action-primary { background: #fff; border-color: #bbf7d0; color: #166534; }
.content-detail-action-primary:hover { background: #f0fdf4; }
.content-detail-action-danger { background: #fff; border-color: #fecaca; color: #b91c1c; }
.content-detail-action-danger:hover { background: #fee2e2; }
.content-detail-action-secondary:hover { background: #f4f5f7; }
.content-detail-action-form { margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--kcpc-border); display: flex; flex-direction: column; gap: 0.5rem; }
.content-detail-action-form label { display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.82rem; font-weight: 600; }

.content-detail-contributor-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.85rem; }
.content-detail-contributor-list li { font-size: 0.85rem; line-height: 1.5; }
.content-detail-contributor-row { display: flex; align-items: center; gap: 0.65rem; }
.content-detail-avatar {
    flex: none; width: 2rem; height: 2rem; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--kcpc-accent); color: #fff; font-size: 0.8rem; font-weight: 700;
}
.content-detail-contributor-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.content-detail-contributor-name { font-weight: 700; color: var(--kcpc-ink); font-size: 0.85rem; }
.content-detail-contributor-role { font-size: 0.76rem; color: #6b7280; }
.content-detail-contributor-badge {
    flex: none; font-size: 0.7rem; font-weight: 700; color: #1d4ed8; background: #dbeafe;
    padding: 0.2rem 0.55rem; border-radius: 999px; white-space: nowrap;
}

.content-detail-feedback-entry { padding: 0.85rem 0; border-bottom: 1px solid var(--kcpc-border); }
.content-detail-feedback-entry:first-child { padding-top: 0.1rem; }
.content-detail-feedback-entry:last-child { border-bottom: none; padding-bottom: 0.1rem; }
.content-detail-feedback-entry p { margin: 0.35rem 0 0; font-size: 0.85rem; line-height: 1.5; }

/* ENG-087: Team Workload management dashboard. */
.team-workload-asof {
    display: flex; align-items: center; gap: 0.5rem; background: var(--kcpc-surface);
    border: 1px solid var(--kcpc-border); border-radius: 8px; padding: 0.6rem 1rem;
    font-size: 0.85rem; color: #4b5563; white-space: nowrap; height: fit-content;
}
.asof-icon, .info-icon { color: #9ca3af; }
.team-workload-refresh {
    background: none; border: none; cursor: pointer; color: #6b7280; font-size: 1rem;
    padding: 0 0.1rem; line-height: 1; margin-left: 0.3rem;
}
.team-workload-refresh:hover { color: var(--kcpc-accent); }

.team-workload-tabs { display: flex; gap: 1.5rem; border-bottom: 1px solid var(--kcpc-border); margin-bottom: 1.25rem; }
.team-workload-tab {
    padding: 0.6rem 0.1rem; font-weight: 600; font-size: 0.92rem; color: #6b7280;
    text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.team-workload-tab.active { color: var(--kcpc-accent); border-bottom-color: var(--kcpc-accent); }
.team-workload-tab:hover:not(.active) { color: var(--kcpc-ink); }
/* Team > Performance's own tab bar is the one place this app's shared active-tab color (red/pink,
   .team-workload-tab.active above) is deliberately overridden to blue, matching the reference
   screenshot exactly - scoped to .team-kpi-tabs only, so Workload's own tab bar is untouched. */
.team-kpi-tabs .team-workload-tab.active { color: #1d4ed8; border-bottom-color: #1d4ed8; }

/* Team > Performance KPI cards - deliberately its own centered-content layout (title above a
   pastel circular icon, then the value as the strongest visual element, then a muted subtitle)
   rather than the shared left-aligned .kpi-card row layout used elsewhere, matching the reference
   screenshot; still the same pastel icon-background palette already established by .kpi-card-icon
   variants, just applied to a centered card shape. Aggregate-only by design - no per-employee
   breakdown is ever rendered from this card set. */
.team-perf-kpi-cards { display: grid; grid-template-columns: repeat(5, 1fr); gap: 1rem; margin-bottom: 1.5rem; }
@media (max-width: 1100px) { .team-perf-kpi-cards { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 700px) { .team-perf-kpi-cards { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .team-perf-kpi-cards { grid-template-columns: 1fr; } }
.team-perf-kpi-card {
    display: flex; flex-direction: column; align-items: center; text-align: center; gap: 0.45rem;
    background: var(--kcpc-surface); border: 1px solid var(--kcpc-border); border-radius: 8px;
    padding: 1.25rem 1rem;
}
.team-perf-kpi-icon {
    width: 2.6rem; height: 2.6rem; border-radius: 50%;
    display: flex; align-items: center; justify-content: center; font-size: 1.2rem;
}
.team-perf-kpi-card.perf-completed .team-perf-kpi-icon { background: #d1fae5; color: #047857; }
.team-perf-kpi-card.perf-inprogress .team-perf-kpi-icon { background: #dbeafe; color: #1d4ed8; }
.team-perf-kpi-card.perf-rate .team-perf-kpi-icon { background: #ede9fe; color: #6d28d9; }
.team-perf-kpi-card.perf-delay .team-perf-kpi-icon { background: #ffedd5; color: #c2410c; }
.team-perf-kpi-card.perf-ontime .team-perf-kpi-icon { background: #ccfbf1; color: #0f766e; }
.team-perf-kpi-title { font-size: 0.85rem; font-weight: 600; color: #6b7280; }
.team-perf-kpi-value { font-size: 1.6rem; font-weight: 800; color: var(--kcpc-ink); }
.team-perf-kpi-subtitle { font-size: 0.78rem; color: #6b7280; }

.team-workload-filters {
    display: flex; align-items: flex-end; gap: 1.25rem; flex-wrap: wrap;
    background: var(--kcpc-surface); border: 1px solid var(--kcpc-border); border-radius: 10px;
    padding: 1rem 1.25rem; margin-bottom: 1.25rem;
}
.team-workload-filters .filter-field { display: flex; flex-direction: column; gap: 0.3rem; }
.team-workload-filters .filter-field label { font-size: 0.78rem; font-weight: 600; color: #4b5563; }
.team-workload-filters select, .team-workload-filters input[type="date"] {
    padding: 0.45rem 0.6rem; border: 1px solid var(--kcpc-border); border-radius: 6px; font-size: 0.85rem;
    background: var(--kcpc-surface); color: var(--kcpc-ink); height: 2.3rem;
}
.filter-date-range { display: flex; align-items: center; gap: 0.4rem; }
.filter-date-sep { color: #9ca3af; }
.filter-checkbox-field {
    display: flex; align-items: center; gap: 0.4rem; font-size: 0.85rem; color: var(--kcpc-ink);
    height: 2.3rem; white-space: nowrap;
}
.team-workload-clear { height: 2.3rem; display: inline-flex; align-items: center; }

/* Active Tasks by Stage / Assignee Load: kept at the ~40/60 width ratio, but now stretched to
   equal height too (Assignee Load can hold far more rows than the always-6-row Stage summary).
   The equal-height itself is enforced by team-workload-dashboard.js measuring the Stage card's
   rendered height and applying it to the Assignee card - CSS `align-items: stretch` alone can't
   do this, since a Grid/Flex row's height is set by its tallest CONTENT, and Assignee Load's
   content is exactly the thing that must NOT be allowed to grow the row. Once JS sets that fixed
   height, `.team-workload-table-scroll` (flex:1, overflow-y:auto) is what turns the overflow into
   an internal scrollbar instead of the card (or page) growing. */
.team-workload-cards { display: grid; grid-template-columns: 2fr 3fr; gap: 1.25rem; align-items: stretch; }
@media (max-width: 1100px) { .team-workload-cards { grid-template-columns: 1fr; } }
.team-workload-card { margin-bottom: 0; display: flex; flex-direction: column; }
.team-workload-card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.75rem; }
.team-workload-card-header h2 { margin: 0; }
.team-workload-table-scroll { overflow-y: auto; min-height: 0; }
/* CSS-only safety net: caps Assignee Load's scroll area even if JS hasn't run yet (or fails for
   any reason) - the page can never grow unbounded from a long employee list either way. JS
   (team-workload-dashboard.js, ResizeObserver-driven) overrides this with the Stage card's exact
   rendered height on every browser that runs it, for a pixel-perfect match; this value is only
   the fallback baseline. flex:1 on the desktop grid still lets it grow to fill the row when the
   Stage card is taller than this baseline. */
.team-workload-card-assignee .team-workload-table-scroll { flex: 1; max-height: 420px; }
/* Stacked layout (request's own responsive rule): let Assignee Load take its natural full height
   here - no fixed/max height, ordinary page scroll - the internal-scroll treatment is a desktop/
   tablet-side-by-side concern only. */
@media (max-width: 1100px) {
    .team-workload-card-assignee .team-workload-table-scroll { max-height: none; }
}
.team-workload-assignee-table thead th { position: sticky; top: 0; background: #f9fafb; z-index: 1; }
.team-workload-stage-table td, .team-workload-assignee-table td { vertical-align: middle; }
.team-workload-stage-table .num, .team-workload-assignee-table .num { text-align: right; }
.team-workload-total-row { background: #f9fafb; font-weight: 700; }
.team-workload-total-row td { border-top: 2px solid var(--kcpc-border); }

.stage-dot {
    display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 0.55rem;
}
.stage-dot-Shoot { background: #16a34a; }
.stage-dot-Edit { background: #2563eb; }
.stage-dot-Publishing { background: #ea580c; }
.stage-dot-Performance { background: #a855f7; }
/* Model is talent participation, not a real workflow-assignable stage (see TeamWorkloadService's
   own modelRow() comment) - a neutral gray keeps it visually distinct from the 4 real stages
   above without implying it is one of them. */
.stage-dot-Model { background: #6b7280; }

.team-workload-assignee-cell { display: flex; align-items: center; gap: 0.6rem; font-weight: 600; }

/* Date Range fix: the info icon now sits inline inside the filter label itself (every other
   Workload info-icon is a sibling in a .team-workload-card-header row instead) - a small negative
   margin keeps its larger click/focus target from visually pushing the label text apart. */
.team-workload-filters .filter-field label .info-icon { margin-left: 0.2rem; }
.team-workload-filters .filter-checkbox-field .info-icon { margin-left: 0.3rem; }
.team-workload-filter-btn { height: 2.3rem; }

/* Employee-wise UI update: one stage-wise breakdown panel per employee, all server-rendered
   up front and hidden by default - "Open" toggles exactly one visible at a time (see
   team-workload-dashboard.js). Reuses the same .panel/.data-table look as the two cards above,
   just nested inside the Assignee Load card rather than a top-level sibling (see the JSPF's own
   comment for why - the Stage-filter-only AJAX partial swap must keep replacing it as one unit). */
.team-workload-breakdown { margin-top: 1rem; border-top: 1px solid var(--kcpc-border); padding-top: 1rem; }
.team-workload-breakdown h3 { margin: 0 0 0.75rem; font-size: 0.95rem; }

/* Employee -> Stage -> Content ID drill-down: one collapsed <details> per stage row, nested inside
   that same row via a colspan cell so it stays visually attached to its own Active/Delayed/On Hold
   counts (never a separate table) - the Content ID list inside always reconciles exactly with
   Active Tasks above by construction (see AssigneeLoadRow's own javadoc). */
.team-workload-content-items-row td { padding-top: 0; padding-bottom: 0.6rem; border-top: none; }
.team-workload-content-details { font-size: 0.85rem; }
.team-workload-content-details summary { cursor: pointer; color: var(--kcpc-muted, #6b7280); user-select: none; }
.team-workload-content-list { list-style: none; margin: 0.5rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.35rem; }
.team-workload-content-list li { display: flex; align-items: center; gap: 0.6rem; }
.team-workload-item-status { font-size: 0.8rem; }
.team-workload-item-delayed { color: #dc2626; font-weight: 600; }
.team-workload-item-active { color: #16a34a; }

.team-workload-footnote { display: flex; align-items: flex-start; gap: 0.5rem; margin-top: 1.25rem; }

.team-workload-loading { opacity: 0.5; pointer-events: none; transition: opacity 0.15s ease; }

/* ENG-088: CEO/MM Idea Queue dashboard. */
.idea-queue-filters {
    display: flex; align-items: flex-end; gap: 1.25rem; flex-wrap: wrap;
    background: var(--kcpc-surface); border: 1px solid var(--kcpc-border); border-radius: 10px;
    padding: 1rem 1.25rem; margin-bottom: 1.25rem;
}
.idea-queue-filters .filter-field { display: flex; flex-direction: column; gap: 0.3rem; }
.idea-queue-filters .filter-field label { font-size: 0.78rem; font-weight: 600; color: #4b5563; }
.idea-queue-filters .filter-field-search { flex: 1 1 240px; min-width: 200px; }
.idea-queue-filters select, .idea-queue-filters input[type="date"], .idea-queue-filters input[type="text"] {
    padding: 0.45rem 0.6rem; border: 1px solid var(--kcpc-border); border-radius: 6px; font-size: 0.85rem;
    background: var(--kcpc-surface); color: var(--kcpc-ink); height: 2.3rem;
}
.idea-queue-filters input[type="text"] { width: 100%; }
.idea-queue-clear { height: 2.3rem; display: inline-flex; align-items: center; gap: 0.35rem; }

.idea-queue-table-panel { max-width: none; padding: 0; overflow: hidden; }
.idea-queue-table { margin-bottom: 0; }
.idea-queue-table th, .idea-queue-table td { padding: 0.65rem 1rem; }
.idea-id-link { color: #1d4ed8; font-weight: 700; text-decoration: none; }
.idea-id-link:hover { text-decoration: underline; }
.idea-queue-title-cell {
    max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.idea-queue-submitter { display: inline-flex; align-items: center; gap: 0.4rem; }
.submitter-icon { color: #9ca3af; font-size: 0.85rem; }
.idea-queue-action-btn { display: inline-flex; align-items: center; gap: 0.35rem; white-space: nowrap; }
.idea-queue-sort-link { color: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 0.3rem; }
.idea-queue-sort-link:hover { color: var(--kcpc-accent); }
.sort-icon { font-size: 0.75rem; color: #9ca3af; }
/* Scoped override, not global - see the .status-underreview/.status-reopened comments above. */
.idea-queue-table .status-pill.status-underreview { background: #dbeafe; color: #1d4ed8; }

.idea-queue-pagination { padding: 0.85rem 1.25rem; border-top: 1px solid var(--kcpc-border); flex-wrap: wrap; gap: 1rem; }
.idea-queue-page-size select {
    padding: 0.35rem 0.6rem; border: 1px solid var(--kcpc-border); border-radius: 6px; font-size: 0.82rem;
    background: var(--kcpc-surface); color: var(--kcpc-ink);
}

.idea-queue-loading { opacity: 0.5; pointer-events: none; transition: opacity 0.15s ease; }

/* ============================================================================
   Idea Detail / Review redesign - reuses .content-detail-body/-main/-sidebar's
   existing 73/27 two-column split and card conventions (see the ENG-082 block
   above); everything below is presentation-only for idea-detail.jsp.
   ============================================================================ */
.idea-detail-topbar { margin-bottom: 0.9rem; }
.idea-detail-back-link { display: inline-block; margin-bottom: 0.5rem; color: var(--kcpc-accent); font-weight: 600; font-size: 0.85rem; text-decoration: none; }
.idea-detail-back-link:hover { text-decoration: underline; }
.idea-detail-title-row { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.idea-detail-title-row h1 { margin: 0; font-size: 1.4rem; }
.idea-detail-sep { color: #9ca3af; font-weight: 400; }

.idea-detail-body { margin-top: 1rem; }

.idea-detail-card { padding: 1.1rem 1.4rem; }
.idea-detail-card-title {
    display: flex; align-items: center; gap: 0.6rem;
    margin: 0 0 1rem; font-size: 1rem; font-weight: 700; color: var(--kcpc-ink);
}
.idea-detail-card-title-plain { padding-left: 0; }
.idea-detail-icon-circle {
    flex: none; width: 30px; height: 30px; border-radius: 50%;
    background: #ede9fe; color: #6d28d9;
    display: flex; align-items: center; justify-content: center;
}
.idea-detail-icon-circle svg { width: 16px; height: 16px; }
/* Pushes the Script Description note-icon button to the card header's top-right corner, aligned
   with the "Idea Details" title on the same flex row - only present when the button itself is
   rendered (the icon disappears entirely, not just hidden, when there is no description). */
.idea-detail-header-note-btn { margin-left: auto; }

.idea-detail-fields-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 2.5rem; }
.idea-detail-col { display: flex; flex-direction: column; }
.idea-detail-row {
    display: flex; flex-direction: column; gap: 0.3rem;
    padding: 0.65rem 0; border-bottom: 1px solid var(--kcpc-border); font-size: 0.85rem;
}
.idea-detail-row-last { border-bottom: none; }
.idea-detail-field-label {
    display: flex; align-items: center; gap: 0.45rem;
    color: #6b7280; font-weight: 600; font-size: 0.8rem;
}
.idea-detail-field-label svg { width: 14px; height: 14px; flex: none; }
.idea-detail-field-value { color: var(--kcpc-ink); font-weight: 500; padding-left: 1.4rem; word-break: break-word; }
.idea-detail-ref-link { display: inline-flex; align-items: center; gap: 0.3rem; color: #1d4ed8; text-decoration: none; word-break: break-all; }
.idea-detail-ref-link:hover { text-decoration: underline; }
.idea-detail-ref-link svg { width: 13px; height: 13px; flex: none; }

.idea-history-table-wrap { overflow-x: auto; }
.idea-history-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.idea-history-table th {
    text-align: left; padding: 0.55rem 0.75rem; background: #f9fafb;
    border-bottom: 1px solid var(--kcpc-border); font-size: 0.72rem; font-weight: 700;
    color: #9ca3af; text-transform: uppercase; letter-spacing: 0.03em; white-space: nowrap;
}
.idea-history-table td { padding: 0.6rem 0.75rem; border-bottom: 1px solid var(--kcpc-border); vertical-align: top; }
.idea-history-table tr:last-child td { border-bottom: none; }
.idea-history-time { white-space: nowrap; color: #6b7280; }
.idea-history-remarks { max-width: 320px; }

.idea-action-badge {
    display: inline-block; padding: 0.15rem 0.55rem; border-radius: 999px;
    font-size: 0.75rem; font-weight: 600; white-space: nowrap;
}
.idea-action-badge-submitted { background: #dbeafe; color: #1d4ed8; }
.idea-action-badge-approved { background: #dcfce7; color: #166534; }
.idea-action-badge-rejected { background: #fee2e2; color: #991b1b; }
.idea-action-badge-retained { background: #fef3c7; color: #92400e; }
.idea-action-badge-reopened { background: #ede9fe; color: #6d28d9; }

.idea-detail-status-card { padding: 1rem 1.15rem; }
.idea-detail-status-card-head { display: flex; align-items: center; gap: 0.65rem; flex-wrap: wrap; }
.idea-detail-status-card-icon {
    flex: none; width: 34px; height: 34px; border-radius: 8px;
    background: #ede9fe; color: #6d28d9;
    display: flex; align-items: center; justify-content: center;
}
.idea-detail-status-card-icon svg { width: 17px; height: 17px; }
.idea-detail-status-card-title { font-weight: 700; font-size: 0.9rem; flex: 1; min-width: 120px; }
.idea-detail-status-card-badge { margin-left: auto; }
.idea-detail-status-card-updated { margin: 0.6rem 0 0; font-size: 0.78rem; color: #6b7280; }

.idea-detail-timeline-card { padding: 1.1rem 1.15rem; }
.idea-timeline { list-style: none; margin: 0 0 1rem; padding: 0; }
.idea-timeline-item { position: relative; display: flex; gap: 0.75rem; padding-bottom: 1.35rem; }
.idea-timeline-item:last-child { padding-bottom: 0; }
.idea-timeline-item:not(:last-child)::before {
    content: ''; position: absolute; left: 14px; top: 30px; bottom: 0; width: 2px; background: var(--kcpc-border);
}
.idea-timeline-dot {
    position: relative; z-index: 1; flex: none; width: 30px; height: 30px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center; color: #fff;
}
.idea-timeline-dot svg { width: 14px; height: 14px; }
.idea-timeline-dot-submitted { background: #6d28d9; }
.idea-timeline-dot-approved { background: #16a34a; }
.idea-timeline-dot-rejected { background: #dc2626; }
.idea-timeline-dot-retained { background: #d97706; }
.idea-timeline-dot-reopened { background: #6d28d9; }
.idea-timeline-dot-current { background: #e5e7eb; color: #6b7280; }
.idea-timeline-body { flex: 1; min-width: 0; padding-top: 0.1rem; }
.idea-timeline-label { font-weight: 700; font-size: 0.86rem; color: var(--kcpc-ink); }
.idea-timeline-meta { font-size: 0.78rem; color: #6b7280; }
.idea-timeline-current-label { color: var(--kcpc-accent); font-weight: 600; }

.idea-detail-timeline-note {
    display: flex; gap: 0.55rem; align-items: flex-start;
    background: #eff6ff; border: 1px solid #bfdbfe; color: #1e40af;
    border-radius: 8px; padding: 0.75rem 0.85rem; font-size: 0.82rem;
}
.idea-detail-timeline-note svg { flex: none; width: 16px; height: 16px; margin-top: 0.1rem; }
.idea-detail-timeline-note p { margin: 0; line-height: 1.45; }

.idea-detail-review-card { padding: 1.2rem 1.4rem; }
.idea-detail-review-grid { display: grid; grid-template-columns: 1.7fr 1fr; gap: 2rem; align-items: start; }
.idea-detail-review-grid > form { min-width: 0; }
.idea-detail-marks-row { margin-top: 0.5rem; }
#idea-review-reason-label { display: block; margin-top: 0.75rem; font-weight: 600; font-size: 0.85rem; }
#idea-review-reason { width: 100%; padding: 0.6rem; margin-top: 0.35rem; border: 1px solid var(--kcpc-border); border-radius: 6px; font: inherit; resize: vertical; }
.idea-detail-reason-counter-row { display: flex; justify-content: flex-end; margin-top: 0.3rem; }

.idea-detail-guidelines {
    background: #f5f3ff; border: 1px solid #e0d7fb; border-radius: 8px; padding: 1rem 1.1rem;
}
.idea-detail-guidelines h3 { margin: 0 0 0.85rem; font-size: 0.88rem; font-weight: 700; color: #5b21b6; }
.idea-guideline { display: flex; gap: 0.55rem; margin-bottom: 0.9rem; }
.idea-guideline:last-child { margin-bottom: 0; }
.idea-guideline-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; margin-top: 0.4rem; }
.idea-guideline strong { display: block; font-size: 0.84rem; margin-bottom: 0.15rem; }
.idea-guideline p { margin: 0; font-size: 0.78rem; color: #4b5563; line-height: 1.4; }
.idea-guideline-approve .idea-guideline-dot { background: #16a34a; }
.idea-guideline-approve strong { color: #166534; }
.idea-guideline-reject .idea-guideline-dot { background: #dc2626; }
.idea-guideline-reject strong { color: #991b1b; }
.idea-guideline-retain .idea-guideline-dot { background: #d97706; }
.idea-guideline-retain strong { color: #92400e; }

@media (max-width: 900px) {
    .idea-detail-fields-grid { grid-template-columns: 1fr; }
    .idea-detail-review-grid { grid-template-columns: 1fr; }
}

/* ============================================================================
   Manager Reviews Workspace - one page, four pending-review queues (Ideas/
   Planning/Shoot/Edit). Queue+detail split uses its own 62/38 ratio (spec asks
   for 60-65/35-40, distinct from .content-detail-body's 73/27) since the queue
   table needs more room here than Content Detail's summary sidebar did.
   ============================================================================ */
/* .reviews-tabs-row wraps .reviews-tabs + the "+ Create Idea" button on the same line - the
   border/spacing that used to live on .reviews-tabs itself moved up here so it spans the full row
   width, not just under the tab links. */
.reviews-tabs-row {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    border-bottom: 1px solid var(--kcpc-border); margin-bottom: 1rem;
}
.reviews-tabs { display: flex; gap: 0.25rem; }
.reviews-tab {
    display: inline-flex; align-items: center; padding: 0.65rem 0.9rem;
    color: #6b7280; font-weight: 600; font-size: 0.9rem; text-decoration: none;
    border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.reviews-tab:hover { color: var(--kcpc-ink); }
.reviews-tab.active { color: #1d4ed8; border-bottom-color: #1d4ed8; }
.reviews-tab .count-badge { margin-left: 0.4rem; }

.reviews-filters {
    display: flex; align-items: flex-end; gap: 0.85rem; flex-wrap: wrap;
    background: var(--kcpc-surface); border: 1px solid var(--kcpc-border); border-radius: 8px;
    padding: 0.75rem 1rem; margin-bottom: 0.9rem; font-size: 0.85rem;
}
.reviews-filters .filter-field { display: flex; flex-direction: column; gap: 0.25rem; }
.reviews-filters .filter-field label { font-size: 0.72rem; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.02em; }
.reviews-filters input[type="text"], .reviews-filters input[type="date"], .reviews-filters select {
    padding: 0.4rem 0.55rem; border: 1px solid var(--kcpc-border); border-radius: 6px; font-size: 0.85rem;
}
.reviews-filters .filter-field-search input { min-width: 220px; }
/* "Delayed only" is one atomic control: box + text never split or shrink. The global
   `form input { width: 100%; padding; margin-top }` rule also hits this checkbox; inside a
   shrink-to-fit flex label that percentage is circular, and Safari resolved it to a wide box that
   pushed the text onto a second line over the Clear button (Blink happened to ignore it). */
.filter-field-checkbox { flex: none; flex-direction: row !important; align-items: center; gap: 0.4rem !important; padding-bottom: 0.45rem; }
.filter-field-checkbox label { display: inline-flex; align-items: center; gap: 0.4rem; margin: 0; white-space: nowrap; text-transform: none !important; font-weight: 600 !important; font-size: 0.85rem !important; color: var(--kcpc-ink) !important; }
.filter-field-checkbox input[type="checkbox"] { flex: none; width: auto; margin: 0; padding: 0; }
.reviews-clear { flex: none; display: inline-flex; align-items: center; gap: 0.3rem; height: 2.2rem; white-space: nowrap; }

.reviews-body { display: flex; gap: 1.25rem; align-items: flex-start; }
.reviews-queue { flex: 1 1 62%; min-width: 0; }
.reviews-detail { flex: 0 1 38%; min-width: 340px; position: sticky; top: 1rem; max-height: calc(100vh - 2rem); overflow-y: auto; }

/* Planning Details: a dedicated full-width section below the queue/review-panel row (never
   squeezed into .reviews-detail's narrow ~38% column) - a sibling of .reviews-body, so it spans
   the same full width as the page's main content area. */
.reviews-planning-fullwidth { margin-top: 1.25rem; }

/* Edit tab: Publishing Planning sits in the main column directly under the queue panel (never in
   the narrow ~38% .reviews-detail column), with its confirm button as the card's footer. */
.reviews-queue-planning { margin-top: 1.25rem; }
.reviews-queue-planning .reviews-planning-card { margin-top: 0; }
.reviews-planning-confirm { justify-content: flex-end; margin-top: 0.75rem; }

/* Planned Outputs inside the Publishing Planning card (Edit Review): the channel table, its
   "+ Add Channel" picker and the per-row actions. Same panel/table/typography language as the rest
   of the planning cards - only the layout pieces below are its own. */
.reviews-planned-channels { margin-top: 1.1rem; padding-top: 0.9rem; border-top: 1px solid var(--kcpc-border); }
.reviews-planned-channels-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.reviews-planned-channels-head > div { min-width: 0; }
.reviews-planned-channels-title { margin: 0; font-size: 0.95rem; font-weight: 700; }
.reviews-planned-channels-head .reviews-field-hint { margin-top: 0.2rem; }
.reviews-planned-channels-head button { flex: none; white-space: nowrap; }
/* Publisher Task Detail: the same Planned Outputs section in a card of its own. Inside Content
   Detail's Publishing card the editor's top rule separates it from the Platform chips above; as a
   card's first content it would only leave an empty band, so it is dropped there. The heading block
   also takes the free width, keeping "+ Add Channel" top-right as on Content Detail in this
   narrower column instead of wrapping under the description. */
#publisherPlannedOutputsPanel > .reviews-planned-channels { margin-top: 0; padding-top: 0; border-top: none; }
#publisherPlannedOutputsPanel .reviews-planned-channels-head > div { flex: 1 1 0; }
.reviews-planned-channels-scroll { margin-top: 0.75rem; overflow-x: auto; }
.reviews-planned-channels-table { width: 100%; }
.reviews-planned-channels-table th, .reviews-planned-channels-table td { font-size: 0.83rem; vertical-align: middle; }
.reviews-planned-channel-main { display: flex; align-items: center; gap: 0.45rem; font-weight: 600; }
.reviews-planned-channel-actions { display: flex; gap: 0.35rem; white-space: nowrap; }
/* Collab With: one compact removable chip per collaborator, wrapping when a main channel has
   several. The x is the per-collaborator remove; the row's dustbin is the main-channel delete. */
.reviews-planned-collab-cell { white-space: normal; }
.reviews-collab-chip {
    display: inline-flex; align-items: center; gap: 0.25rem; margin: 0.1rem 0.25rem 0.1rem 0;
    padding: 0.1rem 0.2rem 0.1rem 0.45rem; border: 1px solid var(--kcpc-border); border-radius: 999px;
    background: #f9fafb; font-size: 0.78rem; line-height: 1.5; max-width: 100%;
}
.reviews-collab-chip-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reviews-collab-chip-remove {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 1.05rem; height: 1.05rem; margin: 0; padding: 0; border: 0; border-radius: 50%;
    background: transparent; color: #6b7280; font-size: 0.9rem; line-height: 1; cursor: pointer;
}
.reviews-collab-chip-remove:hover { background: #e5e7eb; color: var(--kcpc-ink); }
.reviews-planned-channel-actions button { width: auto; margin-top: 0; padding: 0.25rem 0.5rem; line-height: 1.1; }
.reviews-planned-channel-picker {
    display: flex; align-items: flex-end; gap: 0.75rem; flex-wrap: wrap;
    margin-top: 0.75rem; padding: 0.75rem 0.85rem;
    background: #f9fafb; border: 1px solid var(--kcpc-border); border-radius: 8px;
}
.reviews-planned-channel-picker > label { flex: 1 1 260px; min-width: 0; font-weight: 600; font-size: 0.85rem; }
.reviews-planned-channel-picker-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.reviews-planned-channel-picker-actions { margin-left: auto; align-items: center; }
.reviews-planned-channel-picker-actions button { width: auto; margin-top: 0; }
/* The picker now hosts the shared Planning grid, so it stacks rather than sitting on one line. */
.reviews-planned-channel-picker { display: block; }
.reviews-planned-channel-picker .reviews-outputs-grid-wrap { margin-bottom: 0.6rem; }
.reviews-planned-channel-picker-actions { display: flex; justify-content: flex-end; gap: 0.5rem; flex-wrap: wrap; }
.reviews-planned-channel-log { margin-top: 0.5rem; font-size: 0.78rem; color: #6b7280; }
.reviews-planned-channel-log:empty { display: none; }

.reviews-table-panel { padding: 1rem 1.2rem; }
.reviews-queue-title { margin: 0 0 0.85rem; font-size: 1rem; font-weight: 700; display: flex; align-items: center; gap: 0.5rem; }
.reviews-table-scroll { overflow-x: auto; }
.reviews-table { width: 100%; }
.reviews-table th { white-space: nowrap; }
.reviews-row { cursor: pointer; }
.reviews-row.reviews-row-active { background: #eff6ff; }
.reviews-row:hover { background: #f9fafb; }
.reviews-row.reviews-row-active:hover { background: #eff6ff; }
.reviews-view-btn { display: inline-flex; align-items: center; justify-content: center; width: 1.9rem; padding: 0.3rem 0; }
.reviews-sort-link { color: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 0.3rem; }
.reviews-sort-link:hover { color: var(--kcpc-accent); }

.reviews-pagination { padding-top: 0.85rem; margin-top: 0.6rem; border-top: 1px solid var(--kcpc-border); flex-wrap: wrap; gap: 1rem; }
.reviews-page-size select { padding: 0.35rem 0.6rem; border: 1px solid var(--kcpc-border); border-radius: 6px; font-size: 0.82rem; }

/* Loading state, scoped to the queue/detail region only - never the whole page (spec §14). Cleared
   in both the fetch success AND catch paths in reviews-workspace.js (this session already found and
   fixed the opposite mistake once, in pipeline-dashboard.js - see that file's history). */
.reviews-loading { opacity: 0.55; pointer-events: none; transition: opacity 0.15s ease; }

.reviews-detail-empty { padding: 1.5rem; text-align: center; }
.reviews-detail-card { padding: 1.1rem 1.3rem; display: flex; flex-direction: column; gap: 0.1rem; }
.reviews-detail-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; }
.reviews-detail-title { margin: 0; font-size: 1.05rem; font-weight: 700; }
.reviews-detail-id-row { font-size: 0.8rem; color: #6b7280; margin: 0.1rem 0 0.6rem; }

.reviews-detail-section { padding: 0.75rem 0; border-top: 1px solid var(--kcpc-border); }
.reviews-detail-card > .reviews-detail-section:first-of-type { border-top: none; padding-top: 0.5rem; }
.reviews-detail-subhead { margin: 0 0 0.5rem; font-size: 0.72rem; font-weight: 700; color: #9ca3af; text-transform: uppercase; letter-spacing: 0.03em; }
.reviews-field-row { display: flex; align-items: baseline; gap: 0.75rem; padding: 0.28rem 0; font-size: 0.85rem; }
.reviews-field-label { width: 150px; flex: none; color: #6b7280; font-weight: 600; }
.reviews-field-value { color: var(--kcpc-ink); font-weight: 500; word-break: break-word; }
.reviews-freetext { margin: 0; font-size: 0.85rem; color: var(--kcpc-ink); white-space: pre-wrap; }

/* "Reviewing Idea" card: single-column inline field list (see reviews-ideas.jspf) - every
   .reviews-field-row above already renders label+value on one line by default, this is just the
   list container; the shared 2-column .reviews-detail-fields-grid/.reviews-detail-col classes stay
   untouched for reviews-shoot.jspf/reviews-edit.jspf. Description/Details' always-visible note
   icon sits right after its inline preview text/dash, with a small consistent gap. */
.reviews-detail-section-list { display: flex; flex-direction: column; }
.reviews-field-value-with-icon .script-description-icon-btn { margin-left: 0.35rem; vertical-align: middle; }

.reviews-history-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.6rem; }
.reviews-history-list li { padding-bottom: 0.5rem; border-bottom: 1px solid var(--kcpc-border); font-size: 0.82rem; }
.reviews-history-list li:last-child { border-bottom: none; padding-bottom: 0; }
.reviews-history-meta { display: block; margin-top: 0.2rem; font-size: 0.76rem; color: #6b7280; }
.reviews-history-reason { margin: 0.3rem 0 0; font-size: 0.82rem; color: var(--kcpc-ink); }
.reviews-history-details { margin-top: 0.6rem; font-size: 0.82rem; }
.reviews-history-details summary { cursor: pointer; color: #1d4ed8; font-weight: 600; }

.reviews-feedback-box { border-radius: 8px; padding: 0.7rem 0.85rem; font-size: 0.84rem; }
.reviews-feedback-box.status-completed { background: #f0fdf4; border: 1px solid #bbf7d0; }
.reviews-feedback-box.status-rejected { background: #fff7ed; border: 1px solid #fed7aa; }
/* ENG-090: Skip Stage - muted/neutral, distinct from Approved (green) and Rework (orange). */
.reviews-feedback-box.status-skipped { background: #f3f4f6; border: 1px solid #e5e7eb; }
.reviews-feedback-box p { margin: 0 0 0.4rem; color: var(--kcpc-ink); }
.reviews-feedback-meta { font-size: 0.76rem; color: #6b7280; display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }

.idea-action-badge.status-completed { background: #dcfce7; color: #166534; }
.idea-action-badge.status-rejected { background: #fff7ed; color: #9a3412; }
.idea-action-badge.status-skipped { background: #e5e7eb; color: #374151; }

.reviews-decision-section { display: flex; flex-direction: column; gap: 0.5rem; }
.reviews-decision-buttons, .reviews-plan-decision-buttons { display: flex; gap: 0.6rem; flex-wrap: wrap; }
/* Edit Review -> Request Shoot Rework: New Planned Shoot Date + the Shoot team that gets the reshoot. */
.reviews-shoot-rework-fields { display: flex; flex-direction: column; gap: 0.5rem; }
.reviews-shoot-rework-fields.hidden { display: none; }
.reviews-shoot-rework-fields label { display: flex; flex-direction: column; gap: 0.25rem; font-weight: 600; font-size: 0.85rem; }
.reviews-shoot-rework-team-list { margin: 0.25rem 0 0; padding-left: 1.1rem; font-size: 0.85rem; }
.reviews-decision-btn {
    flex: 1 1 auto; display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem;
    padding: 0.55rem 0.9rem; border-radius: 7px; font-size: 0.85rem; font-weight: 700; cursor: pointer;
    border: 1px solid var(--kcpc-border); background: #fff; color: var(--kcpc-ink);
}
.reviews-decision-btn:disabled { opacity: 0.6; cursor: not-allowed; }
.reviews-decision-approve { background: #16a34a; border-color: #16a34a; color: #fff; }
.reviews-decision-approve:hover:not(:disabled) { background: #15803d; }
.reviews-decision-reject { background: #fff; border-color: #fecaca; color: #b91c1c; }
.reviews-decision-reject:hover:not(:disabled) { background: #fee2e2; }
.reviews-decision-retain { background: #7c3aed; border-color: #7c3aed; color: #fff; }
.reviews-decision-retain:hover:not(:disabled) { background: #6d28d9; }
.reviews-decision-btn-selected { box-shadow: 0 0 0 3px rgba(29, 78, 216, 0.25); }
/* Reviews -> Ideas "Retained" sub-view (added after Idea Queue was removed from CEO/MM nav) - its
   own small toggle above the queue table, and the Reopen button standing in for Approve/Reject/
   Retain in the detail panel once an idea is selected there. Reopen deliberately does NOT share
   .reviews-decision-btn (its click handler posts to the Approve/Reject/Retain decision endpoint,
   which Reopen must never hit) - this duplicates just its base look, in the same blue Retain
   already uses since Reopen is the same kind of neutral/administrative action. */
.reviews-idea-subtabs { display: flex; gap: 0.4rem; margin-bottom: 0.75rem; }
.reviews-idea-subtab { font-size: 0.8rem; padding: 0.4rem 0.2rem; }
.reviews-idea-reopen-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem;
    padding: 0.55rem 0.9rem; border-radius: 7px; font-size: 0.85rem; font-weight: 700; cursor: pointer;
    border: 1px solid #93c5fd; background: #fff; color: #1d4ed8;
}
.reviews-idea-reopen-btn:hover:not(:disabled) { background: #eff6ff; }
.reviews-idea-reopen-btn:disabled { opacity: 0.6; cursor: not-allowed; }
.reviews-decision-rework { background: #fff; border-color: #fecaca; color: #b91c1c; }
.reviews-decision-rework:hover:not(:disabled) { background: #fee2e2; }
.reviews-marks-row { margin: 0.2rem 0; }
#reviewsIdeaReason, #reviewsPlanReason { width: 100%; padding: 0.6rem; border: 1px solid var(--kcpc-border); border-radius: 6px; font: inherit; resize: vertical; margin-top: 0.3rem; }
#reviewsIdeaReasonLabel, #reviewsPlanReasonLabel { font-weight: 600; font-size: 0.85rem; }
.reviews-decision-error {
    background: #fee2e2; border: 1px solid #fecaca; color: #991b1b; border-radius: 6px;
    padding: 0.5rem 0.7rem; font-size: 0.82rem;
}

/* Idea Review & Planning redesign: top card 2-column field grid (Title stays full-width above it),
   mirrors .idea-detail-fields-grid/.idea-detail-col's own layout for the same kind of content. */
.reviews-detail-fields-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 2rem; }
.reviews-detail-col { display: flex; flex-direction: column; }
.reviews-field-row-full { flex-direction: column; align-items: flex-start; gap: 0.15rem; }

/* Approve info banner - same informational-blue convention as .note-box, just with an icon and a
   little more emphasis since it explains the consequence of the primary action below it. */
.reviews-approve-banner {
    display: flex; align-items: flex-start; gap: 0.6rem; margin: 0.75rem 0;
    background: #eef2ff; border: 1px solid #c7d2fe; color: #3730a3; border-radius: 8px;
    padding: 0.65rem 0.85rem; font-size: 0.85rem;
}
.reviews-approve-banner svg { width: 18px; height: 18px; flex: none; margin-top: 0.1rem; }

/* Numbered planning sections (Planning Basics / Schedule / Planned Outputs / Initial Shoot
   Assignment / Team Marks) - small blue circled ordinal + title, each its own white card. */
.reviews-planning-card { margin-top: 0.9rem; padding: 1rem 1.1rem; }
.reviews-planning-card:first-child { margin-top: 1rem; }
.reviews-section-heading {
    display: flex; align-items: center; gap: 0.55rem; margin: 0 0 0.75rem;
    font-size: 0.92rem; font-weight: 700; color: var(--kcpc-ink);
}
.reviews-section-number {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; flex: none; border-radius: 50%;
    background: #eef2ff; color: #4338ca; font-size: 0.78rem; font-weight: 700;
}

/* Planned Outputs: one fixed row per Output Type (Story/Post/Reel/Long Video, V31 redesign - was
   Photography/Reel/Video) - a row's own "select this type" checkbox controls whether it
   contributes an output group to the approval payload. Only two columns: Output Type and
   Platform/Channel - no Reel Type or Output Description field any more. All state (which rows are
   checked, which platforms are selected) lives in the DOM; see reviews-workspace.js - there is no
   Content Plan yet to attach outputs to until the whole approval commits. */
.idea-detail-outputs-heading { margin: 1rem 0 0.2rem; font-size: 0.92rem; font-weight: 700; color: var(--kcpc-ink); }
.reviews-outputs-grid-wrap { overflow-x: auto; }
.reviews-outputs-grid th, .reviews-outputs-grid td { font-size: 0.83rem; padding: 0.6rem 0.7rem; vertical-align: top; }
.reviews-outputs-grid th .muted { font-weight: 400; text-transform: none; letter-spacing: normal; }

.reviews-output-row-disabled .reviews-platform-picker { pointer-events: none; opacity: 0.55; }

.reviews-output-type-toggle { display: flex; align-items: flex-start; gap: 0.6rem; font-weight: 400; cursor: pointer; }
.reviews-output-type-toggle input[type="checkbox"] { width: auto; margin-top: 0.25rem; }
.reviews-output-type-icon {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 2rem; height: 2rem; border-radius: 8px;
}
.reviews-output-type-icon svg { width: 1.05rem; height: 1.05rem; }
.reviews-output-type-icon-STORY { background: #fce7f3; color: #9d174d; }
.reviews-output-type-icon-POST { background: #dcfce7; color: #166534; }
.reviews-output-type-icon-REEL { background: #ede9fe; color: #6d28d9; }
.reviews-output-type-icon-LONG_VIDEO { background: #dbeafe; color: #1d4ed8; }
.reviews-output-type-copy { display: flex; flex-direction: column; gap: 0.15rem; }
.reviews-output-type-copy strong { font-size: 0.85rem; }
.reviews-output-type-copy .muted { font-size: 0.74rem; font-weight: 400; }

.reviews-platform-picker { min-width: 190px; }
.reviews-platform-picker-toggle {
    display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
    list-style: none; cursor: pointer; background: var(--kcpc-surface);
    border: 1px solid var(--kcpc-border); border-radius: 6px; padding: 0.4rem 0.55rem; font-size: 0.8rem;
}
.reviews-platform-picker-toggle::-webkit-details-marker { display: none; }
.reviews-platform-chips { display: flex; flex-wrap: wrap; gap: 0.3rem; }
/* .reviews-output-platform-chip carries NO styling of its own any more: the selected-channel chips
   in the Planned Outputs grid are the application's existing Platform x Channel chip
   (.pipeline-platform-chip.muted + .pipeline-platform-icon + .pipeline-platform-count, defined once
   above and rendered by fragments/pipeline-platform-chip.jspf on the Content Pipeline). The class
   survives only as the hook the grid's own popover handler binds to. */
.reviews-platform-picker-count { font-size: 0.72rem; white-space: nowrap; }
.reviews-output-target-checklist { margin-top: 0.4rem; }
.reviews-output-platform-popovers:empty { display: none; }
/* Idea Review & Planning's multi-select Channel picker (planned-outputs-grid.jspf, pogChannelMode) -
   reuses .reviews-platform-picker and its chips; only the pieces below are its own. */
.reviews-output-channel-picker { min-width: 220px; }
/* No Output Type column there: the single Main Channel column is a plain full-width field - its
   header reads like the other .panel labels and the picker runs edge to edge. */
.reviews-outputs-grid.reviews-outputs-grid-channel { border: 0; background: transparent; }
.reviews-outputs-grid-channel th, .reviews-outputs-grid-channel td { padding: 0; border-bottom: 0; background: transparent; }
.reviews-outputs-grid-channel th { font-size: 0.85rem; font-weight: 600; padding-bottom: 0.25rem; }
.reviews-outputs-grid-channel .reviews-platform-picker,
.reviews-outputs-grid-channel .reviews-output-channel-picker { min-width: 0; }
.reviews-output-channel-count { font-size: 0.72rem; white-space: nowrap; }
.reviews-output-channel-checklist { margin-top: 0.4rem; }
.reviews-output-row-disabled .reviews-output-channel-hint { opacity: 0.55; }
.reviews-output-channel-hint { margin: 0.3rem 0 0; font-size: 0.72rem; }
.reviews-output-channel-data, .reviews-output-channel-collab[hidden], .reviews-output-channel-collab-empty[hidden] { display: none !important; }
.reviews-output-channel-collab {
    display: flex; flex-direction: column; gap: 0.2rem;
    margin: 0.1rem 0 0.4rem 1.4rem; padding-left: 0.6rem; border-left: 2px solid var(--kcpc-border, #e3e3e3);
}
.reviews-output-channel-collab-label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.03em; }
.reviews-output-channel-collab-options { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.9rem; }
.reviews-output-channel-collab-item { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.78rem; font-weight: 400; white-space: nowrap; }
.reviews-output-channel-collab-item input { width: auto; }
.reviews-output-channel-collab-empty { font-size: 0.75rem; font-style: italic; }
.reviews-output-channel-option { display: flex; flex-wrap: wrap; align-items: center; column-gap: 0.4rem; }
.reviews-output-channel-option > .reviews-output-channel-collab { flex-basis: 100%; }
.reviews-platform-popover {
    background: var(--kcpc-surface); border: 1px solid var(--kcpc-border); border-radius: 10px;
    box-shadow: 0 6px 16px rgba(15, 23, 42, 0.1); padding: 0.65rem 0.75rem; margin-top: 0.5rem;
    min-width: min(260px, 100%); max-width: 100%; overflow-x: auto;
}
.reviews-platform-popover-header { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.4rem; }
.reviews-platform-popover-title { display: flex; align-items: center; gap: 0.35rem; font-weight: 700; font-size: 0.8rem; }
.reviews-platform-popover-published { font-size: 0.7rem; color: #6b7280; white-space: nowrap; }
.reviews-platform-popover-table { width: 100%; border-collapse: collapse; font-size: 0.73rem; }
.reviews-platform-popover-table th { text-align: left; color: #6b7280; font-weight: 600; padding: 2px 8px 2px 0; white-space: nowrap; }
.reviews-platform-popover-table td { padding: 3px 8px 3px 0; white-space: nowrap; }

.reviews-drive-input { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.25rem; }
.reviews-drive-input svg { width: 16px; height: 16px; flex: none; color: #4338ca; }
.reviews-drive-input input { flex: 1 1 auto; margin-top: 0; }

.reviews-schedule-hint { display: block; margin-top: 0.25rem; font-size: 0.72rem; font-weight: 400; color: #6b7280; }
/* Standard Planning Mode: real-time inline error when the calculated Shoot/Edit Date lands
   before today - never an alert/popup, clears itself the moment a later Planned Live Date
   recalculates both dates back into range. */
.reviews-schedule-error { display: block; margin-top: 0.25rem; font-size: 0.72rem; font-weight: 600; color: #b91c1c; }
.reviews-field-hint { margin: 0.4rem 0 0; font-size: 0.78rem; color: #6b7280; }

/* Bottom confirm bar - the actual submit action once a decision is selected above; label text is
   set by JS per decision (Approve & Assign Shoot / Reject Idea / Retain Idea). */
.reviews-decision-confirm-bar {
    display: flex; justify-content: flex-end; gap: 0.6rem; margin-top: 1rem;
    padding-top: 0.85rem; border-top: 1px solid var(--kcpc-border);
}
.reviews-decision-confirm-btn {
    padding: 0.6rem 1.1rem; border-radius: 7px; font-size: 0.88rem; font-weight: 700; cursor: pointer;
    border: 1px solid #1d4ed8; background: #1d4ed8; color: #fff;
}
.reviews-decision-confirm-btn:hover:not(:disabled) { background: #1e40af; }
.reviews-decision-confirm-btn:disabled { opacity: 0.6; cursor: not-allowed; }

.reviews-qualifying-picker { margin: 0.2rem 0; }
.reviews-qualifying-checklist { display: flex; flex-direction: column; gap: 0.3rem; max-height: 140px; overflow-y: auto; margin-top: 0.35rem; }

.delay-badge { display: inline-block; padding: 0.12rem 0.55rem; border-radius: 999px; font-size: 0.72rem; font-weight: 700; white-space: nowrap; }
.delay-badge.delay-ontime { background: #dcfce7; color: #166534; }
.delay-badge.delay-late { background: #fee2e2; color: #b91c1c; }

@media (max-width: 1100px) {
    .reviews-body { flex-direction: column; }
    .reviews-queue, .reviews-detail { flex: 1 1 100%; width: 100%; min-width: 0; }
    .reviews-detail { position: static; max-height: none; }
}

/* ============================================================================
   CEO/MM Reports Workspace - KPI Dashboard / Delayed Deliverables / Administrative
   Actions / Audit History / Export, one shared tab bar + table/filter/pagination
   visual language. Missing/absent values render as a plain "-" everywhere in this
   section (never an em-dash/mdash) - see the JSPs; this stylesheet doesn't need to
   do anything special for that, a hyphen is just text.
   ============================================================================ */
.reports-asof {
    display: flex; align-items: center; gap: 0.5rem; background: var(--kcpc-surface);
    border: 1px solid var(--kcpc-border); border-radius: 8px; padding: 0.6rem 1rem;
    font-size: 0.85rem; color: #4b5563; white-space: nowrap; height: fit-content;
}
.reports-asof svg { width: 15px; height: 15px; flex: none; }

.reports-tabs { display: flex; gap: 1.5rem; border-bottom: 1px solid var(--kcpc-border); margin-bottom: 1.25rem; }
.reports-tab {
    padding: 0.6rem 0.1rem; font-weight: 600; font-size: 0.92rem; color: #6b7280;
    text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.reports-tab.active { color: var(--kcpc-accent); border-bottom-color: var(--kcpc-accent); }
.reports-tab:hover:not(.active) { color: var(--kcpc-ink); }

/* Loading state, scoped to one report's own dynamic region only - never the whole page (spec
   §17). Cleared in both the fetch success AND catch paths in reports-workspace.js. */
.reports-loading { opacity: 0.55; pointer-events: none; transition: opacity 0.15s ease; }

.reports-filters {
    display: flex; align-items: flex-end; gap: 1.1rem; flex-wrap: wrap;
    background: var(--kcpc-surface); border: 1px solid var(--kcpc-border); border-radius: 10px;
    padding: 0.9rem 1.1rem; margin-bottom: 1.1rem;
}
.reports-filters .filter-field { display: flex; flex-direction: column; gap: 0.3rem; }
.reports-filters .filter-field label { font-size: 0.76rem; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.02em; }
.reports-filters input[type="text"], .reports-filters input[type="date"], .reports-filters select {
    padding: 0.45rem 0.6rem; border: 1px solid var(--kcpc-border); border-radius: 6px; font-size: 0.85rem;
    height: 2.35rem; background: var(--kcpc-surface); color: var(--kcpc-ink);
}
.reports-filters .filter-field-search input { min-width: 220px; }
.reports-clear, .reports-filter-submit { height: 2.35rem; display: inline-flex; align-items: center; gap: 0.35rem; white-space: nowrap; }
.reports-filter-submit svg { width: 14px; height: 14px; }
.reports-filter-note { flex-basis: 100%; margin: 0.4rem 0 0; font-size: 0.78rem; }

/* KPI Dashboard's date range is the form's only field - a compact single-line toolbar instead of
   the label-above-input column layout other (multi-field) .reports-filters forms use. Scoped to
   .kpi-date-toolbar only, so Delayed Deliverables/Admin Actions/Audit History filter bars are
   unaffected. */
.kpi-date-toolbar { padding: 0.55rem 0.9rem; align-items: center; }
.kpi-date-toolbar .kpi-date-field { flex-direction: row; align-items: center; gap: 0.55rem; }
.kpi-date-toolbar .kpi-date-field label { margin: 0; white-space: nowrap; }
/* Apply sits on the same line as the date fields: cancel the global submit-button margin-top and
   size it to the 2.35rem filter controls beside it. */
.kpi-date-toolbar .kpi-date-apply-btn { margin: 0; height: 2.35rem; padding: 0 1rem; display: inline-flex; align-items: center; }

.reports-kpi-group { padding: 1.1rem 1.3rem; }
.reports-kpi-group-title { margin: 0 0 0.9rem; font-size: 1rem; font-weight: 700; }
.kpi-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.3rem; }
.kpi-title { font-weight: 600; font-size: 0.85rem; color: var(--kcpc-ink); }
.kpi-code { font-size: 0.7rem; color: #9ca3af; font-weight: 600; white-space: nowrap; }
.kpi-breakdown { list-style: none; margin: 0.55rem 0 0; padding: 0.5rem 0 0; border-top: 1px solid var(--kcpc-border); display: flex; flex-direction: column; gap: 0.2rem; }
.kpi-breakdown li { display: flex; justify-content: space-between; gap: 0.5rem; font-size: 0.76rem; color: #4b5563; }
.kpi-breakdown-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kpi-breakdown-count { font-weight: 700; color: var(--kcpc-ink); flex: none; }
.kpi-breakdown-more { margin-top: 0.4rem; font-size: 0.78rem; }
.kpi-breakdown-more summary { cursor: pointer; color: #1d4ed8; font-weight: 600; }
.kpi-breakdown-more .kpi-breakdown { border-top: none; padding-top: 0.4rem; }

/* KPI Dashboard (Overview/Workflow & SLA/Content & Publishing/Quality & Reviews/Performance) */
.kpi-cards.kpi-cards-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) {
    .kpi-cards.kpi-cards-4 { grid-template-columns: repeat(2, 1fr); }
}
.kpi-view-tabs { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.kpi-view-tab {
    padding: 0.5rem 0.95rem; border-radius: 999px; font-weight: 600; font-size: 0.85rem;
    color: #6b7280; text-decoration: none; background: var(--kcpc-surface); border: 1px solid var(--kcpc-border);
}
.kpi-view-tab.active { color: #fff; background: var(--kcpc-accent); border-color: var(--kcpc-accent); }
.kpi-view-tab:hover:not(.active) { color: var(--kcpc-ink); border-color: #9ca3af; }

.kpi-overview-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin-bottom: 1.5rem; }
@media (max-width: 1100px) {
    .kpi-overview-grid { grid-template-columns: 1fr; }
}
.kpi-overview-grid .panel { padding: 1.1rem 1.3rem; }
.kpi-overview-grid.kpi-overview-grid-2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 700px) {
    .kpi-overview-grid.kpi-overview-grid-2 { grid-template-columns: 1fr; }
}

.kpi-attention-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.6rem; }
.kpi-attention-list li { display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; }
.kpi-attention-icon { color: #ea580c; }
.kpi-attention-text { flex: 1; }
.kpi-attention-link { color: var(--kcpc-accent); font-weight: 700; text-decoration: none; }

.kpi-funnel { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; }
.kpi-funnel-stage {
    width: 100%; text-align: center; padding: 0.6rem 0.8rem; border-radius: 8px;
    background: #eff6ff; display: flex; flex-direction: column;
}
.kpi-funnel-stage.kpi-funnel-approved { background: #f0fdf4; }
.kpi-funnel-stage.kpi-funnel-planned { background: #faf5ff; }
.kpi-funnel-stage.kpi-funnel-published { background: #fff7ed; }
.kpi-funnel-count { font-size: 1.2rem; font-weight: 800; color: var(--kcpc-ink); }
.kpi-funnel-label { font-size: 0.76rem; color: #6b7280; }
.kpi-funnel-arrow { color: #9ca3af; font-size: 0.9rem; }
.kpi-funnel-branch { display: flex; gap: 1.2rem; font-size: 0.78rem; color: #6b7280; margin: 0.1rem 0; }
.kpi-funnel-branch-item strong { color: var(--kcpc-ink); margin-left: 0.25rem; }
.kpi-funnel-note { margin-top: 0.6rem; font-size: 0.78rem; }

/* Overview (ENG-097 redesign): Current Work Ownership / Upcoming Channel Plan block styling. */
.kpi-block-subtitle { margin: -0.4rem 0 0.9rem; font-size: 0.82rem; }

.kpi-upcoming-plan { display: flex; flex-direction: column; gap: 0.7rem; max-height: 420px; overflow-y: auto; }
.kpi-upcoming-date-group { border-bottom: 1px solid var(--kcpc-border); padding-bottom: 0.6rem; }
.kpi-upcoming-date-group:last-child { border-bottom: none; padding-bottom: 0; }
.kpi-upcoming-date { font-weight: 700; font-size: 0.88rem; color: var(--kcpc-ink); margin-bottom: 0.35rem; }
.kpi-upcoming-channel-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.kpi-upcoming-channel-list li { display: flex; justify-content: space-between; font-size: 0.85rem; color: #374151; }
.kpi-upcoming-channel-name::before { content: "\2022"; margin-right: 0.4rem; color: #9ca3af; }
.kpi-upcoming-channel-count { font-weight: 700; color: var(--kcpc-ink); }

/* Current Work Ownership -> "Open" drill-down (reports-kpi-ownership-drilldown.js). */
.kpi-drilldown-header h3 { margin: 0 0 0.15rem; }
.kpi-drilldown-counts { font-weight: 700; margin: 0.3rem 0 1rem; }
.kpi-drilldown-tabs { display: flex; gap: 0.5rem; margin-bottom: 1rem; border-bottom: 1px solid var(--kcpc-border); }
.kpi-drilldown-tab {
    background: none; border: none; border-bottom: 2px solid transparent; padding: 0.5rem 0.2rem;
    margin-right: 1rem; font-size: 0.88rem; font-weight: 600; color: #6b7280; cursor: pointer;
}
.kpi-drilldown-tab.active { color: var(--kcpc-accent); border-bottom-color: var(--kcpc-accent); }
.kpi-drilldown-panel.hidden { display: none; }

/* Upcoming Channel Plan card header row (title + calendar-icon trigger, top-right) - a dedicated
   flex wrapper rather than reusing .card-head-row, since that class's own `h2 { margin: 0; }`
   override would change this card's existing title-to-subtitle spacing as an unintended side
   effect. The trigger button itself reuses .idea-details-trigger as-is (already the app's small
   secondary icon-button convention) - no new button styling needed. */
.kpi-upcoming-plan-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }

/* Upcoming Channel Plan -> calendar popover (reports-kpi-calendar.js). Reuses the shared
   .kcpc-modal-* shell (same as the Current Work Ownership drill-down above) for visual
   consistency within this same card row. */
.kpi-calendar-modal { width: min(360px, 92vw); }
.kpi-calendar-nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.6rem; }
.kpi-calendar-nav .btn-outline { padding: 0.25rem 0.6rem; font-size: 0.85rem; }
.kpi-calendar-month-label { font-weight: 700; font-size: 0.92rem; }
.kpi-calendar-weekdays {
    display: grid; grid-template-columns: repeat(7, 1fr); text-align: center;
    font-size: 0.72rem; color: #6b7280; margin-bottom: 0.3rem;
}
.kpi-calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 0.2rem; }
/* Every day cell shares this base "normal" look - only .kpi-calendar-cell-planned/-selected below
   add anything further, so an unplanned date always stays visually normal, per spec. */
.kpi-calendar-cell {
    display: flex; align-items: center; justify-content: center; height: 2.1rem; border-radius: 6px;
    font-size: 0.82rem; color: var(--kcpc-ink); background: none; border: 1px solid transparent;
    font-family: inherit;
}
.kpi-calendar-cell-empty { visibility: hidden; }
/* Only a planned date is ever rendered as a real <button> (see reports-kpi-calendar.js) - an
   unplanned date is a plain, non-interactive <span> with no special styling at all. */
button.kpi-calendar-cell-planned {
    cursor: pointer; font-weight: 700; background: #eff6ff; border-color: #bfdbfe; color: #1d4ed8;
}
button.kpi-calendar-cell-planned:hover { background: #dbeafe; }
button.kpi-calendar-cell-selected { background: #1d4ed8; border-color: #1d4ed8; color: #fff; }
/* Explicit, same pattern as .pipeline-platform-chip:focus-visible above - a keyboard user tabbing
   through planned dates/nav/close must always see exactly where focus is. */
.kpi-calendar-cell-planned:focus-visible, .kpi-calendar-prev:focus-visible,
.kpi-calendar-next:focus-visible { outline: 2px solid var(--kcpc-accent); outline-offset: 1px; }
.kpi-calendar-legend {
    display: flex; gap: 1rem; margin-top: 0.5rem; font-size: 0.72rem; color: #6b7280; flex-wrap: wrap;
}
.kpi-calendar-legend-dot {
    display: inline-block; width: 0.6rem; height: 0.6rem; border-radius: 50%; margin-right: 0.3rem;
    vertical-align: middle;
}
.kpi-calendar-legend-dot-planned { background: #1d4ed8; opacity: 0.35; }
.kpi-calendar-legend-dot-selected { background: #1d4ed8; }
.kpi-calendar-detail { margin-top: 0.9rem; padding-top: 0.8rem; border-top: 1px solid var(--kcpc-border); }
.kpi-calendar-detail-date { margin: 0 0 0.5rem; font-size: 0.88rem; font-weight: 700; }
.kpi-calendar-detail-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.35rem; }
.kpi-calendar-detail-list li { display: flex; justify-content: space-between; font-size: 0.85rem; gap: 0.75rem; }
.kpi-calendar-detail-count { font-weight: 700; }
/* Content Details: an optional, collapsed-by-default <details> section (only rendered when the
   data actually carries contentIds - see reports-kpi-calendar.js) - a plain list, not a table,
   since it's just an id + a static "Planned" status pill per row. */
.kpi-calendar-content-details { margin-top: 0.7rem; font-size: 0.82rem; }
.kpi-calendar-content-details summary { cursor: pointer; font-weight: 700; color: var(--kcpc-ink); }
.kpi-calendar-content-list {
    list-style: none; margin: 0.5rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.35rem;
    max-height: 180px; overflow-y: auto;
}
.kpi-calendar-content-list li { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; }
.kpi-calendar-content-id { font-family: monospace; }

.kpi-metric-row { display: flex; justify-content: space-between; padding: 0.4rem 0; border-bottom: 1px solid var(--kcpc-border); font-size: 0.85rem; }
.kpi-metric-row:last-of-type { border-bottom: none; }
.kpi-footnote { margin-top: 0.6rem; font-size: 0.76rem; }
.kpi-view-link { margin-top: 0.6rem; }
.kpi-view-link a { color: var(--kcpc-accent); font-weight: 700; text-decoration: none; }
.kpi-dashboard-footnote { margin-top: 1rem; }

/* ================================================================== KPI Dashboard charts
   (visual analytics phase). Every value drawn here is rendered server-side in JSTL/EL directly
   from the same approved DTO fields already shown as text elsewhere on the page - no chart
   library, no client-side calculation. Bar widths are simple proportional scaling (value/total or
   value/max) of numbers already displayed as exact text alongside the bar, never a substitute for
   the real number. Semantic colors are restrained and reuse the existing kpi-card/stage-dot
   palette (see .kpi-card.kpi-completed/.kpi-delayed/.stage-dot-* above) - never a rainbow. */

.kpi-chart-empty-note { font-size: 0.82rem; color: #9ca3af; font-style: italic; padding: 0.5rem 0; }

/* Horizontal bar chart: one row per category - label | proportional track+fill | exact value.
   Reused for the Funnel, Within SLA % by Stage, Rework Rate by Stage, Platform/Channel
   Distribution, CTR rankings, and the ORIGINAL vs REPOST comparison charts. */
.kpi-hbar-chart { display: flex; flex-direction: column; gap: 0.5rem; margin: 0.6rem 0; }
.kpi-hbar-row { display: grid; grid-template-columns: minmax(90px, 130px) 1fr auto; align-items: center; gap: 0.6rem; }
.kpi-hbar-row.kpi-hbar-row-branch { grid-template-columns: minmax(70px, 100px) 1fr auto; margin-left: 1.2rem; }
.kpi-hbar-label { font-size: 0.8rem; font-weight: 600; color: var(--kcpc-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi-hbar-track { position: relative; height: 0.95rem; background: #eef0f3; border-radius: 999px; overflow: hidden; }
.kpi-hbar-track.kpi-hbar-track-thin { height: 0.6rem; }
.kpi-hbar-fill { height: 100%; border-radius: 999px; min-width: 2px; }
.kpi-hbar-value { font-size: 0.78rem; font-weight: 700; color: var(--kcpc-ink); white-space: nowrap; text-align: right; }
.kpi-hbar-value .kpi-hbar-sub { font-size: 0.68rem; color: #6b7280; font-weight: 500; margin-left: 0.3rem; }

.kpi-hbar-fill-positive { background: #047857; }
.kpi-hbar-fill-warning { background: #c2410c; }
.kpi-hbar-fill-danger { background: #b91c1c; }
.kpi-hbar-fill-neutral { background: #1d4ed8; }
.kpi-hbar-fill-neutral-2 { background: #6d28d9; }
.kpi-hbar-fill-original { background: #1d4ed8; }
.kpi-hbar-fill-repost { background: #a855f7; }
.kpi-hbar-fill-retained { background: #d97706; }
.kpi-hbar-fill-rejected { background: #b91c1c; }

/* Donut chart: fixed-size SVG ring + legend list. Reused for Planned Output Mix and Target
   Completion. Segment colors cycle through a small restrained qualitative palette (never a rainbow). */
.kpi-donut-wrap { display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap; }
.kpi-donut-svg { flex: none; }
.kpi-donut-center-value { font-size: 15px; font-weight: 700; fill: var(--kcpc-ink); }
.kpi-donut-center-label { font-size: 8px; fill: #6b7280; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; }
.kpi-donut-legend { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; flex: 1 1 170px; min-width: 160px; }
.kpi-donut-legend li { display: flex; align-items: center; gap: 0.45rem; font-size: 0.78rem; color: var(--kcpc-ink); }
.kpi-donut-legend li.kpi-donut-legend-na { color: #6b7280; }
.kpi-donut-swatch { width: 0.65rem; height: 0.65rem; border-radius: 3px; flex: none; }
.kpi-donut-legend-count { margin-left: auto; font-weight: 700; }
.kpi-donut-legend-pct { color: #6b7280; font-size: 0.72rem; min-width: 3.2rem; text-align: right; }

.kpi-donut-color-0, .kpi-donut-color-positive { stroke: #047857; background: #047857; }
.kpi-donut-color-1 { stroke: #1d4ed8; background: #1d4ed8; }
.kpi-donut-color-2 { stroke: #6d28d9; background: #6d28d9; }
.kpi-donut-color-3 { stroke: #c2410c; background: #c2410c; }
.kpi-donut-color-4 { stroke: #0f766e; background: #0f766e; }
.kpi-donut-color-5 { stroke: #be185d; background: #be185d; }
.kpi-donut-color-track { stroke: #eef0f3; background: #eef0f3; }
.kpi-donut-color-na { stroke: #9ca3af; background: #9ca3af; }

/* Segmented single-row bar - a whole-bar split into proportional colored segments in place, used
   for Delay Aging and the ORIGINAL/REPOST proportion bar. */
.kpi-segbar { display: flex; height: 1.7rem; border-radius: 6px; overflow: hidden; background: #eef0f3; }
.kpi-segbar-segment { display: flex; align-items: center; justify-content: center; font-size: 0.7rem; font-weight: 700; color: #fff; overflow: hidden; white-space: nowrap; }
.kpi-segbar-legend { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; margin-top: 0.55rem; font-size: 0.76rem; color: var(--kcpc-ink); }
.kpi-segbar-legend-item { display: flex; align-items: center; gap: 0.35rem; }

@media (max-width: 700px) {
    .kpi-hbar-row { grid-template-columns: 90px 1fr auto; }
    .kpi-donut-wrap { flex-direction: column; align-items: flex-start; }
}

.reports-table-panel { padding: 1rem 1.2rem; }
.reports-table-scroll { overflow-x: auto; }
.reports-table { width: 100%; }
.reports-table th { white-space: nowrap; }
.reports-pagination { padding-top: 0.85rem; margin-top: 0.6rem; border-top: 1px solid var(--kcpc-border); flex-wrap: wrap; gap: 1rem; }
.reports-page-size select { padding: 0.35rem 0.6rem; border: 1px solid var(--kcpc-border); border-radius: 6px; font-size: 0.82rem; }
.reports-open-btn { white-space: nowrap; }
.reports-info-banner { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 1rem; }
.reports-meta-subtext { font-size: 0.76rem; color: #6b7280; }
.reports-reason-cell { max-width: 320px; }
.reports-timestamp-cell { white-space: nowrap; }
/* Logs (Audit History) Content ID column - a business Content ID ("C-0926-0001") is a fixed,
   short, non-wrapping shape, so a modest min-width keeps the column stable across rows without
   crowding Record/Module/Reason next to it. */
.audit-content-id-col { min-width: 110px; white-space: nowrap; }
.page-ellipsis { color: #9ca3af; padding: 0 0.2rem; }

.delay-badge.delay-mild { background: #ffedd5; color: #c2410c; }
.delay-badge.delay-strong { background: #fee2e2; color: #b91c1c; }

.admin-action-badge {
    display: inline-block; padding: 0.15rem 0.55rem; border-radius: 999px;
    font-size: 0.75rem; font-weight: 600; white-space: nowrap;
}
.admin-action-badge.admin-action-reassign { background: #dbeafe; color: #1d4ed8; }
.admin-action-badge.admin-action-reschedule { background: #ede9fe; color: #6d28d9; }
.admin-action-badge.admin-action-hold { background: #fee2e2; color: #b91c1c; }
.admin-action-badge.admin-action-resume { background: #dcfce7; color: #166534; }
.admin-action-badge.admin-action-cancel { background: #f3f4f6; color: #6b7280; }
.admin-action-badge.admin-action-reopen { background: #fef9c3; color: #854d0e; }
.admin-action-badge.admin-action-idea_retained { background: #fef3c7; color: #92400e; }
.admin-action-badge.admin-action-permission_grant { background: #dcfce7; color: #166534; }
.admin-action-badge.admin-action-permission_revoke { background: #fee2e2; color: #b91c1c; }
.admin-action-badge.admin-action-generic { background: #eef2ff; color: #3730a3; }

/* Export screen. Generate Export sits beside the Export Format field (not full-width dropdown +
   floating bottom-right button) - align-items: flex-end lines its bottom edge up with the
   dropdown's own bottom edge, since the field column is taller (label + gap + select) than the
   button alone, same technique .pipeline-filter-bar uses to line up mixed-height filter groups.
   flex-wrap lets the button drop to its own line on narrow viewports without horizontal overflow. */
.export-format-panel { padding: 1rem 1.2rem; display: flex; align-items: flex-end; gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem; }
.export-format-field { display: flex; flex-direction: column; gap: 0.4rem; }
.export-format-label { font-weight: 700; font-size: 0.85rem; }
.export-format-select {
    height: 42px; padding: 0 0.7rem; border: 1px solid var(--kcpc-border); border-radius: 6px;
    font-size: 0.9rem; width: 340px; max-width: 100%;
}
/* Compact primary button, not the oversized/clipped default an <svg> with no explicit size and no
   inherited control-height var renders at (browsers default an unsized SVG to 300x150). */
.export-generate-btn { height: 42px; }
.export-generate-btn svg { width: 16px; height: 16px; flex: none; }
.export-scope-panel { padding: 1.1rem 1.3rem; }
.export-scope-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1rem; }
.export-scope-head h2 { margin: 0; font-size: 1rem; }
.export-selected-count { font-size: 0.82rem; color: #6b7280; font-weight: 600; }
.export-scope-groups { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1.5rem; }
.export-scope-group-head { margin-bottom: 0.6rem; padding-bottom: 0.4rem; border-bottom: 1px solid var(--kcpc-border); }
.export-select-all { display: flex; align-items: center; gap: 0.5rem; font-size: 0.88rem; cursor: pointer; }
.export-scope-checklist { display: flex; flex-direction: column; gap: 0.5rem; }
.export-scope-item { display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; color: var(--kcpc-ink); cursor: pointer; }
.export-note { margin: 1rem 0; }
.export-actions { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.export-summary { font-size: 0.85rem; color: #6b7280; }

@media (max-width: 900px) {
    .reports-filters { flex-direction: column; align-items: stretch; }
    .reports-filters .filter-field-search input { min-width: 0; }
}

/* Administration shell - Users/Business Roles/Permissions/Publishing Catalogue, one secondary
   tab bar (fragments/admin-tabs.jspf), same visual recipe as .reports-tabs/.reports-tab. */
.admin-tabs { display: flex; gap: 1.5rem; border-bottom: 1px solid var(--kcpc-border); margin-bottom: 1.25rem; }
.admin-tab {
    padding: 0.6rem 0.1rem; font-weight: 600; font-size: 0.92rem; color: #6b7280;
    text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.admin-tab.active { color: var(--kcpc-accent); border-bottom-color: var(--kcpc-accent); }

/* ENG-091: Administration screens visual modernization (Users/Business Roles/Permissions/
   Publishing Catalogue) - UI only, reusing the app's existing card/table/badge/button/banner
   system (.panel, .data-table, .status-pill, .btn-primary, .btn-outline, .note-box, .pagination)
   wherever it already fits, adding only the handful of layout/badge primitives those screens
   still needed (2-col/3-col workspace grids, a compact search+segmented-filter toolbar, a
   green/grey Active-Deactivated badge pair, small icon-buttons for catalogue row actions, and a
   user-avatar chip). No route, form field, or validation behavior changes anywhere in this block
   or the markup that uses it. */
.admin-page-lead { color: #6b7280; font-size: 0.9rem; margin: -0.75rem 0 1.25rem; max-width: 780px; }

/* Active/Deactivated - same shape as every other .status-pill, own colors (green vs neutral grey,
   never red, so a deactivated row doesn't read as an error state). */
.status-pill.status-active { background: #dcfce7; color: #166534; }
.status-pill.status-inactive { background: #f3f4f6; color: #6b7280; }

/* Users/Permissions tables: row-compactness + long-email safety without touching .data-table
   globally (other screens' tables keep their current row height/wrapping). */
.admin-table td, .admin-table th { padding: 0.55rem 0.75rem; }
.admin-table .admin-email-cell { word-break: break-all; }
.admin-table .admin-access-class { color: #6b7280; font-size: 0.82rem; }

/* Users page header + "Import Users" compact action (User CSV Import feature). */
.admin-users-header-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.admin-users-header-row h1 { margin: 0; }

/* Compact icon-buttons (catalogue row Edit, and any other row-level icon action) - square, same
   family as .btn-outline (blue) but sized for a single glyph instead of a text label. */
.icon-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2rem; height: 2rem; padding: 0; border-radius: 6px;
    border: 1px solid var(--kcpc-border); background: var(--kcpc-surface); color: #6b7280;
    cursor: pointer; font-size: 0.95rem; line-height: 1;
}
.icon-btn:hover { background: #f4f5f7; color: var(--kcpc-ink); }

/* Compact destructive/affirmative outline actions (Deactivate/Activate row buttons) - same family
   as .btn-outline (blue) but red for Deactivate and green for Activate, matching the reference
   screens; still a plain <button type="submit"> inside the existing <form>, never a new endpoint. */
/* button.btn-outline-* (not just .btn-outline-*): these only ever land on a <button> nested
   inside a .panel/.action-form, and ".panel button"/".action-form button" (element+class - higher
   specificity than a bare class selector) would otherwise win the cascade and repaint these solid
   red regardless of this rule's own background/color/border/padding here. */
button.btn-outline-danger {
    display: inline-flex; align-items: center; justify-content: center; gap: 0.3rem;
    background: transparent; color: #b91c1c; border: 1px solid #fecaca; border-radius: 6px;
    padding: 0.35rem 0.8rem; margin-top: 0; font-size: 0.8rem; font-weight: 600; cursor: pointer; width: auto;
}
button.btn-outline-danger:hover { background: #fef2f2; }
button.btn-outline-success {
    display: inline-flex; align-items: center; justify-content: center; gap: 0.3rem;
    background: transparent; color: #166534; border: 1px solid #bbf7d0; border-radius: 6px;
    padding: 0.35rem 0.8rem; margin-top: 0; font-size: 0.8rem; font-weight: 600; cursor: pointer; width: auto;
}
button.btn-outline-success:hover { background: #f0fdf4; }

/* Search + segmented All/Active/Deactivated toolbar (Business Roles) - client-side only (the
   underlying list is already fully server-rendered, un-paginated), same 42px control-height
   convention pipeline-filter-bar established. */
.admin-toolbar {
    display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
    flex-wrap: wrap; margin-bottom: 1rem;
}
.admin-search-field { position: relative; flex: 1 1 240px; max-width: 320px; }
.admin-search-field input {
    width: 100%; height: 2.35rem; padding: 0 0.75rem 0 2.1rem;
    border: 1px solid var(--kcpc-border); border-radius: 7px; font-size: 0.85rem;
}
.admin-search-icon {
    position: absolute; left: 0.65rem; top: 50%; transform: translateY(-50%);
    color: #9ca3af; font-size: 0.85rem; pointer-events: none;
}
.segmented-control { display: inline-flex; gap: 0.3rem; background: transparent; }
.segmented-btn {
    height: 2.35rem; padding: 0 0.9rem; border-radius: 7px; border: 1px solid var(--kcpc-border);
    background: var(--kcpc-surface); color: var(--kcpc-ink); font-size: 0.82rem; font-weight: 600;
    cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem;
}
.segmented-btn .dot { width: 0.4rem; height: 0.4rem; border-radius: 999px; display: inline-block; }
.segmented-btn.dot-active .dot { background: #166534; }
.segmented-btn.dot-inactive .dot { background: #b91c1c; }
.segmented-btn.active { background: var(--kcpc-accent); border-color: var(--kcpc-accent); color: #fff; }
.segmented-btn.active .dot { background: #fff; }

/* Business Roles two-column desktop workspace. */
.admin-2col { display: grid; grid-template-columns: 65% 1fr; gap: 1.25rem; align-items: start; }
@media (max-width: 1100px) {
    .admin-2col { grid-template-columns: 1fr; }
}

/* Publishing Catalogue: Platforms/Channels as an equal-width, equal-height top row (they're both
   simple two-column tables and read better side by side than each claiming a third of the width),
   Publication Targets as a full-width card below it (it carries the widest table - Platform |
   Channel | Target Name | Active | Actions - and needs the room). align-items:stretch + height:
   100% on the cards is what makes the two top cards match height even when their row counts
   differ, rather than each shrinking to its own content. */
.catalogue-master-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    align-items: stretch;
}
.catalogue-master-row > .panel {
    height: 100%;
    display: flex;
    flex-direction: column;
    margin-bottom: 0;
}
.publication-targets-card { margin-top: 16px; }
/* A long Platforms/Channels list scrolls inside its own card instead of stretching the card (and
   therefore its sibling) taller than the page can comfortably show. */
.catalogue-table-scroll { max-height: 360px; overflow-y: auto; }
@media (max-width: 700px) {
    .catalogue-master-row { grid-template-columns: 1fr; }
}
/* User Detail (permission-admin-ui layout revision): User Information + Permission Summary sit
   side by side on top (roughly 2:1, ~65-70% / 30-35%) as compact header-context cards; the unified
   Permission Management table is a full-width panel below, so its 9 columns get the whole page
   width instead of being squeezed into a narrow right column. Both top cards stack single-file
   below 1100px, matching every other admin workspace's breakpoint in this file. */
.admin-userdetail-top { display: grid; grid-template-columns: 2fr 1fr; gap: 1.25rem; align-items: start; margin-bottom: 1.25rem; }
@media (max-width: 1100px) {
    .admin-userdetail-top { grid-template-columns: 1fr; }
}
.panel-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.7rem; height: 1.7rem; border-radius: 7px; font-size: 0.85rem; vertical-align: middle;
    margin-right: 0.15rem;
}
.panel-icon.panel-icon-blue { background: #eef2ff; color: #3730a3; }
.admin-avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.5rem; height: 2.5rem; border-radius: 999px;
    background: #eef2ff; color: #3730a3; font-weight: 700; font-size: 0.9rem;
}
.admin-userdetail-identity { display: flex; align-items: center; gap: 0.75rem; margin: 1rem 0; }
.admin-userdetail-identity .admin-userdetail-name { font-weight: 700; }
.admin-userdetail-identity .admin-userdetail-email { color: #6b7280; font-size: 0.82rem; }

/* Business Role / Access Class / Account Status / Account Created as a single divided row, not
   stacked vertical fields - matches the wider card's available horizontal space. */
.admin-userinfo-fields {
    display: flex; flex-wrap: wrap; gap: 1.75rem; padding: 0.9rem 0;
    border-top: 1px solid var(--kcpc-border); border-bottom: 1px solid var(--kcpc-border);
}
.admin-userinfo-fields .admin-userdetail-field-label { font-size: 0.78rem; color: #6b7280; font-weight: 600; margin-bottom: 0.2rem; }
.admin-userinfo-fields .admin-userdetail-field-value { font-size: 0.88rem; font-weight: 600; }

/* Deactivate/Activate + Change Business Role action links - plain icon+text summaries, side by
   side, that expand in place (native <details>) to reveal the reason field. */
.admin-userdetail-actions { display: flex; flex-wrap: wrap; gap: 1.5rem; margin-top: 1rem; }
.admin-action-summary {
    cursor: pointer; font-weight: 600; font-size: 0.85rem; list-style: none;
    display: flex; align-items: center; gap: 0.45rem;
}
.admin-action-summary::-webkit-details-marker { display: none; }
.admin-action-summary::marker { content: ""; }
.admin-action-danger { color: #b91c1c; }
.admin-action-success { color: #166534; }
.admin-action-warn { color: #c2410c; }

.info-icon { color: #9ca3af; font-size: 0.8rem; cursor: help; margin-left: 0.2rem; }

/* Permission Summary card - 4 stat tiles (icon over count over label) laid out in a row, dynamically
   derived (never hardcoded) from the same rows rendered in the table below (permission-admin-ui spec §14). */
.perm-summary-stats { display: flex; justify-content: space-between; gap: 0.5rem; margin: 1rem 0; }
.perm-summary-stat { display: flex; flex-direction: column; align-items: center; gap: 0.35rem; flex: 1; text-align: center; }
.perm-summary-icon {
    width: 2.3rem; height: 2.3rem; border-radius: 8px; display: inline-flex; align-items: center;
    justify-content: center; font-size: 1rem; flex: none;
}
.perm-summary-icon.perm-icon-total { background: #eef2ff; color: #3730a3; }
.perm-summary-icon.perm-icon-granted { background: #dcfce7; color: #166534; }
.perm-summary-icon.perm-icon-restricted { background: #ffedd5; color: #c2410c; }
.perm-summary-icon.perm-icon-notgranted { background: #fee2e2; color: #b91c1c; }
.perm-summary-count { font-weight: 700; font-size: 1.4rem; color: var(--kcpc-ink); }
.perm-summary-label { color: #6b7280; font-size: 0.76rem; }
.perm-summary-note { font-size: 0.76rem; color: #9ca3af; margin: 0.7rem 0 0; padding-top: 0.7rem; border-top: 1px solid var(--kcpc-border); }

/* Unified Permission Management table (permission-admin-ui final redesign) - one table replaces
   the old separate Grant-checklist / Current-Granted-Permissions tables, Modify flow, "+ Grant
   More", and advanced custom-scope form entirely. */
.perm-checklist-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 0.9rem; }
.perm-checklist-lead { color: #6b7280; font-size: 0.85rem; margin: 0.2rem 0 0; max-width: 640px; }
.perm-checklist-toolbar { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.perm-checklist-search { position: relative; }
.perm-checklist-search input {
    width: 240px; max-width: 100%; height: 2.3rem; padding: 0 0.7rem 0 2.1rem;
    border: 1px solid var(--kcpc-border); border-radius: 7px; font-size: 0.85rem;
}
.perm-checklist-search .admin-search-icon { color: #9ca3af; }
/* Checkbox + label rendered as one compact bordered control, height-matched to the search input so
   the two line up cleanly on the same row instead of the bare checkbox+text floating unaligned. */
.perm-checklist-filter {
    display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.82rem; color: var(--kcpc-ink);
    white-space: nowrap; height: 2.3rem; padding: 0 0.75rem; border: 1px solid var(--kcpc-border);
    border-radius: 7px; background: var(--kcpc-surface); flex: none;
}
.perm-checklist-filter input[type="checkbox"] { margin: 0; width: 1rem; height: 1rem; cursor: pointer; accent-color: var(--kcpc-accent); flex: none; }
.perm-checklist-empty { padding: 1rem 0; color: #9ca3af; font-size: 0.85rem; text-align: center; }

.perm-mgmt-table th, .perm-mgmt-table td { vertical-align: middle; white-space: nowrap; }
.perm-mgmt-table { min-width: 920px; } /* forces the .reports-table-scroll wrapper to scroll rather than the page */
.perm-name-cell { white-space: normal; }
/* #permChecklistPanel prefix is required specificity to beat the generic ".panel button" rule
   (filled coral background + margin-top:1rem) that otherwise turns every <button> in this panel -
   the name link, Update, Manage(N) - into an unreadable filled pill with clipped/invisible text. */
#permChecklistPanel .perm-name-link {
    background: none; border: none; padding: 0; margin: 0; cursor: pointer;
    color: var(--kcpc-ink); font-weight: 700; font-size: 0.85rem; text-align: left;
    /* A PERSISTENT dotted underline, not a hover-only one: the name is the only affordance for the
       Permission Details modal, and an affordance that appears only on hover is invisible to a
       touch user and to anyone who never happens to hover that cell. It stays dotted/grey rather
       than becoming a blue link so it is not mistaken for navigation - it opens a read-only
       modal, it does not leave the page. */
    text-decoration: underline dotted; text-decoration-color: #c7cbd1; text-underline-offset: 3px;
}
#permChecklistPanel .perm-name-link:hover {
    color: #1d4ed8; text-decoration: underline solid; text-decoration-color: currentColor;
}
.perm-code-muted { color: #9ca3af; font-size: 0.7rem; font-family: monospace; margin-top: 0.1rem; }

.perm-checkbox { width: 1.15rem; height: 1.15rem; cursor: pointer; accent-color: var(--kcpc-accent); }
.perm-checkbox:disabled { cursor: default; accent-color: #166534; opacity: 1; }
.perm-checkbox.perm-checkbox-multi:disabled { accent-color: #1d4ed8; }

.perm-inline-select, .perm-inline-input {
    height: 2rem; padding: 0 0.5rem; border: 1px solid var(--kcpc-border); border-radius: 6px;
    font-size: 0.8rem; background: var(--kcpc-surface); color: var(--kcpc-ink); width: 9.5rem;
}
.perm-inline-select.perm-scope-select { width: 11.5rem; } /* must fit "Stage Restricted" without clipping */
.perm-inline-input.perm-reason-input { width: 8rem; }
.perm-inline-input.perm-expiry-input { width: 9rem; }
.perm-inline-select.perm-stage-select[multiple] { height: auto; padding: 0.2rem; width: 11.5rem; }
.perm-inline-input.perm-item-input { width: 8.5rem; }
.perm-inline-select:disabled, .perm-inline-input:disabled { background: #f4f5f7; color: #9ca3af; cursor: not-allowed; }
.perm-dash { color: #9ca3af; }

/* Fixed width so the button occupies identical space in every row (granted/not-granted, wrapped
   in a <form> or bare) regardless of disabled state or the transient "Updated" flash beside it. */
#permChecklistPanel .perm-update-form { display: inline-block; margin: 0; vertical-align: middle; }
#permChecklistPanel .perm-update-btn {
    margin: 0; width: 5.5rem; height: 2rem; padding: 0 0.5rem; border-radius: 6px; border: 1px solid var(--kcpc-border);
    background: var(--kcpc-surface); color: var(--kcpc-ink); font-size: 0.8rem; font-weight: 600; cursor: pointer;
    text-align: center; vertical-align: middle;
}
#permChecklistPanel .perm-update-btn:disabled { color: #9ca3af; cursor: not-allowed; background: #f4f5f7; }
#permChecklistPanel .perm-update-btn:not(:disabled) { border-color: var(--kcpc-accent); color: var(--kcpc-accent); background: var(--kcpc-surface); }
.perm-update-saved { color: #166534; font-size: 0.76rem; font-weight: 600; margin-left: 0.4rem; }
#permChecklistPanel .perm-expand-btn {
    margin: 0 0 0 0.4rem; height: 2rem; padding: 0 0.6rem; border-radius: 6px; border: 1px solid var(--kcpc-border);
    background: var(--kcpc-surface); color: #1d4ed8; font-size: 0.78rem; font-weight: 600; cursor: pointer;
}

.perm-status-badge {
    display: inline-block; padding: 0.2rem 0.6rem; border-radius: 999px;
    font-size: 0.76rem; font-weight: 700; white-space: nowrap;
}
.perm-status-badge.perm-status-global { background: #dcfce7; color: #166534; }
.perm-status-badge.perm-status-restricted { background: #ffedd5; color: #c2410c; }
.perm-status-badge.perm-status-none { background: #f3f4f6; color: #6b7280; }
.perm-status-badge.perm-status-multi { background: #dbeafe; color: #1d4ed8; }

/* Multi-active-grant sub-row (permission-admin-ui: never merge/hide/collapse simultaneous active
   grants into one editable row) - a compact nested table, individually revocable per grant. */
.perm-multi-subrow > td { padding-top: 0; padding-bottom: 0.9rem; background: #f9fafb; }
.perm-multi-detail-table { width: 100%; margin-top: 0.4rem; border: 1px solid var(--kcpc-border); border-radius: 8px; overflow: hidden; }
.perm-multi-detail-table th, .perm-multi-detail-table td { padding: 0.45rem 0.65rem; font-size: 0.78rem; }
.perm-multi-detail-table thead { background: #f4f5f7; }
.perm-multi-note { font-size: 0.76rem; color: #6b7280; margin: 0.4rem 0 0; }

/* Permission detail drawer - native <dialog>, no JS modal library needed. */
/* DELIBERATELY NO `position` DECLARATION - do not add one back. A modal <dialog> lives in the TOP
   LAYER, and a top-layer box's containing block is the INITIAL containing block: a viewport-sized
   rectangle anchored at the DOCUMENT origin, never the currently scrolled viewport. This rule used
   to say `position: relative`, and because an ID selector outranks the UA's own `dialog:modal`
   rule it won - so the dialog was laid out against that document-origin box (i.e. up at the top of
   the page) instead of being viewport-fixed. showModal()'s focusing step then had to scroll the
   dialog into view, which dragged the whole Permission Management list back to the top on every
   single details click. Omitting `position` lets the UA's `dialog { position: absolute }` /
   `dialog:modal { position: fixed; inset: 0; margin: auto }` pair apply untouched: the dialog is
   centred in the CURRENT viewport, nothing needs scrolling, and the list stays exactly where the
   user left it. Either UA value is still a positioned ancestor, so .perm-detail-close below keeps
   anchoring to the dialog. */
#permDetailDialog {
    border: none; border-radius: 12px; padding: 0; width: min(480px, 92vw);
    box-shadow: 0 12px 32px rgba(0,0,0,0.18);
}
#permDetailDialog::backdrop { background: rgba(15, 23, 42, 0.45); }
.perm-detail-body { padding: 1.4rem 1.5rem; }
.perm-detail-name { font-size: 1.05rem; font-weight: 700; margin: 0; }
.perm-detail-code { font-family: monospace; color: #9ca3af; font-size: 0.78rem; margin: 0.2rem 0 1rem; }
.perm-detail-section-title { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: #6b7280; margin: 1rem 0 0.4rem; }
.perm-detail-section-title:first-of-type { margin-top: 0; }
.perm-detail-text { font-size: 0.86rem; color: var(--kcpc-ink); line-height: 1.5; margin: 0; }
.perm-detail-close { position: absolute; top: 0.9rem; right: 1rem; background: none; border: none; font-size: 1.1rem; color: #9ca3af; cursor: pointer; }
.perm-detail-close:hover { color: var(--kcpc-ink); }
/* The dialog now carries five sections (allows / does not allow / scope / this user's grant /
   important) instead of one, so the BODY scrolls rather than the dialog: .perm-detail-close is
   absolutely positioned against the dialog, and letting the dialog itself scroll would scroll the
   X away from the content it closes. max-height is viewport-relative so a short phone screen gets
   a scrollable panel instead of a clipped one. */
.perm-detail-body { max-height: min(78vh, 620px); overflow-y: auto; }
/* Padding-right keeps the first heading clear of the absolutely-positioned X. */
.perm-detail-name { padding-right: 2rem; }
.perm-detail-text .perm-status-badge { margin-right: 0.45rem; vertical-align: baseline; }
.perm-detail-grant-detail { display: inline; }
.perm-detail-actions { margin-top: 1.4rem; text-align: right; }
/* Same specificity note as .perm-name-link above: the generic ".panel button" rule does not reach
   inside <dialog>, but #permDetailDialog is used anyway so this stays immune to it moving. */
#permDetailDialog .perm-detail-close-btn {
    margin: 0; min-width: 5.5rem; height: 2.1rem; padding: 0 1rem; border-radius: 6px;
    border: 1px solid var(--kcpc-border); background: var(--kcpc-surface); color: var(--kcpc-ink);
    font-size: 0.82rem; font-weight: 600; cursor: pointer;
}
#permDetailDialog .perm-detail-close-btn:hover { border-color: var(--kcpc-accent); color: var(--kcpc-accent); }
#permDetailDialog .perm-detail-close-btn:focus-visible,
.perm-detail-close:focus-visible,
#permChecklistPanel .perm-name-link:focus-visible {
    outline: 2px solid var(--kcpc-accent); outline-offset: 2px; border-radius: 4px;
}
@media (max-width: 560px) {
    #permDetailDialog { width: 94vw; }
    .perm-detail-body { padding: 1.1rem 1.1rem 1.2rem; max-height: 80vh; }
    .perm-detail-actions { text-align: center; }
    #permDetailDialog .perm-detail-close-btn { width: 100%; }
}

/* Idea Details popup (My Work / Task Detail screens) - same native <dialog> pattern as
   #permDetailDialog above, no JS modal library needed. .idea-details-trigger is a small inline
   icon sitting right next to Content Name, not the full 2rem .icon-btn row-action size. */
.idea-details-trigger {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.5rem; height: 1.5rem; padding: 0; border-radius: 6px; margin-left: 0.35rem;
    border: 1px solid var(--kcpc-border); background: var(--kcpc-surface); color: #6b7280;
    cursor: pointer; font-size: 0.82rem; line-height: 1; vertical-align: middle;
}
.idea-details-trigger:hover { background: #f4f5f7; color: var(--kcpc-ink); }
.idea-details-dialog {
    position: relative; border: none; border-radius: 12px; padding: 0; width: min(560px, 92vw);
    box-shadow: 0 12px 32px rgba(0,0,0,0.18);
}
.idea-details-dialog::backdrop { background: rgba(15, 23, 42, 0.45); }
.idea-details-body { padding: 1.4rem 1.5rem; }
.idea-details-heading { font-size: 1.05rem; font-weight: 700; margin: 0 0 1rem; }
.idea-details-field { margin-bottom: 1rem; }
.idea-details-field:last-child { margin-bottom: 0; }
.idea-details-field-label { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: #6b7280; margin-bottom: 0.3rem; }
.idea-details-field-value { font-size: 0.86rem; color: var(--kcpc-ink); line-height: 1.5; overflow-wrap: break-word; word-break: break-word; white-space: pre-wrap; }
.idea-details-link-value { white-space: normal; }
.idea-details-close { position: absolute; top: 0.9rem; right: 1rem; background: none; border: none; font-size: 1.1rem; color: #9ca3af; cursor: pointer; }

/* Footer under the unified table - just a live row count (search/granted-only filter updates it in
   JS). No pagination: the permission catalogue (19 rows today) always renders in full on one page;
   pagination only earns its keep once the catalogue grows past what search/filter can't handle. */
.perm-mgmt-footer {
    margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--kcpc-border);
    font-size: 0.8rem; color: #6b7280;
}

@media (max-width: 700px) {
    .perm-checklist-search input { width: 100%; }
    .perm-checklist-toolbar { width: 100%; }
}

#permChecklistToast.ajax-error {
    position: fixed; bottom: 1.25rem; right: 1.25rem; z-index: 1000;
    background: #fef2f2; border: 1px solid #fecaca; border-radius: 8px;
    padding: 0.6rem 0.9rem; box-shadow: 0 4px 14px rgba(0,0,0,0.12); margin-top: 0;
}

/* Publishing Catalogue platform icon reused verbatim from the Pipeline dashboard's own local
   full-color SVG set (static/icons/platforms/) - same <img> markup, no new asset pipeline. */
.catalogue-platform-cell { display: flex; align-items: center; gap: 0.5rem; }
.catalogue-platform-icon { width: 18px; height: 18px; display: block; flex: none; border-radius: 5px; }
.catalogue-row-actions { display: flex; gap: 0.4rem; }
.catalogue-edit-panel { padding: 0.9rem 1rem; border-top: 1px solid var(--kcpc-border); background: #fafafa; }
/* Create Platform/Channel/Target body - toggled via the header's "+ Create X" button
   (data-toggle-panel, admin-shared.js) rather than a <details> disclosure, so the trigger can sit
   top-right in .card-head-row instead of above/below the table. */
.catalogue-create-body { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--kcpc-border); }

/* Card header row (title + right-aligned "+ Create X" trigger) - Platforms/Channels/Targets cards. */
.card-head-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.75rem; }
.card-head-row h2 { margin: 0; }
/* Same ".panel button" specificity problem as button.btn-outline-danger/-success above - without
   this, the "+ Create X" header button would render solid red instead of the intended compact
   blue outline, and pick up an unwanted margin-top that misaligns it in the header row. */
.card-head-row button.btn-outline {
    background: transparent; color: #1d4ed8; border: 1px solid #93c5fd;
    padding: 0.35rem 0.8rem; margin-top: 0; font-size: 0.8rem; font-weight: 600;
}
.card-head-row button.btn-outline:hover { background: #eff6ff; }

/* Password visibility toggle (Create User's Initial Password field) - purely client-side
   show/hide, never changes what gets submitted. */
.password-field { position: relative; }
.password-field input { padding-right: 2.25rem; }
.password-field .password-toggle {
    position: absolute; right: 0.5rem; top: 50%; transform: translateY(-50%);
    background: none; border: none; color: #9ca3af; cursor: pointer; font-size: 0.9rem; padding: 0.2rem;
    margin: 0; width: auto; opacity: 0.7;
}
.password-field .password-toggle.password-visible { color: var(--kcpc-accent); opacity: 1; }

/* Login screen only: the same .password-field/.password-toggle toggle above, plus an actual
   eye/eye-slash shape change (a diagonal line drawn across the eye glyph while masked, removed
   once revealed) - scoped to .auth-card so Create User's own toggle (color/opacity only) is
   untouched. The button is already `position: absolute` (base rule above), which is itself a
   valid containing block for this ::after - no extra `position` declaration needed (adding one
   here would tie in specificity with the base rule and, by source order, silently override its
   `position: absolute` with `relative`, breaking the button's placement). */
.auth-card .password-toggle::after {
    content: ''; position: absolute; left: 10%; right: 10%; top: 50%; height: 1px;
    background: currentColor; transform: translateY(-50%) rotate(-45deg);
}
.auth-card .password-toggle.password-visible::after { display: none; }

/* Compact single-row Create User form (Full Name | Email | Initial Password | Business Role |
   Reason) on desktop, stacking on narrower viewports. */
.admin-inline-form { display: grid; grid-template-columns: repeat(5, 1fr); gap: 1rem; align-items: start; }
.admin-inline-form label { margin-top: 0; }
@media (max-width: 1100px) {
    .admin-inline-form { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
    .admin-inline-form { grid-template-columns: 1fr; }
}
.admin-inline-form-actions { display: flex; align-items: flex-end; }
.admin-inline-form-actions button { margin-top: 0; width: 100%; }

/* Users page Edit User modal (.kcpc-modal-* shell reused as-is) - compact 2-column form, Reason
   spans both columns at the bottom. Access Class is disabled/readonly: it only ever mirrors the
   selected Business Role's own access class (BRS-REQ-001/002), never an independent field. */
.admin-edit-user-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; align-items: start; }
.admin-edit-user-grid label { margin-top: 0; }
.admin-edit-user-grid input[disabled] { background: var(--kcpc-surface-muted, #f1f5f9); color: #6b7280; }
.admin-edit-user-reason { grid-column: 1 / -1; }
@media (max-width: 640px) {
    .admin-edit-user-grid { grid-template-columns: 1fr; }
    .admin-edit-user-reason { grid-column: auto; }
}
/* Edit User modal footer: Cancel and Save Changes previously rendered at visibly different
   heights - Cancel inherits .btn-outline's own smaller padding/font-size/1px-border, Save Changes
   inherits the generic button[type="submit"] rule's larger padding/font-size/no-border, and those
   two rules were never reconciled anywhere else in the app. Same fix .pipeline-filter-bar already
   uses for the identical class of bug: an explicit height (picked to match Save Changes' own prior
   natural height, so neither button visibly grows or shrinks) plus inline-flex centering, scoped to
   these two button ids only - .btn-outline and button[type="submit"] everywhere else in the app,
   including every other .kcpc-modal-footer, are untouched. box-sizing:border-box is already global
   (see the top-of-file `* {}` rule); redeclared here only as the same defensive pin that precedent
   uses, so Cancel's 1px border can never again push it taller than this fixed height. */
#editUserCancelBtn, #editUserSaveBtn {
    display: inline-flex; align-items: center; justify-content: center;
    height: 2.5rem; min-height: 2.5rem; box-sizing: border-box;
}
.admin-actions-cell { text-align: right; white-space: nowrap; }

/* Fixed-position transient toast, shared positioning for any bottom-right confirmation (paired
   with .alert-success/.alert-error for coloring - same combinable-class approach
   #permChecklistToast.ajax-error already uses for its own error-only toast). */
.admin-toast {
    position: fixed; bottom: 1.25rem; right: 1.25rem; z-index: 1000;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12); max-width: 340px;
}
.admin-tab:hover:not(.active) { color: var(--kcpc-ink); }

/* ================================================================== Planned Live Date calendar
   (kcpc-date-picker.js). Deliberately the SAME visual language as the Upcoming Channel Plan
   calendar (.kpi-calendar-* above) - same 7-column grid, same cell size/radius, same blue
   selected state, same muted weekday header - so the two calendars read as one product. Kept as
   its own class namespace rather than reusing .kpi-calendar-*: that one is a read-only data
   viewer living inside a modal, this is an anchored form control with a disabled-date rule, and
   collapsing them would couple a Planning form to the KPI dashboard's markup. Applies only to a
   field that opted in with data-kcpc-calendar. */
.kcpc-datepicker {
    position: fixed; z-index: 1100; width: 300px; max-width: 92vw;
    background: #fff; border: 1px solid var(--kcpc-border); border-radius: 10px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.14); padding: 0.75rem;
}
.kcpc-datepicker-nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.6rem; }
.kcpc-datepicker-nav .btn-outline { padding: 0.25rem 0.6rem; font-size: 0.85rem; }
.kcpc-datepicker-month-label { font-weight: 700; font-size: 0.92rem; }
.kcpc-datepicker-weekdays {
    display: grid; grid-template-columns: repeat(7, 1fr); text-align: center;
    font-size: 0.72rem; color: #6b7280; margin-bottom: 0.3rem;
}
.kcpc-datepicker-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 0.2rem; }
.kcpc-datepicker-cell {
    display: flex; align-items: center; justify-content: center; height: 2.1rem; border-radius: 6px;
    font-size: 0.82rem; color: var(--kcpc-ink); background: none; border: 1px solid transparent;
    font-family: inherit;
}
.kcpc-datepicker-cell-empty { visibility: hidden; }
/* Selectable = a real <button> (today and every future date). */
button.kcpc-datepicker-cell { cursor: pointer; }
button.kcpc-datepicker-cell:hover { background: #eff6ff; border-color: #bfdbfe; color: #1d4ed8; }
/* Past dates: rendered as non-interactive <span>s by kcpc-date-picker.js - visibly greyed, never
   merely un-clickable. A past date is never marked planned either. */
.kcpc-datepicker-cell-disabled { color: #c3c8d0; background: #f3f4f6; cursor: not-allowed; }
.kcpc-datepicker-cell-today { font-weight: 700; border-color: #bfdbfe; }
/* Content already planned: the COMPLETE cell gets a clear background - deliberately no dot, badge
   or any other indicator. Same blue family as the selected state, one step lighter, so a planned
   date reads as "notable" and the selected date still reads as "chosen" when both are on screen. */
button.kcpc-datepicker-cell-planned {
    background: #dbeafe; border-color: #93c5fd; color: #1d4ed8; font-weight: 700;
}
button.kcpc-datepicker-cell-planned:hover { background: #bfdbfe; }
button.kcpc-datepicker-cell-selected,
button.kcpc-datepicker-cell-selected:hover { background: #1d4ed8; border-color: #1d4ed8; color: #fff; }
.kcpc-datepicker-cell:focus-visible, .kcpc-datepicker-prev:focus-visible,
.kcpc-datepicker-next:focus-visible { outline: 2px solid var(--kcpc-accent); outline-offset: 1px; }
/* Legend: three states, each shown as a full-cell swatch rather than a dot, because the cells they
   describe are themselves whole-cell highlights. */
.kcpc-datepicker-legend {
    display: flex; flex-wrap: wrap; gap: 0.3rem 0.8rem; margin-top: 0.55rem;
    font-size: 0.7rem; color: #6b7280;
}
.kcpc-datepicker-legend-item { display: inline-flex; align-items: center; gap: 0.3rem; }
.kcpc-datepicker-legend-swatch {
    display: inline-block; width: 0.85rem; height: 0.85rem; border-radius: 4px; flex: none;
    border: 1px solid transparent;
}
.kcpc-datepicker-legend-swatch-planned { background: #dbeafe; border-color: #93c5fd; }
.kcpc-datepicker-legend-swatch-free { background: #fff; border-color: var(--kcpc-border); }
.kcpc-datepicker-legend-swatch-past { background: #f3f4f6; border-color: #e5e7eb; }
/* Detail panel: "Planned Content By Channel" for the clicked date. Mirrors the Upcoming Channel
   Plan calendar's own .kpi-calendar-detail block. */
.kcpc-datepicker-detail { margin-top: 0.7rem; padding-top: 0.7rem; border-top: 1px solid var(--kcpc-border); }
.kcpc-datepicker-detail-hint, .kcpc-datepicker-detail-empty {
    margin: 0; font-size: 0.78rem; color: #6b7280;
}
.kcpc-datepicker-detail-date { margin: 0 0 0.35rem; font-size: 0.88rem; font-weight: 700; }
.kcpc-datepicker-detail-caption {
    margin: 0 0 0.4rem; font-size: 0.7rem; color: #6b7280; text-transform: uppercase;
    letter-spacing: 0.03em; font-weight: 700;
}
.kcpc-datepicker-detail-list {
    list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.35rem;
    max-height: 150px; overflow-y: auto;
}
.kcpc-datepicker-detail-list li { display: flex; justify-content: space-between; font-size: 0.82rem; gap: 0.75rem; }
.kcpc-datepicker-detail-count { font-weight: 700; }
/* Accordion channel rows (kcpc-date-picker.js). The collapsed row must look EXACTLY like the plain
   channel/count line it replaces - only a caret is added ahead of the handle - so the popup reads
   the same until someone chooses to expand one. */
.kcpc-datepicker-detail-list li.kcpc-datepicker-detail-item {
    /* Overrides the row rule above: this item stacks its header and its Content ID list, and it is
       the header BUTTON that carries the channel/count flex row. */
    display: block;
}
.kcpc-datepicker-detail-toggle {
    display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
    width: 100%; padding: 0; border: none; background: none; cursor: pointer;
    font: inherit; font-size: 0.82rem; color: inherit; text-align: left;
}
.kcpc-datepicker-detail-toggle:hover .kcpc-datepicker-detail-channel { text-decoration: underline; }
.kcpc-datepicker-detail-toggle:focus-visible { outline: 2px solid #93c5fd; outline-offset: 2px; }
/* Fixed width so channel names stay left-aligned with each other whether open or closed. */
.kcpc-datepicker-detail-caret { flex: none; width: 0.75rem; color: #6b7280; font-size: 0.7rem; }
.kcpc-datepicker-detail-toggle .kcpc-datepicker-detail-channel { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.kcpc-datepicker-detail-contents {
    list-style: none; margin: 0.25rem 0 0; padding: 0 0 0 1.4rem;
    display: flex; flex-direction: column; gap: 0.15rem;
    /* Internal scrolling rather than an ever-taller popover when a channel holds many items. */
    max-height: 108px; overflow-y: auto;
}
/* REQUIRED, not belt-and-braces. A collapsed row is marked with the `hidden` ATTRIBUTE, which the
   browser honours only through its own `[hidden] { display: none }` UA rule - and the author
   `display: flex` immediately above outranks any UA rule, so without this the list stays visible
   and the accordion looks like it does nothing (the caret flips, the content never hides). Any
   future `display` declaration on this class has to keep this companion rule. */
.kcpc-datepicker-detail-contents[hidden] { display: none; }
/* Undo the parent list's space-between row layout for these nested items. */
.kcpc-datepicker-detail-list .kcpc-datepicker-detail-contents li {
    display: block; justify-content: flex-start; gap: 0; font-size: 0.75rem;
}
.kcpc-datepicker-detail-contents li::before { content: '\2013'; color: #9ca3af; margin-right: 0.35rem; }
.kcpc-datepicker-detail-content-link, .kcpc-datepicker-detail-content-id { color: #6b7280; }
.kcpc-datepicker-detail-content-link { text-decoration: none; }
.kcpc-datepicker-detail-content-link:hover { color: var(--kcpc-ink); text-decoration: underline; }
/* "C-0926-0005 - Summer Collection Reel": the id keeps the existing muted weight and never wraps
   away from its title, while a long title wraps within the popover instead of widening it. */
.kcpc-datepicker-detail-content-id { white-space: nowrap; }
.kcpc-datepicker-detail-content-title { color: #6b7280; overflow-wrap: anywhere; }
.kcpc-datepicker-detail-content-link:hover .kcpc-datepicker-detail-content-title { color: var(--kcpc-ink); }
/* The field keeps its native <input type="date"> behaviour and validation; only the browser's own
   picker indicator is hidden, so this calendar is the single one a click can ever open. */
input[data-kcpc-calendar]::-webkit-calendar-picker-indicator { display: none; }
input[data-kcpc-calendar] { cursor: pointer; }

/* Notification sound preference toggle - sits in the bell dropdown's footer next to "View all"
   (notification-sound.js). A plain checkbox row, deliberately quiet: it is a per-device
   convenience, not a primary action. */
.app-header-notification-menu-footer {
    display: flex; align-items: center; gap: 0.5rem;
    /* The separator moves up here from .app-header-notification-view-all (which is now one of two
       children rather than the whole row), so the rule still spans the menu's full width. */
    border-top: 1px solid var(--kcpc-border);
}
.app-header-notification-menu-footer .app-header-notification-view-all {
    flex: 1 1 auto; border-top: none;
}
.app-header-notification-sound-toggle {
    display: inline-flex; align-items: center; gap: 0.35rem; cursor: pointer;
    padding: 0.5rem 0.75rem; font-size: 0.75rem; color: #6b7280; white-space: nowrap;
}
.app-header-notification-sound-toggle input { cursor: pointer; margin: 0; }
.app-header-notification-sound-toggle:hover { color: var(--kcpc-ink); }

/* Content Detail -> Publishing -> Planned Outputs. The table itself reuses the Idea Review &
   Planning grid's own classes (.reviews-outputs-grid / .reviews-output-*) so both screens look
   identical; only these two Content-Detail-specific details are additional, because that screen
   displays real stored outputs rather than selectable types. */
.content-detail-output-reeltypes { display: inline-flex; gap: 0.3rem; margin-left: 0.5rem; vertical-align: middle; }
.content-detail-output-title { display: block; margin-top: 0.2rem; font-size: 0.78rem; }
/* Read-only here: the row is a display of what was planned, never a control to toggle. */
#contentDetailPlannedOutputs .reviews-output-type-toggle { cursor: default; }
#contentDetailPlannedOutputs .reviews-platform-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; }
#cdPlannedOutputsStatus.cd-outputs-error { color: #b91c1c; font-weight: 600; }
.channel-check-item-locked { opacity: 0.65; cursor: not-allowed; }

/* V43 "Collab With". Purely additive: the Planning grid's channel checklist and the Content
   Pipeline platform popover are otherwise unchanged, so these rules only style the new nested
   collaborator block and the new popover column - no existing selector is redefined. */
.reviews-output-collab {
    margin: 0.15rem 0 0.35rem 1.4rem;
    padding-left: 0.6rem;
    border-left: 2px solid var(--kcpc-border, #e3e3e3);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
}
.reviews-output-collab.hidden { display: none; }
.reviews-output-collab-label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.03em; }
.reviews-output-collab-item { font-size: 0.78rem; }
.pipeline-channel-collab { white-space: normal; }
.pipeline-channel-collab-handle { display: inline-block; }
.pipeline-channel-collab-handle + .pipeline-channel-collab-handle { margin-left: 0.3rem; }
.reviews-output-collab-empty { font-size: 0.75rem; font-style: italic; }
.reviews-output-collab-empty.hidden { display: none; }
.reviews-output-collab .channel-check-item.hidden { display: none; }
.reviews-platform-popover-collab { white-space: normal; }
/* Content ID search in the shared task filter panel - sized to sit on the same baseline as the
   date cards and picker already in that row, nothing else in the bar is restyled. */
.mw-filter-search input[type="search"] {
    width: 10rem;
    /* Matches the date picker and the Today/Tomorrow card labels in this same bar
       (.mw-date-card-picker input[type="date"] / .mw-date-card-label, both 0.8rem). Without these
       the input fell back to the browser's default control font - a different family AND a larger
       size than everything beside it. font-family is inherited for the same reason: inputs do not
       inherit it on their own, so it would otherwise stay the UA font while its neighbours use the
       app's. Size and family only - width, height, border and padding are untouched. */
    font-size: 0.8rem;
    font-family: inherit;
}

/* Database Backup -> Settings. Two configuration cards side by side (backup, cleanup) instead of
   one long settings table: the two are independent switches, and a table implied they were rows
   of one list. Tokens, radius, borders and button styles are the existing admin ones. */
.backup-settings-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem;
    align-items: start;
    margin-bottom: 1rem;
}
@media (max-width: 900px) {
    .backup-settings-grid { grid-template-columns: 1fr; }
}
.backup-settings-card {
    border: 1px solid var(--kcpc-border);
    border-radius: 8px;
    overflow: hidden;
    background: var(--kcpc-surface);
}
.backup-settings-card-head {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.7rem 0.9rem;
    border-bottom: 1px solid var(--kcpc-border);
}
/* Subtle tints, not saturated fills - the header identifies the card, it is not a banner. */
.backup-settings-card-backup .backup-settings-card-head { background: #eff6ff; border-bottom-color: #dbeafe; }
.backup-settings-card-cleanup .backup-settings-card-head { background: #ecfdf5; border-bottom-color: #d1fae5; }
.backup-settings-card-icon {
    flex-shrink: 0;
    width: 1.9rem;
    height: 1.9rem;
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.95rem;
}
.backup-settings-card-backup .backup-settings-card-icon { background: #dbeafe; }
.backup-settings-card-cleanup .backup-settings-card-icon { background: #d1fae5; }
.backup-settings-card-title { font-weight: 700; font-size: 0.9rem; line-height: 1.2; }
.backup-settings-card-subtitle { font-size: 0.78rem; color: #6b7280; line-height: 1.25; }
.backup-settings-card-body { padding: 0.35rem 0.9rem 0.9rem; }

/* label | control | description - one grid so labels and controls line up across every row. */
.backup-setting-row {
    display: grid;
    grid-template-columns: 11rem minmax(9rem, 1fr) 1.35fr;
    gap: 0.75rem;
    align-items: start;
    padding: 0.6rem 0;
    border-bottom: 1px solid #f0f1f3;
}
.backup-setting-row:last-child { border-bottom: 0; padding-bottom: 0; }
.backup-setting-label { font-size: 0.82rem; font-weight: 600; padding-top: 0.4rem; }
.backup-setting-help { font-size: 0.75rem; color: #6b7280; line-height: 1.35; padding-top: 0.35rem; }
@media (max-width: 1200px) {
    .backup-setting-row { grid-template-columns: 1fr; gap: 0.35rem; }
    .backup-setting-label, .backup-setting-help { padding-top: 0; }
}

/* A real switch rather than a bare checkbox: the underlying control is still the checkbox the
   form posts, so keyboard and form semantics are unchanged - only its appearance is. */
.kcpc-switch { display: inline-flex; align-items: center; gap: 0.55rem; cursor: pointer; }
.kcpc-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.kcpc-switch-track {
    position: relative;
    width: 2.5rem;
    height: 1.35rem;
    border-radius: 999px;
    background: #cbd5e1;
    transition: background 0.15s ease-in-out;
    flex-shrink: 0;
}
.kcpc-switch-track::after {
    content: "";
    position: absolute;
    top: 0.17rem;
    left: 0.19rem;
    width: 1rem;
    height: 1rem;
    border-radius: 50%;
    background: #fff;
    transition: transform 0.15s ease-in-out;
}
.kcpc-switch input:checked + .kcpc-switch-track { background: #16a34a; }
.kcpc-switch input:checked + .kcpc-switch-track::after { transform: translateX(1.13rem); }
.kcpc-switch input:focus-visible + .kcpc-switch-track { outline: 2px solid #93c5fd; outline-offset: 2px; }
/* The ON/OFF label follows the checkbox live, in CSS: server-rendered text alone would still
   read "OFF" after the operator flicks the switch, right up until they saved. */
.kcpc-switch-state { font-size: 0.78rem; font-weight: 700; }
.kcpc-switch-state-on { color: #16a34a; display: none; }
.kcpc-switch-state-off { color: #6b7280; }
.kcpc-switch input:checked ~ .kcpc-switch-state-on { display: inline; }
.kcpc-switch input:checked ~ .kcpc-switch-state-off { display: none; }

/* Cron/number inputs: normal admin form controls, with the unit or icon sitting inside the box. */
.backup-input-wrap { position: relative; display: block; }
.backup-input-wrap input {
    width: 100%;
    padding: 0.42rem 2rem 0.42rem 0.6rem;
    border: 1px solid var(--kcpc-border);
    border-radius: 6px;
    font-size: 0.82rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    letter-spacing: 0.04em;
}
.backup-input-wrap-unit input { padding-right: 3.1rem; font-family: inherit; letter-spacing: normal; }
.backup-input-icon {
    position: absolute;
    right: 0.55rem;
    top: 50%;
    transform: translateY(-50%);
    color: #9ca3af;
    display: flex;
    pointer-events: none;
}
.backup-input-unit {
    position: absolute;
    right: 0.55rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.78rem;
    color: #6b7280;
    pointer-events: none;
}
/* The plain-English reading of the cron above it - derived, never a second source of truth. */
.backup-schedule-hint {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.4rem;
    padding: 0.28rem 0.55rem;
    border-radius: 6px;
    background: #eff6ff;
    border: 1px solid #dbeafe;
    color: #1d4ed8;
    font-size: 0.74rem;
}
.backup-settings-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}
.backup-settings-actions-buttons { display: flex; align-items: center; gap: 0.6rem; }
.backup-settings-actions-buttons button[type="submit"] { width: auto; margin-top: 0; padding: 0.55rem 1.4rem; }
.backup-settings-note {
    display: flex;
    align-items: flex-start;
    gap: 0.45rem;
    font-size: 0.76rem;
    color: #6b7280;
    line-height: 1.35;
}
.backup-settings-note svg { flex-shrink: 0; margin-top: 0.1rem; color: #3b82f6; }

/* Database Backup -> Cleanup Status. A full-width operational card, deliberately outside the
   Settings block: those cards hold controls an operator sets, this holds only what the system
   reports. Reuses the settings-card shell (header, icon, radius, borders) with its own tint. */
.backup-settings-card-status .backup-settings-card-head { background: #f5f3ff; border-bottom-color: #ede9fe; }
.backup-settings-card-status .backup-settings-card-icon { background: #ede9fe; }
.backup-cleanup-status-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
    padding-top: 0.5rem;
}
@media (max-width: 1000px) {
    .backup-cleanup-status-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
    .backup-cleanup-status-grid { grid-template-columns: 1fr; }
}
.backup-cleanup-status-block { display: flex; flex-direction: column; gap: 0.3rem; min-width: 0; }
.backup-cleanup-status-label {
    font-size: 0.72rem;
    font-weight: 700;
    color: #6b7280;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.backup-cleanup-status-value { font-size: 0.9rem; font-weight: 600; }
.backup-cleanup-status-detail { font-size: 0.75rem; color: #6b7280; line-height: 1.35; }

/* Content Detail -> inline editing of the content-level metadata (Title, SKU, Script Description).
   The pencil sits beside the value and matches the existing script-description icon button; the
   form it reveals uses the page's own button row, so this adds no new visual language. */
.content-meta-edit-btn {
    background: none; border: none; cursor: pointer; font-size: 0.95rem; line-height: 1;
    padding: 0.1rem 0.3rem; border-radius: 6px; color: #6b7280; vertical-align: middle;
}
.content-meta-edit-btn:hover { background: var(--kcpc-surface-muted, #f1f5f9); color: var(--kcpc-ink); }
.content-meta-edit-form {
    margin: 0.5rem 0 0.75rem;
    padding: 0.75rem;
    border: 1px solid var(--kcpc-border);
    border-radius: 8px;
    background: var(--kcpc-bg);
}
.content-meta-edit-form label { display: block; font-size: 0.8rem; font-weight: 600; margin-bottom: 0.5rem; }
.content-meta-edit-form input[type="text"],
.content-meta-edit-form textarea {
    display: block; width: 100%; margin-top: 0.25rem; padding: 0.42rem 0.6rem;
    border: 1px solid var(--kcpc-border); border-radius: 6px; font-size: 0.85rem; font-weight: 400;
}
.content-meta-edit-form .btn-row { margin-top: 0.5rem; text-align: left; }

/* Auto-linked URLs inside user-entered text (DisplayText#linkify, kcpc:linkify). Deliberately the
   only styling this feature adds: the surrounding typography, spacing and layout of every field it
   appears in are untouched, so a description or comment with no URL in it renders byte-identically
   to before.
   overflow-wrap:anywhere is the load-bearing rule - a 300-character Drive URL is one unbreakable
   token, and without it the link would widen its container and push the layout sideways (a <pre>
   Script Description or a narrow comment column being the worst cases). */
.kcpc-autolink {
    color: #1d4ed8;
    text-decoration: underline;
    overflow-wrap: anywhere;
    word-break: break-word;
}
.kcpc-autolink:hover { color: #1e40af; }

/* Shoot Planning (V56): the selected Shoot Lead is never offered in the Support Team list. */
.model-check-item.shoot-team-excluded { display: none !important; }

/* ------------------------------------------------------------------ Publication Links & Performance
   workspace: ONE unified work queue. Link entry and performance update are two halves of one job,
   so the page is a single card rather than two - the visual language is My Work's own data-table,
   platform chip and status pill, not a new one. */
.work-queue-scroll { overflow-x: auto; }
#publication-work-queue-table { min-width: 860px; }
/* The per-platform tally that keeps a multi-target content to ONE row - the same chip My Work's
   platform filter uses. */
.work-queue-targets .platform-badge {
    display: inline-flex; align-items: center;
    margin: 0 0.25rem 0.25rem 0;
    padding: 2px 8px; border-radius: 14px;
    background: #f1f3ff; color: var(--kcpc-ink);
    font-size: 0.72rem; font-weight: 600;
    white-space: nowrap;
}
.work-queue-progress .pending-link-progress { white-space: nowrap; }
.work-queue-progress .work-queue-performance-progress { font-size: 0.78rem; white-space: nowrap; }

/* Small screens: the row becomes a stacked card keyed by each cell's own data-label, so the queue
   stays readable on a phone instead of forcing a horizontal scroll through eight columns. */
@media (max-width: 700px) {
    #publication-work-queue-table { min-width: 0; }
    #publication-work-queue-table thead { display: none; }
    #publication-work-queue-table tr.publication-work-row {
        display: block;
        margin-bottom: 0.75rem;
        padding: 0.6rem 0.75rem;
        border: 1px solid var(--kcpc-border);
        border-radius: 8px;
    }
    #publication-work-queue-table tr.publication-work-row td {
        display: flex; justify-content: space-between; gap: 1rem;
        border: none; padding: 0.25rem 0;
        text-align: right;
    }
    #publication-work-queue-table tr.publication-work-row td::before {
        content: attr(data-label);
        font-size: 0.72rem; font-weight: 600; color: #6b7280;
        text-align: left; flex: 0 0 auto;
    }
    .work-queue-targets, .work-queue-progress { flex-wrap: wrap; }
}


/* ---- Platform Icon picker (Administration -> Publishing Catalogue, Create/Edit Platform) ------
   Icon + name per option, the checked one highlighted with CSS alone (no script), and a live
   preview above. Uses the existing catalogue form spacing/colours - no new design language. */
.platform-icon-picker { display: block; margin: 0.35rem 0 0.15rem; }
.platform-icon-picker-title { display: block; font-size: 0.82rem; font-weight: 600; margin-bottom: 0.3rem; }
.platform-icon-preview { display: flex; align-items: center; gap: 0.45rem; margin-bottom: 0.4rem; }
.platform-icon-preview-img { flex: 0 0 auto; }
.platform-icon-options { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.platform-icon-option {
    display: inline-flex; align-items: center; gap: 0.35rem;
    padding: 0.28rem 0.5rem; border: 1px solid #d5d9e0; border-radius: 6px;
    cursor: pointer; font-size: 0.8rem; background: #fff; line-height: 1;
}
.platform-icon-option:hover { border-color: #9aa4b2; }
/* The radio itself is the state; it is visually hidden rather than removed so the control stays
   keyboard-reachable and screen-reader-announced. */
.platform-icon-option input[type="radio"] {
    position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0;
}
.platform-icon-option:has(input[type="radio"]:checked) {
    border-color: #1d4ed8; background: #eef2ff; font-weight: 600;
}
.platform-icon-option:has(input[type="radio"]:focus-visible) { outline: 2px solid #1d4ed8; outline-offset: 1px; }


/* Publication Links & Performance listing: the Task Due Date cell holds only the date, and the
   Status cell can carry the workflow status plus a deadline indicator beside it. */
.work-queue-due { white-space: nowrap; }
/* Overdue Task Due Date, on the CELL only (Publication Links & Performance -> Active listing).
   A subtle tint rather than a saturated fill: the date itself must stay the most readable thing
   in the cell, so the text colour is darkened for contrast instead of the background being
   deepened. Scoped to this one class - it never applies to the Completed history table, whose
   deadlines are historical and not actively overdue. */
.work-queue-due-overdue {
    background: #fdecec;
    color: #8a1c1c;
    font-weight: 600;
    border-radius: 5px;
}
.work-queue-status {
    /* The workflow status badge and its deadline indicator stack one below the other.
       align-items: flex-start keeps each badge at its own width instead of stretching it
       across the cell, and the gap is the same spacing they had side by side. A row with a
       single badge renders identically to before. */
    display: flex; flex-direction: column; align-items: flex-start; gap: 0.3rem;
}
/* .status-pill.status-onhold carries a legacy margin-left for the inline contexts it was written
   for; in this stacked cell that would indent the hold badge relative to the one beneath it. Reset
   here only - the global rule is untouched, so every other screen keeps its existing spacing. */
.work-queue-status .status-pill { margin-left: 0; }

/* Weekly Planning. The table is at most one row per category plus the reporting-only rows, so it
   is never given a fixed height: the Total row in <tfoot> is the summary the screen exists for and
   must always be visible without scrolling. Only horizontal overflow is allowed, for narrow
   viewports, which keeps the page body from scrolling sideways as a whole. */
.weekly-planning-table-wrap { overflow-x: auto; }
#weekly-planning-table tfoot th {
    background: #f9fafb;
    border-top: 2px solid var(--kcpc-border);
    font-weight: 700;
}
/* The numeric columns read as numbers, not as text that happens to be digits. */
#weekly-planning-table tbody td:nth-child(n+2):nth-child(-n+4),
#weekly-planning-table tfoot th:nth-child(n+2):nth-child(-n+4),
#weekly-planning-table thead th:nth-child(n+2):nth-child(-n+4) { text-align: right; }
#weekly-planning-table tbody td:last-child,
#weekly-planning-table thead th:last-child { text-align: right; }

/* Weekly Planning row actions. THREE separate controls, never one menu, because they do three
   different things and only one of them deletes anything:
     .icon-btn         Edit target   - neutral, the existing pencil
     .icon-btn-danger  Delete target - red, and it really does delete a record
   Red marks the one action that deletes something, so it is the ONLY red control in the row. */
.weekly-planning-actions { white-space: nowrap; text-align: right; }
.weekly-planning-action { display: inline-block; vertical-align: middle; margin-left: 0.25rem; }
.weekly-planning-action:first-child { margin-left: 0; }
/* An OPEN action becomes a block so its confirmation stacks BENEATH the icon row instead of
   beside it. Side by side, two open panels laid themselves out horizontally and ran off the end of
   the scroll container; stacked, the row grows downward, which nothing clips. */
.weekly-planning-action[open] { display: block; margin: 0.35rem 0 0; }
/* The revealed confirmation stays in normal flow, exactly like the Category Catalogue's own edit
   panel. It is deliberately NOT absolutely positioned: .weekly-planning-table-wrap sets
   overflow-x, which makes it a clipping context on BOTH axes, so a floating panel would be cut off
   at the row instead of overlaying it. In flow it simply expands the row, which is unclipped,
   needs no z-index, and works the same on a phone. */
.weekly-planning-action[open] > .catalogue-edit-panel {
    width: 20rem; max-width: 100%; text-align: left; white-space: normal;
    margin-left: auto;          /* stays under the icons rather than drifting left */
    border: 1px solid var(--kcpc-border); border-radius: 6px;
}
.icon-btn-danger { color: #b91c1c; border-color: #fecaca; }
.icon-btn-danger:hover { background: #fef2f2; color: #991b1b; }

/* Weekly Planning: the inline Set Qty box and its Update button, one pair per row.
   The row is the editor - there is no modal - so the controls have to sit inside a table cell
   without stretching it: a narrow number box, and buttons restated at button+class specificity
   because ".panel button"/".action-form button" would otherwise repaint them solid red. Red stays
   with Delete, the only one of the two that removes anything. */
.weekly-planning-qty-cell { white-space: nowrap; }
.weekly-planning-qty-form { display: inline-flex; align-items: center; gap: 0.4rem; margin: 0; }
input.weekly-planning-qty-input {
    width: 5.5rem; margin: 0; padding: 0.3rem 0.5rem; text-align: right;
    border: 1px solid var(--kcpc-border); border-radius: 6px; font-size: 0.85rem;
}
input.weekly-planning-qty-input:focus { outline: 2px solid #93c5fd; outline-offset: 0; }
/* An empty box means "no target set" - not zero. The placeholder says so rather than showing a 0
   the user never chose. */
input.weekly-planning-qty-input::placeholder { color: #9ca3af; font-style: italic; }
.weekly-planning-actions-cell { white-space: nowrap; text-align: right; }
/* Scoped to the cell on purpose. ".app-main button[type=submit]" makes every submit button in the
   app a right-aligned BLOCK - sensible for a form footer, but here it put Delete on its own line
   when the two must sit side by side. That selector is (0,2,1); a bare button.class is only
   (0,1,1) and loses, so this one is written to outrank it rather than to look tidier. */
.weekly-planning-actions-cell button.weekly-planning-update-btn {
    display: inline-block; vertical-align: middle;
    width: auto; margin: 0; padding: 0.3rem 0.85rem;
    background: transparent; color: #1d4ed8; border: 1px solid #93c5fd; border-radius: 6px;
    font-size: 0.78rem; font-weight: 700;
}
.weekly-planning-actions-cell button.weekly-planning-update-btn:hover:not(:disabled) { background: #eff6ff; }
/* Also outranks ".panel button:disabled", which would otherwise paint it solid grey. */
.weekly-planning-actions-cell button.weekly-planning-update-btn:disabled {
    opacity: 0.45; cursor: default; background: transparent; color: #93c5fd;
}
/* The per-row outcome: a refusal sits under the box it came from, not in a page-top banner where
   it loses the connection to the row. */
.weekly-planning-row-error { display: block; margin-top: 0.25rem; color: #b91c1c; font-size: 0.75rem; white-space: normal; }
.weekly-planning-row-saved { display: block; margin-top: 0.25rem; color: #166534; font-size: 0.75rem; }
tr.weekly-planning-row-just-saved { background: #f0fdf4; }
@media (max-width: 700px) {
    input.weekly-planning-qty-input { width: 4.5rem; }
    .weekly-planning-actions-cell button.weekly-planning-update-btn { padding: 0.3rem 0.6rem; }
}

/* Content Pipeline pagination. Scoped to .pipeline-pagination so the nine other screens sharing
   the base .pagination class are untouched.

   The row must WRAP rather than be clipped: the old fix-by-hiding (overflow:hidden) would have
   made the last pages unreachable instead of tidy. With the compact window there are at most nine
   controls, so wrapping only ever matters on a narrow screen - where the count text and the
   buttons drop onto separate lines instead of pushing the page sideways. */
.pipeline-pagination { flex-wrap: wrap; gap: 0.6rem 1rem; }
.pipeline-pagination .pagination-controls { flex-wrap: wrap; justify-content: flex-end; }
/* The ellipsis is display-only - never a link, and never styled to look like one.

   Scoped to .pipeline-pagination deliberately. Logs (Audit History) already renders .page-ellipsis
   inside its own .pagination-controls and already has a rule for it higher up in this file; an
   unscoped selector here would have silently restyled that screen's padding and given it a
   min-width it never asked for. */
.pipeline-pagination .pagination-controls .page-ellipsis {
    border: none; background: transparent; color: #9ca3af; cursor: default;
    min-width: 1rem; padding: 0 0.15rem;
}
@media (max-width: 700px) {
    /* Stacked, each part on its own line, still without any horizontal page overflow. */
    .pipeline-pagination { justify-content: flex-start; }
    .pipeline-pagination .pipeline-per-page,
    .pipeline-pagination .pagination-controls { width: 100%; }
    .pipeline-pagination .pagination-controls { justify-content: flex-start; }
}

/* Reports -> KPI Dashboard -> Employee Performance. Wide table: it scrolls horizontally inside
   .reports-table-scroll with the # and Employee columns pinned, rather than squashing 11 columns. */
.stage-badge.stage-model { background: #fce7f3; color: #be185d; }
.kpi-date-toolbar .employee-perf-filter { flex-direction: row; align-items: center; }
.kpi-date-toolbar .employee-perf-filter.filter-field-search { margin-left: auto; }
.employee-perf-head { margin: 0.25rem 0 0.75rem; }
.employee-perf-head .reports-kpi-group-title { font-size: 1.25rem; margin-bottom: 0.25rem; }
.employee-perf-summary { font-size: 0.82rem; margin-bottom: 0.6rem; }
.employee-perf-table { min-width: 1100px; }
.employee-perf-cards { margin-bottom: 1rem; }
.employee-perf-table th, .employee-perf-table td { white-space: nowrap; vertical-align: middle; }
.employee-perf-table .employee-perf-roles { white-space: normal; min-width: 11rem; }
.employee-perf-roles .stage-badge { margin: 0.1rem 0.3rem 0.1rem 0; }
.employee-perf-table .employee-perf-col-index { position: sticky; left: 0; width: 2.6rem; min-width: 2.6rem; z-index: 1; }
.employee-perf-table .employee-perf-col-name { position: sticky; left: 2.6rem; z-index: 1; box-shadow: 1px 0 0 var(--kcpc-border); }
.employee-perf-table td.employee-perf-col-index, .employee-perf-table td.employee-perf-col-name { background: var(--kcpc-surface); }
.employee-perf-table th.employee-perf-col-index, .employee-perf-table th.employee-perf-col-name { background: #f9fafb; z-index: 2; }
.employee-perf-table td.employee-perf-completed { background: #eff6ff; font-weight: 700; }
/* Actions stays pinned to the right edge of the horizontally scrolling table, so View Details is
   always reachable; opaque backgrounds keep scrolled cells from showing through. */
.employee-perf-table .employee-perf-col-actions { position: sticky; right: 0; z-index: 1; box-shadow: -1px 0 0 var(--kcpc-border); }
.employee-perf-table td.employee-perf-col-actions { background: var(--kcpc-surface); }
.employee-perf-table th.employee-perf-col-actions { background: #f9fafb; z-index: 2; }
.employee-perf-pagination { flex-wrap: wrap; gap: 0.75rem; }
.employee-perf-pagination .reports-page-size { display: inline-flex; align-items: center; gap: 0.4rem; margin-left: auto; }
.employee-perf-pagination .reports-page-size label { font-size: 0.82rem; white-space: nowrap; }
.employee-perf-pagination .reports-page-size { flex-shrink: 0; }
