/* ============================================================================
   TicketX — Columbus brand theme (light). Single source of truth for design
   tokens. Component rules reference the tokens below — never a raw hex, rem or
   px value.

   Every value here traces to Columbus Brand Guidelines V3 (June 2025):
   colours p.20–22, typography p.24–29, corner radii p.37. Where the interface
   needs a step the guidelines do not name — a hover shade, a hairline, an
   accessible text colour for a pale brand fill — it is derived from a brand
   colour rather than introduced as a new hue, and says so.
   ============================================================================ */
:root {
    /* ---- Primary palette (p.20) ----------------------------------------
       Columbus Blue carries the brand. -dark is the same hue taken down for
       hover/active; -tint and -pale are the guidelines' Light Blue and Pale
       Blue, so a selected row and a filled button are the same family. */
    --cx-primary: #02018C;      /* Columbus Blue */
    --cx-primary-dark: #01015F; /* derived: Columbus Blue, darkened for hover */
    --cx-primary-tint: #DFE5FF; /* Light Blue */
    --cx-primary-pale: #C2CDFB; /* Pale Blue */

    /* Orange is an *emphasiser only* — small icons and CTA buttons (p.20), and
       never as a block beside blue or black (p.22, "NEVER USE THESE COLOR
       COMBINATIONS"). Nothing full-bleed should ever reach for this. */
    --cx-accent: #FF831D;       /* Orange */
    --cx-accent-pale: #FFD1AD;  /* Pale Orange */
    --cx-accent-tint: #FEE8CF;  /* Light Orange */

    --cx-beige: #F2E9E5;        /* Beige */
    --cx-white: #FFFFFF;        /* White */
    --cx-black: #000000;        /* Black */

    /* ---- Secondary palette (p.21) — "different stages in a process" ----
       Used below to colour ticket state, never as decoration. */
    --cx-secondary-green: #539095;
    --cx-secondary-purple: #CDA5C7;
    --cx-secondary-yellow: #EBD691;
    --cx-secondary-blue: #4B65B3;

    /* ---- Surfaces & text ----
       The guidelines carry no neutral grey, so the page, hairline and body ink
       are the blue-derived neutrals already shipping in the notification emails
       (NotificationEmailPalette) — the two channels now match. */
    --cx-page: #F4F5FB;
    --cx-surface: var(--cx-white);
    --cx-ink: #16202C;
    --cx-ink-muted: #676E7C;   /* 5.1:1 on white, 4.7:1 on the page, 4.5:1 on the tints */
    --cx-border: #E1E4F4;
    --cx-border-strong: #C2CDFB;   /* Pale Blue */
    /* Alias kept because rules across the shell and login already reference it. */
    --cx-bg: var(--cx-page);

    /* ---- Semantic status ----
       Several brand colours are too pale to carry text at badge sizes, so each
       one that needs to do both jobs has an accessible ink (the plain name) and
       the brand colour itself for fills and dots (-solid). Measured, ink on its
       own tint: amber 7.8:1, green 7.9:1, blue 6.2:1, AI 7.4:1, red 5.7:1 — all
       clear AA, as does every one of them on white. Orange is a fill only: white
       on --cx-accent is 2.5:1, so it never carries text. */

    /* SLA breach, escalation and critical priority. The brand palette holds no
       red, and the notification emails resolve that by carrying a breach in
       black. The UI does not: on a queue full of tickets, red is the signal
       agents actually scan for, and dropping it cost real legibility. Red stays
       here as a functional colour, exactly as it was before the brand pass —
       the two channels differ deliberately. */
    --cx-critical: var(--cx-red);
    --cx-critical-tint: var(--cx-red-tint);

    --cx-amber: #5C4A12;            /* derived: Yellow, darkened — 8.6:1 on white */
    --cx-amber-solid: var(--cx-secondary-yellow);
    --cx-amber-tint: #FAF3DE;       /* derived: Yellow at ~25% */

    --cx-green: #1E4A4D;            /* derived: Green, darkened — 9.8:1 on white */
    --cx-green-solid: var(--cx-secondary-green);
    --cx-green-tint: #DCEAEA;       /* derived: Green at ~20% */
    --cx-green-line: #C3DCDD;       /* derived: Green at ~35%, hairline */

    --cx-blue: #3B4F8F;             /* derived: Medium Blue, darkened — 7.8:1 on white */
    --cx-blue-solid: var(--cx-secondary-blue);
    --cx-blue-tint: var(--cx-primary-tint);

    /* Functional exception, deliberately outside the brand palette: a failed
       validation and a destructive button need an unambiguous danger signal,
       and the guidelines legislate brand communication, not UI state. Confined
       to .cx-btn-danger, .cx-validation and invalid inputs — ticket state and
       SLA use the brand tokens above. */
    --cx-red: #B42318;
    --cx-red-tint: #FBEAE8;
    --cx-red-line: #E6CCCC;      /* hairline for red badges */

    /* The customer-sentiment lamp. One lamp showing the reported reading, so
       these are four alternative colours for a single lamp rather than a
       three-light set. Red and green are the status tokens above, so the header
       speaks one red and one green; each gradient's middle stop is the colour
       the lamp reads as, and the lighter and darker stops are only shading. The
       neutral lamp keeps its own yellow: --cx-amber is darkened for text
       contrast, which is correct as a label and muddy as a light. Held as tokens
       so the rules stay literal-free. */
    --cx-lamp-negative: radial-gradient(circle at 32% 30%, #e2796f 0%, var(--cx-red) 52%, #7f150e 100%);
    --cx-lamp-negative-glow: rgba(180, 35, 24, .25);
    --cx-lamp-neutral: radial-gradient(circle at 32% 30%, #ffe9a3 0%, #ffbe0a 52%, #e08900 100%);
    --cx-lamp-neutral-glow: rgba(255, 190, 10, .3);
    --cx-lamp-neutral-ink: #ffbe0a; /* the neutral lamp's own colour, for the word beside it */
    --cx-lamp-positive: radial-gradient(circle at 32% 30%, #82b944 0%, var(--cx-green) 52%, #274a0b 100%);
    --cx-lamp-positive-glow: rgba(59, 109, 17, .25);
    --cx-lamp-unknown: radial-gradient(circle at 32% 30%, #d7dbe2 0%, #b0b7c3 55%, #8d95a3 100%);

    --cx-grey-tint: #EEF0F7;

    /* AI-generated content. Brand Purple, which the guidelines reserve for
       stages in a process and which collides with none of the status colours
       above: a summary the model wrote must stay visibly distinct from a fact
       the platform is asserting. 8.5:1 on white, 7.4:1 on its own tint. */
    --cx-ai: #6B3D63;               /* derived: Purple, darkened */
    --cx-ai-tint: #F7ECF5;          /* derived: Purple at ~20% */

    /* Type scale. Steps are rem, so the single px value on <body> below is the
       one lever that sets overall density. Do not add sizes outside this scale. */
    --fs-3xs: .74rem;   /* 11px */
    --fs-2xs: .8rem;    /* 12px */
    --fs-xs: .867rem;   /* 13px */
    --fs-sm: .934rem;   /* 14px — body text */
    --fs-md: 1rem;      /* 15px */
    --fs-base: 1.067rem; /* 16px */
    --fs-lg: 1.134rem;  /* 17px */
    --fs-xl: 1.25rem;   /* 19px */
    --fs-2xl: 1.467rem; /* 22px */
    --fs-3xl: 1.6rem;
    --fs-4xl: 2rem;

    /* Leading (p.26): headlines 1.1, body 1.25. --lh-tight is what the dense
       queues and tables already use and is left where it was, so raising the
       body from 1.45 to the specified 1.25 does not also squeeze the tables. */
    --lh-display: 1.1;
    --lh-normal: 1.25;
    --lh-tight: 1.25;

    /* Tracking (p.27): Feature Display optical/0, Roobert optical/-10. */
    --tracking-display: 0;
    --tracking-body: -.01em;

    /* Spacing scale (≈4/8/12/16/24/32 at the 15px base). */
    --sp-1: .25rem;
    --sp-2: .5rem;
    --sp-3: .75rem;
    --sp-4: 1rem;
    --sp-5: 1.5rem;
    --sp-6: 2rem;

    --cx-radius-sm: 7px;
    --cx-radius-md: 11px;
    --cx-radius-lg: 14px;
    /* Legacy alias — the small radius is what the ~30 existing usages meant. */
    --cx-radius: var(--cx-radius-sm);
    /* Standalone imagery (p.37): 16px under 700px wide, 22px at or above it.
       These are for pictures and logos, not for controls. */
    --cx-radius-img: 16px;
    --cx-radius-img-lg: 22px;

    /* Primary fonts (p.25). Both are licensed faces and are not redistributed
       in this repo: the stacks pick them up when installed, and otherwise fall
       back to the guidelines' own nominated substitutes (p.29) — Times New
       Roman for Feature Display, Arial for Roobert. To self-host, drop the
       licensed .woff2 files into wwwroot/fonts and uncomment the @font-face
       block below; nothing else needs to change. See wwwroot/fonts/README.md. */
    --cx-font-display: "Feature Display", "Times New Roman", Times, serif;
    --cx-font: Roobert, Arial, Helvetica, sans-serif;
    --cx-mono: "Cascadia Mono", Consolas, "SF Mono", monospace;

    --cx-shadow-sm: 0 1px 2px rgba(2, 1, 140, .06), 0 1px 3px rgba(2, 1, 140, .08);
    --cx-shadow-md: 0 8px 24px rgba(2, 1, 140, .09);
    --cx-shadow-pop: 0 12px 32px rgba(2, 1, 140, .14);
    --cx-shadow: var(--cx-shadow-sm);
}

/* Licensed brand faces — see wwwroot/fonts/README.md before uncommenting.
@font-face { font-family: "Roobert"; src: url("fonts/Roobert-Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Roobert"; src: url("fonts/Roobert-SemiBold.woff2") format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Feature Display"; src: url("fonts/FeatureDisplay-Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
*/

* { box-sizing: border-box; }

html, body {
    margin: 0;
    height: 100%;
    font-family: var(--cx-font);
    font-size: 15px;
    line-height: var(--lh-normal);
    letter-spacing: var(--tracking-body);
    color: var(--cx-ink);
    background: var(--cx-page);
}

/* Hierarchy (p.28): H1 and H2 are Feature Display Regular, H3/H4 and body are
   Roobert. The display face is a headline weight by design — do not bold it. */
h1, h2 {
    font-family: var(--cx-font-display);
    font-weight: 400;
    letter-spacing: var(--tracking-display);
    line-height: var(--lh-display);
    color: var(--cx-ink);
}
h1 { font-size: var(--fs-2xl); margin: 0; }
h2 { font-size: var(--fs-xl); margin: 0 0 var(--sp-2); }
h3 { font-weight: 400; }
h4 { font-weight: 600; }
a { color: var(--cx-primary); text-decoration: none; }
a:hover { text-decoration: underline; }
.cx-mono { font-family: var(--cx-mono); font-size: .85em; letter-spacing: 0; }
.cx-muted { color: var(--cx-ink-muted); }
.cx-eyebrow { font-size: var(--fs-2xs); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--cx-ink-muted); }
/* Opt a heading out of the display face where the surrounding UI is dense
   enough that a serif headline would fight the data (card titles, panels). */
.cx-heading-ui { font-family: var(--cx-font); font-weight: 600; letter-spacing: var(--tracking-body); }

/* ============================ App shell (top nav) ========================
   The shell is a normal document that scrolls, not a fixed-height viewport with
   panes scrolling inside it. The old height:100vh + overflow:auto chain meant
   anything of unpredictable length — a conversation, an activity log, a long
   list — got its own inner scrollbar and its own scroll position, and the
   browser's find, scroll restoration and page-down all stopped working on it.

   Only the chrome sticks: the top bar, and (in the workspace) the ticket header
   and tab strip. Everything else scrolls with the page. */
.cx-shell { display: flex; flex-direction: column; min-height: 100vh; }

.cx-topbar {
    display: flex; align-items: center; gap: 1.5rem;
    height: 56px; padding: 0 1.25rem; flex: none;
    background: var(--cx-surface); border-bottom: 1px solid var(--cx-border);
    position: sticky; top: 0; z-index: 60;
}
/* Columbus logotype lockup. The mark is never redrawn, recoloured or restyled
   (p.13): only the two supplied files are used — blue on light surfaces, white
   on dark (p.12). Height stays clear of the 15px digital minimum (p.11), and
   the product name is held off at the edge of the clearspace zone (p.10) by a
   hairline rather than butting against the mark. */
.cx-brand { display: flex; align-items: center; gap: var(--sp-3); color: var(--cx-ink); }
.cx-brand:hover { text-decoration: none; }
.cx-logo { height: 22px; width: auto; display: block; flex: none; }
.cx-logo-sm { height: 18px; }
.cx-brand-divider { width: 1px; height: 20px; background: var(--cx-border-strong); flex: none; }
.cx-brand-word { font-size: var(--fs-lg); font-weight: 600; letter-spacing: var(--tracking-body); }

/* The Evolve Centrum lockup (BrandLogo). Scale is set via inline font-size on .cx-evc — the
   CENTRUM line's size in pixels — and everything else follows it in em. The tagline only ever
   appears at a large scale, so it lands on its own row via flex-basis rather than a fixed layout. */
.cx-evc { display: inline-flex; flex-wrap: wrap; align-items: baseline; justify-content: center; column-gap: .4em; font-family: var(--cx-font); color: var(--cx-ink); }
.cx-evc-evolve { display: inline-flex; align-items: center; gap: .35em; font-size: .5em; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--cx-accent); }
.cx-evc-rule { width: 1.4em; height: 1px; background: var(--cx-accent); flex: none; }
.cx-evc-centrum { font-family: var(--cx-font-display); font-weight: 400; letter-spacing: .04em; text-transform: uppercase; color: var(--cx-primary); line-height: 1; }
.cx-evc-tag { flex-basis: 100%; display: inline-flex; align-items: center; justify-content: center; gap: .5em; margin-top: .3em; font-size: .28em; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--cx-ink-muted); }
.cx-evc-dash { width: 1.2em; height: 1px; background: var(--cx-border-strong); flex: none; }

.cx-topnav { display: flex; align-items: stretch; gap: .25rem; height: 100%; }
.cx-topnav-link {
    display: inline-flex; align-items: center; padding: 0 .85rem; height: 100%;
    color: var(--cx-ink-muted); font-weight: 600; border-bottom: 2px solid transparent;
}
.cx-topnav-link:hover { color: var(--cx-ink); text-decoration: none; }
.cx-topnav-link.active { color: var(--cx-primary-dark); border-bottom-color: var(--cx-primary); }
.cx-topnav-link.disabled { opacity: .5; pointer-events: none; }

.cx-topbar-spacer { flex: 1; }
.cx-topbar-right { display: flex; align-items: center; gap: 1rem; }
.cx-clock { font-size: var(--fs-sm); color: var(--cx-ink-muted); font-variant-numeric: tabular-nums; }
.cx-avatar {
    width: 30px; height: 30px; border-radius: 999px; flex: none;
    background: var(--cx-primary); color: var(--cx-white); display: inline-flex; align-items: center; justify-content: center;
    font-size: var(--fs-2xs); font-weight: 600;
}
.cx-avatar-sm { width: 24px; height: 24px; font-size: var(--fs-3xs); }

/* ── User menu ──────────────────────────────────────────── */
.cx-user-menu { position: relative; }
.cx-user-menu-trigger {
    background: none; border: none; padding: 0; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
}
.cx-user-menu-backdrop { position: fixed; inset: 0; z-index: 40; }
.cx-user-menu-panel {
    position: absolute; right: 0; top: calc(100% + .4rem);
    width: 220px;
    background: var(--cx-surface); border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-md); box-shadow: var(--cx-shadow-md);
    z-index: 50; overflow: hidden;
}
.cx-user-menu-header { padding: .75rem 1rem; }
.cx-user-menu-header-name { font-weight: 600; font-size: var(--fs-md); color: var(--cx-ink); }
.cx-user-menu-header-role { font-size: var(--fs-2xs); color: var(--cx-ink-muted); margin-top: .1rem; }
.cx-user-menu-divider { height: 1px; background: var(--cx-border); }
.cx-user-menu-item {
    display: block; width: 100%; padding: .55rem 1rem;
    font-size: var(--fs-sm); color: var(--cx-ink);
    background: none; border: none; text-align: left; cursor: pointer;
}
.cx-user-menu-item:hover { background: var(--cx-bg); }
.cx-time-zone-browser-option { margin-top: .75rem; border: 1px solid var(--cx-border); border-radius: var(--cx-radius-md); }
.cx-time-zone-results { max-height: 280px; margin-top: .5rem; overflow-y: auto; border: 1px solid var(--cx-border); border-radius: var(--cx-radius-md); }
.cx-time-zone-option { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; width: 100%; padding: .65rem .85rem; border: 0; border-bottom: 1px solid var(--cx-border); background: var(--cx-surface); color: var(--cx-ink); text-align: left; cursor: pointer; }
.cx-time-zone-option:last-child { border-bottom: 0; }
.cx-time-zone-option:hover, .cx-time-zone-option.active { background: var(--cx-bg); }
.cx-time-zone-option:disabled { cursor: wait; opacity: .65; }
.cx-time-zone-detail { color: var(--cx-ink-muted); font-size: var(--fs-sm); }
.cx-time-zone-hint { margin: .75rem 0; }
.cx-user-menu-dev-badge {
    display: inline-block; margin-left: .4rem; font-size: var(--fs-3xs);
    padding: .1rem .35rem; background: var(--cx-amber-tint); color: var(--cx-amber);
    border-radius: 9999px; font-weight: 600; vertical-align: middle;
}
.cx-user-menu-sublist { background: var(--cx-bg); }
.cx-user-menu-subitem {
    display: flex; align-items: baseline; gap: .5rem;
    width: 100%; padding: .45rem 1rem .45rem 1.25rem;
    font-size: var(--fs-sm); color: var(--cx-ink-muted);
    background: none; border: none; text-align: left; cursor: pointer;
}
.cx-user-menu-subitem:hover { background: var(--cx-border); color: var(--cx-ink); }
.cx-user-menu-subitem-role { font-size: var(--fs-2xs); color: var(--cx-ink-muted); }
.cx-user-menu-signout { color: var(--cx-red); }
.cx-user-menu-signout:hover { background: var(--cx-red-tint); }

/* ── Internal login page ────────────────────────────────── */
.cx-login-shell {
    min-height: 100vh; display: flex;
    align-items: center; justify-content: center;
    background: var(--cx-bg); padding: 2rem;
}
.cx-login-card {
    width: 100%; max-width: 400px;
    background: var(--cx-surface); border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-lg); padding: 2.5rem;
    box-shadow: var(--cx-shadow-md);
}
.cx-login-brand { margin-bottom: 2rem; }
.cx-login-brand-stacked { display: flex; flex-direction: column; align-items: center; gap: .75rem; }
.cx-login-title { font-family: var(--cx-font-display); font-size: var(--fs-2xl); font-weight: 400; letter-spacing: var(--tracking-display); line-height: var(--lh-display); color: var(--cx-ink); margin-bottom: 1.5rem; }
.cx-label { display: block; font-size: var(--fs-sm); font-weight: 400; color: var(--cx-ink); margin-bottom: .3rem; }
.cx-input {
    display: block; width: 100%; padding: .5rem .75rem;
    font-size: var(--fs-md); color: var(--cx-ink);
    background: var(--cx-surface); border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius); box-sizing: border-box;
}
.cx-input:focus { outline: 2px solid var(--cx-primary); outline-offset: 1px; border-color: transparent; }
/* Buttons live in one place — see the "Buttons" block below. */
.cx-login-divider { display: flex; align-items: center; gap: .75rem; margin: 1.25rem 0; font-size: var(--fs-2xs); color: var(--cx-ink-muted); text-transform: uppercase; letter-spacing: .04em; }
.cx-login-divider::before, .cx-login-divider::after { content: ""; flex: 1; height: 1px; background: var(--cx-border); }
.cx-login-error { margin-bottom: 1rem; padding: .55rem .75rem; font-size: var(--fs-sm); color: var(--cx-red); background: var(--cx-red-tint); border: 1px solid var(--cx-red); border-radius: var(--cx-radius); }
.cx-login-dev-note { margin-top: 1.25rem; font-size: var(--fs-2xs); color: var(--cx-ink-muted); text-align: center; }

.cx-body { flex: 1; display: flex; align-items: flex-start; }
/* The admin nav sticks under the top bar and scrolls on its own only when it is
   taller than the screen; the page itself still scrolls normally past it. */
.cx-adminnav {
    width: 240px; flex: none; align-self: stretch;
    position: sticky; top: 56px; max-height: calc(100vh - 56px); overflow-y: auto;
    background: var(--cx-surface); border-right: 1px solid var(--cx-border); padding: var(--sp-2) 0 var(--sp-6);
}
.cx-content { flex: 1; padding: var(--sp-5) var(--sp-5) var(--sp-6); min-width: 0; }
.cx-content-flush { flex: 1; min-width: 0; }

/* Admin sub-navigation (reuses old sidebar styling) */
.cx-nav-group { margin-top: .85rem; }
.cx-nav-group-title {
    padding: .35rem 1rem; font-size: var(--fs-2xs); font-weight: 600; text-transform: uppercase; letter-spacing: .06em;
    color: var(--cx-ink-muted);
}
.cx-nav-link { display: block; padding: .4rem 1rem .4rem 1.25rem; color: var(--cx-ink); border-left: 3px solid transparent; }
.cx-nav-link:hover { background: var(--cx-page); text-decoration: none; }
.cx-nav-link.active { background: var(--cx-primary-tint); border-left-color: var(--cx-primary); color: var(--cx-primary-dark); font-weight: 600; }

/* ---- Page header / toolbar / breadcrumb ---- */
.cx-page-header { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.cx-page-header .cx-page-actions { margin-left: auto; display: flex; gap: .5rem; }
.cx-toolbar { display: flex; gap: .5rem; align-items: center; margin-bottom: .75rem; flex-wrap: wrap; }
.cx-breadcrumb { font-size: var(--fs-xs); color: var(--cx-ink-muted); margin-bottom: .35rem; }
.cx-breadcrumb a { color: var(--cx-ink-muted); }

/* ---- Cards ---- */
.cx-card { background: var(--cx-surface); border: 1px solid var(--cx-border); border-radius: var(--cx-radius-lg); box-shadow: var(--cx-shadow-sm); padding: var(--sp-4); }
.cx-empty { color: var(--cx-ink-muted); padding: 2rem; text-align: center; }
.cx-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1rem; }

/* ---- Dense tables ---- */
.cx-table-wrap { border: 1px solid var(--cx-border); border-radius: var(--cx-radius-lg); overflow: hidden; background: var(--cx-surface); box-shadow: var(--cx-shadow-sm); }
/* For rows wide enough that the columns plus the actions no longer fit — clipping the last column
   is worse than a scrollbar, so this scrolls the table itself instead of the page. */
.cx-table-wrap-scroll { overflow-x: auto; }
.cx-table { width: 100%; border-collapse: collapse; background: var(--cx-surface); }
/* Queue and admin lists are meant to be dense — the larger base size must not
   turn them into a scroll. They take the tighter line height and the lower
   steps of the type scale rather than opting out of the system. */
.cx-table th {
    text-align: left; font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .03em;
    color: var(--cx-ink-muted); font-weight: 600; line-height: var(--lh-tight);
    padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--cx-border); background: var(--cx-surface); white-space: nowrap;
}
.cx-table td { padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--cx-border); vertical-align: middle; font-size: var(--fs-md); line-height: var(--lh-tight); }
.cx-table tbody tr:last-child td { border-bottom: none; }
.cx-table tbody tr:hover { background: var(--cx-page); }
.cx-table .cx-row-actions { width: 1%; text-align: right; white-space: nowrap; }
/* Auto table layout gives this column whatever space the others don't use, so without a shrink-
   to-fit width the header (centred over the full, padded-out column) and the buttons (hugging the
   right edge) land in different places. Pinning the width removes that gutter. */
