@import '/shared/css/portal-chrome.css';

/* File: portal-department/css/department-portal-identity.css
 *
 * The Department Desk's own look.
 *
 * This portal is a workplace. The people in it are here all day, working a queue, and the
 * screen is a tool rather than a document. So it is the opposite of the Support portal in
 * every decision that is not the ECVALLA identity itself: the chrome is a dark ink band that
 * frames the work instead of a white page header, the rhythm is dense rather than spacious,
 * counts are large and tabular because they are read at a glance, and the hero is a queue —
 * rows of work, ordered, some of them urgent — instead of a person's own small pile.
 *
 * Same palette, same two typefaces, same rule that colour only ever means a state. Nothing
 * else is shared with the other two portals.
 *
 * Loads after ecvalla-identity.css and portal-auth.css.
 */

.dp-portal {
    margin: 0;
    background: var(--ecv-canvas, #f5f5f3);
    color: var(--ecv-ink, #17191b);
}

/* Figures in this portal are compared down a column, so they are tabular and aligned. */
.dp-figure {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

/* ================================================================== *
 * Home — the hero
 *
 * A full-bleed ink panel, left-aligned, with the queue itself as the motif: rows of work of
 * varying length, the urgent ones marked, the resolved ones falling away. Where the Support
 * portal shows one person's cards and administration shows a control matrix, this shows the
 * ================================================================== */

/* Hosts the shared front-door texture (.phero-canvas, in shared/css/portal-chrome.css).
   `isolation` is what the mount needs: it keeps the canvas's z-index: -1 inside this
   element, above its own background and below its content, rather than behind the page. */
.dhome {
    position: relative;
    isolation: isolate;
    height: calc(100svh - 66px);
    max-height: calc(100svh - 66px);
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: 18px clamp(20px, 3.5vw, 56px) 10px;
    box-sizing: border-box;
    overflow: hidden;
    background: var(--ecv-canvas, #f5f5f3);
    color: var(--text-color, #17191b);
}

.dhero {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    align-items: center;
    gap: clamp(28px, 4vw, 64px);
    flex: 1 1 0;
    min-height: 0;
    max-width: 1600px;
    margin: 0 auto;
    width: 100%;
}

.dhero-copy {
    display: flex;
    flex-direction: column;
    justify-content: center;
    max-width: 720px;
}

.dhero-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 12px;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--ecv-muted, #73787b);
}

.dhero h1 {
    margin: 0 0 14px;
    font-size: clamp(34px, 4.5vw, 54px);
    line-height: 1.08;
    letter-spacing: -.03em;
    font-weight: 800;
    color: var(--text-color, #17191b);
}

.dhero h1 em {
    display: inline-block;
    font-style: normal;
    color: var(--ecv-muted, #73787b);
    margin-inline-start: 6px;
}

.dhero-lede {
    margin: 0 0 24px;
    max-width: 62ch;
    font-size: clamp(15px, 1.35vw, 17.5px);
    line-height: 1.6;
    color: var(--ecv-muted, #73787b);
}

.dhero-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
}

.dhero-btn {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    min-height: 50px;
    padding: 0 28px;
    border: 1px solid var(--sys-action-primary, var(--ecv-ink, #17191b));
    border-radius: 10px;
    background: var(--sys-action-primary, var(--ecv-ink, #17191b));
    /* Tracks its own plate: paper is white on a light theme and ink on a dark one, so the
     * label is always the plate's opposite. A literal #ffffff !important here was white on
     * white the moment the theme flipped the plate. */
    color: var(--sys-action-primary-text, #ffffff);
    font-size: 15.5px;
    font-weight: 700;
    text-decoration: none;
    box-shadow: 0 4px 14px rgba(23, 25, 27, 0.18);
    transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.18s ease, box-shadow 0.18s ease;
}

/* :visited must not repaint a button, and the children inherit — stated without
 * !important so the theme keeps the last word. */
.dhero-btn,
.dhero-btn:visited {
    color: var(--sys-action-primary-text, #ffffff);
}

.dhero-btn i,
.dhero-btn span {
    color: inherit;
}

.dhero-btn:hover,
.dhero-btn:focus {
    /* One step off the resting plate, in whichever direction the theme is going. */
    background: color-mix(in srgb, var(--sys-action-primary) 88%, var(--sys-surface-page));
    color: var(--sys-action-primary-text, #ffffff);
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba(23, 25, 27, 0.3);
}

@supports not (background: color-mix(in srgb, red 50%, blue)) {
    .dhero-btn:hover,
    .dhero-btn:focus { background: var(--ecv-ink-soft, #2b2e30); }
}

.dhero-btn.is-ghost {
    background: transparent;
    color: var(--sys-text-primary, var(--text-color, #17191b));
    border-color: var(--sys-border, var(--ecv-line, #e5e6e4));
    box-shadow: none;
}

.dhero-btn.is-ghost i,
.dhero-btn.is-ghost span {
    color: inherit;
}

.dhero-btn.is-ghost:hover {
    background: var(--sys-surface-hover, var(--ecv-soft, rgba(0, 0, 0, .05)));
    color: var(--sys-text-primary, var(--text-color, #17191b));
}

.dhero-btn:focus-visible {
    outline: 2px solid var(--ecv-ink, #17191b);
    outline-offset: 3px;
}

.dhero-note {
    margin: 0;
    font-size: 12px;
    color: var(--ecv-muted, #73787b);
}

.dhero-note b {
    color: var(--text-color, #17191b);
}

.dhero-note button {
    border: 0;
    background: transparent;
    padding: 0;
    color: var(--text-color, #17191b);
    font: inherit;
    font-weight: 700;
    text-decoration: underline;
    cursor: pointer;
}

.dhero-note button:focus-visible {
    outline: 2px solid var(--ecv-ink, #17191b);
    outline-offset: 2px;
}

.dhero-art {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    min-height: 0;
}

.dhero-art svg {
    display: block;
    width: 100%;
    height: 100%;
    max-height: 330px;
    object-fit: contain;
}

/* Light mode queue svg strokes and fills */
.dhero-art svg line {
    stroke: var(--ecv-line, #e5e6e4);
}

.dhero-art svg text {
    fill: var(--ecv-muted, #73787b);
}

.dhero-art svg rect[fill-opacity] {
    fill: var(--ecv-paper, #ffffff);
    stroke: var(--ecv-line, #e5e6e4);
}

.dhero-art svg rect[fill="#ffffff"] {
    fill: var(--text-color, #17191b);
}

/* Rows advance animation */
.dhero-art .queue-row-anim {
    animation: dhero-advance 9s ease-in-out infinite;
}

.dhero-art .queue-row-anim:nth-of-type(2) { animation-delay: -1.5s; }
.dhero-art .queue-row-anim:nth-of-type(3) { animation-delay: -3s; }
.dhero-art .queue-row-anim:nth-of-type(4) { animation-delay: -4.5s; }
.dhero-art .queue-row-anim:nth-of-type(5) { animation-delay: -6s; }

@keyframes dhero-advance {
    0%, 100% { translate: 0 0; opacity: 1; }
    50% { translate: 10px 0; opacity: .78; }
}

@media (prefers-reduced-motion: reduce) {
    .dhero-art .queue-row-anim {
        animation: none;
    }
}

/* ------------------------------------------------------------------ *
 * Desk Capabilities Grid
 * ------------------------------------------------------------------ */

.dfacts {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 14px;
    max-width: 1600px;
    margin: 0 auto 12px;
    width: 100%;
    flex-shrink: 0;
}

.dfact-card {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 14px 18px;
    border-radius: 10px;
    background: var(--ecv-paper, #ffffff);
    border: 1px solid var(--ecv-line, #e5e6e4);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
    transition: border-color 0.18s ease, transform 0.18s ease;
}

.dfact-card:hover {
    border-color: var(--ecv-ink, #17191b);
    transform: translateY(-1px);
}

.dfact-card i {
    font-size: 18px;
    color: var(--ecv-ink, #17191b);
    flex-shrink: 0;
    margin-top: 2px;
}

.dfact-card h2 {
    margin: 0 0 4px;
    font-size: 13.5px;
    font-weight: 700;
    color: var(--text-color, #17191b);
    letter-spacing: -.01em;
}

.dfact-card p {
    margin: 0;
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--ecv-muted, #73787b);
}

.dfoot {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: space-between;
    max-width: 1600px;
    margin: 0 auto;
    width: 100%;
    padding: 8px 0 2px;
    border-top: 1px solid var(--ecv-line, #e5e6e4);
    font-size: 11.5px;
    color: var(--ecv-muted, #73787b);
    flex-shrink: 0;
}

/* ================================================================== *
 * Dark Theme Explicit Overrides for Department Home
 * ================================================================== */

html.dark-theme .dhome,
[data-theme="dark"] .dhome {
    background: #111417;
    color: #e9eae8;
}

html.dark-theme .dhero h1,
[data-theme="dark"] .dhero h1 {
    color: #ffffff;
}

html.dark-theme .dhero h1 em,
[data-theme="dark"] .dhero h1 em {
    color: rgba(255, 255, 255, 0.55);
}

html.dark-theme .dhero-lede,
[data-theme="dark"] .dhero-lede {
    color: rgba(255, 255, 255, 0.78);
}

html.dark-theme .dhero-eyebrow,
[data-theme="dark"] .dhero-eyebrow {
    color: rgba(255, 255, 255, 0.65);
}

/* The dark-theme rules for .dhero-btn were removed: the token pair above resolves both
 * themes, and the filled button's override was losing to an !important in the base
 * rule anyway — which is what made it a white label on a white plate. */

html.dark-theme .dhero-note,
[data-theme="dark"] .dhero-note {
    color: rgba(255, 255, 255, 0.55);
}

html.dark-theme .dhero-note b,
html.dark-theme .dhero-note button,
[data-theme="dark"] .dhero-note b,
[data-theme="dark"] .dhero-note button {
    color: #ffffff;
}

html.dark-theme .dhero-art svg line,
[data-theme="dark"] .dhero-art svg line {
    stroke: rgba(255, 255, 255, 0.18);
}

html.dark-theme .dhero-art svg text,
[data-theme="dark"] .dhero-art svg text {
    fill: rgba(255, 255, 255, 0.4);
}

html.dark-theme .dhero-art svg rect[fill-opacity],
[data-theme="dark"] .dhero-art svg rect[fill-opacity] {
    fill: #ffffff;
    stroke: rgba(255, 255, 255, 0.15);
}

html.dark-theme .dhero-art svg rect[fill="#ffffff"],
[data-theme="dark"] .dhero-art svg rect[fill="#ffffff"] {
    fill: #ffffff;
}

html.dark-theme .dfact-card,
[data-theme="dark"] .dfact-card {
    background: #17191b;
    border-color: rgba(255, 255, 255, 0.12);
    box-shadow: none;
}

html.dark-theme .dfact-card:hover,
[data-theme="dark"] .dfact-card:hover {
    border-color: rgba(255, 255, 255, 0.3);
}

html.dark-theme .dfact-card i,
[data-theme="dark"] .dfact-card i {
    color: rgba(255, 255, 255, 0.85);
}

html.dark-theme .dfact-card h2,
[data-theme="dark"] .dfact-card h2 {
    color: #ffffff;
}

html.dark-theme .dfact-card p,
[data-theme="dark"] .dfact-card p {
    color: rgba(255, 255, 255, 0.65);
}

html.dark-theme .dfoot,
[data-theme="dark"] .dfoot {
    border-top-color: rgba(255, 255, 255, 0.12);
    color: rgba(255, 255, 255, 0.5);
}

@media (max-width: 960px), (max-height: 700px) {
    .dhome {
        height: auto;
        min-height: calc(100svh - 66px);
        max-height: none;
        overflow-y: auto;
        padding: 24px 20px 20px;
        gap: 20px;
    }

    .dhero {
        grid-template-columns: 1fr;
        padding-top: 10px;
        gap: 20px;
    }

    .dhero-art {
        order: 2;
        max-width: 440px;
        margin: 0 auto;
        height: auto;
    }

    .dfacts {
        grid-template-columns: 1fr;
    }
}

/* ================================================================== *
 * Sign-in — split panel
 *
 * The queue motif on the ink half, the single action on the light half. Deliberately not a
 * centred card on an open page: that is the Support portal's sign-in, and these two screens
 * must not be mistaken for one another when somebody is looking at a bookmark.
 *
 * No Back control: this page is the portal's entrance.
 * ================================================================== */

.dlogin {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
    height: calc(100svh - 66px);
    overflow: hidden;
}

.dlogin-aside {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 18px;
    padding: clamp(24px, 3vw, 48px);
    background: var(--ecv-ink, #17191b);
    color: #fff;
    overflow: hidden;
}

.dlogin-aside h2 {
    margin: 0;
    font-size: clamp(24px, 3.2vw, 38px);
    line-height: 1.12;
    letter-spacing: -.024em;
    max-width: 22ch;
}

.dlogin-aside p {
    margin: 0;
    max-width: 42ch;
    font-size: 14.5px;
    line-height: 1.7;
    color: rgba(255, 255, 255, .7);
}

.dlogin-aside svg {
    display: block;
    width: 100%;
    max-width: 420px;
    height: auto;
}

.dlogin-main {
    display: grid;
    place-items: center;
    padding: 20px;
    background: #f5f5f3;
    color: #17191b;
}

/* In dark mode, force the right panel to stand out with a contrasting surface */
html.dark-theme .dlogin-main,
html[data-theme="dark"] .dlogin-main {
    background: #1e2124;
    color: #e9eae8;
}

html.dark-theme .dlogin-card h1,
html[data-theme="dark"] .dlogin-card h1 {
    color: #ffffff;
}

html.dark-theme .dlogin-card > p:first-of-type,
html[data-theme="dark"] .dlogin-card > p:first-of-type {
    color: rgba(255, 255, 255, .7);
}

html.dark-theme .dlogin-kicker,
html[data-theme="dark"] .dlogin-kicker {
    color: rgba(255, 255, 255, .6);
}

.dlogin-card {
    width: 100%;
    max-width: 400px;
    display: grid;
    gap: 18px;
}

.dlogin-card h1 {
    margin: 0;
    font-size: clamp(22px, 3vw, 28px);
    letter-spacing: -.02em;
    line-height: 1.2;
}

.dlogin-card > p:first-of-type {
    margin: -8px 0 0;
    color: var(--ecv-muted, #73787b);
    font-size: 14px;
    line-height: 1.65;
}

.dlogin-kicker {
    margin: 0;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--ecv-muted, #73787b);
}

html[dir="rtl"] .dlogin-kicker {
    letter-spacing: normal;
    text-transform: none;
    font-size: 12.5px;
}

@media (max-width: 940px) {
    .dlogin {
        grid-template-columns: 1fr;
        min-height: 0;
    }

    /* The panel becomes a short band above the action on a phone rather than disappearing:
     * it is how somebody confirms which portal they have opened. */
    .dlogin-aside {
        padding: 28px 20px 32px;
        gap: 16px;
    }

    .dlogin-aside svg {
        display: none;
    }
}

/* ================================================================== *
 * Overview
 *
 * The department's own numbers, then the work that needs a decision. Large tabular figures
 * on a hairline grid — read, not browsed.
 * ================================================================== */

.dover {
    max-width: 100%;
    width: 100%;
    margin: 0;
    padding: clamp(20px, 3vw, 36px) clamp(14px, 2.4vw, 32px) 80px;
    box-sizing: border-box;
}

.dp-portal .dept-shell,
.dp-portal .dept-main,
.dp-portal .dover {
    max-width: 100%;
    width: 100%;
    box-sizing: border-box;
}

.dover-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 22px;
}

.dover-head h1 {
    margin: 0 0 4px;
    font-size: clamp(21px, 2.6vw, 28px);
    letter-spacing: -.018em;
}

.dover-head p {
    margin: 0;
    color: var(--ecv-muted, #73787b);
    font-size: 14px;
}

.dover-kpis {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 1px;
    margin-bottom: 26px;
    background: var(--ecv-line, #e5e6e4);
    border: 1px solid var(--ecv-line, #e5e6e4);
    border-radius: 14px;
    overflow: hidden;
}

.dover-kpis article {
    background: var(--ecv-paper, #fff);
    padding: 20px 22px 22px;
}

.dover-kpis b {
    display: block;
    margin-bottom: 10px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ecv-muted, #73787b);
}

html[dir="rtl"] .dover-kpis b {
    letter-spacing: normal;
    text-transform: none;
    font-size: 12.5px;
}

.dover-kpis strong {
    display: block;
    font-size: clamp(28px, 3.6vw, 40px);
    line-height: 1;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}

.dover-kpis a {
    display: inline-block;
    margin-top: 12px;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--ecv-ink, #17191b);
}

.dover-section {
    margin-bottom: 26px;
    background: var(--ecv-paper, #fff);
    border: 1px solid var(--ecv-line, #e5e6e4);
    border-radius: 14px;
    overflow: hidden;
}

.dover-section-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 16px 22px;
    border-bottom: 1px solid var(--ecv-line, #e5e6e4);
}

.dover-section-head h2 {
    margin: 0;
    font-size: 15px;
    letter-spacing: -.005em;
}

.dover-section-head a {
    font-size: 12.5px;
    font-weight: 700;
    color: var(--ecv-ink, #17191b);
}

.dover-row {
    display: grid;
    grid-template-columns: minmax(0, 92px) minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 14px;
    padding: 14px 22px;
    border-bottom: 1px solid var(--ecv-line, #e5e6e4);
    color: inherit;
    text-decoration: none;
}

.dover-row:last-child {
    border-bottom: 0;
}

.dover-row:hover {
    background: var(--ecv-canvas, #f5f5f3);
}

.dover-row:focus-visible {
    outline: 2px solid var(--ecv-ink, #17191b);
    outline-offset: -2px;
}

.dover-ref {
    font-size: 12px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--ecv-muted, #73787b);
}

.dover-subject {
    font-size: 14px;
    font-weight: 700;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dover-age {
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    color: var(--ecv-muted, #73787b);
    white-space: nowrap;
}

.dover-empty {
    padding: 34px 22px;
    text-align: center;
    color: var(--ecv-muted, #73787b);
    font-size: 13.5px;
}

.dover-skeleton {
    height: 54px;
    border-bottom: 1px solid var(--ecv-line, #e5e6e4);
    background: linear-gradient(90deg, var(--sys-skeleton-base) 25%, var(--sys-skeleton-sheen) 37%, var(--sys-skeleton-base) 63%);
    background-size: 400% 100%;
    animation: dover-shimmer 1.3s ease-in-out infinite;
}

@keyframes dover-shimmer {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

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

@media (max-width: 760px) {
    .dover-row {
        grid-template-columns: minmax(0, 1fr) auto;
        row-gap: 4px;
    }

    .dover-ref {
        grid-column: 1 / -1;
    }
}

/* ------------------------------------------------------------------ *
 * Rail palette — the Department Desk
 *
 * Ink like administration, but a degree warmer and a shade lighter: this is a room people work
 * in all day, not a control panel they visit to change a rule. The resting text is brighter
 * because these rows are read constantly rather than scanned occasionally.
 * ------------------------------------------------------------------ */

/* The queue is dense: it gets the full width of the content column. */
.dp-portal .pcontent { padding-inline: 0; }

/* Premium department operations workspace -------------------------------- */
.dp-portal { --ops-navy:var(--text-color, #17191b); --ops-blue:var(--ecv-ink, #17191b); --ops-soft:var(--ecv-soft, #eff0ee); --ops-line:var(--ecv-line, #e5e6e4); --ops-muted:var(--text-light, #73787b); --ops-radius:10px; overflow-x:hidden; }
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.ops-page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;padding:28px 0 22px;border-bottom:1px solid var(--ops-line)}
.ops-page-head h1{margin:2px 0 5px;font-size:clamp(23px,2.5vw,32px);line-height:1.18;letter-spacing:-.035em}.ops-page-head>div>p:last-child{margin:0;color:var(--ops-muted);font-size:13px}
.ops-eyebrow{margin:0!important;color:var(--ops-muted);font-size:9.5px!important;font-weight:700;letter-spacing:.16em;text-transform:uppercase}.ops-head-actions,.ops-detail-actions{display:flex;align-items:center;gap:9px}.ops-live{display:inline-flex;align-items:center;gap:7px;color:var(--text-color);font-size:11px;font-weight:700}.ops-live i{width:7px;height:7px;border-radius:50%;background:var(--success-color);box-shadow:0 0 0 3px var(--success-light)}
.ops-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:36px;padding:0 13px;border:1px solid var(--ecv-line);border-radius:8px;background:var(--ecv-paper);color:var(--ops-navy);font:700 12px inherit;text-decoration:none;cursor:pointer}.ops-btn:hover{border-color:var(--ecv-muted);background:var(--ecv-soft)}.ops-btn-primary{background:var(--sys-action-primary);border-color:var(--sys-action-primary);color:var(--sys-action-primary-text)}.ops-btn-primary:hover{background:var(--ecv-ink-soft);border-color:var(--ecv-ink-soft)}.ops-btn:focus-visible,.ops-icon-btn:focus-visible,.ops-view-tabs button:focus-visible,.ops-kpi:focus-visible,.queue-row:focus-visible{outline:3px solid var(--primary-light-transparent);outline-offset:2px}.ops-btn:disabled,.ops-pagination button:disabled{opacity:.42;cursor:not-allowed}
.ops-dashboard{padding-top:0}/* auto-fit, not repeat(8): eight fixed tracks with a 125px floor need 1056px, so the grid
   forced a horizontally scrolling page on anything narrower. portal-chrome.css does carry
   responsive overrides for this class, but this file loads AFTER it at equal specificity, so
   they never applied; below 768px portal-mobile.css loads later still and corrected it,
   which is why only tablet widths were broken. auto-fit needs no media query and cannot
   fall out of step with one: eight across when there is room, fewer when there is not. */.ops-kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(125px,1fr));gap:8px;margin:16px 0}.ops-kpi{position:relative;min-height:104px;padding:14px;border:1px solid var(--ops-line);border-radius:var(--ops-radius);background:var(--ecv-paper);color:inherit;text-decoration:none;box-shadow:0 1px 2px rgba(16,30,48,.025);transition:border-color .15s,box-shadow .15s,transform .15s}.ops-kpi:hover{border-color:var(--ecv-muted);box-shadow:0 5px 15px rgba(16,30,48,.07);transform:translateY(-1px)}.ops-kpi-icon{position:absolute;inset-block-start:12px;inset-inline-end:12px;display:grid;place-items:center;width:25px;height:25px;border-radius:7px;background:var(--ecv-soft);color:var(--text-light);font-size:11px}.ops-kpi-icon.is-warning{background:var(--ecv-soft);color:var(--warning-color)}.ops-kpi-icon.is-priority{background:var(--ecv-red-wash);color:var(--danger-color)}.ops-kpi-icon.is-success{background:var(--success-light);color:var(--success-dark)}.ops-kpi b{display:block;max-width:calc(100% - 25px);color:var(--ops-muted);font-size:10px;text-transform:uppercase;letter-spacing:.08em}.ops-kpi strong{display:block;margin:13px 0 5px;color:var(--ops-navy);font-size:26px;line-height:1;font-variant-numeric:tabular-nums}.ops-kpi small{color:var(--text-light);font-size:10px}
.ops-dashboard-grid{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(270px,.7fr);gap:12px}.ops-panel{min-width:0;border:1px solid var(--ops-line);border-radius:var(--ops-radius);background:var(--ecv-paper);overflow:hidden}.ops-panel-full{grid-column:1/-1}.ops-panel-head{display:flex;align-items:center;justify-content:space-between;gap:14px;min-height:63px;padding:12px 16px;border-bottom:1px solid var(--ops-line)}.ops-panel-head h2{margin:3px 0 0;font-size:14px}.ops-panel-head>a{color:var(--text-color);font-size:11px;font-weight:700;text-decoration:none}.ops-panel-head>a i{margin-inline-start:5px}.ops-ticket-row{display:grid;grid-template-columns:5px minmax(0,1fr) auto minmax(105px,auto) 18px;align-items:center;gap:12px;min-height:58px;padding:9px 16px;border-bottom:1px solid var(--ecv-line);color:inherit;text-decoration:none}.ops-ticket-row:last-child{border:0}.ops-ticket-row:hover{background:var(--ecv-soft)}.ops-ticket-priority{width:3px;height:30px;border-radius:3px;background:var(--ecv-line)}.ops-ticket-priority.is-high{background:var(--warning-color)}.ops-ticket-priority.is-critical{background:var(--danger-color)}.ops-ticket-main{min-width:0}.ops-ticket-main b{display:block;overflow:hidden;color:var(--text-color);font-size:12px;text-overflow:ellipsis;white-space:nowrap}.ops-ticket-main small{display:block;margin-top:4px;color:var(--text-light);font-size:10px}.ops-ref{font-weight:700;font-variant-numeric:tabular-nums;color:var(--text-light)}.ops-sla{font-size:10px;text-align:end;color:var(--text-light)}.ops-sla b,.ops-sla small{display:block}.ops-sla.is-risk b{color:var(--warning-color)}.ops-row-arrow{color:var(--text-muted);font-size:9px}.ops-empty{display:grid;place-items:center;padding:30px 18px;text-align:center}.ops-empty>span{display:grid;place-items:center;width:32px;height:32px;margin-bottom:8px;border-radius:50%;background:var(--success-light);color:var(--success-dark);font-size:11px}.ops-empty b{font-size:12px}.ops-empty p{margin:4px 0 0;color:var(--ops-muted);font-size:11px}.ops-empty.is-error>span{background:var(--ecv-red-wash);color:var(--danger-color)}
.ops-workload{padding:7px 15px}.ops-agent{display:grid;grid-template-columns:29px 1fr auto;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--ecv-line)}.ops-agent:last-child{border:0}.ops-avatar{display:grid;place-items:center;width:29px;height:29px;border-radius:8px;background:var(--ecv-soft);color:var(--text-light);font-size:10px;font-weight:700}.ops-agent>span:nth-child(2){min-width:0}.ops-agent b{display:block;overflow:hidden;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.ops-agent i{display:block;width:100%;height:3px;margin-top:6px;border-radius:4px;background:linear-gradient(to right,var(--ecv-ink) var(--load),var(--ecv-soft) var(--load))}.ops-agent strong{font-size:12px;font-variant-numeric:tabular-nums}.ops-volume{min-height:183px;padding:20px}.ops-bars{display:flex;align-items:end;justify-content:space-between;gap:8px;height:143px}.ops-bars>div{display:grid;grid-template-rows:1fr auto auto;align-items:end;justify-items:center;height:100%;flex:1}.ops-bars span{align-self:end;width:min(26px,75%);border-radius:4px 4px 1px 1px;background:var(--ecv-ink)}.ops-bars b{margin-top:5px;font-size:9px}.ops-bars small{margin-top:3px;color:var(--ops-muted);font-size:9px}.ops-row-skeleton{height:58px;border-bottom:1px solid var(--ecv-line);background:linear-gradient(90deg,var(--ecv-soft) 25%,var(--ecv-soft) 38%,var(--ecv-soft) 62%);background-size:400% 100%;animation:dover-shimmer 1.3s infinite}

/* Zero-gap full-viewport workspace layout */
.dp-portal .pcontent,
.dp-portal .ops-queue-page,
.dp-portal #queueView,
.dp-portal .ops-workspace,
.dp-portal .ops-queue-panel,
.dp-portal .dept-queue,
.dp-portal .dept-main,
.dp-portal .dept-shell {
    padding: 0 !important;
    margin: 0 !important;
    max-width: 100% !important;
    border: none !important;
    border-radius: 0 !important;
}

/* Queue */
.ops-queue-page {
    width: 100%;
    height: calc(100vh - var(--topbar-h, 64px));
    max-height: calc(100vh - var(--topbar-h, 64px));
    padding: 0 !important;
    margin: 0 !important;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
#queueView {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
    flex: 1;
    width: 100%;
}
.ops-queue-toolbar {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    width: 100%;
    box-sizing: border-box;
    border-bottom: 1px solid var(--ops-line);
    background: var(--ecv-paper);
}
.ops-toolbar-end {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-inline-start: auto;
}
.ops-search {
    display: flex;
    align-items: center;
    gap: 9px;
    min-width: 200px;
    max-width: 360px;
    height: 38px;
    padding: 0 11px;
    flex: 1 1 auto;
    border: 1px solid var(--ecv-line);
    border-radius: 8px;
    background: var(--ecv-paper);
    color: var(--text-light);
}
.ops-search:focus-within {
    border-color: var(--ecv-muted);
    box-shadow: 0 0 0 3px var(--primary-light-transparent);
}
.ops-search input {
    min-width: 0;
    flex: 1;
    border: 0;
    outline: 0;
    background: transparent;
    font: 12px inherit;
    color: var(--text-color);
}
.ops-search kbd {
    padding: 2px 5px;
    border: 1px solid var(--ecv-line);
    border-radius: 4px;
    background: var(--ecv-soft);
    font: 9px inherit;
}
.ops-filters-inline {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
}
.ops-filter-select, .ops-sort select {
    height: 38px;
    padding: 0 28px 0 10px;
    border: 1px solid var(--ecv-line);
    border-radius: 8px;
    background: var(--ecv-paper);
    color: var(--text-color);
    font: 11.5px inherit;
    cursor: pointer;
    transition: border-color 0.15s;
}
.ops-filter-select:hover, .ops-sort select:hover {
    border-color: var(--ecv-muted);
}
.ops-clear-btn {
    padding: 6px 10px;
    border: 1px solid var(--ecv-line);
    border-radius: 6px;
    background: var(--ecv-soft);
    color: var(--text-light);
    font: 700 11px inherit;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.ops-clear-btn:hover {
    background: var(--ecv-red-wash, rgba(239, 68, 68, 0.1));
    color: var(--danger-color, #ef4444);
    border-color: var(--danger-color, #ef4444);
}
.ops-workspace {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
}
.ops-queue-panel {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    border: none;
    border-radius: 0;
    background: var(--ecv-paper);
    overflow: hidden;
}
.ops-results-head {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 36px;
    padding: 0 12px;
    border-bottom: 1px solid var(--ops-line);
    background: var(--ecv-soft);
}
.ops-results-head h2 { margin: 0; font-size: 12.5px; font-weight: 700; }
.ops-results-head p { margin: 0; color: var(--ops-muted); font-size: 11px; }
.ops-icon-btn {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 1px solid var(--ecv-line);
    border-radius: 6px;
    background: var(--ecv-paper);
    color: var(--text-light);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}
.ops-icon-btn:hover { background: var(--ecv-soft); color: var(--text-color); }
.ops-table-wrap {
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    overflow-y: auto;
    overflow-x: hidden;
    background: var(--ecv-paper);
    scrollbar-width: thin;
}
.ops-pagination {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 40px;
    padding: 0 14px;
    border-top: 1px solid var(--ops-line);
    color: var(--ops-muted);
    font-size: 12px;
    background: var(--ecv-paper);
}
.ops-ticket-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    table-layout: fixed;
    white-space: nowrap;
}
.ops-ticket-table th:nth-child(1), .ops-ticket-table td:nth-child(1) { width: 11%; }
.ops-ticket-table th:nth-child(2), .ops-ticket-table td:nth-child(2) { width: 25%; }
.ops-ticket-table th:nth-child(3), .ops-ticket-table td:nth-child(3) { width: 18%; }
.ops-ticket-table th:nth-child(4), .ops-ticket-table td:nth-child(4) { width: 10%; }
.ops-ticket-table th:nth-child(5), .ops-ticket-table td:nth-child(5) { width: 12%; }
.ops-ticket-table th:nth-child(6), .ops-ticket-table td:nth-child(6) { width: 9%; }
.ops-ticket-table th:nth-child(7), .ops-ticket-table td:nth-child(7) { width: 7.5%; }
.ops-ticket-table th:nth-child(8), .ops-ticket-table td:nth-child(8) { width: 7.5%; }
.ops-ticket-table th {
    position: sticky;
    top: 0;
    z-index: 10;
    height: 42px;
    padding: 0 8px;
    border-bottom: 1px solid var(--ops-line);
    background: var(--ecv-soft, #1e2124);
    color: var(--text-color);
    font-size: 11px;
    text-align: center;
    text-transform: uppercase;
    letter-spacing: .05em;
    font-weight: 700;
    user-select: none;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    white-space: nowrap;
}
.ops-ticket-table th:hover {
    background: var(--ecv-canvas, #25282c);
    color: var(--text-color);
}
.ops-ticket-table th i {
    margin-inline-start: 4px;
    font-size: 10px;
    opacity: 0.55;
    transition: opacity 0.15s, transform 0.15s;
}
.ops-ticket-table th:hover i, .ops-ticket-table th.is-sorted i {
    opacity: 1;
    color: var(--ecv-ink);
}
.ops-ticket-table td {
    height: 48px;
    padding: 0 10px;
    border-bottom: 1px solid var(--ecv-line);
    color: var(--text-color);
    font-size: 12.5px;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    background: var(--ecv-paper);
}
.ops-ticket-table .queue-row {
    display: table-row;
    background: var(--ecv-paper);
    text-align: center;
    cursor: pointer;
    transition: background 0.15s;
}
.ops-ticket-table .queue-row:hover { background: var(--ecv-soft); }
.ops-ticket-table .queue-row.is-selected { background: var(--ecv-soft); }
.ops-ticket-table .queue-subject {
    display: block;
    max-width: 320px;
    margin: 0 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 13px;
    font-weight: 600;
    text-align: center;
}
.ops-ref {
    font-size: 12.5px;
    font-weight: 700;
    color: var(--text-color);
}
.ops-dept-tag {
    display: inline-block;
    padding: 4px 10px;
    border: 1px solid var(--ecv-line);
    border-radius: 6px;
    background: var(--ecv-soft);
    font-size: 11px;
    font-weight: 700;
}
.ops-priority {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    font-size: 11.5px;
    font-weight: 700;
}
.ops-priority i { width: 7px; height: 7px; border-radius: 50%; background: var(--text-muted); }
.ops-priority.is-high i { background: var(--warning-color); }
.ops-priority.is-critical i { background: var(--danger-color); }
.ops-ticket-table .pill {
    font-size: 11px;
    padding: 4px 10px;
    border-radius: 6px;
    display: inline-block;
}
.ops-pagination { display: flex; align-items: center; justify-content: space-between; min-height: 50px; padding: 0 18px; color: var(--ops-muted); font-size: 12px; }
.ops-pagination>div { display: flex; align-items: center; gap: 9px; }
.ops-pagination button { display: grid; place-items: center; width: 30px; height: 30px; border: 1px solid var(--ecv-line); border-radius: 6px; background: var(--ecv-paper); color: var(--text-light); cursor: pointer; font-size: 12px; }
.ops-table-skeleton td { padding: 12px !important; }
.ops-table-skeleton span { display: block; height: 24px; border-radius: 5px; background: var(--ecv-soft); }

/* --- Ultra-Elite Modal for Ticket Preview --- */
.ops-detail-backdrop {
    position: fixed;
    inset: 0;
    z-index: 10000;
    background: rgba(8, 10, 14, 0.75);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px 16px;
    box-sizing: border-box;
    opacity: 1;
    transition: opacity .25s ease;
}
.ops-detail-backdrop[hidden] { display: none !important; }

.ops-detail-modal {
    position: relative;
    width: 100%;
    max-width: 1180px;
    max-height: 90vh;
    background: var(--ecv-paper, #ffffff);
    border: 1px solid var(--border-color, #272a2e);
    border-radius: 18px;
    box-shadow: 0 32px 96px rgba(0, 0, 0, 0.55);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: modal-zoom-in 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes modal-zoom-in {
    from { transform: scale(0.96) translateY(14px); opacity: 0; }
    to { transform: scale(1) translateY(0); opacity: 1; }
}

.ops-detail-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 18px 24px;
    border-bottom: 1px solid var(--ops-line);
    background: var(--ecv-paper, #ffffff);
    flex: 0 0 auto;
}
.ops-detail-head h2 { margin: 3px 0 0; font-size: 18px; font-weight: 700; color: var(--text-color); }
.dept-eyebrow { margin: 0; color: var(--ops-muted); font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }

.ops-detail-modal-body {
    flex: 1 1 auto;
    overflow-y: auto;
    background: var(--ecv-canvas, #f5f5f3);
}

/* The ticket-page pattern (.tfull-*) moved to shared/css/portal-chrome.css: the Support
 * portal opens tickets the same way now, and a pattern two portals share belongs where
 * both load it. */

/* ================================================================== *
 * Ultra-Elite Premium Modal & Toast Dialogs
 * ================================================================== */
dialog.ops-modal {
    border: none;
    border-radius: 16px;
    padding: 0;
    background: transparent;
    max-width: min(480px, 92vw);
    width: 100%;
    margin: auto;
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.08);
    overflow: hidden;
}

dialog.ops-modal::backdrop {
    background: rgba(0, 0, 0, 0.72);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.ops-modal-card {
    background: var(--ecv-paper, #17191b);
    color: var(--text-color, #f0f0f0);
    padding: 24px;
    display: grid;
    gap: 16px;
    border-radius: 16px;
    border: 1px solid var(--ecv-line, rgba(255, 255, 255, 0.08));
    animation: modalScaleIn 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes modalScaleIn {
    from { opacity: 0; transform: scale(0.94) translateY(6px); }
    to { opacity: 1; transform: scale(1) translateY(0); }
}

/* The markup says `ops-modal-head` — in both modals that use it. This rule was written as
 * `.ops-modal-header` and therefore matched nothing, which is why the icon sat above the
 * title instead of beside it: with no flex row, the two children simply stacked. Both names
 * are matched so neither spelling can break it again. */
.ops-modal-head,
.ops-modal-header {
    display: flex;
    align-items: center;
    gap: 14px;
}

.ops-modal-icon {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: 12px;
    font-size: 18px;
    flex: 0 0 auto;
}

.ops-modal-icon.is-warning {
    background: rgba(245, 158, 11, 0.15);
    color: var(--warning-color, #f59e0b);
    border: 1px solid rgba(245, 158, 11, 0.25);
}

.ops-modal-icon.is-danger {
    background: rgba(239, 68, 68, 0.15);
    color: var(--danger-color, #ef4444);
    border: 1px solid rgba(239, 68, 68, 0.25);
}

.ops-modal-icon.is-success {
    background: rgba(16, 185, 129, 0.15);
    color: var(--success-color, #10b981);
    border: 1px solid rgba(16, 185, 129, 0.25);
}

.ops-modal-icon.is-info {
    background: rgba(59, 130, 246, 0.15);
    color: #3b82f6;
    border: 1px solid rgba(59, 130, 246, 0.25);
}

.ops-modal-title {
    margin: 0;
    font-size: 16px;
    font-weight: 700;
    color: var(--text-color, #f0f0f0);
    line-height: 1.25;
}

.ops-modal-subtitle {
    margin: 3px 0 0;
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ops-muted, #8b9296);
}

.ops-modal-body {
    font-size: 13px;
    line-height: 1.55;
    color: var(--text-muted, #a0a6aa);
}

.ops-modal-text {
    margin: 0;
}

.ops-modal-input-wrap {
    display: grid;
    gap: 8px;
    margin-top: 12px;
    width: 100%;
}

.ops-modal-input-label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-color, #e0e0e0);
}

.ops-modal-input {
    width: 100%;
    min-height: 96px;
    box-sizing: border-box;
    border-radius: 8px;
    background: var(--ecv-canvas, #111315);
    border: 1px solid var(--ecv-line, rgba(255, 255, 255, 0.12));
    color: var(--text-color, #f0f0f0);
    padding: 10px 12px;
    font: inherit;
    font-size: 13px;
    line-height: 1.45;
    resize: vertical;
}

.ops-modal-input:focus {
    outline: none;
    border-color: var(--warning-color, #f59e0b);
    box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.2);
}

.ops-modal-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 8px;
}

.ops-btn-ghost {
    background: transparent;
    border: 1px solid var(--ecv-line, rgba(255, 255, 255, 0.12));
    color: var(--text-color, #f0f0f0);
}

.ops-btn-ghost:hover {
    background: var(--ecv-soft, rgba(255, 255, 255, 0.06));
}

/* Toast */
.ops-toast {
    position: fixed;
    bottom: 24px;
    right: 24px;
    z-index: 10000;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 18px;
    border-radius: 10px;
    background: var(--ecv-paper, #1c1f24);
    color: var(--text-color, #fff);
    border: 1px solid var(--ecv-line, rgba(255, 255, 255, 0.12));
    box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
    font-size: 12.5px;
    font-weight: 600;
    opacity: 0;
    transform: translateY(12px) scale(0.96);
    transition: opacity 0.22s ease, transform 0.22s ease;
    pointer-events: none;
}

.ops-toast.is-visible {
    opacity: 1;
    transform: translateY(0) scale(1);
    pointer-events: auto;
}

.ops-toast.is-success i { color: var(--success-color, #10b981); }
.ops-toast.is-error i { color: var(--danger-color, #ef4444); }
.ops-toast.is-warning i { color: var(--warning-color, #f59e0b); }
.ops-toast.is-info i { color: #3b82f6; }




/* ================================================================== *
 * Hero — filling the viewport, not floating in it
 *
 * Same correction as the Support portal, and for the same reason: .dhome pins the section to
 * the viewport, but the copy sat as a centred lump with dead bands above and below. The copy
 * column now distributes its three bands to the padding, and the type scale gains a
 * viewport-height term so a tall screen gets a larger headline rather than more emptiness.
 *
 * .dhome is a fixed-height flex column with `overflow: hidden`, so nothing here may grow the
 * page — the distribution happens strictly inside the height the shell already granted.
 * ================================================================== */

.dhome {
    padding-block: clamp(12px, 1.8vh, 26px) clamp(10px, 1.4vh, 20px);
}

.dhero {
    align-items: stretch;
    padding-block: 0;
}

.dhero-copy {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: clamp(12px, 1.7vh, 24px);
    min-height: 0;
    height: 100%;
}

.dhero-copy > h1,
.dhero h1 {
    margin-block: 0;
    font-size: clamp(40px, 3.3vw + 1.8vh, 88px);
    line-height: 1.04;
    letter-spacing: -.03em;
}

.dhero-eyebrow { margin-block: 0; }

.dhero-lede {
    margin-block: clamp(10px, 1.5vh, 20px) 0;
    max-width: 48ch;
    font-size: clamp(15.5px, .58vw + .58vh, 21px);
    line-height: 1.6;
}

.dhero-actions {
    margin-block: clamp(12px, 1.8vh, 24px) 0;
    flex-wrap: wrap;
}

.dhero-btn {
    min-height: clamp(50px, 5.8vh, 64px);
    padding-inline: clamp(24px, 2.1vw, 36px);
    font-size: clamp(15px, .38vw + .38vh, 17.5px);
}

.dhero-note {
    margin-block: 0;
    padding-top: clamp(8px, 1.2vh, 16px);
}

/* The queue motif is the second column: it scales to the row it shares rather than to a
 * number, so it stays in proportion to a headline that now grows. */
.dhero-art {
    align-self: center;
    min-height: 0;
    max-height: 100%;
}

.dhero-art svg {
    width: 100%;
    height: auto;
    max-height: min(74vh, 680px);
}

@media (max-height: 640px) {
    .dhome { height: auto; max-height: none; overflow: visible; }
    .dhero-copy { justify-content: flex-start; height: auto; }
}

@media (max-width: 900px) {
    .dhero-copy { height: auto; justify-content: flex-start; }
    .dhero-art svg { max-height: 34vh; }
}

/* ================================================================== *
 * Hero — rhythm and optical alignment
 *
 * Same two corrections as the Support hero, for the same reasons: `space-between` was spending
 * the leftover height on every gap at once, so no single space was chosen, and the 88px
 * headline sat visibly right of the column it heads because a glyph's ink begins inside its
 * box. Related bands now sit close, the slack pools once above the trust strip, and the
 * display type is pulled left by its measured side bearing.
 * ================================================================== */

.dhero-copy {
    justify-content: flex-start;
    gap: 0;
}

.dhero-eyebrow { margin-block: auto clamp(16px, 2.2vh, 28px); }
.dhero-lede { margin-block: clamp(16px, 2.2vh, 26px) 0; }

/* No optical compensation: measured side bearing is 1px, the same as the body text. */

.dhero-copy > .phero-slot-note {
    margin-block: auto 0;
    padding-top: clamp(14px, 2vh, 22px);
}

/* The queue motif keeps its own proportions. An inline <svg> is not a replaced element, so the
 * `object-fit: contain` that used to sit here did nothing at all; what actually held the
 * drawing in shape was its viewBox, and stretching height to 100% fought it. Width-driven with
 * automatic height is the honest way to say "scale, don't distort". */
.dhero-art svg {
    height: auto;
    object-fit: unset;
}

/* ================================================================== *
 * Ticket detail header — keep the reference, subject and actions apart
 * ================================================================== */

.dp-portal .tfull-head-inner {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
    min-height: 56px;
    padding-block: 7px;
}

/* .ops-queue-page is itself the scroll container and already begins below the portal top bar.
 * A 64px sticky inset here therefore created a second, empty top-bar-height gap. */
.dp-portal .tfull-head {
    top: 0;
}

.dp-portal .tfull-back {
    flex: 0 0 auto;
}

.dp-portal .tfull-title {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 3px;
    min-width: 0;
    margin: 0;
    text-align: left;
}

.dp-portal .tfull-eyebrow {
    width: max-content;
    max-width: 100%;
    padding: 2px 0;
    line-height: 1.25;
}

.dp-portal .tfull-eyebrow span {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    direction: ltr;
    unicode-bidi: isolate;
}

.dp-portal .tfull-title h1 {
    min-width: 0;
    max-width: 100%;
    margin: 0;
    line-height: 1.2;
    overflow-wrap: anywhere;
    text-align: left;
}

.dp-portal .tfull-head-actions {
    flex: 0 0 auto;
    min-width: max-content;
    margin-left: auto;
}

html[dir="rtl"] .dp-portal .tfull-head-actions {
    margin-right: auto;
    margin-left: 0;
}

@media (max-width: 700px) {
    .dp-portal .tfull-head-inner {
        flex-wrap: wrap;
        row-gap: 10px;
        min-height: 0;
        padding-block: 7px;
    }

    .dp-portal .tfull-title {
        flex-basis: auto;
    }

    .dp-portal .tfull-head-actions {
        flex: 0 0 100%;
        width: 100%;
        min-width: 0;
        justify-content: flex-end;
        margin-left: 0;
    }

    html[dir="rtl"] .dp-portal .tfull-head-actions {
        justify-content: flex-start;
        margin-right: 0;
    }
}

/* The delegation page's directory notice.
 *
 * Colleague names on this page come only from the API — the users table's RLS gives a session
 * its own row and no more — so when that call fails every name but one disappears. This says so,
 * in the place the names should be, with the reason. It used to be a console warning, which is
 * to say invisible to the person deciding who to assign work to. */
.del-notice {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin: 0 0 14px;
    padding: 11px 14px;
    border: 1px solid var(--ecv-amber-line, rgba(176, 122, 12, .32));
    border-inline-start: 3px solid var(--ecv-amber, #8a5d00);
    border-radius: 10px;
    background: var(--ecv-amber-wash, rgba(176, 122, 12, .1));
    color: var(--text-color);
    font-size: 12.5px;
    line-height: 1.6;
}

.del-notice i {
    flex: 0 0 auto;
    margin-top: 2px;
    color: var(--ecv-amber, #8a5d00);
}

/* The "require a file" checkbox, inline with the composer's actions. */
.ops-inline-check {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-inline-end: auto;
    color: var(--text-light);
    font-size: 12px;
    cursor: pointer;
    user-select: none;
}

.ops-inline-check input {
    width: 15px;
    height: 15px;
    accent-color: var(--sys-action-warning, #8a5d00);
    cursor: pointer;
}

.ops-inline-check:hover { color: var(--text-color); }

.ops-field-group .ops-inline-check {
    margin: 8px 0 0;
    display: flex;
}

/* The words a test-fix request will send.
 *
 * The detail box is hidden for that kind because there is nothing to type — but the message
 * still goes out over this person's department, so they get to read it first. A preset nobody
 * can see is a message somebody sent without knowing what it said. */
.ops-preset-note {
    margin: 0 0 4px;
    padding: 10px 12px;
    border: 1px dashed var(--ecv-line);
    border-radius: 9px;
    background-color: var(--ecv-soft);
    color: var(--text-color);
    font-size: 12.5px;
    line-height: 1.55;
}

.ops-preset-note::before {
    content: "Will be sent to the requester:";
    display: block;
    margin-bottom: 4px;
    color: var(--text-light);
    font-size: 10.5px;
    font-weight: 800;
    letter-spacing: .1em;
    text-transform: uppercase;
}

/* ================================================================== *
 * Ticket status labels — RAG
 *
 * The same three meanings the requester's lifecycle bar uses, so a status means one thing across
 * the whole system:
 *
 *   red    nobody owns this yet, or it has stopped — the wait is not being worked
 *   amber  in flight: the team is on it, or it is back with somebody
 *   green  finished
 *
 * Statuses are generated as `dept-status-<slug>` from the stored value, so each is named here
 * rather than guessed at from a pattern — a status nobody has styled falls back to the neutral
 * pill instead of borrowing a colour it has not earned.
 *
 * Colour is never the only signal: every pill carries its own text, which is the label itself.
 * The washes and text tints are the paired tokens, so all of this holds in both themes.
 * ================================================================== */

/* Not yet owned, or stopped. */
.pill.dept-status-new,
.pill.dept-status-open,
.pill.dept-status-cancelled {
    background: var(--ecv-red-wash, rgba(173, 41, 31, .12));
    border: 1px solid var(--ecv-red-line, rgba(173, 41, 31, .32));
    color: var(--ecv-red);
}

/* Being worked, or waiting on a person. */
.pill.dept-status-assigned,
.pill.dept-status-in-progress,
.pill.dept-status-waiting-for-user,
.pill.dept-status-waiting-for-requester,
.pill.dept-status-waiting-for-internal-team {
    background: var(--ecv-amber-wash, rgba(176, 122, 12, .14));
    border: 1px solid var(--ecv-amber-line, rgba(176, 122, 12, .32));
    color: var(--ecv-amber);
}

/* Done. */
.pill.dept-status-resolved,
.pill.dept-status-closed {
    background: var(--ecv-green-wash, rgba(19, 129, 59, .12));
    border: 1px solid var(--ecv-green-line, rgba(19, 129, 59, .32));
    color: var(--ecv-green);
}

/* Shared shape, so the three groups differ only in colour. */
.pill[class*="dept-status-"] {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .02em;
    white-space: nowrap;
}

/* --- Your access ------------------------------------------------------------
 *
 * The screen that tells a person what their role actually lets them do. Two
 * shapes only: a plain list for the things they hold, and chips for the actions —
 * held ones solid, the rest outlined and dimmed.
 *
 * The dimmed chips are deliberate. Hiding an action somebody lacks makes the
 * interface look complete and leaves them guessing why a colleague can do
 * something they cannot; showing it, greyed, answers the question before it is
 * asked. Colour is not carrying that difference on its own — the icon changes
 * from a tick to a dash, so it survives greyscale and colour-blindness.
 */

.ops-plain-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.ops-plain-list li {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px;
    padding: 10px 12px;
    border: 1px solid var(--ops-line, var(--border-color, #e5e6e4));
    border-radius: 12px;
    background-color: var(--ops-surface, var(--bg-white, #fff));
    font-size: 13px;
}

.ops-plain-list li small {
    font-size: 11.5px;
    color: var(--ops-text-muted, var(--text-light, #6c7174));
}

.ops-muted {
    margin: 8px 0 0;
    font-size: 12.5px;
    color: var(--ops-text-muted, var(--text-light, #6c7174));
}

.ops-permission-group + .ops-permission-group { margin-block-start: 16px; }

.ops-permission-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-block-start: 8px;
}

.ops-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    border-radius: 999px;
    border: 1px solid var(--ops-line, var(--border-color, #e5e6e4));
    font-size: 12px;
    line-height: 1.3;
}

.ops-chip i { font-size: 10px; }

.ops-chip.is-on {
    border-color: transparent;
    background-color: var(--ops-accent-wash, var(--ecv-green-wash, rgba(31, 122, 74, .12)));
    color: var(--ops-accent-ink, var(--ecv-green, #1f7a4a));
    font-weight: 600;
}

.ops-chip.is-off {
    color: var(--ops-text-muted, var(--text-light, #6c7174));
    opacity: .75;
}

/* ---------------------------------------------------------------------------
 * Classification
 * ---------------------------------------------------------------------------
 *
 * The department queue is where agents actually work tickets, so it is where the
 * classification most needs to be unmissable: a banner across the record before a word of it
 * is read, and a pill in the list so opening one is never a surprise.
 *
 * Deliberately the same wording and the same two colours as the Administration portal. An
 * agent who works in both should not have to learn the mark twice.
 */
.ops-classification-banner {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 10px 0 0;
    padding: 10px 16px;
    border-radius: 8px;
    font-size: 0.84rem;
    font-weight: 600;
    line-height: 1.4;
    border-inline-start: 3px solid currentColor;
}

.ops-classification-banner[data-level="restricted"] {
    background: rgba(183, 121, 31, 0.12);
    color: #8a5a13;
}

.ops-classification-banner[data-level="confidential"] {
    background: rgba(155, 44, 44, 0.12);
    color: #86251f;
}

:root[data-theme="dark"] .ops-classification-banner[data-level="restricted"] {
    background: rgba(214, 158, 46, 0.16);
    color: #e5b95e;
}

:root[data-theme="dark"] .ops-classification-banner[data-level="confidential"] {
    background: rgba(197, 76, 68, 0.18);
    color: #f0928a;
}

.ops-classification-pill[data-level="restricted"] {
    background: rgba(183, 121, 31, 0.16);
    color: #8a5a13;
}

.ops-classification-pill[data-level="confidential"] {
    background: rgba(155, 44, 44, 0.16);
    color: #86251f;
}

:root[data-theme="dark"] .ops-classification-pill[data-level="restricted"] {
    background: rgba(214, 158, 46, 0.2);
    color: #e5b95e;
}

:root[data-theme="dark"] .ops-classification-pill[data-level="confidential"] {
    background: rgba(197, 76, 68, 0.22);
    color: #f0928a;
}