.cx-table th.cx-row-actions { text-align: center; }
/* Buttons in a row-actions cell need air between them — two adjacent buttons with touching edges
   read as one control, and mis-clicking Publish instead of Edit is not a cheap mistake. */
.cx-table .cx-row-actions > * + * { margin-left: var(--sp-2); }
.cx-table-clickable tbody tr { cursor: pointer; }
.cx-th-sortable { cursor: pointer; user-select: none; }
.cx-th-sortable:hover { color: var(--cx-ink); }
.cx-sort-caret { font-size: var(--fs-3xs); margin-left: .25rem; color: var(--cx-ink-muted); opacity: .45; }
.cx-th-sortable:hover .cx-sort-caret { opacity: .8; }
.cx-sort-caret.cx-sort-active { opacity: 1; color: var(--cx-primary); }

/* Inline per-column filter row sitting under the table header. */
.cx-filter-row td { padding: .35rem .75rem; border-bottom: 1px solid var(--cx-border); background: var(--cx-page); vertical-align: middle; }
.cx-filter-input { font-size: var(--fs-sm); padding: .25rem .4rem; }
.cx-filter-dates { display: flex; gap: .35rem; align-items: center; }
.cx-filter-dates .cx-filter-input { min-width: 0; }

/* Advanced filter panel (ADO #2832) — a collapsible grid of extra conditions under the panel head. */
.cx-advanced-filters { padding: var(--sp-3); border-bottom: 1px solid var(--cx-border); background: var(--cx-page); }
.cx-advanced-filters-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: var(--sp-3);
    margin-bottom: var(--sp-3);
}
.cx-advanced-filters-grid label { display: flex; flex-direction: column; gap: .25rem; font-size: var(--fs-sm); }
.cx-advanced-filters-grid label > span { color: var(--cx-ink-muted); font-weight: 600; }
.cx-advanced-filters-grid select, .cx-advanced-filters-grid input { min-width: 0; }
.cx-advanced-filters-actions { margin-top: var(--sp-3); }
.cx-advanced-filters-grid .cx-filter-dates .cx-input { padding-left: .45rem; padding-right: .3rem; font-size: var(--fs-xs); }

/* Saved-view "Save as…" name prompt row (ADO #2328). */
.cx-save-view-prompt {
    display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-2) var(--sp-3);
    border-bottom: 1px solid var(--cx-border); background: var(--cx-page); font-size: var(--fs-sm);
}
.cx-save-view-prompt label { display: flex; align-items: center; gap: .3rem; white-space: nowrap; }

/* Pager footer below the queue table — see the single "Pager" block below. */

/* ---- Buttons ----
   The one button definition. Variants are additive classes on .cx-btn; the
   Button component is the only thing that should be composing them. */
.cx-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-1);
    font: inherit; font-size: var(--fs-md); font-weight: 600;
    padding: var(--sp-2) var(--sp-3); border-radius: var(--cx-radius-md);
    border: 1px solid var(--cx-border-strong); background: var(--cx-surface); color: var(--cx-ink); cursor: pointer;
    box-shadow: var(--cx-shadow-sm);
}
.cx-btn:hover { border-color: var(--cx-primary); color: var(--cx-primary-dark); text-decoration: none; }
/* Keyboard users must be able to see where they are (WCAG 2.4.7). */
.cx-btn:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: 2px; }
.cx-btn-primary { background: var(--cx-primary); border-color: var(--cx-primary); color: var(--cx-white); }
.cx-btn-primary:hover { background: var(--cx-primary-dark); border-color: var(--cx-primary-dark); color: var(--cx-white); }
.cx-btn-secondary { background: var(--cx-surface); color: var(--cx-ink); border-color: var(--cx-border-strong); text-decoration: none; }
.cx-btn-secondary:hover { border-color: var(--cx-primary); color: var(--cx-primary-dark); text-decoration: none; }
.cx-btn-soft { background: var(--cx-primary-tint); border-color: transparent; color: var(--cx-primary-dark); box-shadow: none; }
.cx-btn-soft:hover { background: var(--cx-primary-tint); border-color: var(--cx-primary); }
.cx-btn-danger { color: var(--cx-red); }
.cx-btn-danger:hover { background: var(--cx-red); border-color: var(--cx-red); color: var(--cx-white); }
.cx-btn:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; }
.cx-btn-sm { padding: var(--sp-1) var(--sp-2); font-size: var(--fs-xs); }
.cx-btn-ghost { border-color: transparent; background: transparent; box-shadow: none; }
.cx-btn-ghost:hover { background: var(--cx-page); border-color: transparent; }

/* ---- Forms ---- */
.cx-field { margin-bottom: var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-1); }
.cx-field label { font-size: var(--fs-xs); font-weight: 600; color: var(--cx-ink-muted); }

/* "Go to the record this field points at" icon, sat in the field's label. Sized to the label rather
   than to a button: it is a way through to another record, not an action on this form. */
.cx-record-link {
    display: inline-flex; align-items: center; vertical-align: middle;
    margin-left: .35rem; color: var(--cx-primary-dark); opacity: .75;
}
.cx-record-link svg { width: .85rem; height: .85rem; }
.cx-record-link:hover, .cx-record-link:focus-visible { opacity: 1; }
.cx-input, .cx-select, .cx-textarea {
    font: inherit; padding: var(--sp-2) var(--sp-3); border: 1px solid var(--cx-border-strong); border-radius: var(--cx-radius-md);
    background: var(--cx-surface); color: var(--cx-ink); width: 100%;
}
.cx-input:focus, .cx-select:focus, .cx-textarea:focus { outline: none; border-color: var(--cx-primary); box-shadow: 0 0 0 3px var(--cx-primary-tint); }
/* Windows high-contrast and forced-colours modes drop box-shadow, so the ring
   above would be invisible there. Keep a real outline for keyboard focus. */
.cx-input:focus-visible, .cx-select:focus-visible, .cx-textarea:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: 1px; }
/* Native select arrow, drawn from the token palette so the control does not read
   as an unstyled browser default next to the rest of the form. */
.cx-select {
    appearance: none; -webkit-appearance: none;
    padding-right: calc(var(--sp-3) * 2 + 10px);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' stroke='%2366707E' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat: no-repeat; background-position: right var(--sp-3) center;
}
/* Disabled / read-only controls (e.g. a field gated on an earlier choice): a filled grey, muted
   text, a dashed border and a not-allowed cursor make "not editable yet" unmistakable everywhere. */
.cx-input:disabled, .cx-select:disabled, .cx-textarea:disabled,
.cx-input[readonly], .cx-textarea[readonly] {
    /* background-color, not the shorthand — the shorthand would clear the
       select's arrow image and leave a disabled select looking like a text box. */
    background-color: var(--cx-grey-tint); color: var(--cx-ink-muted);
    border-style: dashed; border-color: var(--cx-border-strong);
    cursor: not-allowed; box-shadow: none; opacity: 1;
}
/* Dim the field's label too, so the whole control reads as inactive. */
.cx-field:has(select:disabled, input:disabled, textarea:disabled) label { color: var(--cx-ink-muted); opacity: .7; }
.cx-search { max-width: 280px; }
/* Role editor: grouped permission checklist */
.cx-perm-group { margin-top: .4rem; }
.cx-perm-cat { font-size: var(--fs-2xs); font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--cx-ink-muted); margin: .35rem 0 .2rem; }
.cx-perm-item { display: flex; align-items: flex-start; gap: .5rem; padding: .25rem 0; font-weight: 400; cursor: pointer; }
.cx-perm-item input { margin-top: .2rem; }
.cx-validation { color: var(--cx-red); font-size: var(--fs-xs); }
.cx-form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 1rem; }
.cx-form-grid-3 { grid-template-columns: repeat(3, 1fr); }
.cx-form-section { font-size: var(--fs-2xs); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--cx-ink-muted); margin: 1.1rem 0 .5rem; padding-bottom: .35rem; border-bottom: 1px solid var(--cx-border); }
.cx-form-section:first-child { margin-top: 0; }

/* ---- Badges (status) ----
   The tone variants are what the Badge component emits. The four older
   *-active/-inactive/-dwh/-restricted classes are the same shapes named for
   their original single use; they alias onto the tones. */
.cx-badge { display: inline-flex; align-items: center; gap: var(--sp-1); font-size: var(--fs-2xs); font-weight: 600; padding: .1rem var(--sp-2); border-radius: 999px; background: var(--cx-grey-tint); color: var(--cx-ink-muted); border: 1px solid var(--cx-border); }
.cx-badge-dot { width: 6px; height: 6px; border-radius: 999px; background: currentColor; flex: none; }
.cx-badge-success, .cx-badge-active { background: var(--cx-green-tint); color: var(--cx-green); border-color: var(--cx-green-line); }
.cx-badge-danger, .cx-badge-inactive { background: var(--cx-red-tint); color: var(--cx-red); border-color: var(--cx-red-line); }
.cx-badge-brand, .cx-badge-dwh { background: var(--cx-primary-tint); color: var(--cx-primary); border-color: var(--cx-primary-pale); }
.cx-badge-warning, .cx-badge-restricted { background: var(--cx-amber-tint); color: var(--cx-amber); border-color: var(--cx-amber-solid); }
.cx-badge-info { background: var(--cx-blue-tint); color: var(--cx-blue); border-color: var(--cx-primary-pale); }
.cx-badge-ai { background: var(--cx-ai-tint); color: var(--cx-ai); border-color: var(--cx-secondary-purple); }
/* ADO #2299 — an escalated ticket, called out in the queue and the workspace header. */
.cx-badge-escalated { background: var(--cx-red-tint); color: var(--cx-red); border-color: var(--cx-red-line); text-transform: uppercase; letter-spacing: .02em; }
/* ADO #2739 — a ticket marked a duplicate; it closes silently otherwise, so this is the only
   visible cue in the header (the state pill just reads "Closed"). */
.cx-badge-duplicate { background: var(--cx-amber-tint); color: var(--cx-amber); border-color: var(--cx-amber-solid); text-transform: uppercase; letter-spacing: .02em; }

/* ---- Priority chips ---- */
.cx-chip { display: inline-flex; align-items: center; font-size: var(--fs-2xs); font-weight: 600; letter-spacing: .03em; text-transform: uppercase; padding: .12rem .45rem; border-radius: 4px; }
.cx-prio-critical { background: var(--cx-red-tint); color: var(--cx-red); }
.cx-prio-high { background: var(--cx-amber-tint); color: var(--cx-amber); }
.cx-prio-moderate { background: var(--cx-blue-tint); color: var(--cx-blue); }
.cx-prio-low { background: var(--cx-grey-tint); color: var(--cx-ink-muted); }

/* ---- State pills ---- */
.cx-state { display: inline-flex; align-items: center; gap: .3rem; font-size: var(--fs-2xs); font-weight: 600; padding: .14rem .5rem; border-radius: 999px; border: 1px solid var(--cx-border); background: var(--cx-grey-tint); color: var(--cx-ink-muted); white-space: nowrap; }
.cx-state-new { background: var(--cx-grey-tint); color: var(--cx-ink-muted); }
.cx-state-inprogress { background: var(--cx-amber-tint); color: var(--cx-amber); border-color: var(--cx-amber-solid); }
.cx-state-onhold { background: var(--cx-ai-tint); color: var(--cx-ai); border-color: var(--cx-secondary-purple); }
.cx-state-resolved { background: var(--cx-green-tint); color: var(--cx-green); border-color: var(--cx-green-line); }
.cx-state-closed { background: var(--cx-grey-tint); color: var(--cx-ink-muted); }

/* Priority status dot */
.cx-dot { width: 8px; height: 8px; border-radius: 999px; display: inline-block; flex: none; }
.cx-dot-critical { background: var(--cx-critical); }
.cx-dot-high { background: var(--cx-accent); }
.cx-dot-moderate { background: var(--cx-blue-solid); }
.cx-dot-low { background: var(--cx-border-strong); }
.cx-dot-muted { background: var(--cx-border-strong); }
.cx-dot-ok { background: var(--cx-green-solid); }
.cx-dot-risk { background: var(--cx-amber-solid); }
.cx-dot-breach { background: var(--cx-critical); }
.cx-dot-paused { background: var(--cx-blue-solid); }

/* Phase 4 — live SLA badge (header tiles, tab dots, queue column) */
.cx-sla-badge { display: inline-flex; align-items: baseline; gap: .3rem; white-space: nowrap; }
.cx-sla-badge .cx-dot { align-self: center; }
.cx-sla-badge .cx-sla-detail { color: var(--cx-ink-muted); font-weight: 400; }
.cx-sla-badge.cx-sla-risk .cx-sla-headline { color: var(--cx-amber); }
.cx-sla-badge.cx-sla-breach .cx-sla-headline { color: var(--cx-critical); }

/* ---- SLA placeholder pill (engine pending) ---- */
.cx-sla-pending { display: inline-flex; align-items: center; gap: .3rem; font-size: var(--fs-2xs); color: var(--cx-ink-muted); background: var(--cx-grey-tint); border: 1px dashed var(--cx-border-strong); border-radius: 999px; padding: .1rem .5rem; white-space: nowrap; }

/* ---- Pager ----
   One definition, merged from the two that used to be split across this file
   (the queue-table footer and the standalone list pager). Both rendered as the
   union of the two blocks, so the union is what is preserved here. */
.cx-pager {
    display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-3); margin-top: var(--sp-3);
    border-top: 1px solid var(--cx-border);
    color: var(--cx-ink-muted); font-size: var(--fs-sm);
}
.cx-pager-actions { display: flex; gap: var(--sp-1); }

/* ---- Modal ---- */
.cx-modal-backdrop { position: fixed; inset: 0; background: rgba(27,42,48,.35); display: flex; align-items: center; justify-content: center; padding: 6vh 1rem; z-index: 50; }
/* Flex column, not a single scrolling block: header and footer stay put and only the body
   scrolls, so a close button and a primary action (e.g. "Open ticket") never scroll out of
   reach on a long preview. */
.cx-modal { background: var(--cx-surface); border-radius: var(--cx-radius-lg); width: min(760px, 92vw); max-height: 84vh; overflow: hidden; box-shadow: var(--cx-shadow-pop); margin: auto; display: flex; flex-direction: column; }
.cx-modal-header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1rem 1.25rem; border-bottom: 1px solid var(--cx-border); flex: none; }
.cx-modal-header h2 { margin: 0; }
.cx-modal-close { border: none; background: transparent; cursor: pointer; color: var(--cx-ink-muted); font-size: var(--fs-lg); line-height: 1; padding: .1rem .3rem; flex-shrink: 0; }
.cx-modal-close:hover { color: var(--cx-red); }
.cx-modal-body { padding: 1.25rem; overflow-y: auto; flex: 1 1 auto; min-height: 0; }
.cx-modal-footer { display: flex; justify-content: flex-end; gap: .5rem; padding: 1rem 1.25rem; border-top: 1px solid var(--cx-border); flex: none; }

/* ---- Full-page busy overlay (e.g. escalate) ---- */
.cx-busy-overlay { position: fixed; inset: 0; background: rgba(27,42,48,.25); display: flex; align-items: center; justify-content: center; z-index: 200; }
/* cx-ws-body has no height of its own — it's just however tall the ticket content is — so
   centering across its full inset:0 box (the old behaviour) put the spinner however far down
   a long ticket happened to be, off-screen if the page was scrolled to the top. Sticky + a
   viewport-height box (negative margin so it doesn't reserve that height in the flow) keeps it
   pinned to the visible viewport instead, wherever the page is scrolled. top offset clears the
   sticky topbar (56px) plus the sticky tab strip below it. */
.cx-busy-overlay-inline { position: sticky; top: 104px; height: 100vh; margin-bottom: -100vh; }
.cx-busy-spinner { width: 48px; height: 48px; border-radius: 50%; border: 4px solid rgba(255,255,255,.6); border-top-color: var(--cx-primary); animation: cx-busy-spin .8s linear infinite; }
@keyframes cx-busy-spin { to { transform: rotate(360deg); } }

/* ============================ Dashboard ================================= */
.cx-dash { display: block; }
.cx-dash-main { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
.cx-dash-top { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
.cx-stat-card { background: var(--cx-surface); border: 1px solid var(--cx-border); border-radius: var(--cx-radius-lg); padding: var(--sp-4); box-shadow: var(--cx-shadow-sm); }
.cx-stat-num { font-size: var(--fs-4xl); font-weight: 600; line-height: 1; }
.cx-stat-sub { font-size: var(--fs-xs); color: var(--cx-ink-muted); margin-top: .35rem; }
.cx-stat-row { display: flex; align-items: baseline; gap: .5rem; }
.cx-stat-num.cx-stat-alert { color: var(--cx-critical); }
.cx-stat-clickable { cursor: pointer; }
.cx-stat-clickable:hover { border-color: var(--cx-primary); }
.cx-delta-up { color: var(--cx-green); font-size: var(--fs-sm); font-weight: 600; }
.cx-delta-down { color: var(--cx-red); font-size: var(--fs-sm); font-weight: 600; }

.cx-panel { background: var(--cx-surface); border: 1px solid var(--cx-border); border-radius: var(--cx-radius-lg); box-shadow: var(--cx-shadow-sm); }
.cx-panel-head { display: flex; align-items: center; gap: .75rem; padding: .75rem 1rem; border-bottom: 1px solid var(--cx-border); }
.cx-panel-head h2 { margin: 0; font-size: var(--fs-base); }
.cx-panel-head .cx-panel-actions { margin-left: auto; display: flex; gap: .4rem; align-items: center; }
.cx-panel-body { padding: .5rem 0; }

.cx-headsup { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; }
.cx-headsup .cx-stat-num { font-size: var(--fs-3xl); color: var(--cx-primary-dark); }
/* ADO #4051: each count opens the tickets behind it. */
.cx-headsup-item { display: flex; flex-direction: column; align-items: flex-start; gap: .15rem; padding: .5rem .6rem; margin: -.5rem -.6rem; border: 1px solid transparent; border-radius: var(--cx-radius-sm); background: none; font: inherit; text-align: left; color: inherit; cursor: pointer; }
.cx-headsup-item:hover { border-color: var(--cx-primary); }
.cx-headsup-item:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: 2px; }

.cx-reco { display: flex; flex-direction: column; gap: .5rem; }
.cx-reco-item { border: 1px solid var(--cx-border); border-radius: var(--cx-radius); padding: .5rem .65rem; }
.cx-reco-item strong { display: block; font-size: var(--fs-md); }
.cx-reco-item span { font-size: var(--fs-xs); color: var(--cx-ink-muted); }

.cx-comingsoon-card { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .4rem; color: var(--cx-ink-muted); text-align: center; padding: 1rem; border: 1px dashed var(--cx-border-strong); border-radius: var(--cx-radius); background: var(--cx-grey-tint); }

/* ============================ Workspace ================================= */
.cx-ws { display: flex; flex-direction: column; }

/* Positioning context for the inline busy overlay shown while a case tab's data is (re)loading. */
.cx-ws-body { position: relative; }

/* Tab strip */
.cx-tabs { display: flex; align-items: stretch; gap: 0; background: var(--cx-page); border-bottom: 1px solid var(--cx-border); padding: .35rem .5rem 0; overflow-x: auto; position: sticky; top: 56px; z-index: 50; }
.cx-tab { display: inline-flex; align-items: center; gap: .45rem; padding: .45rem .7rem; border: 1px solid var(--cx-border); border-bottom: none; border-radius: var(--cx-radius) var(--cx-radius) 0 0; background: var(--cx-grey-tint); color: var(--cx-ink-muted); cursor: pointer; white-space: nowrap; max-width: 230px; }
.cx-tab.active { background: var(--cx-surface); color: var(--cx-ink); font-weight: 600; }
/* The link must itself be a shrinkable flex container - otherwise its unstyled <a> box refuses to
   shrink below the full customer-name width, which pushes .cx-tab-close past the tab's max-width
   and behind the next tab (and keeps .cx-tabs from ever registering the overflow, hiding the
   scrollbar too). min-width:0 + overflow:hidden lets it shrink so .cx-tab-name's ellipsis engages. */
.cx-tab-link { display: inline-flex; align-items: center; gap: .45rem; flex: 1 1 auto; min-width: 0; overflow: hidden; text-decoration: none; color: inherit; }
.cx-tab .cx-dot { flex-shrink: 0; }
.cx-tab .cx-tab-num { font-family: var(--cx-mono); font-size: var(--fs-xs); flex-shrink: 0; }
.cx-tab .cx-tab-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-sm); min-width: 0; }
.cx-tab .cx-tab-close { border: none; background: transparent; cursor: pointer; color: var(--cx-ink-muted); font-size: var(--fs-md); padding: 0 .1rem; flex-shrink: 0; }
.cx-tab .cx-tab-close:hover { color: var(--cx-red); }

/* A knowledge article opened from the suggestions panel. Same tab shape, but tinted and marked so
   it never reads as a case in the agent's queue — it carries no number, priority or SLA. */
.cx-tab-article { background: var(--cx-blue-tint); }
.cx-tab-article.active { background: var(--cx-surface); box-shadow: inset 0 2px 0 var(--cx-blue); }
.cx-tab-article-icon { color: var(--cx-blue); font-weight: 600; }
/* The article fills the workspace body, so it needs the padding the ticket chrome would have given it. */
.cx-kb-intab { padding: var(--sp-4); }

/* Auxiliary tabs (the full similar-cases list): same shape as an article tab, different accent so
   the three kinds in the strip stay tellable apart. */
.cx-tab-aux { background: var(--cx-grey-tint); }
.cx-tab-aux.active { background: var(--cx-surface); box-shadow: inset 0 2px 0 var(--cx-ink-muted); }
.cx-tab-aux-icon { color: var(--cx-ink-muted); font-weight: 600; }

/* A button that reads as a link. Used where a click must stay in the app: Blazor intercepts anchor
   clicks for enhanced navigation before preventDefault can stop it, so an <a href> would navigate
   away however it is wired. */
.cx-linkbutton { background: none; border: 0; padding: 0; margin: 0; font: inherit; color: var(--cx-primary-dark); cursor: pointer; text-align: left; }
.cx-linkbutton:hover { text-decoration: underline; }

/* Semantic-search banner on the knowledge page: says why the order is what it is, and offers the
   way back to ordinary browsing. */
.cx-kb-semantic-note { display: inline-flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--cx-ink-muted); }
.cx-kb-match { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* "View all" and similar links sitting in a Card's header actions. */
.cx-card-link { font-size: var(--fs-2xs); color: var(--cx-primary-dark); text-decoration: none; }
.cx-card-link:hover { text-decoration: underline; }

.cx-similar-all { padding: .5rem 0; }

/* Dense, borderless rows rather than a bordered grid - a bottom hairline per row is enough
   separation, and the smaller body font matches the density of the rest of the side panel
   instead of inheriting the page's larger base size. */
.cx-similar-all-table { width: 100%; border-collapse: collapse; font-size: var(--fs-xs); }
.cx-similar-all-table th {
  text-align: left; font-weight: 600; font-size: var(--fs-3xs); text-transform: uppercase;
  letter-spacing: .03em; color: var(--cx-ink-muted); padding: .45rem .6rem; border-bottom: 1px solid var(--cx-border);
  white-space: nowrap;
}
.cx-similar-all-table th:first-child, .cx-similar-all-table td:first-child { padding-left: 1.25rem; }
.cx-similar-all-table th:last-child, .cx-similar-all-table td:last-child { padding-right: 1.25rem; }
.cx-similar-all-table td { padding: .45rem .6rem; border-bottom: 1px solid var(--cx-border); vertical-align: middle; }
.cx-similar-all-table tbody tr:last-child td { border-bottom: none; }
.cx-similar-all-table tbody tr:hover { background: var(--cx-page); }
/* Every column but the title stays on one line - a case number, customer name or state pill
   wrapping mid-word reads as broken, not dense, so only the title (the one column worth
   letting run long) is allowed to wrap. */
.cx-similar-all-table th:not(:first-child), .cx-similar-all-table td:not(:first-child) { white-space: nowrap; }
.cx-similar-all-number, .cx-similar-all-score { font-variant-numeric: tabular-nums; }
/* .cx-similar-title is shared with the sidebar's larger similar-case list; scoped down here to
   match this table's smaller row height rather than resizing the shared class. */
.cx-similar-all-table .cx-similar-title { font-size: var(--fs-xs); }
.cx-tab-dirty { color: var(--cx-amber); font-weight: 600; }
.cx-tab-add { border: none; background: transparent; cursor: pointer; padding: .45rem .7rem; color: var(--cx-ink-muted); }

/* Header strip. Not sticky: it carries the title, meta line and four SLA tiles,
   which together are tall enough that pinning them would eat the screen. The
   ticket tab strip above it stays pinned, and that is what an agent needs while
   scrolling — which ticket they are in. */
.cx-ws-header { background: var(--cx-surface); border-bottom: 1px solid var(--cx-border); padding: var(--sp-4) var(--sp-5); }
.cx-ws-id { font-size: var(--fs-xs); color: var(--cx-ink-muted); }
/* First header line: the id/customer summary on the left, the state select and Reply pinned
   together to the right of that same line. */
.cx-ws-id-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.cx-ws-id-row-actions { display: flex; align-items: center; gap: var(--sp-2); flex: none; }
.cx-ws-title-row { display: flex; align-items: flex-start; flex-wrap: wrap; gap: var(--sp-3); margin: var(--sp-1) 0 var(--sp-2); }
.cx-ws-title-row h1 { font-size: var(--fs-2xl); letter-spacing: -.01em; }
.cx-ws-reporter-line { font-size: var(--fs-sm); color: var(--cx-ink-muted); margin-bottom: var(--sp-2); }
.cx-ws-reporter-line b { color: var(--cx-ink); font-weight: 600; }
.cx-ws-state-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; margin-bottom: var(--sp-2); }
.cx-ws-meta { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4); font-size: var(--fs-sm); color: var(--cx-ink-muted); }
.cx-ws-meta b { color: var(--cx-ink); font-weight: 600; }

/* Compact SLA/metric tiles that scale with the available width: they grow to share the header row,
   wrap when there is no room, and are bounded so they neither get cramped nor sprawl on wide screens.
   The ring is a status ring — see SlaIndicator for why it carries no progress arc. */
.cx-sla-strip { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-2); }
.cx-sla-tile {
    flex: 1 1 190px; min-width: 180px; max-width: 360px;
    display: flex; align-items: center; gap: var(--sp-3);
    background: var(--cx-surface);
    border: 1px solid var(--cx-border); border-radius: var(--cx-radius-md);
    padding: var(--sp-2) var(--sp-3); box-shadow: var(--cx-shadow-sm);
}
.cx-sla-tile-text { min-width: 0; }
.cx-sla-tile .cx-sla-title { font-size: var(--fs-3xs); text-transform: uppercase; letter-spacing: .04em; color: var(--cx-ink-muted); font-weight: 600; }
.cx-sla-tile .cx-sla-value { font-size: var(--fs-sm); font-weight: 600; margin-top: .1rem; }
.cx-sla-tile .cx-sla-detail { color: var(--cx-ink-muted); font-weight: 400; }

.cx-sla-ring { position: relative; width: 34px; height: 34px; flex: none; display: grid; place-items: center; }
.cx-sla-ring svg { position: absolute; inset: 0; }
.cx-sla-ring-track { fill: none; stroke-width: 3; stroke: var(--cx-grey-tint); }
.cx-sla-ring-value { fill: none; stroke-width: 3; stroke: var(--cx-border-strong); }
.cx-sla-ring-icon { position: relative; font-size: var(--fs-sm); line-height: 1; color: var(--cx-ink-muted); }

.cx-sla-ok .cx-sla-ring-value { stroke: var(--cx-green-solid); }
.cx-sla-ok .cx-sla-ring-icon, .cx-sla-ok .cx-sla-headline { color: var(--cx-green); }
.cx-sla-risk .cx-sla-ring-value { stroke: var(--cx-amber-solid); }
.cx-sla-risk .cx-sla-ring-icon, .cx-sla-risk .cx-sla-headline { color: var(--cx-amber); }
.cx-sla-breach .cx-sla-ring-value { stroke: var(--cx-critical); }
.cx-sla-breach .cx-sla-ring-icon, .cx-sla-breach .cx-sla-headline { color: var(--cx-critical); }
.cx-sla-paused .cx-sla-ring-value { stroke: var(--cx-blue-solid); }
.cx-sla-paused .cx-sla-ring-icon, .cx-sla-paused .cx-sla-headline { color: var(--cx-blue); }
/* No snapshot yet: a dashed ring says "nothing here to read" without inventing a status. */
.cx-sla-none .cx-sla-ring-value { stroke: var(--cx-border-strong); stroke-dasharray: 3 4; }
.cx-sla-none .cx-sla-headline { color: var(--cx-ink-muted); font-weight: 600; }

/* Two columns: the work, and the context.

   This replaces the previous three-column layout, whose left rail held the
   classification and assignment editors. Those now live in the Details tab as a
   proper form, which is what the narrow rail was fighting: 14 fields stacked in
   300px is a scroll, not a layout. What is left in the sidebar is the handful of
   things worth glancing at without leaving the conversation.

   The collapsible-rail focus mode went with the left rail. It existed to claw
   back width the rails were taking; with one rail there is enough room without
   it.

   Both columns scroll with the page. The sidebar is deliberately NOT sticky and
   has no overflow of its own: a pane that scrolls independently is a second
   scroll region, with its own position and its own scrollbar, and it puts the
   context out of step with the conversation it belongs to. One page, one
   scrollbar — the same rule the rest of the shell now follows. */
.cx-ws-cols {
    display: grid; align-items: start;
    /* The ticket and what helps with it, at the proportions of the single-page redesign. */
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    gap: var(--sp-5);
    padding: var(--sp-5);
    /* Full width, like the header above it: capping the columns left wide screens with empty gutters. */
    width: 100%;
}
.cx-ws-col { min-width: 0; }
.cx-ws-centre { display: flex; flex-direction: column; gap: var(--sp-4); outline: none; }
.cx-ws-side { display: flex; flex-direction: column; gap: var(--sp-4); }

@media (max-width: 1280px) { .cx-ws-cols { gap: var(--sp-4); } }

/* Narrow: one column, the conversation first — it is what the agent came for. */
@media (max-width: 980px) {
    .cx-ws-cols { grid-template-columns: minmax(0, 1fr); padding: var(--sp-4); }
    .cx-ws-centre { order: 1; }
    .cx-ws-side { order: 2; }
    .cx-ws-header { padding: var(--sp-3) var(--sp-4); }
}

.cx-side-block { margin-bottom: 1.1rem; }
.cx-side-block h3 { font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .05em; color: var(--cx-ink-muted); margin: 0 0 .4rem; }
.cx-side-field { font-size: var(--fs-sm); margin-bottom: .35rem; }
.cx-side-field .k { color: var(--cx-ink-muted); }

/* ---- Sidebar: reporter ---- */
.cx-reporter-line { font-size: var(--fs-sm); color: var(--cx-ink-muted); overflow-wrap: anywhere; }

/* ---- Sidebar: key/value list ---- */
.cx-kv { margin: 0; }
.cx-kv-row {
    display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
    padding: var(--sp-2) 0; border-bottom: 1px solid var(--cx-border); font-size: var(--fs-sm);
}
.cx-kv-row:last-of-type { border-bottom: none; }
.cx-kv-row dt { color: var(--cx-ink-muted); }
.cx-kv-row dd { margin: 0; font-weight: 600; text-align: right; }
.cx-kv-link { margin-top: var(--sp-2); padding-left: 0; padding-right: 0; color: var(--cx-primary-dark); }

/* ADO #2715 — escalation history list on the Details tab. */
.cx-escalation-history { list-style: none; margin: 0 0 var(--sp-3); padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.cx-escalation-entry { font-size: var(--fs-sm); border-left: 3px solid var(--cx-primary); background: var(--cx-grey-tint); padding: var(--sp-2) var(--sp-3); border-radius: var(--cx-radius-sm); }
.cx-escalation-reason { color: var(--cx-ink-muted); font-style: italic; margin-top: .15rem; }

/* ADO #2808 — per-field from → to detail on the audit log. The surrounding timeline styles
   come from the design system's ActivityTimeline; only the field-diff rows are local. */
.cx-audit-changes { display: flex; flex-direction: column; gap: .15rem; margin-bottom: .3rem; }
.cx-audit-change { font-size: .8rem; }
.cx-audit-field { font-weight: 600; margin-right: .4rem; }
.cx-audit-arrow { margin: 0 .3rem; color: var(--cx-ink-muted); }

/* Account-move panel in the sidebar. */
.cx-edit-panel { border: 1px solid var(--cx-border); border-radius: var(--cx-radius-md); padding: var(--sp-3); margin: var(--sp-2) 0; background: var(--cx-surface); }
.cx-edit-confirm { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; margin-top: var(--sp-2); }
.cx-btn-xs { font-size: var(--fs-2xs); padding: .15rem .45rem; }

/* A select sized to its content, for toolbars rather than forms. */
.cx-select-auto { width: auto; }

/* Ticket-state select in the header id row: sized to a comfortable, readable width rather than
   shrink-wrapping to whichever option text happens to be selected. */
.cx-select-state { width: auto; min-width: 200px; max-width: 280px; }


/* ---- Timeline (ActivityTimeline) ----
   A date-grouped list with a connecting rail down the left. The rail is drawn on
   the item, not as a separate element, so it cannot fall out of step with the
   rows when the feed grows. */
.cx-timeline { padding: var(--sp-2) var(--sp-4) var(--sp-5); }
.cx-timeline-head { display: flex; align-items: center; justify-content: space-between; padding: var(--sp-3) 0 var(--sp-1); }
.cx-timeline-label { font-size: var(--fs-2xs); font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--cx-ink-muted); }
.cx-timeline-sort { font-size: var(--fs-xs); color: var(--cx-ink-muted); }
.cx-timeline-empty { color: var(--cx-ink-muted); padding: var(--sp-5) 0; text-align: center; }
.cx-timeline-list, .cx-timeline-entries { list-style: none; margin: 0; padding: 0; }
.cx-timeline-group + .cx-timeline-group { margin-top: var(--sp-2); }

.cx-date-sep {
    display: flex; align-items: center; gap: var(--sp-3);
    margin: var(--sp-4) 0 var(--sp-1);
    font-size: var(--fs-3xs); font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
    color: var(--cx-ink-muted);
}
.cx-date-sep::before, .cx-date-sep::after { content: ""; flex: 1; height: 1px; background: var(--cx-border); }

.cx-tl-item { display: flex; gap: var(--sp-3); position: relative; padding: var(--sp-2) 0; }
.cx-tl-item::before { content: ""; position: absolute; left: 15px; top: 0; bottom: 0; width: 1px; background: var(--cx-border); }
.cx-tl-item:first-child::before { top: 18px; }
.cx-tl-item:last-child::before { bottom: auto; height: 18px; }
.cx-tl-dot {
    width: 31px; height: 31px; border-radius: 999px; flex: none; z-index: 1;
    display: flex; align-items: center; justify-content: center;
    font-size: var(--fs-3xs); font-weight: 600;
    background: var(--cx-grey-tint); border: 1px solid var(--cx-border); color: var(--cx-ink-muted);
}
.cx-tl-dot-agent { background: var(--cx-primary-tint); border-color: var(--cx-primary-pale); color: var(--cx-primary-dark); }
.cx-tl-dot-customer { background: var(--cx-amber-tint); border-color: var(--cx-amber-solid); color: var(--cx-amber); }
.cx-tl-dot-internal { background: var(--cx-amber-tint); border-color: var(--cx-amber-solid); color: var(--cx-amber); }
.cx-tl-dot-ai { background: var(--cx-ai-tint); border-color: var(--cx-secondary-purple); color: var(--cx-ai); }
.cx-tl-dot-system { background: var(--cx-grey-tint); color: var(--cx-ink-muted); }
.cx-tl-body { flex: 1; min-width: 0; }

.cx-tl-system-row { margin: 0; padding-top: var(--sp-2); font-size: var(--fs-xs); color: var(--cx-ink-muted); }
.cx-tl-system-row .cx-tl-who { color: var(--cx-ink); font-weight: 600; margin-left: var(--sp-2); }
.cx-tl-system-row time { font-family: var(--cx-mono); font-size: var(--fs-3xs); margin-left: var(--sp-2); }

.cx-msg-card { background: var(--cx-surface); border: 1px solid var(--cx-border); border-radius: var(--cx-radius-md); padding: var(--sp-3); }
.cx-msg-card-head { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-1); flex-wrap: wrap; }
.cx-msg-who { font-weight: 600; font-size: var(--fs-md); }
.cx-msg-meta { margin-left: auto; display: flex; align-items: center; gap: var(--sp-2); }
.cx-msg-when { font-family: var(--cx-mono); font-size: var(--fs-3xs); color: var(--cx-ink-muted); }
.cx-msg-edited { font-size: var(--fs-3xs); font-style: italic; color: var(--cx-ink-muted); }
.cx-msg-edit-btn { font-size: var(--fs-3xs); padding: 0 var(--sp-1); height: auto; }
.cx-msg-body { font-size: var(--fs-md); white-space: pre-wrap; overflow-wrap: anywhere; }
.cx-msg-customer { border-left: 3px solid var(--cx-amber); }
.cx-msg-agent { border-left: 3px solid var(--cx-primary); }
.cx-msg-internal { background: var(--cx-amber-tint); border-color: var(--cx-amber-solid); }
.cx-msg-ai { background: var(--cx-ai-tint); border-left: 3px solid var(--cx-ai); }
.cx-channel-badge { font-size: var(--fs-3xs); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--cx-ink-muted); background: var(--cx-grey-tint); border-radius: 3px; padding: .05rem .3rem; }

.cx-load-more { display: flex; margin: var(--sp-4) auto 0; border-style: dashed; border-color: var(--cx-border-strong); }
.cx-load-more:hover { background: var(--cx-page); border-color: var(--cx-primary); }

/* ---- Composer ---- */
.cx-composer {
    background: var(--cx-surface);
    border-bottom: 1px dashed var(--cx-border-strong);
    padding: var(--sp-4);
}
.cx-composer-modes { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.cx-composer-mode {
    font: inherit; font-size: var(--fs-xs); font-weight: 600; cursor: pointer;
    padding: var(--sp-1) var(--sp-3); border-radius: 999px;
    border: 1px solid var(--cx-border-strong); background: var(--cx-surface); color: var(--cx-ink-muted);
}
.cx-composer-mode:hover:not(:disabled) { color: var(--cx-ink); }
.cx-composer-mode:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: 2px; }
.cx-composer-mode:disabled { opacity: .5; cursor: not-allowed; }
.cx-composer-mode.active-customer { background: var(--cx-primary); border-color: var(--cx-primary); color: var(--cx-white); }
.cx-composer-mode.active-internal { background: var(--cx-amber-tint); border-color: var(--cx-amber-solid); color: var(--cx-amber); }
.cx-composer-draft { margin-left: auto; font-size: var(--fs-xs); color: var(--cx-ink-muted); }
.cx-composer-input { min-height: 84px; resize: vertical; background: var(--cx-page); }
.cx-composer-input:focus { background: var(--cx-surface); }
/* The @mention menu sits under the textarea rather than at the caret: the caret's pixel position
   is not knowable server-side, and a menu that jumps around is harder to hit than a fixed one. */
.cx-composer-mentions { position: static; margin-top: calc(var(--sp-1) * -1); max-height: 180px; overflow-y: auto; }
.cx-composer-actions { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-3); }
.cx-composer-tools { display: flex; align-items: center; gap: var(--sp-1); }
.cx-composer-spacer { flex: 1; }

/* Visible to screen readers, not to the eye — for labels a sighted user reads
   from the placeholder but an assistive-tech user still needs announced. */
.cx-visually-hidden {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Skeleton / coming soon */
.cx-skeleton { border: 1px solid var(--cx-border); border-radius: var(--cx-radius); padding: .65rem; margin-bottom: .75rem; background: var(--cx-surface); }
.cx-skeleton h4 { margin: 0 0 .4rem; font-size: var(--fs-sm); color: var(--cx-ink); }
.cx-skel-line { height: 10px; border-radius: 4px; background: linear-gradient(90deg, var(--cx-grey-tint), var(--cx-page), var(--cx-grey-tint)); margin-bottom: .4rem; }
.cx-skel-line.short { width: 60%; }
.cx-coming-soon { font-size: var(--fs-xs); color: var(--cx-ink-muted); font-style: italic; }

/* Misc utility */
.cx-row { display: flex; align-items: center; gap: .5rem; }
.cx-wrap { flex-wrap: wrap; }
.cx-spacer { flex: 1; }
.cx-stack { display: flex; flex-direction: column; gap: .5rem; }
.cx-nowrap { white-space: nowrap; }

/* ---- Blazor error UI ---- */
#blazor-error-ui { display: none; position: fixed; bottom: 0; left: 0; right: 0; background: var(--cx-red-tint); border-top: 1px solid var(--cx-red); color: var(--cx-red); padding: .75rem 1.25rem; z-index: 1000; }
#blazor-error-ui .dismiss { cursor: pointer; float: right; }

/* ============================================================
   Customer portal (Phase 5) — a calm, trustworthy customer-facing
   area on the shared Columbus tokens, distinct from the agent shell.
   ============================================================ */
.cxp-shell { min-height: 100vh; display: flex; flex-direction: column; background: var(--cx-page); }
.cxp-skip { position: absolute; left: -9999px; top: 0; z-index: 100; background: var(--cx-surface); color: var(--cx-primary); padding: .5rem .75rem; border: 1px solid var(--cx-primary); border-radius: var(--cx-radius); }
.cxp-skip:focus { left: .5rem; top: .5rem; }
.cxp-topbar {
    display: flex; align-items: center; height: 60px; padding: 0 1.5rem;
    background: var(--cx-surface); border-bottom: 1px solid var(--cx-border);
}
.cxp-brand { display: flex; align-items: center; gap: var(--sp-3); color: var(--cx-ink); }
.cxp-brand-word { font-size: var(--fs-lg); font-weight: 600; letter-spacing: var(--tracking-body); }
/* A customer's own logo, shown in place of the product lockup when the account
   supplies one. Rounded per p.37 (under 700px wide → 16px). */
.cxp-logo { max-height: 34px; max-width: 180px; object-fit: contain; border-radius: var(--cx-radius-img); }
.cxp-topbar-spacer { flex: 1; }
.cxp-corp-logo { height: 26px; width: auto; }

.cxp-main { flex: 1; display: flex; }
.cxp-card-wrap { width: 100%; display: flex; justify-content: center; align-items: flex-start; padding: 3rem 1.5rem; }
.cxp-card {
    width: 100%; max-width: 26rem; background: var(--cx-surface);
    border: 1px solid var(--cx-border); border-radius: var(--cx-radius-lg);
    box-shadow: var(--cx-shadow); padding: 2rem 2rem 2.25rem;
}
.cxp-h1 { font-family: var(--cx-font-display); font-size: var(--fs-3xl); font-weight: 400; letter-spacing: var(--tracking-display); line-height: var(--lh-display); color: var(--cx-ink); margin: 0 0 .35rem; }
.cxp-sub { color: var(--cx-ink-muted); margin: 0 0 1.5rem; }

.cxp-form { display: flex; flex-direction: column; gap: 1.1rem; }
.cxp-form-inline { margin-top: 1.75rem; }
.cxp-field { display: flex; flex-direction: column; gap: .4rem; }
.cxp-label { font-weight: 600; color: var(--cx-ink); font-size: var(--fs-base); }
.cxp-hint { color: var(--cx-ink-muted); font-size: var(--fs-sm); margin: .15rem 0 0; }
.cxp-input {
    font: inherit; color: var(--cx-ink); background: var(--cx-surface);
    border: 1px solid var(--cx-border-strong); border-radius: var(--cx-radius);
    padding: .6rem .7rem;
}
.cxp-input:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: 1px; border-color: var(--cx-primary); }

.cxp-btn {
    font: inherit; font-weight: 600; cursor: pointer; border-radius: var(--cx-radius);
    padding: .6rem 1rem; border: 1px solid transparent;
}
.cxp-btn:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: 2px; }
.cxp-btn-primary { background: var(--cx-primary); color: var(--cx-white); }
.cxp-btn-primary:hover { background: var(--cx-primary-dark); }
.cxp-btn-ghost { background: var(--cx-surface); color: var(--cx-ink); border-color: var(--cx-border-strong); }
.cxp-btn-ghost:hover { background: var(--cx-grey-tint); }

.cxp-alert {
    background: var(--cx-red-tint); border: 1px solid var(--cx-red); color: var(--cx-red);
    border-radius: var(--cx-radius); padding: .6rem .75rem; margin-bottom: 1.25rem; font-size: var(--fs-base);
}
.cxp-alert-success {
    background: var(--cx-green-tint); border: 1px solid var(--cx-green); color: var(--cx-green);
    border-radius: var(--cx-radius); padding: .6rem .75rem; margin-bottom: 1.25rem; font-size: var(--fs-base);
}
.cxp-comingsoon {
    background: var(--cx-grey-tint); border: 1px dashed var(--cx-border-strong); color: var(--cx-ink-muted);
    border-radius: var(--cx-radius); padding: 1rem; font-size: var(--fs-base);
}

/* ---- Portal ticket list ---- */
.cxp-page { width: 100%; max-width: 72rem; margin: 0 auto; padding: 2rem 1.5rem; }
.cxp-page-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1rem; }
.cxp-muted { color: var(--cx-ink-muted); }
.cxp-mono { font-family: var(--cx-mono); font-size: .85em; }
.cxp-empty { padding: 2rem; text-align: center; color: var(--cx-ink-muted); background: var(--cx-surface); border: 1px solid var(--cx-border); border-radius: var(--cx-radius); }

.cxp-toolbar { display: flex; flex-wrap: wrap; gap: .6rem; margin-bottom: 1rem; }
.cxp-search { flex: 1 1 22rem; }
.cxp-select {
    font: inherit; color: var(--cx-ink); background: var(--cx-surface);
    border: 1px solid var(--cx-border-strong); border-radius: var(--cx-radius); padding: .55rem .6rem;
}
.cxp-select:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: 1px; }

.cxp-table { width: 100%; border-collapse: collapse; background: var(--cx-surface); border: 1px solid var(--cx-border); border-radius: var(--cx-radius); overflow: hidden; }
.cxp-table th { text-align: left; background: var(--cx-grey-tint); border-bottom: 1px solid var(--cx-border); padding: 0; }
.cxp-table td { padding: .6rem .8rem; border-bottom: 1px solid var(--cx-border); }
.cxp-table tbody tr:last-child td { border-bottom: none; }
.cxp-row { cursor: pointer; }
.cxp-row:hover { background: var(--cx-primary-tint); }
.cxp-sort { width: 100%; text-align: left; background: none; border: none; font: inherit; font-weight: 600; color: var(--cx-ink); cursor: pointer; padding: .6rem .8rem; }
.cxp-sort:hover { color: var(--cx-primary); }
.cxp-sort:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: -2px; }

.cxp-pager { display: flex; align-items: center; gap: 1rem; justify-content: center; margin-top: 1rem; }

/* ---- Portal ticket detail ---- */
.cxp-link { color: var(--cx-primary); font-weight: 600; }
.cxp-card-wide { max-width: none; margin-bottom: 1rem; }
.cxp-h2 { font-size: var(--fs-lg); font-weight: 600; margin: 0 0 .6rem; color: var(--cx-ink); }
.cxp-detail-head { margin-bottom: 1rem; }
.cxp-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .75rem; }
.cxp-detail-meta { display: flex; flex-wrap: wrap; gap: .4rem 1rem; margin-top: .4rem; color: var(--cx-ink-muted); align-items: center; }
.cxp-pill { background: var(--cx-primary-tint); color: var(--cx-primary-dark); border-radius: 999px; padding: .15rem .6rem; font-size: var(--fs-sm); font-weight: 600; }

.cxp-timeline { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .9rem; }
.cxp-timeline-entry { border-left: 2px solid var(--cx-border-strong); padding: 0 0 0 .9rem; }
.cxp-timeline-meta { display: flex; flex-wrap: wrap; gap: .25rem 1rem; align-items: baseline; }
.cxp-timeline-head { font-weight: 600; color: var(--cx-ink); }
.cxp-timeline-body { margin: .3rem 0 0; white-space: pre-wrap; }

/* ============================================================
   Customer portal dashboard (Phase 5a).

   This workspace was built on its own teal palette, which appears nowhere in
   Columbus Brand Guidelines V3. The local names below are kept — several
   hundred rules reference them — but every value now resolves to a brand token,
   so the dashboard reads as Columbus without a sweeping rename. The --teal-*
   names are therefore historical; treat them as "the accent" and take new
   values from the tokens at the top of this file.

   Scoped under .pd-app so it never touches the agent (cx-) or the
   rest of the portal (cxp-) styles.
   ============================================================ */
.pd-app {
    --teal: var(--cx-primary); --teal-deep: var(--cx-primary-dark); --teal-darker: var(--cx-primary-dark);
    --teal-tint: var(--cx-primary-tint); --teal-tint-2: var(--cx-page); --teal-glow: rgba(2,1,140,.16);
    --bg: var(--cx-page); --surface: var(--cx-surface); --surface-2: #FAFBFE;
    --border: var(--cx-border); --border-strong: var(--cx-border-strong);
    --ink: var(--cx-ink); --ink-2: #4A5468; --ink-3: var(--cx-ink-muted);
    --ok: var(--cx-green-solid); --ok-bg: var(--cx-green-tint);
    --warn: var(--cx-amber); --warn-bg: var(--cx-amber-tint);
    --risk: var(--cx-critical); --risk-bg: var(--cx-critical-tint);
    --shadow-sm: var(--cx-shadow-sm);
    --shadow-md: var(--cx-shadow-md);
    --shadow-lg: var(--cx-shadow-pop);
    display: grid; grid-template-columns: 264px 1fr; min-height: 100vh; background: var(--bg); color: var(--ink);
    font-family: var(--cx-font); letter-spacing: var(--tracking-body);
}
.pd-app svg { width: 19px; height: 19px; flex: none; }

/* sidebar */
.pd-sidebar { background: var(--surface); border-right: 1px solid var(--border); display: flex; flex-direction: column; position: sticky; top: 0; height: 100vh; }
/* The logotype sits alone above the product descriptor, so the mark keeps its
   clearspace (p.10) and is not competing with a wordmark on the same line. */
.pd-brand { padding: 20px 22px 16px; display: flex; flex-direction: column; align-items: flex-start; gap: 9px; border-bottom: 1px solid var(--border); }
.pd-logo { height: 22px; width: auto; display: block; }
.pd-brand-text { display: flex; flex-direction: column; line-height: 1.1; }
.pd-brand-text .pr { font-size: 12px; color: var(--ink-3); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
.pd-nav { padding: 16px 14px; flex: 1; overflow-y: auto; }
.pd-nav-label { font-size: 12px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); padding: 6px 12px 8px; }
.pd-nav-item { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 10px; color: var(--ink-2); font-weight: 400; font-size: 14.5px; margin-bottom: 2px; transition: .16s; }
.pd-nav-item svg { stroke-width: 1.9; }
.pd-nav-item:hover { background: var(--teal-tint-2); color: var(--ink); }
.pd-nav-item.active { background: var(--teal-tint); color: var(--teal-darker); font-weight: 600; }
.pd-nav-item.pd-disabled { color: var(--ink-3); cursor: default; }
.pd-count { margin-left: auto; font-size: 12px; background: var(--bg); color: var(--ink-2); padding: 1px 8px; border-radius: 20px; }
.pd-nav-item.active .pd-count { background: var(--cx-white); color: var(--teal-darker); }
.pd-sidebar-foot { padding: 14px; border-top: 1px solid var(--border); display: flex; align-items: center; gap: 11px; }
.pd-cust-logo { width: 38px; height: 38px; border-radius: 9px; flex: none; background: var(--cx-ink); color: var(--cx-white); display: grid; place-items: center; font-weight: 600; font-size: 14px; }
.pd-cust-meta { line-height: 1.25; min-width: 0; }
.pd-cust-meta .nm { font-weight: 600; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pd-cust-meta .sub { font-size: 12px; color: var(--ink-3); }

/* main + topbar */
.pd-main { display: flex; flex-direction: column; min-width: 0; }
.pd-topbar { height: 64px; background: rgba(255,255,255,.85); backdrop-filter: blur(12px); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 14px; padding: 0 30px; position: sticky; top: 0; z-index: 30; }
.pd-crumb { font-weight: 600; font-size: 18px; letter-spacing: -.02em; }
.pd-raise { margin-left: auto; display: inline-flex; align-items: center; gap: 7px; background: var(--cx-primary); color: var(--cx-white); font-weight: 600; font-size: 14px; padding: 9px 15px; border-radius: 10px; box-shadow: 0 4px 12px var(--teal-glow); }
.pd-raise:hover { transform: translateY(-1px); }
.pd-raise svg { width: 17px; height: 17px; }
.pd-user { position: relative; }
.pd-user-trigger { display: flex; align-items: center; gap: 10px; padding: 5px 8px 5px 6px; border-radius: 11px; cursor: pointer; list-style: none; user-select: none; }
.pd-user-trigger::-webkit-details-marker { display: none; }
.pd-user-trigger:hover { background: var(--teal-tint-2); }
.pd-user-trigger > svg:last-child { width: 16px; height: 16px; color: var(--ink-3); transition: transform .16s; }
.pd-user[open] .pd-user-trigger > svg:last-child { transform: rotate(180deg); }
.pd-avatar { width: 36px; height: 36px; border-radius: 9px; flex: none; background: var(--cx-primary); color: var(--cx-white); display: grid; place-items: center; font-weight: 600; font-size: 13px; }
.pd-who { line-height: 1.2; text-align: left; }
.pd-who .n { font-weight: 600; font-size: 13.5px; }
.pd-who .r, .pd-who .e { font-size: 12px; color: var(--ink-3); }
.pd-dropdown { position: absolute; right: 0; top: 54px; width: 250px; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; box-shadow: var(--shadow-lg); padding: 8px; z-index: 40; }
.pd-dd-head { padding: 8px 10px 12px; display: flex; gap: 11px; align-items: center; border-bottom: 1px solid var(--border); margin-bottom: 6px; }
.pd-dd-form { margin: 0; }
.pd-dd-item { display: flex; align-items: center; gap: 12px; padding: 9px 12px; border-radius: 9px; color: var(--ink-2); font-size: 14px; font-weight: 400; width: 100%; text-align: left; background: none; border: none; cursor: pointer; font-family: inherit; }
.pd-dd-item svg { width: 18px; height: 18px; }
.pd-dd-item.danger { color: var(--risk); }
.pd-dd-item.danger:hover { background: var(--risk-bg); }

/* content */
.pd-content { padding: 28px 30px 50px; max-width: 1380px; width: 100%; margin: 0 auto; }
.pd-greeting { margin-bottom: 20px; }
.pd-greeting h1 { font-size: 25px; font-weight: 600; letter-spacing: -.02em; }
.pd-greeting p { color: var(--ink-2); font-size: 14.5px; margin-top: 3px; }

.pd-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 24px; }
.pd-stat { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 16px 18px; box-shadow: var(--shadow-sm); }
.pd-stat-lbl { font-size: 12px; color: var(--ink-3); font-weight: 400; display: flex; align-items: center; gap: 7px; }
.pd-stat-lbl svg { width: 15px; height: 15px; color: var(--teal); }
.pd-stat-val { font-size: 28px; font-weight: 600; letter-spacing: -.02em; margin-top: 6px; line-height: 1; }
.pd-stat-val.risk { color: var(--risk); }
.pd-stat-sub { font-size: 12px; color: var(--ink-3); margin-top: 6px; }

/* card grid */
.pd-grid { display: grid; grid-template-columns: 1.55fr 1fr; gap: 22px; align-items: start; }
.pd-rail { display: flex; flex-direction: column; gap: 22px; }
.pd-card { background: var(--surface); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow-sm); overflow: hidden; }
.pd-card-head { display: flex; align-items: center; gap: 11px; padding: 16px 20px 13px; border-bottom: 1px solid var(--border); }
.pd-card-ico { width: 34px; height: 34px; border-radius: 9px; background: var(--teal-tint); color: var(--teal-darker); display: grid; place-items: center; flex: none; }
.pd-card-ico svg { width: 18px; height: 18px; stroke-width: 1.9; }
.pd-card-head h3 { font-size: 16px; font-weight: 600; letter-spacing: -.01em; }
.pd-card-head .sub { font-size: 12px; color: var(--ink-3); margin-top: 1px; }
.pd-more { margin-left: auto; font-size: 13px; color: var(--teal); font-weight: 600; display: flex; align-items: center; gap: 4px; }
.pd-more svg { width: 15px; height: 15px; }
.pd-empty, .pd-coming { padding: 20px; color: var(--ink-3); font-size: 13.5px; }
.pd-coming { background: var(--teal-tint-2); margin: 12px; border: 1px dashed var(--border-strong); border-radius: 11px; }
.pd-empty a, .pd-coming a { color: var(--teal); font-weight: 600; }

/* tickets */
.pd-ticket { display: grid; grid-template-columns: auto 1fr auto; gap: 14px; align-items: center; padding: 13px 20px; border-bottom: 1px solid var(--border); transition: .14s; cursor: pointer; }
.pd-ticket:last-child { border-bottom: none; }
.pd-ticket:hover { background: var(--teal-tint-2); }
.pd-prio { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.pd-prio.critical { background: var(--risk); box-shadow: 0 0 0 3px var(--risk-bg); }
.pd-prio.high { background: var(--cx-accent); box-shadow: 0 0 0 3px var(--cx-accent-tint); }
.pd-prio.moderate { background: var(--warn); box-shadow: 0 0 0 3px var(--warn-bg); }
.pd-prio.low { background: var(--ink-3); box-shadow: 0 0 0 3px var(--cx-grey-tint); }
.pd-t-body { min-width: 0; }
.pd-t-top { display: flex; align-items: center; gap: 9px; margin-bottom: 3px; }
.pd-t-id { font-family: var(--cx-mono); font-size: 12px; color: var(--teal-darker); font-weight: 400; }
.pd-t-state { font-size: 12px; font-weight: 600; padding: 2px 8px; border-radius: 20px; background: var(--bg); color: var(--ink-2); }
.pd-t-title { font-weight: 600; font-size: 14.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pd-t-meta { font-size: 12px; color: var(--ink-3); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pd-t-sla { text-align: right; flex: none; }
.pd-sla-pill { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 20px; font-size: 12px; font-weight: 600; white-space: nowrap; }
.pd-sla-pill.ok { background: var(--ok-bg); color: var(--ok); }
.pd-sla-pill.warn { background: var(--warn-bg); color: var(--warn); }
.pd-sla-pill.risk { background: var(--risk-bg); color: var(--risk); }
.pd-sla-pill.done { background: var(--bg); color: var(--ink-3); }
.pd-sla-clock { font-family: var(--cx-mono); font-size: 12px; color: var(--ink-3); margin-top: 4px; display: block; }

/* contracts */
.pd-contract { padding: 6px 8px 10px; }
.pd-contract-head { padding: 12px 12px 10px; }
.pd-contract-head .nm { font-weight: 600; font-size: 14px; letter-spacing: -.01em; }
.pd-contract-head .ref { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.pd-cline { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 11px; }
.pd-cline:hover { background: var(--teal-tint-2); }
.pd-cline-bar { width: 3px; align-self: stretch; border-radius: 3px; background: var(--teal); flex: none; }
.pd-cline-body { flex: 1; min-width: 0; }
.pd-cline-body .svc { font-weight: 600; font-size: 13.5px; }
.pd-sla-code { font-family: var(--cx-mono); font-size: 12px; font-weight: 400; padding: 3px 9px; border-radius: 7px; background: var(--teal-tint); color: var(--teal-darker); flex: none; white-space: nowrap; }

.pd-note { text-align: center; margin-top: 30px; font-size: 12px; color: var(--ink-3); }

/* shared: back link, alerts, buttons, form controls (used by create/view/list) */
.pd-sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; }
.pd-back { display: inline-flex; align-items: center; gap: 7px; color: var(--ink-2); font-size: 13.5px; font-weight: 600; margin-bottom: 14px; }
.pd-back svg { width: 16px; height: 16px; }
.pd-back:hover { color: var(--teal-darker); }

.pd-alert { background: var(--risk-bg); color: var(--risk); border: 1px solid var(--cx-red-line); border-radius: 11px; padding: 11px 14px; font-size: 13.5px; font-weight: 400; margin-bottom: 16px; }

.pd-btn { display: inline-flex; align-items: center; justify-content: center; gap: 7px; font: inherit; font-size: 14px; font-weight: 600; padding: 10px 18px; border-radius: 11px; border: 1px solid transparent; cursor: pointer; transition: .16s; }
.pd-btn:disabled { opacity: .55; cursor: default; }
.pd-btn-primary { background: var(--cx-primary); color: var(--cx-white); box-shadow: 0 4px 12px var(--teal-glow); }
.pd-btn-primary:not(:disabled):hover { transform: translateY(-1px); }
.pd-btn-ghost { background: var(--surface); color: var(--ink-2); border-color: var(--border-strong); }
.pd-btn-ghost:not(:disabled):hover { background: var(--teal-tint-2); color: var(--ink); border-color: var(--teal); }
.pd-btn-sm { padding: 3px 10px; font-size: 12px; border-radius: 8px; }

.pd-field { margin-bottom: 16px; }
.pd-label { display: block; font-size: 13px; font-weight: 600; color: var(--ink-2); margin-bottom: 6px; }
.pd-input, .pd-select { width: 100%; font: inherit; font-size: 14.5px; color: var(--ink); background: var(--surface-2); border: 1.5px solid var(--border-strong); border-radius: 11px; padding: 10px 13px; transition: .16s; }
.pd-input:focus, .pd-select:focus { outline: none; border-color: var(--teal); background: var(--cx-white); box-shadow: 0 0 0 3px var(--teal-glow); }
/* Disabled / read-only controls: same "not editable yet" cue as the workspace, in the portal palette. */
.pd-input:disabled, .pd-select:disabled,
.pd-input[readonly], .pd-textarea[readonly] {
    background: var(--bg); color: var(--ink-3);
    border-style: dashed; border-color: var(--border-strong);
    cursor: not-allowed; box-shadow: none; opacity: 1;
}
.pd-field:has(select:disabled, input:disabled, textarea:disabled) .pd-label { color: var(--ink-3); opacity: .8; }
/* #3178: service request details — the form section heading, the required marker, the read-only list */
.pd-form-section { font-size: 14px; font-weight: 600; color: var(--ink); margin: 6px 0 12px; }
.pd-required, .cx-required { color: var(--cx-red); font-weight: 600; }
.pd-details { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 8px 16px; margin: 0; font-size: 14px; }
.pd-details-row { display: contents; }
.pd-details dt { color: var(--ink-3); }
.pd-details dd { margin: 0; color: var(--ink); overflow-wrap: anywhere; }
@media (max-width: 560px) { .pd-details { grid-template-columns: minmax(0, 1fr); gap: 2px; } .pd-details dd { margin-bottom: 8px; } }
.pd-textarea { resize: vertical; min-height: 96px; line-height: 1.5; }

/* create-ticket form card */
.pd-form-card { background: var(--surface); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow-sm); padding: 24px 26px; max-width: 760px; }
.pd-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
.pd-form-actions { display: flex; gap: 10px; margin-top: 8px; }
/* Portal user management (#3976): the invite/edit form above the table of who has access. */
.pd-user-form { margin-bottom: 18px; padding: 20px 22px; }
.pd-user-form h2 { margin: 0 0 4px; font-size: 16px; }
.pd-form-hint { margin: 0 0 16px; font-size: 13px; color: var(--ink-3); }
.pd-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
.pd-row-actions { display: flex; gap: 8px; justify-content: flex-end; white-space: nowrap; }
@media (max-width: 640px) { .pd-field-row { grid-template-columns: 1fr; } }


/* self solve: AI-deflection button, suggestions rail, and confirmation card */
.pd-btn-ai { background: var(--cx-ai-tint); color: var(--cx-ai); border-color: var(--cx-secondary-purple); }
.pd-btn-ai:not(:disabled):hover { background: var(--cx-ai-tint); filter: brightness(0.97); }
.pd-btn-ai svg { width: 15px; height: 15px; }

.pd-new-layout-split { display: flex; align-items: flex-start; gap: 22px; }
.pd-new-layout-split .pd-form-card { flex: 1 1 480px; max-width: none; }

.pd-suggest { flex: 0 0 320px; background: var(--surface); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow-sm); padding: 18px 20px; }
.pd-suggest-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 12px; }
.pd-suggest-head h3 { font-size: 14.5px; font-weight: 600; margin: 0; }
.pd-suggest-head .sub { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.pd-suggest-ico { flex: none; width: 30px; height: 30px; border-radius: 9px; background: var(--cx-ai-tint); color: var(--cx-ai); display: grid; place-items: center; }
.pd-suggest-ico svg { width: 16px; height: 16px; }
.pd-suggest .pd-kb-hits { margin-top: 0; }

.pd-solved { text-align: center; padding: 40px 32px; }
.pd-solved-ico { width: 52px; height: 52px; border-radius: 999px; background: var(--teal-tint); color: var(--teal-darker); display: grid; place-items: center; margin: 0 auto 16px; }
.pd-solved-ico svg { width: 26px; height: 26px; }
.pd-solved h2 { font-size: 18px; font-weight: 600; margin-bottom: 8px; }
.pd-solved p { color: var(--ink-2); font-size: 13.5px; margin-bottom: 20px; }
.pd-solved .pd-form-actions { justify-content: center; }

/* knowledge article overlay */
.pd-overlay-backdrop { position: fixed; inset: 0; background: rgba(15, 20, 30, .45); display: flex; align-items: flex-start; justify-content: center; padding: 40px 20px; z-index: 60; overflow-y: auto; }
.pd-overlay { background: var(--surface); border-radius: 16px; box-shadow: var(--shadow-lg); width: 100%; max-width: 640px; max-height: calc(100vh - 80px); overflow-y: auto; }
.pd-overlay-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; padding: 20px 24px; border-bottom: 1px solid var(--border); position: sticky; top: 0; background: var(--surface); }
.pd-overlay-title { font-size: 17px; font-weight: 600; margin: 0; }
.pd-overlay-close { flex: none; background: none; border: none; color: var(--ink-3); cursor: pointer; padding: 4px; border-radius: 8px; }
.pd-overlay-close:hover { background: var(--surface-2); color: var(--ink); }
.pd-overlay-close svg { width: 18px; height: 18px; }
.pd-overlay-body { padding: 20px 24px; }
.pd-overlay-foot { padding: 16px 24px 22px; border-top: 1px solid var(--border); display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pd-overlay-solve svg { width: 15px; height: 15px; }
.pd-overlay-blocked { font-size: 12.5px; color: var(--ink-3); }
.pd-overlay-confirm { display: flex; flex-direction: column; gap: 12px; width: 100%; }
.pd-overlay-confirm span { font-size: 13.5px; color: var(--ink-2); }
.pd-overlay-confirm-actions { display: flex; gap: 10px; }


/* ticket detail */
.pd-detail-head { display: flex; align-items: flex-start; gap: 18px; margin-bottom: 18px; }
.pd-detail-titles { min-width: 0; }
.pd-detail-eyebrow { display: flex; align-items: center; gap: 10px; margin-bottom: 7px; }
.pd-detail-head h1 { font-size: 23px; font-weight: 600; letter-spacing: -.02em; line-height: 1.2; }
.pd-detail-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; color: var(--ink-3); font-size: 13px; margin-top: 7px; }
.pd-detail-meta .pd-dot { color: var(--border-strong); }
.pd-detail-actions { margin-left: auto; display: flex; flex-wrap: wrap; gap: 8px; flex: none; }
.pd-status-pill { font-size: 12px; font-weight: 600; padding: 3px 11px; border-radius: 20px; background: var(--teal-tint); color: var(--teal-darker); white-space: nowrap; }
.pd-hold-notice { margin-top: 10px; padding: 10px 14px; border-radius: 8px; background: var(--warn-bg); color: var(--ink-2); font-size: 14px; line-height: 1.5; }
.pd-hold-notice strong { color: var(--ink-1, inherit); }
.pd-hold-notice p { margin: 4px 0 0; white-space: pre-wrap; }

.pd-detail-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 22px; align-items: start; }
.pd-detail-main { display: flex; flex-direction: column; gap: 22px; }
.pd-card-body { padding: 16px 20px 20px; color: var(--ink-2); font-size: 14.5px; line-height: 1.6; white-space: pre-wrap; }
.pd-card-pad { padding: 16px 20px 20px; }
.pd-card-pad .pd-field:last-of-type { margin-bottom: 14px; }

/* activity timeline */
.pd-timeline { list-style: none; margin: 0; padding: 8px 20px 18px; }
.pd-timeline-entry { display: grid; grid-template-columns: auto 1fr; gap: 13px; position: relative; padding: 10px 0; }
.pd-timeline-entry:not(:last-child)::before { content: ""; position: absolute; left: 4px; top: 24px; bottom: -10px; width: 2px; background: var(--border); }
.pd-timeline-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--teal); margin-top: 5px; box-shadow: 0 0 0 3px var(--teal-tint); z-index: 1; }
.pd-timeline-body { min-width: 0; }
.pd-timeline-meta { display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; }
.pd-timeline-head { font-weight: 600; font-size: 14px; color: var(--ink); }
.pd-timeline-edited { font-size: 12px; font-style: italic; color: var(--ink-3); }
.pd-timeline-meta time { font-size: 12px; color: var(--ink-3); }
.pd-timeline-text { margin-top: 4px; color: var(--ink-2); font-size: 14px; line-height: 1.55; white-space: pre-wrap; }

/* tickets list */
.pd-list-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.pd-list-head .pd-raise { margin-left: 0; }

/* My tickets / All tickets view toggle (portal ticket list) */
.pd-view-toggle { display: inline-flex; background: var(--surface-2); border: 1.5px solid var(--border-strong); border-radius: 11px; padding: 3px; gap: 3px; margin-bottom: 14px; }
.pd-view-toggle button { font: inherit; font-size: 14px; font-weight: 600; padding: 8px 16px; border-radius: 9px; border: none; background: transparent; color: var(--ink-2); cursor: pointer; transition: .15s; }
.pd-view-toggle button.active { background: var(--teal); color: var(--cx-white); }
.pd-view-toggle button:not(.active):hover { background: var(--teal-tint); color: var(--teal-darker); }

.pd-toolbar { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 18px; }
.pd-search { flex: 1; min-width: 240px; display: flex; align-items: center; gap: 9px; background: var(--surface-2); border: 1.5px solid var(--border-strong); border-radius: 11px; padding: 0 13px; transition: .16s; }
.pd-search:focus-within { border-color: var(--teal); background: var(--cx-white); box-shadow: 0 0 0 3px var(--teal-glow); }
.pd-search svg { width: 17px; height: 17px; color: var(--ink-3); }
.pd-search input { flex: 1; border: none; outline: none; background: none; font: inherit; font-size: 14.5px; color: var(--ink); padding: 10px 0; }
.pd-toolbar .pd-select { width: auto; min-width: 150px; flex: none; }

.pd-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.pd-table thead th { text-align: left; padding: 12px 18px; border-bottom: 1px solid var(--border); background: var(--surface-2); }
.pd-table tbody td { padding: 13px 18px; border-bottom: 1px solid var(--border); color: var(--ink-2); }
.pd-table tbody tr:last-child td { border-bottom: none; }
.pd-sort { background: none; border: none; padding: 0; font: inherit; font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); cursor: pointer; }
.pd-sort:hover { color: var(--teal-darker); }
.pd-row { cursor: pointer; transition: .14s; }
.pd-row:hover { background: var(--teal-tint-2); }
.pd-cell-id { font-family: var(--cx-mono); font-size: 12.5px; color: var(--teal-darker); font-weight: 400; }
.pd-cell-title { font-weight: 600; color: var(--ink); }
.pd-cell-muted { color: var(--ink-3); font-size: 13px; white-space: nowrap; }

.pd-pager { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 18px; border-top: 1px solid var(--border); }
.pd-pager-info { font-size: 13px; color: var(--ink-3); }
.pd-pager-info a, .pd-linklike { color: var(--teal); }
.pd-pager-info a:hover, .pd-linklike:hover { text-decoration: underline; }
.pd-linklike { background: none; border: none; padding: 0; margin: 0; font: inherit; cursor: pointer; }
.pd-pager-actions { display: flex; align-items: center; gap: 10px; }
.pd-select-auto { width: auto; }

@media (max-width: 1080px) {
    .pd-app { grid-template-columns: 1fr; }
    .pd-sidebar { display: none; }
    .pd-grid { grid-template-columns: 1fr; }
    .pd-stats { grid-template-columns: repeat(2, 1fr); }
    .pd-detail-grid { grid-template-columns: 1fr; }
    .pd-form-grid { grid-template-columns: 1fr; }
    .pd-detail-actions { margin-left: 0; }
}

/* ---------- Knowledge area (Phase 6) ---------- */
/* The list is a working surface, not an article: it carries seven columns, chip pickers and a
   filter row, so it uses the width it is given rather than a reading measure. */
.cx-kb { padding: 1.25rem 1.5rem; }
.cx-kb-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.cx-kb-head h1 { margin: 0; font-size: var(--fs-2xl); }
.cx-kb-sub { margin: .2rem 0 0; color: var(--cx-ink-muted); font-size: var(--fs-md); }
.cx-kb-empty { color: var(--cx-ink-muted); padding: 1.5rem 0; }

/* ADO #3052 — the advanced filters. Same collapsible panel as the case queue's, but on a wider
   track: chip pickers need room to show what is selected, where a plain select does not. */
.cx-kb-advanced .cx-advanced-filters-grid {
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    margin-bottom: 0;
}
.cx-kb-advanced .cx-advanced-filters-grid > label,
.cx-kb-filter-group { display: flex; flex-direction: column; gap: .25rem; font-size: var(--fs-sm); }
.cx-kb-filter-caption { color: var(--cx-ink-muted); font-weight: 600; }
.cx-kb-filter-sources { display: flex; flex-direction: column; gap: .1rem; }
.cx-kb-filter-sources .cx-check { margin-top: 0; }

/* What the Source column's filter cell reports, since the control itself lives in the panel above.
   Muted and not a control, so it never reads as something that can be typed into. */
.cx-kb-filter-echo { font-size: var(--fs-xs); color: var(--cx-ink-muted); white-space: nowrap; }
.cx-kb-table { border: 1px solid var(--cx-border); border-radius: var(--cx-radius-lg); overflow: hidden; }
.cx-kb-row:hover { background: var(--cx-primary-tint); }

/* ADO #2982/#2981 — the list is now editable, so a row no longer navigates on click (a stray
   click on a select must not leave the page). The title is the link instead. */
.cx-kb-row-selected { background: var(--cx-primary-tint); }
.cx-kb-select { width: 2.5rem; text-align: center; }
.cx-linkish {
    background: none; border: 0; padding: 0; font: inherit; color: var(--cx-primary-dark);
    font-weight: 600; text-align: left; cursor: pointer;
}
.cx-linkish:hover { text-decoration: underline; }
.cx-inline-select, .cx-inline-input { min-width: 8rem; max-width: 14rem; font-size: var(--fs-sm); }

.cx-kb-bulkbar {
    display: flex; align-items: center; gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-3);
    border: 1px solid var(--cx-primary); border-radius: var(--cx-radius-md);
    background: var(--cx-primary-tint);
}
.cx-bulk-panel {
    border: 1px solid var(--cx-border); border-radius: var(--cx-radius-md);
    padding: var(--sp-3); margin-bottom: var(--sp-3); background: var(--cx-surface);
}
.cx-bulk-head { display: flex; align-items: baseline; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.cx-bulk-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3) var(--sp-5); }
.cx-bulk-wide { grid-column: 1 / -1; }
.cx-bulk-actions { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-4); }
.cx-bulk-failures { margin: var(--sp-2) 0 0; padding-left: var(--sp-4); font-size: var(--fs-sm); }
.cx-check { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-2); font-size: var(--fs-sm); }
@media (max-width: 760px) { .cx-bulk-grid { grid-template-columns: 1fr; } }
.cx-kb-title { font-weight: 600; color: var(--cx-ink); }
.cx-kb-summary { font-size: var(--fs-sm); color: var(--cx-ink-muted); margin-top: .15rem; }
.cx-kb-state { display: inline-block; font-size: var(--fs-2xs); font-weight: 600; padding: .15rem .55rem; border-radius: 999px; border: 1px solid var(--cx-border); text-transform: capitalize; }
.cx-kb-state-draft { color: var(--cx-ink-muted); background: var(--cx-surface); }
.cx-kb-state-published { color: var(--cx-amber); background: var(--cx-amber-tint); border-color: var(--cx-amber-tint); }
.cx-kb-state-retired { color: var(--cx-ink-muted); background: var(--cx-border); }
.cx-kb-paging { display: flex; align-items: center; gap: .8rem; margin-top: .9rem; font-size: var(--fs-sm); color: var(--cx-ink-muted); }
.cx-kb-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: .7rem .9rem; }
.cx-kb-multi { min-height: 6rem; }
.cx-kb-actions { display: flex; gap: .5rem; align-items: center; }
.cx-kb-editor .cx-field, .cx-kb-editor .cx-kb-grid { margin-bottom: .9rem; }
.cx-kb-back { font-size: var(--fs-sm); color: var(--cx-primary-dark); text-decoration: none; }
.cx-kb-meta { display: flex; gap: .8rem; align-items: center; margin-top: .35rem; font-size: var(--fs-sm); color: var(--cx-ink-muted); }
.cx-kb-lead { font-size: var(--fs-base); color: var(--cx-ink); margin: .4rem 0 1rem; }
.cx-kb-chips { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: 1.2rem; }
.cx-kb-chip { font-size: var(--fs-xs); padding: .2rem .6rem; border-radius: 999px; background: var(--cx-blue-tint); color: var(--cx-blue); }
.cx-kb-body { white-space: pre-wrap; line-height: 1.6; color: var(--cx-ink); }
/* One email on a ticket, opened from the conversation or the Activity log (ADO #3614). */
.cx-email-meta { display: grid; grid-template-columns: max-content 1fr; gap: .25rem .9rem; margin: .6rem 0 1rem; font-size: var(--fs-sm); }
.cx-email-meta dt { color: var(--cx-ink-muted); }
.cx-email-meta dd { margin: 0; color: var(--cx-ink); overflow-wrap: anywhere; }
.cx-email-body { white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.6; color: var(--cx-ink); padding: 1rem; border: 1px solid var(--cx-border); border-radius: 8px; background: var(--cx-surface); }

@media (max-width: 720px) {
    .cx-kb-grid { grid-template-columns: 1fr; }
}

/* Knowledge suggestions in the agent workspace right column (Phase 6). */
.cx-kb-suggest { border: 1px solid var(--cx-border); border-radius: var(--cx-radius); padding: .55rem .6rem; margin-bottom: .55rem; background: var(--cx-surface); }
.cx-kb-suggest-title { font-weight: 600; font-size: var(--fs-sm); color: var(--cx-primary-dark); text-decoration: none; }
.cx-kb-suggest-title:hover { text-decoration: underline; }
/* Customer sentiment in the ticket header. Colour is not the only carrier of meaning — the reading
   is named in words beside the lamp, and the pill has an aria-label and a tooltip naming it too. */
/* Built to the state pill's metrics — one line, same padding, same 999px radius, same type scale —
   so it sits in that row as another pill rather than as a tile among pills. It therefore needs no
   alignment handling of its own: the title row's align-items:flex-start puts it exactly where it
   puts Open and MODERATE. Deliberately not the SLA tiles' caption-over-value shape; see the
   component's own comment for why. */
.cx-sentiment { display: inline-flex; align-items: center; gap: .35rem; padding: .14rem .55rem; border-radius: 999px; border: 1px solid var(--cx-border); background: var(--cx-grey-tint); color: var(--cx-ink-muted); font-size: var(--fs-2xs); font-weight: 600; vertical-align: middle; line-height: 1.4; }
.cx-sentiment-caption { white-space: nowrap; color: var(--cx-ink-muted); text-transform: uppercase; letter-spacing: .04em; }

/* The reading takes the tone; the caption never does. Sentence case, and left in case rather than
   transformed, so it reads as a word the platform is reporting rather than another label — the
   uppercase caption beside it is the label. Each colour is the exact colour of the lamp: red and
   green are --cx-red/--cx-green, the same tokens the lamps and the SLA headlines use, and neutral
   is the lamp's own yellow, --cx-lamp-neutral-ink. That yellow is a lamp colour and lands near
   1.6:1 as text on this ground; it is here because matching the lamp was chosen over contrast on
   this one word. If it ever needs to be legible as well, --cx-amber is the token "At risk" uses on
   the tiles below. Weight 600 is the heaviest Roobert ships — 700 would be synthesised. */
.cx-sentiment-value { font-weight: 600; white-space: nowrap; }
.cx-sentiment-negative .cx-sentiment-value { color: var(--cx-red); }
.cx-sentiment-neutral .cx-sentiment-value { color: var(--cx-lamp-neutral-ink); }
.cx-sentiment-positive .cx-sentiment-value { color: var(--cx-green); }

/* The reading tints the pill's ground and edge. The edge is a pale wash of the hue — the same
   hairline tokens the other badges in this header use — rather than the full-strength
   --cx-red/--cx-green tokens, which drew a hard dark outline that made this pill louder than
   everything beside it. The caption is never recoloured — one grey caption beside one saturated
   lamp keeps a single thing carrying the signal. Neutral takes no override at all: it keeps the
   base grey ground and grey edge, and the amber lamp is the whole of its reading. */
.cx-sentiment-negative { background: var(--cx-red-tint); border-color: var(--cx-red-line); }
.cx-sentiment-positive { background: var(--cx-green-tint); border-color: var(--cx-green-line); }

/* One lamp, showing the reported reading — there is no dimmed set behind it, so the lamp is simply
   whichever colour the reading is. The colours are the --cx-lamp-* tokens; see their definition for
   why they are their own and not the status palette. The gradient puts the highlight off-centre so
   the lamp reads as illuminated rather than merely filled, and the halo gives it the bloom of a
   lamp rather than the flatness of a status dot.
   Sized to sit inside the pill alongside --fs-2xs text rather than dwarf it. */
.cx-sentiment-lamp { width: .6rem; height: .6rem; border-radius: 50%; flex: none; }
.cx-sentiment-lamp-negative { background: var(--cx-lamp-negative); box-shadow: 0 0 0 2px var(--cx-lamp-negative-glow); }
.cx-sentiment-lamp-neutral { background: var(--cx-lamp-neutral); box-shadow: 0 0 0 2px var(--cx-lamp-neutral-glow); }
.cx-sentiment-lamp-positive { background: var(--cx-lamp-positive); box-shadow: 0 0 0 2px var(--cx-lamp-positive-glow); }

/* No reading yet: the lamp is drawn but unlit, so the pill holds its place and says "pending"
   rather than quietly claiming a sentiment nobody reported. */
.cx-sentiment-lamp-unknown { background: var(--cx-lamp-unknown); }

/* Similar cases (AI-C). Same two-row shape as a knowledge suggestion: title with its match
   score, then the identifying metadata. The customer is always named — matches cross accounts,
   so an agent must see whose case they are opening before they click. */
.cx-similar { border: 1px solid var(--cx-border); border-radius: var(--cx-radius); padding: .55rem .6rem; margin-bottom: .55rem; background: var(--cx-surface); }
.cx-similar-head { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; }
.cx-similar-title { font-weight: 600; font-size: var(--fs-sm); color: var(--cx-primary-dark); text-decoration: none; }
.cx-similar-title:hover { text-decoration: underline; }
.cx-similar-score { flex: none; font-variant-numeric: tabular-nums; }
.cx-similar-foot { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; margin-top: .35rem; font-size: var(--fs-2xs); color: var(--cx-ink-muted); }
.cx-similar-number { font-variant-numeric: tabular-nums; }

/* Title and match score share a row; the score keeps its width so long titles wrap
   against it rather than pushing it out. Tone and shape come from Badge. */
.cx-kb-suggest-head { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; }
.cx-kb-suggest-score { flex: none; font-variant-numeric: tabular-nums; }
.cx-kb-suggest-summary { font-size: var(--fs-xs); color: var(--cx-ink-muted); margin: .2rem 0; }
.cx-kb-suggest-foot { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; margin-top: .35rem; }
.cx-tl-link { margin-left: var(--sp-2); font-size: var(--fs-sm); font-weight: 600; color: var(--cx-primary-dark); }
.cx-kb-suggest-actions { margin-top: var(--sp-3); display: flex; justify-content: flex-end; }
.cx-kb-suggest-badge { font-size: var(--fs-2xs); padding: .1rem .4rem; border-radius: 999px; background: var(--cx-blue-tint); color: var(--cx-blue); }
.cx-kb-suggest-linked { font-size: var(--fs-2xs); color: var(--cx-amber); font-weight: 600; }
.cx-kb-create-from { margin-top: .4rem; width: 100%; }
.cx-kb-dup-warn { font-size: var(--fs-sm); color: var(--cx-amber); background: var(--cx-amber-tint); border-radius: var(--cx-radius); padding: .5rem .6rem; margin-bottom: .6rem; }
.cx-kb-dup-list { margin: 0 0 .8rem; padding-left: 1.1rem; font-size: var(--fs-md); }
.cx-kb-dup-prefill { font-size: var(--fs-sm); color: var(--cx-ink-muted); }

/* Account activity AI summary.
   These used the informational blue, which made a model-written summary look
   like a platform assertion. The AI accent marks machine-generated content
   wherever it appears — here, in knowledge, and on any future AI surface. */
.cx-ai-tag { font-size: var(--fs-2xs); letter-spacing: .03em; text-transform: uppercase; color: var(--cx-ai); margin: 0 0 var(--sp-2); font-weight: 600; }
.cx-ai-badge { display: inline-flex; align-items: center; gap: var(--sp-1); font-size: var(--fs-3xs); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; padding: .1rem var(--sp-2); border-radius: 999px; background: var(--cx-ai-tint); color: var(--cx-ai); }
.cx-ai-summary { font-size: var(--fs-sm); line-height: var(--lh-normal); color: var(--cx-ink); margin: 0 0 .6rem; }
.cx-ai-chips { display: flex; flex-wrap: wrap; gap: .35rem; margin-bottom: .6rem; }
.cx-ai-chip { font-size: var(--fs-2xs); padding: .1rem .45rem; border-radius: 999px; background: var(--cx-ai-tint); color: var(--cx-ai); }
/* AI marker on a tab label, using the same accent as the panel badges. */
.cx-tab-ai { margin-left: .35rem; font-size: var(--fs-3xs); font-weight: 600; letter-spacing: .04em; padding: .05rem .3rem; border-radius: 999px; background: var(--cx-ai-tint); color: var(--cx-ai); }
.cx-ai-subhead { font-size: var(--fs-xs); color: var(--cx-ink); margin: .2rem 0 .35rem; }
.cx-ai-similar { list-style: none; margin: 0 0 .6rem; padding: 0; }
.cx-ai-similar li { display: flex; align-items: center; gap: .4rem; padding: .25rem 0; border-bottom: 1px solid var(--cx-border); }
.cx-ai-similar li:last-child { border-bottom: 0; }
.cx-ai-similar a { font-weight: 600; font-size: var(--fs-xs); color: var(--cx-primary-dark); text-decoration: none; white-space: nowrap; }
.cx-ai-similar a:hover { text-decoration: underline; }
.cx-ai-similar-title { font-size: var(--fs-xs); color: var(--cx-ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cx-related-header { display: flex; align-items: center; justify-content: space-between; margin: 1.25rem 0 .5rem; }
.cx-related-header h2, .cx-related-header h3 { font-size: var(--fs-base); margin: 0; }
.cx-related-header { gap: var(--sp-3); }
.cx-related-search { margin-left: auto; width: 100%; max-width: 18rem; }
/* #3893: the install base tree — indentation carries the path, so the row need not repeat it. */
.cx-tree-cell { display: flex; align-items: center; gap: .35rem; }
.cx-tree-toggle { width: 1.5rem; height: 1.5rem; flex: none; display: inline-flex; align-items: center; justify-content: center;
    border: 0; background: transparent; color: var(--cx-ink-muted); cursor: pointer; border-radius: var(--cx-radius); }
.cx-tree-toggle:hover { background: var(--cx-page); color: var(--cx-ink); }
.cx-tree-toggle-spacer { width: 1.5rem; flex: none; }
.cx-tree-group .cx-tree-label { font-weight: 600; }
.cx-tree-notice { margin: 0 0 .5rem; }

/* Task assignee cell: AsyncSearchSelect plus its Save/Cancel pair, laid out inline */
.cx-task-assignee { display: flex; align-items: flex-start; gap: .4rem; }
.cx-task-assignee .cx-msp { flex: 1; min-width: 0; }

/* Multi-select picker: chips summary + search + highlighted list (MultiSelectPicker.razor) */
.cx-msp { display: flex; flex-direction: column; gap: .4rem; }
.cx-msp-top { display: flex; align-items: flex-start; gap: .5rem; }
.cx-msp-chips { display: flex; flex-wrap: wrap; gap: .35rem; flex: 1; min-height: 1.6rem; align-items: center; }
.cx-msp-empty { font-size: var(--fs-sm); }
.cx-msp-count { flex: 0 0 auto; font-size: var(--fs-xs); color: var(--cx-ink-muted); white-space: nowrap; padding-top: .2rem; }
.cx-chip { display: inline-flex; align-items: center; gap: .3rem; font-size: var(--fs-sm); font-weight: 600;
    color: var(--cx-primary); background: var(--cx-primary-tint); border: 1px solid var(--cx-primary-pale);
    border-radius: 999px; padding: .12rem .3rem .12rem .55rem; }
.cx-chip-x { border: 0; background: transparent; color: var(--cx-primary-dark); cursor: pointer;
    font-size: var(--fs-base); line-height: 1; padding: 0 .15rem; border-radius: 999px; }
.cx-chip-x:hover { background: var(--cx-primary-pale); }
.cx-filter-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); padding: var(--sp-3) var(--sp-4) 0; }
.cx-msp-search { width: 100%; }
/* Dropdown of remaining options, shown only while the search box is focused. In-flow (not absolute)
   so it never clips inside the scrolling edit modal; the modal simply grows to fit. */
.cx-msp-menu { list-style: none; margin: .25rem 0 0; padding: 0; display: flex; flex-direction: column; max-height: 15rem; overflow-y: auto;
    border: 1px solid var(--cx-border-strong); border-radius: var(--cx-radius);
    background: var(--cx-surface); box-shadow: var(--cx-shadow); }
.cx-msp-option { display: block; width: 100%; text-align: left; font-size: var(--fs-md); cursor: pointer;
    padding: .35rem .6rem; border: 0; border-bottom: 1px solid var(--cx-grey-tint); background: transparent;
    color: var(--cx-ink); }
.cx-msp-option:last-child { border-bottom: 0; }
.cx-msp-option:hover, .cx-msp-option-active { background: var(--cx-primary-tint); color: var(--cx-primary-dark); }
.cx-msp-none { padding: .5rem .6rem; font-size: var(--fs-sm); }

/* ── Notification bell ─────────────────────────────────── */
.cx-notification-bell { position: relative; }
.cx-notification-trigger {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--cx-border);
    background: var(--cx-surface);
    color: var(--cx-ink);
    border-radius: 999px;
    width: 34px;
    height: 34px;
    cursor: pointer;
}
.cx-notification-trigger::-webkit-details-marker { display: none; }
.cx-notification-trigger::marker { content: ""; }
.cx-notification-trigger:hover { border-color: var(--cx-primary); }
.cx-notification-icon { font-size: var(--fs-base); }
.cx-notification-live {
    position: absolute;
    right: 2px;
    bottom: 2px;
    width: 8px;
    height: 8px;
    border-radius: 999px;
    border: 1px solid var(--cx-white);
}
.cx-notification-live.connected { background: var(--cx-green-solid); }
.cx-notification-live.disconnected { background: var(--cx-accent); }
.cx-notification-badge {
    position: absolute;
    top: -5px;
    right: -6px;
    min-width: 18px;
    height: 18px;
    border-radius: 999px;
    background: var(--cx-red);
    color: var(--cx-white);
    font-size: var(--fs-3xs);
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 .3rem;
}
.cx-notification-panel {
    position: absolute;
    top: calc(100% + .4rem);
    right: 0;
    width: min(420px, 92vw);
    max-height: 70vh;
    overflow: hidden;
    background: var(--cx-surface);
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-md);
    box-shadow: var(--cx-shadow-md);
    z-index: 40;
    display: flex;
    flex-direction: column;
}
.cx-notification-bell:not([open]) .cx-notification-panel { display: none; }
.cx-notification-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid var(--cx-border);
    padding: .6rem .75rem;
}
.cx-notification-empty {
    padding: 1rem;
    color: var(--cx-ink-muted);
}
.cx-notification-list {
    overflow: auto;
    display: flex;
    flex-direction: column;
}
.cx-notification-item {
    border: none;
    border-bottom: 1px solid var(--cx-border);
    background: var(--cx-surface);
    text-align: left;
    padding: .6rem .75rem;
    cursor: pointer;
}
.cx-notification-item:hover { background: var(--cx-page); }
.cx-notification-item.unread { background: var(--cx-primary-tint); }
.cx-notification-item-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
}
.cx-notification-type { font-size: var(--fs-2xs); color: var(--cx-ink-muted); text-transform: uppercase; font-weight: 600; }
.cx-notification-time { font-size: var(--fs-2xs); color: var(--cx-ink-muted); }
.cx-notification-ticket { font-weight: 600; margin-top: .2rem; color: var(--cx-ink); }
.cx-notification-text { margin-top: .15rem; color: var(--cx-ink-muted); font-size: var(--fs-sm); }
.cx-notification-pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .55rem .75rem;
    border-top: 1px solid var(--cx-border);
}

/* Portal notification bell (reuses cx-notification-* component classes). */
.pd-topbar .cx-notification-bell { margin-left: 2px; }
.pd-topbar .cx-notification-trigger {
    border-color: var(--border-strong);
    background: var(--surface);
    color: var(--ink-2);
    width: 36px;
    height: 36px;
}
.pd-topbar .cx-notification-trigger:hover {
    border-color: var(--teal);
    background: var(--teal-tint-2);
}
.pd-topbar .cx-notification-live { border-color: var(--surface); }
.pd-topbar .cx-notification-panel {
    right: -8px;
    border-color: var(--border);
    box-shadow: var(--shadow-lg);
}
.pd-topbar .cx-notification-item.unread { background: var(--teal-tint-2); }

/* Knowledge article rich-text (Quill) editor + rendered body. */
.cx-kb-quill .ql-container { min-height: 220px; font-size: var(--fs-base); }
.cx-kb-quill .ql-editor { min-height: 220px; }
.cx-kb-body { line-height: 1.6; }
.cx-kb-body h2, .cx-kb-body h3 { margin: 1.2em 0 0.4em; }
.cx-kb-body ul, .cx-kb-body ol { margin: 0.4em 0 0.4em 1.4em; }
.cx-kb-body p { margin: 0.6em 0; }
/* These two referenced --surface/--border, which only exist inside .pd-app, so in
   the agent app they resolved to nothing and the code block rendered unstyled. */
.cx-kb-body pre { background: var(--cx-grey-tint); padding: 0.75em; border-radius: var(--cx-radius-sm); overflow-x: auto; }
.cx-kb-body blockquote { border-left: 3px solid var(--cx-border-strong); margin: 0.6em 0; padding-left: 0.9em; color: var(--cx-ink-muted); }

/* Portal knowledge base list (browse). Article body/chips reuse the cx-kb-* styles. */
.pd-kb-list { list-style: none; margin: 0; padding: 0; }
.pd-kb-item { padding: 0.85rem 1rem; border-bottom: 1px solid var(--border); cursor: pointer; }
.pd-kb-item:last-child { border-bottom: none; }
.pd-kb-item:hover { background: rgba(0, 0, 0, 0.03); }
.pd-kb-title { font-weight: 600; }
.pd-kb-summary { color: var(--cx-ink-muted); font-size: var(--fs-md); margin-top: 0.2rem; }

/* Dashboard Knowledge card: the header search action, the row it reveals, and the route on to
   the full results. The rail is narrow, so the action is icon-only in the header. */
.pd-kb-search { display: flex; gap: 8px; padding: 12px 12px 0; }
.pd-kb-search-only { padding-bottom: 12px; }
.pd-kb-dashboard-results { border-top: 1px solid var(--border); margin-top: 12px; }
.pd-kb-search .pd-search { min-width: 0; }
.pd-kb-search .pd-btn { padding: 10px 14px; flex: none; }
/* Dashboard search hits. Separate from .pd-kb-item (the full knowledge-base page, where the whole
   row is the target) because here only the title opens the article. */
.pd-kb-hits { list-style: none; margin: 0; padding: 0; }
.pd-kb-hit { padding: 13px 20px; border-bottom: 1px solid var(--border); }
.pd-kb-hit:last-child { border-bottom: none; }
.pd-kb-hit-head { display: flex; align-items: flex-start; gap: 10px; }
.pd-kb-hit-title { flex: 1; min-width: 0; font: inherit; font-size: 14.5px; font-weight: 600; text-align: left; color: var(--teal); background: none; border: none; padding: 0; cursor: pointer; }
.pd-kb-hit-title:hover { color: var(--teal-deep); text-decoration: underline; }
.pd-kb-hit-title:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; border-radius: 4px; }
.pd-kb-match { flex: none; font-size: 12px; font-weight: 600; color: var(--teal-darker); background: var(--teal-tint); border-radius: 999px; padding: 3px 9px; white-space: nowrap; }
.pd-kb-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.pd-kb-chip { font-size: 12px; font-weight: 600; color: var(--ink-2); background: var(--surface-2); border: 1px solid var(--border-strong); border-radius: 999px; padding: 2px 9px; }
.pd-kb-chip-state { color: var(--teal-darker); background: var(--teal-tint-2); border-color: var(--teal); }
/* Portal article page. Held to a readable measure rather than the full card width — long-form
   help text at 1500px is unreadable, which is what made the old page feel unfinished. */
.pd-article { padding: 26px 32px 34px; max-width: 820px; }
.pd-article-title { font-size: 25px; font-weight: 600; letter-spacing: -.02em; line-height: 1.25; }
.pd-article-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 10px; font-size: 12.5px; color: var(--ink-3); }
.pd-article-lead { margin-top: 16px; font-size: 15.5px; line-height: 1.6; color: var(--ink-2); }
.pd-article-chips { margin-top: 14px; }
.pd-article-body { margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--border); font-size: 14.5px; line-height: 1.7; color: var(--ink); }
.pd-article-body h1, .pd-article-body h2, .pd-article-body h3, .pd-article-body h4 { font-weight: 600; line-height: 1.3; margin: 1.5em 0 .5em; }
.pd-article-body h1 { font-size: 19px; }
.pd-article-body h2 { font-size: 17px; }
.pd-article-body h3, .pd-article-body h4 { font-size: 15px; }
.pd-article-body p { margin: .75em 0; }
.pd-article-body ul, .pd-article-body ol { margin: .75em 0 .75em 1.4em; }
.pd-article-body li { margin: .3em 0; }
.pd-article-body a { color: var(--teal); font-weight: 600; }
.pd-article-body strong { font-weight: 600; }
.pd-article-body img { max-width: 100%; height: auto; border-radius: 10px; }
.pd-article-body pre { background: var(--surface-2); border: 1px solid var(--border); padding: 12px 14px; border-radius: 10px; overflow-x: auto; font-size: 13px; }
.pd-article-body code { background: var(--surface-2); border-radius: 5px; padding: 1px 5px; font-size: 13px; }
.pd-article-body pre code { background: none; padding: 0; }
.pd-article-body blockquote { border-left: 3px solid var(--teal); margin: .9em 0; padding: 2px 0 2px 14px; color: var(--ink-2); }
.pd-article-body table { width: 100%; border-collapse: collapse; margin: .9em 0; display: block; overflow-x: auto; }
.pd-article-body th, .pd-article-body td { border: 1px solid var(--border); padding: 7px 10px; text-align: left; }
.pd-article-body th { background: var(--surface-2); font-weight: 600; }
.pd-article-body hr { border: none; border-top: 1px solid var(--border); margin: 1.4em 0; }

.pd-kb-foot { padding: 12px 20px; border-top: 1px solid var(--border); }
.pd-kb-foot a { font-size: 13px; color: var(--teal); font-weight: 600; display: inline-flex; align-items: center; gap: 4px; }
.pd-kb-foot svg { width: 15px; height: 15px; }

/* ============================================================================
   Design system components (Phase 7)
   Styles for Components/Shared/Ui/*. Everything here references the tokens at
   the top of this file — if a value is not expressible as a token, the token
   set is missing a step and should gain one rather than being bypassed.
   ============================================================================ */

/* ---- Card ---- */
.cx-card-head { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.cx-card-title {
    margin: 0; font-size: var(--fs-2xs); font-weight: 600; text-transform: uppercase;
    letter-spacing: .05em; color: var(--cx-ink-muted); line-height: var(--lh-tight);
}
.cx-card-head-actions { margin-left: auto; display: flex; align-items: center; gap: var(--sp-1); }
/* Header actions sit beside the title instead of at the far right, for a tag that qualifies the
   heading rather than acting on the card. */
.cx-card-head-inline .cx-card-head-actions { margin-left: 0; }
.cx-card-flush { padding: 0; }
.cx-card-flush .cx-card-head { padding: var(--sp-3) var(--sp-4) 0; margin-bottom: var(--sp-2); }

/* ---- Button icon ---- */
.cx-btn-icon { display: inline-flex; align-items: center; line-height: 1; }

/* ---- Field hint / invalid ---- */
.cx-field-hint { font-size: var(--fs-xs); color: var(--cx-ink-muted); }
/* Child accounts tab: the picker sits above the table, at form width rather than full width. */
.cx-child-account-link { max-width: 28rem; margin: 0 0 var(--sp-4); }

.cx-input-invalid, .cx-input-invalid:focus { border-color: var(--cx-red); }
.cx-input-invalid:focus { box-shadow: 0 0 0 3px var(--cx-red-tint); }

/* ---- Search input ---- */
.cx-searchbox {
    display: inline-flex; align-items: center; gap: var(--sp-2);
    padding: var(--sp-2) var(--sp-3);
    border: 1px solid var(--cx-border-strong); border-radius: var(--cx-radius-md);
    background: var(--cx-surface); max-width: 320px; width: 100%;
}
.cx-searchbox:focus-within { border-color: var(--cx-primary); box-shadow: 0 0 0 3px var(--cx-primary-tint); }
.cx-search-icon { color: var(--cx-ink-muted); flex: none; line-height: 1; }
.cx-search-field {
    flex: 1 1 auto; min-width: 0;
    font: inherit; color: var(--cx-ink); background: none; border: none; outline: none;
}
.cx-search-field::placeholder { color: var(--cx-ink-muted); }
/* The browser's own clear widget would sit next to ours. */
.cx-search-field::-webkit-search-cancel-button { display: none; }
.cx-search-clear {
    flex: none; border: none; background: none; cursor: pointer;
    color: var(--cx-ink-muted); font-size: var(--fs-lg); line-height: 1; padding: 0 var(--sp-1);
}
.cx-search-clear:hover { color: var(--cx-ink); }
.cx-search-clear:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: 2px; border-radius: var(--cx-radius-sm); }

/* ---- Tabs ---- */
.cx-tabstrip {
    display: flex; align-items: stretch; gap: var(--sp-1);
    border-bottom: 1px solid var(--cx-border);
    padding: 0 var(--sp-4);
    background: var(--cx-surface);
    overflow-x: auto;
}

.cx-tab-btn {
    display: inline-flex; align-items: center; gap: var(--sp-2);
    padding: var(--sp-3) var(--sp-3);
    font: inherit; font-size: var(--fs-md); font-weight: 600;
    color: var(--cx-ink-muted); white-space: nowrap; cursor: pointer;
    background: none; border: none; border-bottom: 2px solid transparent;
}
.cx-tab-btn:hover { color: var(--cx-ink); }
.cx-tab-btn.active { color: var(--cx-primary-dark); border-bottom-color: var(--cx-primary); }
.cx-tab-btn:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: -2px; }
.cx-tab-count {
    font-size: var(--fs-3xs); font-weight: 600;
    background: var(--cx-grey-tint); color: var(--cx-ink-muted);
    border-radius: 999px; padding: 0 var(--sp-2);
}
.cx-tab-btn.active .cx-tab-count { background: var(--cx-primary-tint); color: var(--cx-primary-dark); }
/* The panel is focusable so keyboard users land in the content after the strip;
   it should not draw a permanent ring for mouse users. */
[role="tabpanel"]:focus { outline: none; }
[role="tabpanel"]:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: -2px; }

/* ---- Ticket Details tab ----
   The classification/contract/assignment form that used to be a 14-field stack
   in a 300px rail. Two columns at a normal reading width, with explicit Apply /
   Cancel: unlike the rest of the app this is staged-then-committed, because
   several of these fields re-derive the contract line and the SLA clock, and a
   half-finished set of changes must not be applied one field at a time. */
.cx-details { padding: var(--sp-5); }
.cx-details-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3) var(--sp-5); }
.cx-details-grid .cx-field { margin-bottom: 0; }
.cx-details-section {
    grid-column: 1 / -1;
    margin: var(--sp-4) 0 0; padding-top: var(--sp-4);
    border-top: 1px solid var(--cx-border);
    font-size: var(--fs-2xs); font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
    color: var(--cx-ink);
}
.cx-details-section:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.cx-details-wide { grid-column: 1 / -1; }
.cx-details-static { font-size: var(--fs-md); font-weight: 600; padding: var(--sp-2) 0; display: flex; align-items: center; gap: var(--sp-2); }
.cx-details-derived { font-weight: 400; color: var(--cx-ink-muted); font-size: var(--fs-xs); }
.cx-details-actions {
    display: flex; align-items: center; gap: var(--sp-2);
    margin-top: var(--sp-5); padding-top: var(--sp-4);
    border-top: 1px solid var(--cx-border);
}

/* The Apply/Cancel bar renders at both ends of the tab. The top one aligns right and
   carries no rule — it reads as the panel's own controls rather than as a section
   divider. The bottom one keeps its rule, closing the form. */
.cx-details > .cx-details-actions:first-child {
    justify-content: flex-end;
    margin-top: 0; padding-top: 0; padding-bottom: 0;
    border-top: none;
}
.cx-details > .cx-details-actions:first-child .cx-details-hint { margin-left: 0; margin-right: auto; }

/* ---- Ticket summary (title + description), the head of the Details tab ---- */
.cx-summary-edit { display: flex; flex-direction: column; gap: var(--sp-3); margin: var(--sp-4) 0 var(--sp-5); }
.cx-summary-title { font-size: var(--fs-lg); font-weight: 600; }
/* Descriptions arrive at whatever length email-in produces, so the box scrolls
   instead of pushing the rest of the form off the page. */
.cx-summary-description {
    min-height: 7rem; max-height: 22rem; overflow-y: auto; resize: vertical;
    line-height: var(--lh-normal);
}

/* A recorded, non-editable note (the applied temporary solution). */
.cx-applied-note {
    background: var(--cx-grey-tint); border: 1px solid var(--cx-border);
    border-left: 3px solid var(--cx-green);
    border-radius: var(--cx-radius-md); padding: var(--sp-3);
}
.cx-applied-body { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.cx-applied-meta { margin: var(--sp-2) 0 0; font-size: var(--fs-xs); color: var(--cx-ink-muted); }

/* A Details block continuing below the main form — no double top padding. */
.cx-details-continued { padding-top: 0; }
.cx-details-actions .cx-details-hint { margin-left: auto; font-size: var(--fs-xs); color: var(--cx-ink-muted); }

@media (max-width: 760px) { .cx-details-grid { grid-template-columns: 1fr; } }

/* Inline notice inside the Details form (contract-line hold, assignee not in group). */
.cx-inline-warn, .cx-inline-error {
    grid-column: 1 / -1;
    display: flex; align-items: flex-start; gap: var(--sp-2);
    border-radius: var(--cx-radius-sm); padding: var(--sp-2) var(--sp-3);
    font-size: var(--fs-sm); font-weight: 600;
}
.cx-inline-warn { background: var(--cx-amber-tint); border: 1px solid var(--cx-amber-solid); border-left: 3px solid var(--cx-amber); color: var(--cx-amber); }
.cx-inline-error { background: var(--cx-red-tint); border: 1px solid var(--cx-red); border-left: 3px solid var(--cx-red); color: var(--cx-red); }
/* Knowledge and Settings still emit the older class name; it is the same notice.
   Folded into cx-inline-error when those screens are swept. */
.cx-edit-error {
    display: block; border-radius: var(--cx-radius-sm); padding: var(--sp-2) var(--sp-3);
    margin-bottom: var(--sp-2); font-size: var(--fs-sm); font-weight: 600;
    background: var(--cx-red-tint); border: 1px solid var(--cx-red); border-left: 3px solid var(--cx-red); color: var(--cx-red);
}

/* ---- Workspace panel (the tabbed surface holding conversation/details/…) ---- */
.cx-ws-panel {
    background: var(--cx-surface);
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-lg);
    box-shadow: var(--cx-shadow-sm);
    /* Clip sideways only (#3894): overflow: hidden also cut off any picker menu opening downwards out
       of a tab. clip, unlike hidden, leaves the other axis visible. */
    overflow-x: clip;
    overflow-y: visible;
}
.cx-ws-panel .cx-tabstrip { border-radius: var(--cx-radius-lg) var(--cx-radius-lg) 0 0; }

/* ---- Secondary workspace tabs (Attachments, Tasks, Linked items, Relationships) ----
   These grew their own inline-styled layouts, hand-rolled tables and raw hex status
   colours. They now share the Details tab's padding, heading scale and controls, so
   moving between tabs no longer feels like moving between products. */
.cx-tabpane { padding: var(--sp-5); }
.cx-tabpane > .cx-details-section:first-child { margin-top: 0; padding-top: 0; border-top: none; }

/* One row of fields plus its action, wrapping on narrow screens. The action aligns
   to the bottom of the row so it sits on the controls' baseline, not their labels'. */
.cx-tab-form {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-3);
    margin-bottom: var(--sp-4);
}
.cx-tab-form .cx-field { margin-bottom: 0; min-width: 12rem; }
.cx-tab-form .cx-field-grow { flex: 1 1 14rem; }
/* A task description runs to several lines, so it takes a row of its own. */
.cx-tab-form .cx-task-desc-field { flex: 1 0 100%; }
.cx-task-desc-field textarea { resize: vertical; }
.cx-task-desc { font-size: .85em; white-space: pre-wrap; }
.cx-tab-form-stacked { flex-direction: column; align-items: stretch; max-width: 44rem; }
.cx-tab-form-stacked .cx-tab-form { margin-bottom: 0; }

.cx-tab-note { color: var(--cx-ink-muted); margin: 0 0 var(--sp-4); }

/* Tables inside a tab sit flush against the pane rather than in their own card. */
/* The corners are rounded on the corner cells, not by clipping the table: overflow: hidden cut off
   any picker menu opened in a row (#3894), and border-radius has no effect on a collapsed-border
   table without it. */
.cx-table.cx-table-tab { margin-bottom: var(--sp-4); border: 1px solid var(--cx-border); border-radius: var(--cx-radius-md);
    overflow: visible; border-collapse: separate; border-spacing: 0; }
.cx-table-tab thead tr:first-child > :first-child { border-top-left-radius: var(--cx-radius-md); }
.cx-table-tab thead tr:first-child > :last-child { border-top-right-radius: var(--cx-radius-md); }
.cx-table-tab tbody tr:last-child > :first-child { border-bottom-left-radius: var(--cx-radius-md); }
.cx-table-tab tbody tr:last-child > :last-child { border-bottom-right-radius: var(--cx-radius-md); }
.cx-overdue { color: var(--cx-critical); font-weight: 600; }

/* ---- Sidebar panel content (knowledge suggestions, AI summary) ----
   These lived in bare cx-side-block divs with no surface of their own, so a long AI
   briefing ran into the page with nothing containing it. They are Cards now; this is
   only what the content inside them needs. */
.cx-panel-empty { color: var(--cx-ink-muted); font-size: var(--fs-sm); margin: 0 0 var(--sp-3); }
.cx-ai-regenerate { margin-top: var(--sp-3); }
.cx-kb-create-from { margin-top: var(--sp-3); width: 100%; }
/* Each suggestion is a card in its own right, so it needs room on every side. The earlier rule
   set horizontal padding to 0, which left the Attach action pressed against the border. */
.cx-kb-suggest {
    padding: var(--sp-3);
    margin-bottom: var(--sp-2);
    border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-md);
    background: var(--cx-surface);
}
.cx-kb-suggest:last-of-type { margin-bottom: 0; }

/* Suggested First Response (Conversation tab, between the composer and the timeline). */
.cx-first-response-card { margin: var(--sp-3) 0; }
.cx-first-response-generating { display: flex; align-items: center; gap: var(--sp-2); }
.cx-inline-spinner {
    display: inline-block; width: 1em; height: 1em; border-radius: 50%;
    border: 2px solid var(--cx-border); border-top-color: var(--cx-ai);
    animation: cx-spin .7s linear infinite;
}
@keyframes cx-spin { to { transform: rotate(360deg); } }
.cx-first-response {
    margin: 0 0 var(--sp-2); padding: var(--sp-2) var(--sp-3);
    border-left: 3px solid var(--cx-ai); background: var(--cx-ai-tint);
    font-size: var(--fs-md); line-height: var(--lh-normal); color: var(--cx-ink);
}
.cx-first-response-note { font-size: var(--fs-xs); color: var(--cx-ink-muted); margin: 0 0 var(--sp-2); }
.cx-first-response-blocked { color: var(--cx-amber); }
.cx-first-response-sources { margin-bottom: var(--sp-2); }
.cx-first-response-source { display: flex; align-items: baseline; gap: var(--sp-2); font-size: var(--fs-sm); margin-bottom: var(--sp-1); }
.cx-first-response-marker {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    width: 1.25rem; height: 1.25rem; border-radius: 999px;
    background: var(--cx-ai-tint); color: var(--cx-ai); font-size: var(--fs-2xs); font-weight: 600;
}
.cx-first-response-source-link { font-weight: 600; color: var(--cx-primary-dark); }
.cx-first-response-source-link.is-plain { color: var(--cx-ink); cursor: default; }
.cx-first-response-source-detail { color: var(--cx-ink-muted); font-size: var(--fs-xs); }
.cx-first-response-actions { display: flex; justify-content: flex-end; margin-top: var(--sp-2); }
.cx-ai-subhead { font-size: var(--fs-sm); font-weight: 600; color: var(--cx-ink); margin: var(--sp-3) 0 var(--sp-1); }
.cx-ai-subhead:first-child { margin-top: 0; }

/* A checkbox sitting inline with its label, in a toolbar rather than a form column. */
.cx-inline-check { display: flex; align-items: center; gap: var(--sp-1); margin-left: var(--sp-2); font-size: var(--fs-sm); }
.cx-modal-sm { width: min(440px, 92vw); }

/* "Add another row" action under an editable table. */
.cx-row-add { margin-top: var(--sp-2); }

/* The account-move action, sitting under the reporter's details in the same card. */
.cx-reporter-actions { margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px solid var(--cx-border); }

/* The explanatory note under a page heading — was an inline-styled cx-card on
   every report page. */
.cx-page-note {
    background: var(--cx-surface); border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-lg); box-shadow: var(--cx-shadow-sm);
    padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-3);
    color: var(--cx-ink-muted); font-size: var(--fs-sm);
}
.cx-page-header-spaced { margin-top: var(--sp-5); }

/* ── Portal AI assistant hero (AI-H.1, #2816) ────────────────────────────────
   The customer portal's front door: a centred panel at the top of the dashboard
   that greets the contact, takes the first question, and expands in place as the
   conversation runs. Uses the portal's own tokens, so it stays in step with the
   rest of the shell. */
.pd-hero {
    background: linear-gradient(180deg, var(--teal-tint-2) 0%, var(--surface) 62%);
    border: 1px solid var(--border);
    border-radius: 20px;
    box-shadow: var(--shadow-sm);
    padding: 34px 28px 26px;
    margin-bottom: 24px;
    text-align: center;
}

.pd-hero-badge {
    display: inline-flex; align-items: center; gap: 7px;
    background: var(--teal-tint); color: var(--teal-deep);
    font-size: 12.5px; font-weight: 600;
    padding: 5px 13px; border-radius: 999px;
}
.pd-hero-badge .dot {
    width: 7px; height: 7px; border-radius: 50%; background: var(--teal);
}

.pd-hero-title {
    font-family: var(--cx-font-display);
    font-size: 34px; font-weight: 400; letter-spacing: var(--tracking-display);
    line-height: var(--lh-display); color: var(--ink); margin: 16px 0 0;
}
.pd-hero-title .accent { color: var(--cx-primary); }

.pd-hero-sub {
    color: var(--ink-2); font-size: 15px; line-height: 1.5;
    margin: 10px auto 0; max-width: 62ch;
}

/* The ask box — the panel's focal point. */
.pd-hero-ask {
    display: flex; align-items: center; gap: 10px;
    background: var(--surface); border: 1px solid var(--border-strong);
    border-radius: 15px; box-shadow: var(--shadow-sm);
    padding: 8px 8px 8px 16px;
    margin: 22px auto 0; max-width: 720px;
}
.pd-hero-ask:focus-within {
    border-color: var(--teal); box-shadow: 0 0 0 4px var(--teal-glow);
}
.pd-hero-spark { display: grid; place-items: center; color: var(--teal); flex: none; }
.pd-hero-spark svg { width: 19px; height: 19px; }

.pd-hero-input {
    flex: 1; border: 0; outline: 0; background: transparent;
    font: inherit; font-size: 15px; color: var(--ink); padding: 10px 0;
}
.pd-hero-input::placeholder { color: var(--ink-3); }

.pd-hero-send {
    flex: none; width: 42px; height: 42px; border: 0; border-radius: 12px;
    background: var(--teal); color: var(--cx-white); cursor: pointer; display: grid; place-items: center;
}
.pd-hero-send svg { width: 18px; height: 18px; }
.pd-hero-send:hover:not(:disabled) { background: var(--teal-deep); }
.pd-hero-send:disabled { opacity: .45; cursor: not-allowed; }

.pd-hero-foot { color: var(--ink-3); font-size: 13.5px; margin: 16px 0 0; }
.pd-hero-foot a { color: var(--teal-deep); font-weight: 600; }

/* The conversation, once it starts — left-aligned inside the centred panel so the
   text is readable rather than ragged. */
.pd-hero-log {
    max-width: 720px; margin: 24px auto 0; text-align: left;
    display: flex; flex-direction: column; gap: 10px;
    max-height: 420px; overflow-y: auto;
}
.pd-hero-msg {
    max-width: 85%; padding: 10px 14px; border-radius: 13px;
    font-size: 14.5px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere;
}
.pd-hero-msg.me { align-self: flex-end; background: var(--teal); color: var(--cx-white); }
.pd-hero-msg.bot { align-self: flex-start; background: var(--bg); color: var(--ink); }
.pd-hero-msg.degraded { background: var(--cx-accent-tint); color: var(--cx-amber); }

/* The confirmation card: every field that will be written, before anything is. */
.pd-hero-proposal {
    border: 1px solid var(--border-strong); border-radius: 14px;
    background: var(--surface); padding: 16px 18px;
}
.pd-hero-proposal h2 { font-size: 15px; font-weight: 600; margin: 0 0 12px; color: var(--ink); }
.pd-hero-proposal dl {
    margin: 0 0 16px; display: grid; grid-template-columns: auto 1fr;
    gap: 5px 16px; font-size: 13.5px;
}
.pd-hero-proposal dt { color: var(--ink-3); }
.pd-hero-proposal dd { margin: 0; color: var(--ink); overflow-wrap: anywhere; }
/* ADO #3944: the contact confirms which system the ticket concerns on the card itself. */
.pd-hero-proposal-system { margin: 12px 0 4px; }
.pd-hero-proposal-label { color: var(--ink-3); margin: 0 0 6px; }
.pd-hero-proposal-actions { display: flex; gap: 10px; }

.pd-hero-accept, .pd-hero-decline {
    font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
    padding: 9px 16px; border-radius: 10px;
}
.pd-hero-accept { background: var(--teal); color: var(--cx-white); border: 1px solid var(--teal); }
.pd-hero-accept:hover:not(:disabled) { background: var(--teal-deep); }
.pd-hero-decline { background: var(--surface); color: var(--ink-2); border: 1px solid var(--border-strong); }
.pd-hero-decline:hover:not(:disabled) { background: var(--bg); }
.pd-hero-accept:disabled, .pd-hero-decline:disabled { opacity: .5; cursor: not-allowed; }

@media (max-width: 720px) {
    .pd-hero { padding: 26px 18px 22px; }
    .pd-hero-title { font-size: 24px; }
}


/* The link to a ticket the assistant has just raised (#2818). Rendered as a control rather than
   written into the reply text, which is model-generated and HTML-encoded. */
.pd-hero-ticket-link {
    display: inline-block; margin-top: 8px; font-weight: 600;
    color: var(--teal-deep); text-decoration: underline;
}
.pd-hero-msg.bot .pd-hero-ticket-link:hover { color: var(--teal); }

/* ======================= Single-page ticket view ======================== */
/* The header now carries the Escalate action beside state, Reply and Take ownership. */
.cx-ws-id-row-actions { flex-wrap: wrap; justify-content: flex-end; }

/* Description text; its height limit is set with the single-page layout below. */
.cx-description { margin: 0; font-size: var(--fs-sm); line-height: var(--lh-normal); white-space: pre-wrap; overflow-wrap: anywhere; }
.cx-ai-toggle { margin-top: var(--sp-2); font-size: var(--fs-xs); }

/* AI summary, collapsed: the issue and the next step. */
.cx-ai-next { margin: 0 0 .6rem; font-size: var(--fs-xs); color: var(--cx-ink-muted); }
.cx-ai-next strong { color: var(--cx-ink); }

/* The conversation card holds the composer and the timeline, which carry their own spacing. */
.cx-conversation-card .cx-timeline { padding-left: 0; padding-right: 0; padding-bottom: 0; }

/* Watchers: overlapping initials, with the one-click watch toggle beside them. */
.cx-watchers-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); flex-wrap: wrap; }
.cx-watcher-avatars { display: flex; }
.cx-watcher-avatar {
    width: 26px; height: 26px; border-radius: 50%; flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: var(--fs-3xs); font-weight: 600;
    background: var(--cx-primary-pale); color: var(--cx-primary-dark);
    border: 2px solid var(--cx-surface);
}
.cx-watcher-avatar + .cx-watcher-avatar { margin-left: -7px; }
.cx-watcher-avatar-more { background: var(--cx-grey-tint); color: var(--cx-ink-muted); }

/* Collapsible side sections (Ui/Expander). No overflow on the body: an overflow clip would cut
   off the pickers' dropdown menus, as it did on .cx-table-tab and .cx-ws-panel (#3754). */
.cx-expanders { display: flex; flex-direction: column; gap: var(--sp-2); }
.cx-expander { background: var(--cx-surface); border: 1px solid var(--cx-border); border-radius: var(--cx-radius-lg); box-shadow: var(--cx-shadow-sm); }
.cx-expander-head {
    display: flex; align-items: center; gap: var(--sp-2); width: 100%;
    padding: var(--sp-2) var(--sp-3); border: 0; background: transparent; cursor: pointer;
    font: inherit; font-size: var(--fs-sm); font-weight: 600; color: var(--cx-ink); text-align: left;
    border-radius: var(--cx-radius-lg);
}
.cx-expander-head:hover { background: var(--cx-grey-tint); }
.cx-expander-head:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: -2px; }
.cx-expander-chevron { color: var(--cx-ink-muted); width: 1em; flex: none; }
.cx-expander-title { flex: 1; }
.cx-expander-count { font-size: var(--fs-2xs); font-weight: 600; color: var(--cx-ink-muted); background: var(--cx-grey-tint); border-radius: 999px; padding: 0 .45rem; }
.cx-expander-open > .cx-expander-head { border-bottom: 1px solid var(--cx-border); border-radius: var(--cx-radius-lg) var(--cx-radius-lg) 0 0; }
.cx-expander-body > .cx-tabpane, .cx-expander-body > .cx-details { padding: var(--sp-3); }
.cx-expander-body .cx-timeline { padding: 0 var(--sp-3) var(--sp-3); }
/* The side column is narrower than the old tab body: the form's fields go to one column when
   two would not fit, and the task/link forms wrap. */
.cx-expander-body .cx-details-grid { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.cx-expander-body .cx-tab-form .cx-field { min-width: 0; flex: 1 1 12rem; }
.cx-expander-body .cx-table { font-size: var(--fs-xs); }

@media (max-width: 980px) {
    .cx-ws-id-row { flex-wrap: wrap; }
}

/* ================= Calm ticket view (users: "cluttered, hard to read") ================= */
/* Modelled on the Jira issue view users compared it with: one surface for the ticket, sentence-case
   headings at reading size, no boxes inside boxes, and colour kept for what needs attention. */

/* Header: a readable sans-serif title and one short row of tags. */
.cx-ws-title-row h1 { font-family: var(--cx-font); font-weight: 600; font-size: var(--fs-2xl); line-height: 1.3; letter-spacing: 0; }
.cx-ws-title-row { margin: var(--sp-2) 0 0; }
.cx-ws-tags { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-top: var(--sp-2); }
/* Neutral state pill; priority keeps its colour only when it is Critical. */
.cx-ws-header .cx-state { background: var(--cx-grey-tint); color: var(--cx-ink); border-color: var(--cx-border); font-size: var(--fs-xs); }
.cx-ws-header .cx-prio-high, .cx-ws-header .cx-prio-moderate, .cx-ws-header .cx-prio-low { background: var(--cx-grey-tint); color: var(--cx-ink); }

/* Headings: sentence case at reading size instead of small uppercase eyebrows. */
.cx-ws .cx-card-title { font-family: var(--cx-font); font-size: var(--fs-base); font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--cx-ink); }
.cx-ws .cx-card-head { margin-bottom: var(--sp-3); }
.cx-ws .cx-badge-ai { background: var(--cx-grey-tint); color: var(--cx-ink-muted); border-color: var(--cx-border); }
.cx-count { display: inline-flex; align-items: center; justify-content: center; min-width: 1.5rem; padding: 0 .4rem; border-radius: var(--cx-radius-sm); background: var(--cx-grey-tint); color: var(--cx-ink-muted); font-size: var(--fs-xs); font-weight: 600; }
.cx-attachments-card .cx-attachment-upload { margin-left: auto; }
.cx-attachments-card .cx-card-head-actions { flex: 1; }

/* Main column: one white surface, sections divided by a rule rather than boxed. */
.cx-ws-centre { gap: 0; background: var(--cx-surface); border: 1px solid var(--cx-border); border-radius: var(--cx-radius-lg); padding: 0 var(--sp-5); }
.cx-ws-centre > .cx-card { background: transparent; border: 0; border-radius: 0; box-shadow: none; padding: var(--sp-5) 0; }
.cx-ws-centre > .cx-card + .cx-card { border-top: 1px solid var(--cx-border); }
.cx-ws-centre > .cx-inline-error { margin-top: var(--sp-4); }
.cx-description, .cx-ai-summary { font-size: var(--fs-sm); line-height: 1.55; }
.cx-ai-next { font-size: var(--fs-sm); }

/* Attachments: a plain table. */
.cx-attachment-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); table-layout: fixed; }
.cx-attachment-table th { text-align: left; font-size: var(--fs-xs); font-weight: 600; color: var(--cx-ink-muted); padding: 0 var(--sp-2) var(--sp-2) 0; border-bottom: 1px solid var(--cx-border); }
.cx-attachment-table th:nth-child(2) { width: 8.5rem; }
.cx-attachment-table th:nth-child(3) { width: 5.5rem; }
.cx-attachment-table th:nth-child(4) { width: 2rem; }
.cx-attachment-table td { padding: var(--sp-2) var(--sp-2) var(--sp-2) 0; border-bottom: 1px solid var(--cx-border); vertical-align: middle; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cx-attachment-icon { color: var(--cx-ink-muted); margin-right: var(--sp-2); }
.cx-attachment-name { color: var(--cx-primary-dark); }
.cx-attachment-size { color: var(--cx-ink-muted); font-variant-numeric: tabular-nums; }
.cx-attachment-actions { text-align: right; }
.cx-attachment-delete { border: 0; background: transparent; color: var(--cx-ink-muted); cursor: pointer; font-size: var(--fs-lg); line-height: 1; padding: 0 .2rem; border-radius: var(--cx-radius-sm); }
.cx-attachment-delete:hover { color: var(--cx-red); background: var(--cx-grey-tint); }
.cx-attachment-upload { cursor: pointer; }

/* Conversation: messages as plain rows; only internal notes keep a tint, because that difference
   matters. No card borders, no coloured side bars. */
.cx-conversation-card .cx-msg-card { background: transparent; border: 0; padding: 0; border-radius: 0; }
.cx-conversation-card .cx-msg-internal { background: var(--cx-amber-tint); padding: var(--sp-2) var(--sp-3); border-radius: var(--cx-radius-md); }
.cx-conversation-card .cx-msg-body { font-size: var(--fs-sm); line-height: 1.55; }
.cx-conversation-card .cx-msg-when { font-family: var(--cx-font); font-size: var(--fs-xs); }
.cx-conversation-card .cx-tl-dot { background: var(--cx-grey-tint); border-color: var(--cx-border); color: var(--cx-ink-muted); font-size: var(--fs-2xs); }
.cx-conversation-card .cx-tl-item { padding: var(--sp-3) 0; }

/* Side column: flat cards. */
.cx-ws-side .cx-card, .cx-ws-side .cx-expander { box-shadow: none; }

/* Key details: label / value rows. */
.cx-key-details .cx-kv-row { justify-content: flex-start; align-items: baseline; border-bottom: 0; padding: var(--sp-1) 0; }
.cx-key-details .cx-kv-row dt { flex: 0 0 6.5rem; }
.cx-key-details .cx-kv-row dd { flex: 1; min-width: 0; text-align: left; font-weight: 400; overflow-wrap: anywhere; }
.cx-kv-sub { font-size: var(--fs-xs); color: var(--cx-ink-muted); }
.cx-watchers-inline { border-top: 1px solid var(--cx-border); margin-top: var(--sp-3); padding-top: var(--sp-3); }
.cx-watchers-inline-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-2); }
.cx-watchers-label { font-size: var(--fs-sm); color: var(--cx-ink-muted); }

/* SLA: one line per target with a small tag. */
.cx-sla-list { list-style: none; margin: 0; padding: 0; }
.cx-sla-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); padding: var(--sp-1) 0; font-size: var(--fs-sm); }
.cx-sla-row:has(.cx-sla-row-head) { display: block; }
.cx-sla-row-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.cx-sla-elapsed { font-size: var(--fs-xs); color: var(--cx-ink-muted); font-variant-numeric: tabular-nums; }
.cx-sla-row-label { color: var(--cx-ink); }
.cx-sla-row-value { color: var(--cx-ink-muted); font-variant-numeric: tabular-nums; }
.cx-sla-tag { font-size: var(--fs-2xs); font-weight: 600; padding: .1rem .5rem; border-radius: 999px; background: var(--cx-grey-tint); color: var(--cx-ink-muted); white-space: nowrap; }
.cx-sla-row.cx-sla-ok .cx-sla-tag { background: var(--cx-green-tint); color: var(--cx-green); }
.cx-sla-row.cx-sla-risk .cx-sla-tag { background: var(--cx-amber-tint); color: var(--cx-amber); }
.cx-sla-row.cx-sla-breach .cx-sla-tag { background: var(--cx-red-tint); color: var(--cx-red); }
.cx-sla-row.cx-sla-paused .cx-sla-tag { background: var(--cx-blue-tint); color: var(--cx-blue); }

/* Related: knowledge and similar cases in one block. */
.cx-related-part + .cx-related-part { border-top: 1px solid var(--cx-border); margin-top: var(--sp-3); padding-top: var(--sp-3); }
.cx-related-head-row { display: flex; align-items: center; justify-content: space-between; }
.cx-related-head { margin: 0 0 var(--sp-2); font-size: var(--fs-sm); font-weight: 600; color: var(--cx-ink); }
.cx-related .cx-kb-create-from { display: inline-block; width: auto; margin-top: var(--sp-3); font-size: var(--fs-xs); background: none; padding: 0; }
.cx-ws-header .cx-chip.cx-prio-critical { background: var(--cx-red-tint); color: var(--cx-red); }

/* React-only pieces of the ticket view. */
.cx-escalation-card .cx-tab-form-stacked { margin-top: var(--sp-3); }
.cx-watchers-manage .cx-kb-chips { list-style: none; margin: 0 0 var(--sp-2); padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.cx-ws-side .cx-expander-body > .cx-timeline { padding: var(--sp-3); }
.cx-ws-side .cx-expander-body > div:not([class]) { padding: var(--sp-3); }

/* Details: read-only in the side column, edited in a full-screen dialog. */
.cx-details-summary { padding: var(--sp-3); }
.cx-details-summary-actions { display: flex; justify-content: flex-end; margin-bottom: var(--sp-1); }
.cx-details-summary-head { margin: var(--sp-3) 0 var(--sp-1); font-size: var(--fs-sm); font-weight: 600; color: var(--cx-ink); }
.cx-details-summary-head:first-of-type { margin-top: 0; }
.cx-details-summary .cx-kv-row { justify-content: flex-start; align-items: baseline; border-bottom: 0; padding: var(--sp-1) 0; }
.cx-details-summary .cx-kv-row dt { flex: 0 0 8rem; }
.cx-details-summary .cx-kv-row dd { flex: 1; min-width: 0; text-align: left; font-weight: 400; white-space: pre-wrap; overflow-wrap: anywhere; }

/* The Details tab is the form itself; it reads as two columns in the side panel, one when narrow. */
.cx-details-rest { margin-top: var(--sp-4); }
.cx-details-rest .cx-side-head { margin-bottom: var(--sp-2); }

/* SLA box: the policy the targets come from, and the reason a ticket has no SLA clocks. */
.cx-sla-policy { border-bottom: 1px solid var(--cx-border); padding-bottom: var(--sp-2); margin-bottom: var(--sp-1); }
.cx-sla-policy .cx-sla-row-value { color: var(--cx-ink); font-weight: 600; }
.cx-sla-absent { display: block; padding: var(--sp-2); margin: var(--sp-1) 0; border-radius: var(--cx-radius-md); background: var(--cx-amber-tint); color: var(--cx-ink); font-size: var(--fs-sm); }

/* Description at the top of the main column: read-only, and a long body scrolls in its own box. */
.cx-description { max-height: 16rem; overflow-y: auto; padding-right: var(--sp-2); }
.cx-description:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: 2px; }

/* AI summary as a collapsible box in the side column. */
.cx-ai-summary-box .cx-expander-body { padding: var(--sp-3); }
.cx-ai-embedded-badge { margin-bottom: var(--sp-2); }
.cx-ai-embedded .cx-ai-summary, .cx-ai-embedded .cx-ai-next { font-size: var(--fs-sm); }

/* Related as a collapsible box in the side column; "Attach to ticket" ends each suggestion's tag row. */
.cx-related-box .cx-expander-body { padding: var(--sp-3); }
.cx-related-toolbar { display: flex; align-items: center; justify-content: flex-end; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.cx-kb-attach { margin-left: auto; }

/* ============================ Side panel as tabs ============================ */
/* UAT feedback: less scrolling. One card holds the tab strip and the selected tab; the cards that
   used to stack in the column become flat sections inside it. */
.cx-side-panel { background: var(--cx-surface); border: 1px solid var(--cx-border); border-radius: var(--cx-radius-lg); overflow: visible; }
.cx-side-tabs.cx-tabstrip { display: flex; flex-wrap: wrap; gap: 0 var(--sp-1); padding: 0 var(--sp-3); border-bottom: 1px solid var(--cx-border); }
.cx-side-tabs .cx-tab-btn { padding: var(--sp-3) var(--sp-2); font-size: var(--fs-sm); white-space: nowrap; }
.cx-side-tabpanel { padding: var(--sp-4); outline: none; }
.cx-side-tabpanel > .cx-card, .cx-side-tabpanel > .cx-side-section { background: transparent; border: 0; border-radius: 0; box-shadow: none; padding: 0; }
.cx-side-tabpanel > * + * { margin-top: var(--sp-4); padding-top: var(--sp-4) !important; border-top: 1px solid var(--cx-border) !important; }
.cx-side-tabpanel .cx-card-head { margin-bottom: var(--sp-2); }
.cx-side-head { margin: 0 0 var(--sp-2); font-family: var(--cx-font); font-size: var(--fs-base); font-weight: 600; color: var(--cx-ink); }
.cx-side-head-row { display: flex; align-items: center; justify-content: space-between; }
.cx-side-tabpanel > h3.cx-side-head { border-top: 0 !important; padding-top: 0 !important; }
.cx-side-tabpanel > h3.cx-side-head ~ h3.cx-side-head { margin-top: var(--sp-5); }
.cx-side-tabpanel > .cx-tabpane, .cx-side-tabpanel > .cx-details-summary, .cx-side-tabpanel > .cx-timeline { padding: 0; border-top: 0 !important; margin-top: 0; }
.cx-side-tabpanel > .cx-tabpane { padding-top: 0 !important; }

/* SLA tab: each target as a small card with due time and progress. */
.cx-side-tabpanel .cx-sla-list { display: flex; flex-direction: column; gap: var(--sp-2); }
.cx-side-tabpanel .cx-sla-row { border: 1px solid var(--cx-border); border-radius: var(--cx-radius-md); padding: var(--sp-2) var(--sp-3); }
.cx-side-tabpanel .cx-sla-row.cx-sla-none:last-child { border: 0; padding: var(--sp-1) 0; }
.cx-sla-row-detail { margin-left: auto; margin-right: var(--sp-2); font-size: var(--fs-xs); color: var(--cx-ink-muted); }
.cx-sla-row-meta { display: flex; justify-content: space-between; gap: var(--sp-2); flex-wrap: wrap; margin-top: 2px; }
.cx-sla-due { font-size: var(--fs-xs); color: var(--cx-ink-muted); white-space: nowrap; }
.cx-sla-progress { height: 4px; margin-top: var(--sp-2); border-radius: 999px; background: var(--cx-grey-tint); overflow: hidden; }
.cx-sla-progress > span { display: block; height: 100%; background: var(--cx-green-solid); }
.cx-sla-risk .cx-sla-progress > span { background: var(--cx-amber-solid); }
.cx-sla-breach .cx-sla-progress > span { background: var(--cx-critical); }
.cx-coverage .cx-kv-row { justify-content: flex-start; align-items: baseline; border-bottom: 0; padding: var(--sp-1) 0; }
.cx-coverage .cx-kv-row dt { flex: 0 0 8rem; }
.cx-coverage .cx-kv-row dd { flex: 1; min-width: 0; text-align: left; font-weight: 400; }

/* Where the ticket is integrated: header badge and the inline send form. */
.cx-badge-integrated { background: var(--cx-surface); border: 1px solid var(--cx-border); color: var(--cx-ink); text-decoration: none; }
a.cx-badge-integrated:hover { text-decoration: underline; }
.cx-task-push { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.cx-task-push .cx-select { width: auto; max-width: 14rem; }

/* Work-item integration editor: the ordered work item type list (#3499). */
.cx-ordered-list { list-style: none; margin: 0 0 .5rem; padding: 0; display: flex; flex-direction: column; gap: .25rem; }
.cx-ordered-list li { display: flex; align-items: center; gap: .4rem; }
.cx-ordered-list li > span { flex: 1; min-width: 0; }
.cx-check-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr)); gap: .25rem .75rem; }

/* ---- Ticket views (ADO #3978, #3934) ----
   The view menu over the agent list (after Azure DevOps' work item views), the favourites menu
   beside it (after ServiceNow's favourites), the column picker and the share panel. */

.cx-view-head { flex-wrap: wrap; }
.cx-view-head .cx-eyebrow { margin: 0; }
.cx-view-menu { position: relative; }
.cx-view-menu-trigger {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .3rem .6rem; border: 1px solid transparent; border-radius: var(--cx-radius);
    background: var(--cx-bg); color: var(--cx-ink); font: inherit; font-weight: 600; font-size: var(--fs-base);
    cursor: pointer;
}
.cx-view-menu-trigger:hover, .cx-view-menu-trigger[aria-expanded="true"] { border-color: var(--cx-border-strong); background: var(--cx-primary-tint); }
.cx-view-menu-backdrop { position: fixed; inset: 0; z-index: 40; }
.cx-view-menu-panel {
    position: absolute; left: 0; top: calc(100% + .3rem); z-index: 50;
    width: 320px; max-height: min(70vh, 560px); overflow-y: auto; padding: var(--sp-1) 0;
    background: var(--cx-surface); border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-md); box-shadow: var(--cx-shadow-pop);
}
.cx-view-menu-section + .cx-view-menu-section { border-top: 1px solid var(--cx-border); margin-top: var(--sp-1); padding-top: var(--sp-1); }
.cx-view-menu-heading {
    padding: .35rem 1rem .2rem; font-size: var(--fs-3xs); font-weight: 600; letter-spacing: .04em;
    text-transform: uppercase; color: var(--cx-ink-muted);
}
.cx-view-menu-row { display: flex; align-items: center; }
.cx-view-menu-item {
    flex: 1; min-width: 0; display: flex; align-items: center; gap: .4rem;
    padding: .45rem .5rem .45rem 1rem; border: none; background: none; text-align: left;
    font: inherit; font-size: var(--fs-sm); color: var(--cx-ink); cursor: pointer;
}
.cx-view-menu-item:hover, .cx-view-menu-item:focus-visible { background: var(--cx-bg); outline: none; }
.cx-view-menu-item.active { background: var(--cx-primary-tint); font-weight: 600; }
.cx-view-menu-badge {
    margin-left: auto; padding: .05rem .4rem; border-radius: 999px;
    background: var(--cx-bg); color: var(--cx-ink-muted); font-size: var(--fs-3xs); white-space: nowrap;
}
.cx-view-menu-pinned { display: inline-flex; color: var(--cx-primary); }
.cx-star {
    flex: none; width: 2rem; height: 2rem; margin-right: .3rem; border: none; border-radius: var(--cx-radius);
    background: none; color: var(--cx-ink-muted); font-size: var(--fs-md); cursor: pointer;
}
.cx-star:hover, .cx-star:focus-visible { background: var(--cx-bg); color: var(--cx-primary); }
.cx-star.active { color: var(--cx-amber-solid); }
/* The pin beside the star: which view the list opens on. */
.cx-pin {
    flex: none; display: inline-flex; align-items: center; justify-content: center; width: 2rem; height: 2rem;
    border: none; border-radius: var(--cx-radius); background: none; color: var(--cx-ink-muted); cursor: pointer;
}
.cx-pin:hover, .cx-pin:focus-visible { background: var(--cx-bg); color: var(--cx-primary); }
.cx-pin.active { color: var(--cx-primary); }

.cx-view-modified {
    padding: .1rem .5rem; border-radius: 999px; background: var(--cx-amber-tint); color: var(--cx-amber);
    font-size: var(--fs-2xs); font-weight: 600;
}
.cx-view-owner { font-size: var(--fs-2xs); }

.cx-icon-btn {
    display: inline-flex; align-items: center; justify-content: center; width: 1.75rem; height: 1.75rem;
    border: none; border-radius: var(--cx-radius); background: none; color: var(--cx-ink-muted); cursor: pointer;
}
.cx-icon-btn:hover:not(:disabled), .cx-icon-btn:focus-visible { background: var(--cx-bg); color: var(--cx-ink); }
.cx-icon-btn:disabled { opacity: .35; cursor: default; }
.cx-sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.cx-drag-handle { color: var(--cx-ink-muted); cursor: grab; }

.cx-favourites-trigger { font-size: var(--fs-sm); font-weight: 500; }
.cx-favourites-trigger .cx-view-menu-badge { margin-left: 0; }
.cx-favourites-panel { width: 300px; padding: var(--sp-2); }
.cx-favourites-filter { width: 100%; margin-bottom: var(--sp-2); }
.cx-favourites-empty { font-size: var(--fs-2xs); padding: .2rem .3rem; margin: 0; }
.cx-favourites-list { list-style: none; margin: 0; padding: 0; }
.cx-favourites-list li { display: flex; align-items: center; border-radius: var(--cx-radius); }
.cx-favourites-list li.dragging { opacity: .5; }
.cx-favourites-list li:hover { background: var(--cx-bg); }
.cx-favourites-item {
    flex: 1; min-width: 0; padding: .45rem .5rem; border: none; background: none; text-align: left;
    font: inherit; font-size: var(--fs-sm); color: var(--cx-ink); cursor: pointer;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cx-favourites-item.active { font-weight: 600; color: var(--cx-primary); }
.cx-favourites-tools { display: inline-flex; opacity: 0; }
.cx-favourites-list li:hover .cx-favourites-tools, .cx-favourites-list li:focus-within .cx-favourites-tools { opacity: 1; }

.cx-column-picker, .cx-share-dialog {
    margin: var(--sp-2) var(--sp-4); padding: var(--sp-3);
    border: 1px solid var(--cx-border); border-radius: var(--cx-radius-md); background: var(--cx-page);
    display: flex; flex-direction: column; gap: var(--sp-2); max-width: 520px;
}
.cx-column-picker-head { display: flex; align-items: center; justify-content: space-between; }
.cx-column-picker-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.cx-column-picker-list li {
    display: flex; align-items: center; gap: .35rem; padding: .2rem .4rem;
    background: var(--cx-surface); border: 1px solid var(--cx-border); border-radius: var(--cx-radius);
}
.cx-column-picker-list li.dragging { opacity: .5; }
.cx-column-picker-label { flex: 1; font-size: var(--fs-sm); }
.cx-column-picker-foot { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; }
.cx-share-options { border: none; margin: 0; padding: 0; display: flex; gap: var(--sp-4); flex-wrap: wrap; font-size: var(--fs-sm); }
.cx-share-options label { display: flex; align-items: center; gap: .3rem; }
.cx-share-actions { display: flex; gap: var(--sp-2); }

/* ADO #3925 / #3978: the ticket list scrolls sideways once a view shows more columns than fit, and
   its filter row holds multi-choice and searched pickers, whose lists are placed against the window. */
.cx-ticket-list-wrap { overflow-x: auto; }
.cx-field.cx-field-bare { margin: 0; gap: 0; }
.cx-multi-filter-trigger { text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; min-width: 6rem; }
.cx-multi-filter-panel {
    z-index: 50; padding: var(--sp-2); display: flex; flex-direction: column; gap: 2px; align-items: flex-start;
    background: var(--cx-surface); border: 1px solid var(--cx-border); border-radius: var(--cx-radius-md); box-shadow: var(--cx-shadow-pop);
}
.cx-multi-filter-option { display: flex; align-items: center; gap: .45rem; width: 100%; padding: .3rem .4rem; border-radius: var(--cx-radius); font-size: var(--fs-sm); cursor: pointer; }
.cx-multi-filter-option:hover { background: var(--cx-bg); }

/* ADO #4001: what the last export did - how many tickets, or that it stopped at the row limit. */
.cx-export-note {
    display: flex; align-items: center; gap: var(--sp-2); margin: 0; padding: var(--sp-2) var(--sp-4);
    border-bottom: 1px solid var(--cx-border); background: var(--cx-primary-tint); color: var(--cx-primary-dark); font-size: var(--fs-sm);
}

/* #3639: a picker list that floats over its pane, placed by useAnchoredPlacement, instead of opening
   inside the form. */
.cx-msp-menu.cx-msp-menu-floating { margin: 0; box-shadow: var(--cx-shadow-pop); }

/* ADO #3933: filter conditions - one row per condition (field, operator, value), like an ADO query. */
.cx-conditions { display: flex; flex-direction: column; gap: var(--sp-2); }
.cx-conditions-empty { margin: 0; font-size: var(--fs-sm); }
.cx-condition-row {
    display: grid; grid-template-columns: 76px minmax(150px, 200px) minmax(130px, 170px) minmax(0, 1fr) auto;
    align-items: center; gap: var(--sp-2);
}
.cx-condition-row > .cx-select, .cx-condition-row .cx-input { min-width: 0; width: 100%; }
.cx-condition-value { min-width: 0; }
/* "Where" / and / or before each row; a row joined by "or" is indented against the one before it, as one group. */
.cx-condition-join { font-size: var(--fs-sm); }
span.cx-condition-join { padding-left: .5rem; }
.cx-condition-or { padding-left: var(--sp-4); border-left: 2px solid var(--cx-primary-tint); }
.cx-condition-value .cx-filter-dates { display: flex; align-items: center; gap: var(--sp-2); }
.cx-condition-fixed { font-size: var(--fs-sm); }
.cx-conditions-actions { display: flex; gap: var(--sp-2); }
@media (max-width: 720px) {
    .cx-condition-row { grid-template-columns: 64px 1fr 1fr auto; }
    .cx-condition-value { grid-column: 2 / -1; grid-row: 2; }
}

/* ADO #3966: right-click a cell to show only, or filter out, its value. */
.cx-cell-menu {
    z-index: 50; min-width: 200px; max-width: 340px; padding: var(--sp-1) 0;
    background: var(--cx-surface); border: 1px solid var(--cx-border);
    border-radius: var(--cx-radius-md); box-shadow: var(--cx-shadow-pop);
}
.cx-cell-menu .cx-view-menu-item { display: block; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ADO #4012: a list grouped by a field - the toolbar choice, and a heading row per group with its count. */
.cx-group-by { display: inline-flex; align-items: center; gap: .35rem; font-size: var(--fs-sm); color: var(--cx-ink-muted); }
.cx-group-by > span { white-space: nowrap; }
.cx-group-by .cx-select { width: auto; min-width: 9rem; padding-top: .25rem; padding-bottom: .25rem; font-size: var(--fs-sm); }
/* The ticket list's actions wrap rather than push the page sideways on a narrow screen. */
.cx-view-head .cx-panel-actions { flex-wrap: wrap; justify-content: flex-end; }
.cx-table .cx-group-row th {
    padding: 0; background: var(--cx-page); text-transform: none; letter-spacing: 0;
    font-size: var(--fs-sm); color: var(--cx-ink); border-bottom: 1px solid var(--cx-border);
}
.cx-table tbody tr.cx-group-row:hover { background: var(--cx-page); }
.cx-group-toggle {
    display: flex; align-items: center; gap: .5rem; width: 100%; padding: var(--sp-2) var(--sp-3);
    border: none; background: none; font: inherit; font-weight: 600; color: inherit; text-align: left; cursor: pointer;
}
.cx-group-toggle:hover { background: var(--cx-primary-tint); }
.cx-group-toggle:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: -2px; }
.cx-group-caret { width: 1em; color: var(--cx-ink-muted); }
.cx-group-count {
    padding: .05rem .5rem; border-radius: 999px; background: var(--cx-surface); border: 1px solid var(--cx-border);
    color: var(--cx-ink-muted); font-size: var(--fs-2xs); font-weight: 600;
}
.cx-table tbody.cx-group tr:last-child td { border-bottom: 1px solid var(--cx-border); }
.cx-table tbody.cx-group:last-of-type tr:last-child td { border-bottom: none; }
.cx-table .cx-group-more td { background: var(--cx-surface); }
.cx-group-note { font-size: var(--fs-sm); }

/* An overlay opened by a toolbar button (the column chooser), floating over the list rather than pushing it down. */
.cx-popover-anchor { position: relative; }
.cx-popover-backdrop { position: fixed; inset: 0; z-index: 40; }
.cx-column-picker.cx-popover {
    position: absolute; right: 0; top: calc(100% + .3rem); z-index: 50; margin: 0;
    width: 360px; max-width: calc(100vw - 32px); max-height: min(70vh, 560px); overflow-y: auto;
    background: var(--cx-surface); box-shadow: var(--cx-shadow-pop); text-align: left;
}
.cx-popover:focus { outline: none; }

/* ADO #3903: the SLA list on the SLA tab - one column per timer, one row per figure. */
.cx-sla-details { margin-top: var(--sp-3); }
.cx-sla-details-title { margin: 0 0 var(--sp-2); font-size: var(--fs-sm); font-weight: 600; }
.cx-sla-details-wrap { overflow-x: auto; }
.cx-sla-details-table th, .cx-sla-details-table td { font-size: var(--fs-sm); padding: var(--sp-1) var(--sp-2); white-space: nowrap; }
.cx-sla-details-table thead th { white-space: normal; min-width: 8rem; text-transform: none; letter-spacing: 0; color: var(--cx-ink); }
.cx-sla-details-table tbody th { text-transform: none; letter-spacing: 0; font-weight: 500; color: var(--cx-ink-muted); }
.cx-sla-details-breached { color: var(--cx-red); font-weight: 600; }

/* SDM account dashboard (reports/account-dashboard). */
.cx-account-dashboard .cx-report-controls { display: flex; flex-direction: column; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.cx-report-accounts { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-2); }
.cx-report-account-search { min-width: 16rem; flex: 0 1 22rem; }
.cx-report-options { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4); font-size: var(--fs-sm); }
.cx-report-options .cx-select { width: auto; }
.cx-report-status { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); font-size: var(--fs-sm); color: var(--cx-ink-muted); margin-bottom: var(--sp-1); }
.cx-report-scope { font-size: var(--fs-sm); margin: 0 0 var(--sp-4); overflow-wrap: anywhere; }
.cx-report-empty { color: var(--cx-ink-muted); font-size: var(--fs-sm); margin: var(--sp-2) 0; }
.cx-report-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 32rem), 1fr)); gap: var(--sp-4); margin-bottom: var(--sp-4); }
.cx-report-card { min-width: 0; }
.cx-account-dashboard > .cx-report-card { margin-bottom: var(--sp-4); }
.cx-report-card-title { font-family: var(--cx-font); font-size: var(--fs-base); font-weight: 600; margin: 0 0 var(--sp-1); color: var(--cx-ink); }
.cx-report-card-description { font-size: var(--fs-sm); margin: 0 0 var(--sp-3); }
.cx-chart { width: 100%; min-width: 0; }
.cx-chart .recharts-cartesian-axis-tick-value, .cx-chart .recharts-legend-item-text { fill: var(--cx-ink-muted); font-size: 12px; }
.cx-chart .recharts-cartesian-grid line { stroke: var(--cx-border); }
.cx-report-figures { margin-top: var(--sp-2); font-size: var(--fs-sm); }
.cx-report-figures summary { cursor: pointer; color: var(--cx-primary-dark); }
.cx-kpi-table th[scope="row"], .cx-pivot-table th[scope="row"] { text-align: left; font-weight: 500; white-space: nowrap; }
.cx-kpi-table td { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.cx-kpi-met { background: var(--cx-green-tint); color: var(--cx-green); }
.cx-kpi-missed { background: var(--cx-red-tint); color: var(--cx-red); font-weight: 600; }
.cx-kpi-none { color: var(--cx-ink-muted); }
.cx-kpi-overall th, .cx-kpi-overall td { font-weight: 600; }
.cx-pivot-table td { text-align: right; font-variant-numeric: tabular-nums; }
.cx-pivot-group th, .cx-pivot-group td, .cx-pivot-total th, .cx-pivot-total td { font-weight: 600; background: var(--cx-primary-tint); }
.cx-pivot-indent { padding-left: var(--sp-5) !important; }
.cx-report-accounts .cx-chip { text-transform: none; letter-spacing: 0; }
.cx-kpi-table th, .cx-kpi-table td, .cx-pivot-table th, .cx-pivot-table td { padding-left: .45rem; padding-right: .45rem; }
.cx-kpi-table thead th, .cx-pivot-table thead th { text-align: right; }
.cx-kpi-table thead th:first-child, .cx-pivot-table thead th:first-child { text-align: left; }

/* Accounts section: favourite star, and the account page's title line. */
.cx-star-btn { border: 0; background: transparent; cursor: pointer; font-size: 1.15rem; line-height: 1; padding: .1rem .25rem; color: var(--cx-ink-muted); border-radius: 4px; }
.cx-star-btn.active { color: var(--cx-accent); }
.cx-star-btn:hover { background: var(--cx-primary-tint); }
.cx-account-title { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.cx-account-meta { margin: 0 0 var(--sp-3); overflow-wrap: anywhere; }
.cx-view-menu-end .cx-view-menu-panel { left: auto; right: 0; }

/* The customer's own ticket number on their ticket (#3924). */
.pd-external-code { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.pd-external-code .pd-input { flex: 1 1 14rem; min-width: 0; }
.pd-external-code [role="status"] { color: var(--cx-green, #1E4A4D); font-size: 13px; }

/* ADO #4032: a cancelled task stays on the ticket as a record, visibly out of play. */
.cx-task-cancelled td { color: var(--ink-3); }
.cx-task-cancelled td:first-child { text-decoration: line-through; }

/* ADO #4039: the watch list beside the additional assignees on a ticket. */
.cx-watch-rule { margin: 4px 0 0; font-size: 12px; }
.cx-watch-email { display: flex; align-items: flex-end; gap: 8px; margin-top: 8px; }
.pd-watchlist { margin-top: 16px; }
.pd-watchlist ul { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 0; padding: 0; }
.pd-watchlist-add { display: flex; align-items: flex-end; gap: 8px; margin-top: 8px; flex-wrap: wrap; }

/* ADO #4039: the portal's watch list - who else at the customer follows a ticket. */
.pd-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; background: var(--teal-tint-2); color: var(--ink-2); font-size: 13px; }
.pd-chip-x { border: 0; background: none; cursor: pointer; color: var(--ink-3); font-size: 15px; line-height: 1; padding: 0; }
.pd-chip-x:hover { color: var(--ink); }
.pd-muted { color: var(--ink-3); }
.pd-card-sub { margin: 2px 0 0; color: var(--ink-3); font-size: 13px; }
/* ADO #4019: files chosen on a New ticket form (agent dialog and portal page). */
.tx-new-attachments label.cx-btn,
.tx-new-attachments label.pd-btn { cursor: pointer; display: inline-flex; font-weight: 600; color: var(--cx-ink); }
.tx-new-attachments label[aria-disabled="true"] { opacity: 0.6; cursor: default; }
.tx-new-attachments-list { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.tx-new-attachment { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.tx-new-attachment-name { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.tx-new-attachment-size, .tx-new-attachment-status { color: var(--cx-ink-muted); white-space: nowrap; }
.tx-new-attachment-failed .tx-new-attachment-status { color: var(--cx-red); white-space: normal; }

/* Customer coverage check: the account page's Coverage tab and the contract page's summary. */
.cx-coverage { display: flex; flex-direction: column; gap: var(--sp-4); }
.cx-coverage-headline { margin: 0; }
.cx-coverage-filter { max-width: 28rem; }
.cx-coverage-table td { vertical-align: top; }
.cx-coverage-cell { display: flex; flex-direction: column; gap: var(--sp-2); }
.cx-coverage-outcome .cx-field-hint { margin-top: 2px; }
.cx-coverage-row-problem td:first-child { box-shadow: inset 3px 0 0 var(--cx-red); }
.cx-coverage-list { margin: var(--sp-2) 0 0; padding-left: var(--sp-5); }
.cx-coverage-list li + li { margin-top: var(--sp-1); }
.cx-coverage-summary p { margin: 0; }

/* The account page's tab content starts clear of the tab strip. A list tab's own header already
   carries a top margin, so it gives that up rather than doubling the gap. */
.cx-account-tab-body { padding-top: var(--sp-4); }
.cx-account-tab-body > .cx-related-header:first-child { margin-top: 0; }

/* The account page's Contracts tab: each contract a card with its lines beneath. */
.cx-contract-card { margin-bottom: var(--sp-4); }
.cx-contract-card-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.cx-contract-card-head h3 { margin: 0; font-size: var(--fs-base); }
.cx-contract-card-actions { margin-left: auto; display: flex; gap: var(--sp-2); }

/* ADO #3936: the rich-text editor for descriptions and comments, and rich text as it is shown. */
.cx-rte { border: 1px solid var(--cx-border-strong); border-radius: var(--cx-radius-sm); background: var(--cx-surface); overflow: hidden; }
.cx-rte:focus-within { border-color: var(--cx-primary); box-shadow: 0 0 0 3px var(--cx-primary-tint); }
.cx-rte[aria-disabled="true"] { opacity: .7; }
.cx-rte-toolbar { display: flex; flex-wrap: wrap; gap: 2px; padding: 4px 6px; border-bottom: 1px solid var(--cx-border); background: var(--cx-page); }
.cx-rte-btn { min-width: 28px; height: 26px; padding: 0 6px; border: 1px solid transparent; border-radius: 6px; background: none; color: var(--cx-ink); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; }
.cx-rte-btn:hover:not(:disabled) { background: var(--cx-primary-tint); }
.cx-rte-btn-active { background: var(--cx-primary-tint); border-color: var(--cx-border-strong); color: var(--cx-primary); }
.cx-rte-btn:focus-visible { outline: 2px solid var(--cx-primary); outline-offset: 1px; }
.cx-rte-content { min-height: 84px; max-height: 420px; overflow-y: auto; padding: .55rem .75rem; font-size: var(--fs-md); line-height: 1.55; outline: none; overflow-wrap: anywhere; }
.cx-rte-content p.is-editor-empty:first-child::before { content: attr(data-placeholder); float: left; height: 0; color: var(--cx-muted, #8A90A6); pointer-events: none; }
.cx-rte-tall .cx-rte-content { min-height: 160px; }
.cx-rte-content > :first-child, .cx-rich > :first-child { margin-top: 0; }
.cx-rte-content > :last-child, .cx-rich > :last-child { margin-bottom: 0; }
.cx-rte-content p, .cx-rich p { margin: 0 0 .5em; }
.cx-rte-content ul, .cx-rte-content ol, .cx-rich ul, .cx-rich ol { margin: 0 0 .5em; padding-left: 1.4em; }
.cx-rte-content li p, .cx-rich li p { margin: 0; }
.cx-rte-content blockquote, .cx-rich blockquote { margin: 0 0 .5em; padding-left: .8em; border-left: 3px solid var(--cx-border-strong); color: var(--cx-ink-2, inherit); }
.cx-rte-content code, .cx-rich code { padding: 0 .25em; border-radius: 4px; background: var(--cx-page); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .92em; }
.cx-rte-content pre, .cx-rich pre { margin: 0 0 .5em; padding: .5em .7em; border-radius: 6px; background: var(--cx-page); overflow-x: auto; white-space: pre; }
.cx-rte-content pre code, .cx-rich pre code { padding: 0; background: none; }
.cx-rte-content a, .cx-rich a { color: var(--cx-primary); text-decoration: underline; }
.cx-rte-content h2, .cx-rte-content h3, .cx-rte-content h4, .cx-rich h2, .cx-rich h3, .cx-rich h4 { margin: .6em 0 .35em; font-size: 1.05em; }
.cx-rich hr, .cx-rte-content hr { border: 0; border-top: 1px solid var(--cx-border); margin: .75em 0; }
/* Rich text is laid out by its own elements, not by the line breaks the plain-text bodies keep. */
.cx-rich.cx-msg-body, .cx-rich.pd-card-body, .cx-rich.pd-timeline-text, .cx-rich { white-space: normal; }

/* ADO #4054: the header's general ticket search and its results page. */
.cx-global-search { position: relative; }
.cx-global-search-input { width: 16rem; padding-top: .35rem; padding-bottom: .35rem; font-size: var(--fs-sm); }
.cx-global-search-menu { position: absolute; right: 0; top: calc(100% + 4px); z-index: 60; width: 26rem; max-width: 90vw; background: var(--cx-surface); border: 1px solid var(--cx-border); border-radius: var(--cx-radius-md); box-shadow: 0 8px 24px rgba(20, 25, 60, .14); overflow: hidden; }
.cx-global-search-menu ul { list-style: none; margin: 0; padding: 4px 0; }
.cx-global-search-option { display: grid; grid-template-columns: auto 1fr; gap: 2px .6rem; padding: .45rem .75rem; cursor: pointer; }
.cx-global-search-option.active, .cx-global-search-option:hover { background: var(--cx-primary-tint); }
.cx-global-search-number { font-weight: 600; font-variant-numeric: tabular-nums; }
.cx-global-search-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cx-global-search-meta { grid-column: 2; font-size: var(--fs-xs, 12px); color: var(--cx-muted, #6B7280); }
.cx-global-search-empty { margin: 0; padding: .6rem .75rem; color: var(--cx-muted, #6B7280); font-size: var(--fs-sm); }
.cx-global-search-all { display: block; width: 100%; padding: .55rem .75rem; border: 0; border-top: 1px solid var(--cx-border); background: var(--cx-page); color: var(--cx-primary); font: inherit; font-size: var(--fs-sm); text-align: left; cursor: pointer; }
.cx-global-search-all:hover { background: var(--cx-primary-tint); }
.cx-search-page { display: flex; flex-direction: column; gap: 1rem; }
.cx-search-page-form { display: flex; gap: .5rem; max-width: 42rem; }
.cx-search-page-title { margin: 0; font-size: var(--fs-lg, 1.1rem); }
.cx-search-page-note { padding: 1rem; }
.cx-search-page-pager { display: flex; justify-content: flex-end; gap: .5rem; padding: .75rem 1rem; }

/* Several installed systems at once: the technology catalogue as checkboxes. */
.cx-tech-tree { border: 1px solid var(--cx-border-strong); border-radius: var(--cx-radius-sm); background: var(--cx-surface); }
.cx-tech-tree-head { display: flex; align-items: center; gap: .6rem; padding: .45rem .6rem; border-bottom: 1px solid var(--cx-border); }
.cx-tech-tree-head .cx-input { flex: 1 1 auto; }
.cx-tech-tree-list { list-style: none; margin: 0; padding: .35rem .6rem; max-height: 18rem; overflow-y: auto; }
.cx-tech-tree-list li { padding: .15rem 0; }
.cx-tech-tree-list label { display: inline-flex; align-items: center; gap: .35rem; cursor: pointer; font-weight: normal; }
