/* ══════════════════════════════════════════════════════════════════
   The analytics screens — student analytics, and the shared summary/detail results
   Lifted out of three component <style> blocks (#audit-25, slice 3)

   1,053 lines that the styling policy could not reach: a <style> renders in the body, after every
   <link>, so these outranked ui-refinement.css and isolated-fallback.css both, and editing either
   did nothing for them.

   Checked before moving: the three share NO selector with each other and NONE with any stylesheet
   that loads after this one, so neither merging them nor the position can change what renders.

   ⚠ Unlike the auth surface and the admin controls, this code is already PART tokenised — 70
   var(--yb-*) references against 64 colour literals. The literals that remain are mostly the
   deviation ramp (D1-D4) and the sparkline, which are data encodings rather than chrome; they
   deserve names of their own rather than a swap to the brand ramp. That is the same decision
   #audit-29 settled for the counselling journal and it is still open here.
   ══════════════════════════════════════════════════════════════════ */

/* ── from StudentAnalytics.razor ────────────────────────────────────────── */
/* Stretch full-width to match every other search page (.search-container).
       The old max-width:1200px + margin:0 auto centred/contained this panel,
       out of step with Staff / Reader / Student search panels. */
    .counselor-search-panel {
        padding: 1rem;
    }

    /* The search footer (toolbar · counselor toggle · actions) uses the shared
       .yb-search-footer separator; no extra custom border here. The toggle is
       the tallest item, so force every section to centre vertically — otherwise
       the shorter Search/Clear buttons drop to the row's baseline. */
    .counselor-footer {
        row-gap: 0.5rem;
        align-items: center !important;
    }

    .counselor-footer > * {
        align-self: center !important;
    }

    /* Action buttons (Search / Clear) — kept on one line and pushed to the far
       right of the footer. */
    .counselor-footer-actions {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        margin-left: auto;
    }

    .counselor-status {
        column-gap: 0.5rem;
        min-height: 32px;
    }

    /* One row, one height — the filter toolbar, the counseling toggle, the count
       readout, and the Search / Clear / Refresh buttons all share a single 36px
       control height so the footer reads as one aligned line. */
    .counselor-footer .yb-filter-toolbar,
    .counselor-footer .counselor-status,
    .counselor-footer .counselor-toggle,
    .counselor-footer .btn,
    .counselor-footer .e-btn {
        height: 36px;
        min-height: 36px;
        box-sizing: border-box;
    }

    /* Vertically centre the contents of the boxed controls. */
    .counselor-footer .counselor-status {
        align-items: center;
    }

    /* NB: display is set HERE and deliberately NOT on .counselor-toggle. The track is
       an inline-GRID; an inline-flex from this block would silently discard
       grid-template-columns and collapse the thumb to zero width. */
    .counselor-footer .btn,
    .counselor-footer .e-btn {
        padding-top: 0;
        padding-bottom: 0;
        display: inline-flex;
        align-items: center;
        line-height: 1;
    }

    /* Counselor view = an operable CONTROL, styled as a sliding switch: three equal
       thirds on a sunken track with a single coloured thumb that slides between
       them, morphing red/amber/green by position. The moving thumb gives it an
       unmistakable "switch" affordance the read-only stat labels beside it never
       share.

       It was a TWO-position switch until #321, three until the counts were folded in.
       FIVE now, and only three of them are states: Intimation Pending is a subset of
       Already Counselled, and Others merges NO-BASE with the residual so that neither
       becomes unreachable. The figures therefore do NOT sum to the item total — see
       CounselingClassification.SegmentCount. */
    /* ONE GRID, so the thumb, the hover fill and the focus ring cannot disagree.
       They used to be computed three different ways — the thumb from a calc() over
       the padded width, the hover from the flex item's own box, the ring from a
       third radius — and at most widths they landed a pixel or two apart, which is
       what made hovering a segment look misaligned against the pill that appears
       when you pick it. Now every one of them IS a grid cell. */
    .counselor-toggle {
        --counselor-seg-count: 5;
        --counselor-divider: #d3d9e0;
        --counselor-pad: 0.25rem;
        /* the track's inner corner: outer radius minus the padding, or the thumb
           pokes past the groove it sits in */
        --counselor-inner-radius: 6px;
        align-items: stretch;
        background: #eef1f4;
        border: 1px solid #e1e5ea;
        border-radius: 10px;
        box-shadow: inset 0 1px 2px rgba(16, 24, 40, 0.08);
        display: inline-grid;
        grid-template-columns: repeat(var(--counselor-seg-count), minmax(0, 1fr));
        gap: 0;
        min-height: 31px;
        padding: var(--counselor-pad);
        position: relative;
    }

    /* Hairlines on the real cell boundary rather than at 33%/66% of the track, so
       they stay put whatever the segment count is — and they retract around the
       active and hovered cells, where a line would cut into a filled pill. */
    .counselor-seg + .counselor-seg::before {
        background: var(--counselor-divider);
        bottom: 0.2rem;
        content: "";
        left: 0;
        position: absolute;
        top: 0.2rem;
        transition: opacity 0.18s ease;
        width: 1px;
    }

    .counselor-seg.is-active::before,
    .counselor-seg:hover::before,
    .counselor-seg:focus-within::before,
    .counselor-seg.is-active + .counselor-seg::before,
    .counselor-seg:hover + .counselor-seg::before,
    .counselor-seg:focus-within + .counselor-seg::before {
        opacity: 0;
    }

    /* The sliding thumb: one third of the inner width, parked under the active
       segment. Carries the fill + lift, so selection reads by position AND colour.
       translateX is a percentage of the THUMB's own width, so 100%/200% generalise. */
    /* Placed IN the grid, in cell one, rather than measured against the track: its
       width is a column by definition, so translateX(100%) lands exactly on the next
       segment and no calc() has to agree with the layout.
       Both the thumb AND every segment carry an EXPLICIT grid-column. With implicit
       placement the thumb claimed column 1 and the segments were auto-flowed into 2,
       3 and 4 — a four-column track where the thumb slid one cell short of the label
       it was meant to sit under. Two items may share a cell only if both are placed. */
    /* Column 1 is the Watch List (#420), so the resting thumb wears its fill. */
    .counselor-toggle-thumb {
        background: #b54708;
        border-radius: var(--counselor-inner-radius);
        box-shadow: 0 1px 2px rgba(16, 24, 40, 0.2), 0 1px 1px rgba(16, 24, 40, 0.12);
        grid-column: 1;
        grid-row: 1;
        opacity: 1;
        transform: translateX(0);
        transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.22s ease, opacity 0.18s ease;
        z-index: 1;
    }

    .counselor-toggle[data-active="needs_counseling"] .counselor-toggle-thumb {
        background: #b42318;
        transform: translateX(100%);
    }

    /* Fills are chosen dark enough to carry WHITE text: #5925dc is 7.4:1 and #475467
       is 7.5:1 against white, in the same band as the three above (5.2–9:1). The
       counsellor purple token (--yb-counselor #7c5cff) would have been the semantic
       match but only reaches ~3.6:1 as a fill, so the darker step is used. */
    .counselor-toggle[data-active="in_counseling"] .counselor-toggle-thumb {
        background: #5925dc;
        transform: translateX(200%);
    }

    /* Intimated is the settled one — the parent has been told — so it takes the green. */
    .counselor-toggle[data-active="intimated"] .counselor-toggle-thumb {
        background: #0f5132;
        transform: translateX(300%);
    }

    .counselor-toggle[data-active="others"] .counselor-toggle-thumb {
        background: #475467;
        transform: translateX(400%);
    }

    /* The count lives IN the segment. It is a sibling of the label rather than part
       of it, so the label can shorten at 390px while the figure keeps its own space
       and never wraps under the word it belongs to. */
    .counselor-seg-count {
        background: rgba(16, 24, 40, 0.08);
        border-radius: 5px;
        font-size: 0.7rem;
        font-variant-numeric: tabular-nums;
        font-weight: 700;
        line-height: 1;
        margin-left: 0.3rem;
        min-width: 1.15rem;
        padding: 0.15rem 0.25rem;
        text-align: center;
    }

    .counselor-seg.is-active .counselor-seg-count {
        background: rgba(255, 255, 255, 0.22);
        color: #fff;
    }

    [data-theme="dark"] .counselor-seg-count {
        background: rgba(255, 255, 255, 0.12);
    }

    .counselor-seg {
        align-items: center;
        background: transparent;
        border-radius: var(--counselor-inner-radius);
        grid-row: 1;
        color: #475467;
        cursor: pointer;
        display: inline-flex;
        font-size: 0.8rem;
        font-weight: 600;
        gap: 0.4rem;
        justify-content: center;
        line-height: 1;
        margin: 0;
        padding: 0.4rem 0.85rem;
        position: relative;
        transition: color 0.18s ease, background-color 0.18s ease;
        white-space: nowrap;
        z-index: 2;
    }

    /* The native radio is replaced by the thumb, but kept in the DOM (visually
       hidden, not removed) so it stays focusable and arrow-key navigable. */
    .counselor-seg input[type="radio"] {
        height: 1px;
        margin: 0;
        opacity: 0;
        pointer-events: none;
        position: absolute;
        width: 1px;
    }

    .counselor-seg i {
        font-size: 0.9rem;
    }

    /* The unselected segments keep a status-tinted icon, so each reads as a real,
       meaningful option even before it is picked — and so state is not carried by
       the thumb's colour alone. */
    .counselor-seg-need:not(.is-active) i {
        color: #b42318;
    }

    .counselor-seg-watch:not(.is-active) i {
        color: #b54708;
    }

    .counselor-seg-incounsel:not(.is-active) i {
        color: #5925dc;
    }

    .counselor-seg-intimated:not(.is-active) i {
        color: #0f5132;
    }

    /* A segment disabled by policy (SERV0009 enabled:false) is disabled at the
       INPUT, not by a class — the class only carries the look. */
    .counselor-seg:has(input:disabled) {
        cursor: not-allowed;
        opacity: 0.55;
    }

    /* Two labels per segment: the full one, and the short one the 3-up track needs
       on a phone. Only ever one is displayed, and the short one is aria-hidden so
       the accessible name stays the full label at every width. */
    .counselor-seg-short {
        display: none;
    }

    /* Clear hover affordance on the pickable (unselected) half: a soft fill +
       darker text says "you can click this". */
    .counselor-seg:not(.is-active):hover {
        background: rgba(16, 24, 40, 0.06);
        color: #1d2939;
    }

    /* Active half: white text + bold icon, sitting on the coloured thumb. */
    .counselor-seg.is-active {
        color: #ffffff;
    }

    .counselor-seg.is-active i {
        opacity: 1;
    }

    /* Inset rather than offset: an outward ring on a cell flush to the track's
       padding was clipped on the first and last segments, so keyboard focus looked
       different at the ends than in the middle. */
    .counselor-seg:focus-within {
        outline: 2px solid #2563eb;
        outline-offset: -2px;
    }

    /* ── The people who never reached the grid ───────────────────────────────
       NOT a segment, and it cannot become one: these rows are absent from `items`
       altogether, so there is nothing to filter to. It is a note, not a control —
       but it is shown, because a child who was never sensed is not a child who is
       fine. NO-BASE and the residual DO have somewhere to go now: the Others
       segment on the track. */
    .counselor-aside-gap {
        color: #667085;
        font-size: 0.7rem;
        font-style: italic;
        white-space: nowrap;
    }

    /* The hairline between figures. Was a spacer element between the two counts; with three read
       straight off the server's counts it becomes a border, so the markup is one loop over the
       segments and cannot fall out of step with them. */
    .counselor-count + .counselor-count {
        border-left: 1px solid #e1e5ea;
        padding-left: 0.7rem;
    }

    /* Dark theme: the light track read as a white patch. Swap it for a dark
       sunken surface and lift the contrast of text, icons, divider, and the
       stat numbers. The coloured thumb stays — it reads on dark too. */
    [data-theme="dark"] .counselor-toggle {
        --counselor-divider: #3a4860;
        background: #1e293b;
        border-color: #334155;
        box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.35);
    }

    [data-theme="dark"] .counselor-seg {
        color: #cbd5e1;
    }

    /* The ACTIVE cell sits on a saturated thumb, so it does not inherit the resting
       colour. #cbd5e1 on the red thumb (#b42318) measures 4.42:1 — under AA by a
       hair, and only in dark, which is why it survived: light mode already sets
       #fff here and the failure is invisible in every screenshot taken in light.
       White clears all five fills (6.4 / 5.2 / 9.0 / 7.4 / 7.5 : 1). */
    [data-theme="dark"] .counselor-seg.is-active {
        color: #fff;
    }

    [data-theme="dark"] .counselor-seg-need:not(.is-active) i {
        color: #f87171;
    }

    [data-theme="dark"] .counselor-seg-watch:not(.is-active) i {
        color: #fbbf24;
    }

    [data-theme="dark"] .counselor-seg-incounsel:not(.is-active) i {
        color: #b9a6ff;
    }

    [data-theme="dark"] .counselor-seg-intimated:not(.is-active) i {
        color: #4ade80;
    }

    [data-theme="dark"] .counselor-seg:not(.is-active):hover {
        background: rgba(255, 255, 255, 0.08);
        color: #f1f5f9;
    }

    [data-theme="dark"] .counselor-count + .counselor-count {
        border-left-color: #334155;
    }

    [data-theme="dark"] .counselor-aside-gap {
        color: #94a3b8;
    }

    @media (prefers-reduced-motion: reduce) {
        .counselor-toggle-thumb,
        .counselor-seg {
            transition: none;
        }
    }

    @media (max-width: 767.98px) {
        .counselor-search-panel .form-group-flex {
            align-items: flex-start;
            flex-direction: column;
            gap: 0.35rem;
        }

        .counselor-search-panel .form-label-fixed {
            min-width: 0;
        }
    }

    /* Three nowrap labels in a 36px track overflow well before a phone's width — the
       two-segment version never had to care, and there was no media query for the
       toggle at all. Below 480px the track goes full width, keeps its height off the
       footer's fixed 36px, and swaps to the short labels (Watch / Priority / Counselling / Intimated / Others).
       The full label stays the accessible name; only the visible text shortens. */
    @media (max-width: 480px) {
        .counselor-status {
            width: 100%;
        }

        /* FIVE cells, not three. Sized to their contents and allowed to scroll rather
           than compressed to fit: at 390px a full-width track gives each cell ~58px
           while the shortest legible content is ~76px, so every cell clipped and four
           of the five COUNTS were cut away entirely — the figures the control exists
           to show. The track scrolls inside its own box, which is the house rule for
           wide content; the page body still must not.

           100px is measured, not guessed: the widest cell is In Counselling (#420),
           whose short label "Counselling" needs 98px — it clipped by 4px at the old
           92px floor. Raising the floor beats shortening that label to save four
           pixels. If a longer segment is ever added, MEASURE scrollWidth against
           clientWidth per cell at 390px rather than assuming this still fits. */
        .counselor-footer .counselor-toggle {
            grid-template-columns: repeat(var(--counselor-seg-count), minmax(100px, 1fr));
            height: auto;
            max-width: 100%;
            min-height: 36px;
            overflow-x: auto;
            overscroll-behavior-x: contain;
            width: 100%;
        }

        .counselor-seg {
            gap: 0.25rem;
            padding: 0.4rem 0.3rem;
        }

        /* VISUALLY hidden, not display:none. The short label is aria-hidden, so
           removing the full one from the accessibility tree left these radios with no
           accessible name at all below 480px — the comment above this block claimed
           the opposite for as long as it has existed. */
        .counselor-seg-full {
            clip: rect(0 0 0 0);
            clip-path: inset(50%);
            height: 1px;
            overflow: hidden;
            position: absolute;
            white-space: nowrap;
            width: 1px;
        }

        .counselor-seg-short {
            display: inline;
            font-size: 0.68rem;
        }

        .counselor-seg-count {
            font-size: 0.64rem;
            margin-left: 0.2rem;
            min-width: 1rem;
            padding: 0.12rem 0.2rem;
        }
    }

/* ── from AnalyticsSummaryUnified.razor ────────────────────────────────────────── */
.summary-trend-header {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: 0.45rem;
    }

    .summary-trend-title {
        white-space: nowrap;
        color: var(--yb-text-soft);
        letter-spacing: 0.01em;
    }

    .summary-trend-title span {
        color: var(--yb-text-muted);
    }

    .summary-trend-separator {
        opacity: 0.4;
        font-weight: 400;
    }

    .summary-trend-deviation-title {
        white-space: nowrap;
        font-size: 0.7rem;
        font-weight: 700;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: var(--yb-text-soft);
    }

    .summary-trend-deviation-list {
        display: inline-flex;
        align-items: center;
        flex-wrap: nowrap;
        gap: 0.2rem;
        width: fit-content;
        max-width: 100%;
        min-width: auto;
        white-space: nowrap;
    }

    .summary-trend-chart-wrap {
        margin-top: 0.4rem;
    }

    .summary-trend-svg {
        width: 100%;
        height: 84px;
        display: block;
        overflow: visible;
    }

    /* Calm "normal range" zone — a soft band replaces the old caging frame */
    .summary-trend-svg .trend-band {
        fill: rgba(31, 157, 97, 0.10);
    }

    .summary-trend-svg .trend-band-edge {
        stroke: rgba(31, 157, 97, 0.40);
        stroke-width: 1;
        stroke-dasharray: 5 4;
    }

    .summary-trend-svg .trend-baseline {
        stroke: var(--yb-border-strong);
        stroke-width: 1;
    }

    .summary-trend-svg .trend-line {
        fill: none;
        stroke: var(--yb-danger);
        stroke-width: 2;
        stroke-linejoin: round;
        stroke-linecap: round;
    }

    /* ---- Counseling "care track": touchpoints anchored on the trend line ---- */
    .summary-trend-plot {
        position: relative;
    }

    .care-layer {
        position: absolute;
        inset: 0;
        pointer-events: none;
    }

    .care-node {
        position: absolute;
        top: 0;
        bottom: 0;
        width: 16px;
        margin: 0;
        padding: 0;
        border: 0;
        background: none;
        transform: translateX(-50%);
        cursor: pointer;
        pointer-events: auto;
        -webkit-tap-highlight-color: transparent;
    }

    .care-node:focus-visible {
        outline: none;
    }

    /* faint tether from the touchpoint down to the time axis */
    .care-node__tether {
        position: absolute;
        left: 50%;
        top: var(--care-y, 50%);
        bottom: 3px;
        width: 1px;
        transform: translateX(-50%);
        background: var(--yb-accent);
        opacity: 0.22;
        transition: opacity var(--yb-dur) var(--yb-ease);
    }

    /* the touchpoint itself — an accent node carrying a "+" (support added here) */
    .care-node__dot {
        position: absolute;
        left: 50%;
        top: var(--care-y, 50%);
        width: 11px;
        height: 11px;
        border-radius: 50%;
        background: var(--yb-accent);
        box-shadow: 0 0 0 2px var(--yb-card), var(--yb-shadow-xs);
        transform: translate(-50%, -50%);
        transition: transform var(--yb-dur) var(--yb-ease), box-shadow var(--yb-dur) var(--yb-ease);
    }

    .care-node__dot::before,
    .care-node__dot::after {
        content: "";
        position: absolute;
        left: 50%;
        top: 50%;
        background: var(--yb-card);
        border-radius: 1px;
        transform: translate(-50%, -50%);
    }

    .care-node__dot::before {
        width: 5px;
        height: 1.6px;
    }

    .care-node__dot::after {
        width: 1.6px;
        height: 5px;
    }

    .care-node:hover,
    .care-node:focus-visible {
        z-index: 6;
    }

    .care-node:hover .care-node__dot,
    .care-node:focus-visible .care-node__dot {
        transform: translate(-50%, -50%) scale(1.25);
        box-shadow: 0 0 0 2px var(--yb-card), 0 0 0 5px rgba(var(--yb-accent-rgb), 0.18);
    }

    .care-node:hover .care-node__tether,
    .care-node:focus-visible .care-node__tether {
        opacity: 0.5;
    }

    /* aggregate edge flags for out-of-window sessions */
    .care-flag {
        position: absolute;
        top: 6px;
        display: inline-flex;
        align-items: center;
        gap: 1px;
        height: 18px;
        padding: 0 6px;
        border: 0;
        border-radius: var(--yb-radius-pill);
        background: rgba(var(--yb-accent-rgb), 0.12);
        color: var(--yb-accent-text);
        font-size: 0.68rem;
        font-weight: 700;
        line-height: 1;
        cursor: pointer;
        pointer-events: auto;
        transition: background var(--yb-dur) var(--yb-ease);
    }

    .care-flag--before {
        left: 2px;
    }

    .care-flag--after {
        right: 2px;
    }

    .care-flag--before::before {
        content: "\2039";
        font-size: 0.85rem;
    }

    .care-flag--after::after {
        content: "\203A";
        font-size: 0.85rem;
    }

    .care-flag:hover,
    .care-flag:focus-visible {
        background: rgba(var(--yb-accent-rgb), 0.2);
        outline: none;
    }

    .care-flag:hover,
    .care-flag:focus-visible {
        z-index: 6;
    }

    /* shared hover/focus card */
    .care-tip {
        position: absolute;
        left: 50%;
        top: var(--care-y, 50%);
        z-index: 7;
        min-width: 150px;
        transform: translate(-50%, calc(-100% - 12px));
        padding: 0.5rem 0.6rem;
        border-radius: var(--yb-radius-sm);
        background: var(--yb-card);
        border: 1px solid var(--yb-border);
        box-shadow: var(--yb-shadow-md);
        text-align: left;
        opacity: 0;
        visibility: hidden;
        pointer-events: none;
        transition: opacity var(--yb-dur) var(--yb-ease);
    }

    .care-tip::after {
        content: "";
        position: absolute;
        left: 50%;
        top: 100%;
        width: 9px;
        height: 9px;
        background: var(--yb-card);
        border-right: 1px solid var(--yb-border);
        border-bottom: 1px solid var(--yb-border);
        transform: translate(-50%, -55%) rotate(45deg);
    }

    /* edge-flag cards anchor above the flag and align to the chart edge */
    .care-flag .care-tip {
        top: auto;
        bottom: calc(100% + 7px);
        transform: none;
    }

    .care-flag--before .care-tip {
        left: 0;
    }

    .care-flag--after .care-tip {
        left: auto;
        right: 0;
    }

    .care-flag--before .care-tip::after {
        left: 14px;
    }

    .care-flag--after .care-tip::after {
        left: auto;
        right: 14px;
    }

    .care-node:hover .care-tip,
    .care-node:focus-visible .care-tip,
    .care-flag:hover .care-tip,
    .care-flag:focus-visible .care-tip {
        opacity: 1;
        visibility: visible;
    }

    .care-tip__head {
        display: flex;
        align-items: center;
        gap: 0.4rem;
        margin-bottom: 0.25rem;
    }

    .care-tip__chip {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 20px;
        height: 20px;
        border-radius: 50%;
        background: var(--yb-accent);
        color: #fff;
        font-size: 0.66rem;
        font-weight: 700;
        flex: 0 0 auto;
    }

    .care-tip__name {
        font-size: 0.78rem;
        font-weight: 700;
        color: var(--yb-text);
    }

    .care-tip__meta {
        display: block;
        font-size: 0.72rem;
        color: var(--yb-text-muted);
    }

    .care-tip__rel {
        display: block;
        margin-top: 0.1rem;
        font-size: 0.68rem;
        color: var(--yb-text-soft);
    }

    @media (prefers-reduced-motion: reduce) {
        .care-node__dot,
        .care-node__tether,
        .care-flag,
        .care-tip {
            transition: none;
        }
    }

    .summary-trend-empty {
        height: 84px;
        display: flex;
        align-items: center;
        font-size: 0.85rem;
        color: var(--yb-text-soft);
    }

    [data-theme="dark"] .summary-trend-svg .trend-band {
        fill: rgba(45, 200, 130, 0.14);
    }

    [data-theme="dark"] .summary-trend-svg .trend-band-edge {
        stroke: rgba(45, 200, 130, 0.45);
    }

    .summary-deviation-badge {
        display: inline-flex;
        align-items: center;
        gap: 0.22rem;
        text-align: left;
        width: fit-content;
        flex: 0 0 auto;
        white-space: nowrap;
        padding: 0.18rem 0.4rem;
        line-height: 1;
    }

    .summary-deviation-count {
        font-weight: 700;
        min-width: 0;
        text-align: right;
    }

    .summary-deviation-label {
        white-space: nowrap;
    }

    /* ---- The group header STICKS (#254) --------------------------------------
       The cohort lives only in this header — the student cards below carry no
       class or section at all. Scroll a class of forty and the one thing naming
       the class leaves the screen, and every remaining row is a student with no
       cohort. Sticking the header fixes that for the price of one rule, and
       without repeating the class on forty cards that sit directly under a
       heading already saying it.

       The background must be opaque in BOTH themes: a transparent sticky header
       lets the rows scroll visibly through it. Syncfusion's own overflow on the
       item would clip the stuck header, so it is released here. */
    .student-summary-analytics .e-acrdn-item,
    .student-summary-analytics .e-acrdn-panel,
    .student-summary-analytics .accordion-content-wrapper {
        overflow: visible;
    }

    /* Syncfusion's .e-card ships `overflow: hidden auto`, and the layout wrapper the
       whole page sits in is an .e-card. That makes it a SCROLL CONTAINER, so a sticky
       header inside it sticks to the top of the card — which itself scrolls away with
       the window — instead of to the viewport. The header looked sticky in the
       computed styles and still slid off screen; only scrolling a long list showed it.

       `overflow-x: clip` keeps the horizontal clipping the card had while NOT creating
       a scroll container, and it is the one pairing that lets overflow-y stay visible.
       Narrowed with :has() to the card that actually holds this screen, so no other
       page's scrolling changes. Where :has() is unsupported the rule is skipped and
       the header simply behaves as it does today. */
    .full-height-card.e-card:has(.student-summary-analytics) {
        overflow-x: clip;
        overflow-y: visible;
    }

    .student-summary-analytics .e-acrdn-item > .e-acrdn-header {
        position: sticky;
        top: 0;
        z-index: 3;
        background: #fff;
    }

    [data-theme="dark"] .student-summary-analytics .e-acrdn-item > .e-acrdn-header {
        background: var(--yb-surface);
    }

    /* The caveat marker beside the two alert counts — quiet, and never a badge of
       its own: it annotates the numbers, it is not another number. */
    .yb-count-note {
        color: var(--yb-text-muted, #6b7280);
        font-size: 0.85rem;
        cursor: help;
    }

    /* ---- Group-header count chips: dark-mode parity ----
       Bootstrap's .bg-dark is a fixed #212529. Against the dark header (#1c212b)
       that is a 1.05:1 contrast, so the Location pill AND its number lost their
       container entirely while the red Safety pair stayed perfectly visible —
       the two counts sat side by side looking like different kinds of thing.
       The people chip was worse: a dark override had already flattened .bg-light
       to the header's own colour, leaving a hairline border and nothing else.
       Measured, not eyeballed. Light mode is deliberately left untouched. */
    [data-theme="dark"] .student-summary-analytics .e-acrdn-header .badge.bg-dark {
        background: var(--yb-surface-sunken) !important;
        color: var(--yb-text) !important;
        border: 1px solid var(--yb-border-strong);
    }

    [data-theme="dark"] .student-summary-analytics .e-acrdn-header .badge.bg-light {
        background: var(--yb-surface-sunken) !important;
        color: var(--yb-text-muted) !important;
        border-color: var(--yb-border-strong) !important;
    }

    /* ---- Syncfusion accordion + per-student cards: dark-mode parity ----
       Default Syncfusion theme paints the header/panel white, which on a dark
       canvas reads as a solid white patch (worst when all items are collapsed). */
    [data-theme="dark"] .student-summary-analytics .e-accordion,
    [data-theme="dark"] .student-summary-analytics .e-accordion .e-acrdn-item {
        background: transparent !important;
        border-color: var(--yb-border);
    }

    [data-theme="dark"] .student-summary-analytics .e-acrdn-item {
        border: 1px solid var(--yb-border);
    }

    [data-theme="dark"] .student-summary-analytics .e-acrdn-header,
    [data-theme="dark"] .student-summary-analytics .e-acrdn-panel,
    [data-theme="dark"] .student-summary-analytics .e-acrdn-panel .e-acrdn-content {
        background: var(--yb-surface) !important;
        color: var(--yb-text) !important;
    }

    [data-theme="dark"] .student-summary-analytics .e-acrdn-header:hover,
    [data-theme="dark"] .student-summary-analytics .e-acrdn-header:focus,
    [data-theme="dark"] .student-summary-analytics .e-acrdn-item.e-selected > .e-acrdn-header {
        background: var(--yb-surface-2) !important;
    }

    [data-theme="dark"] .student-summary-analytics .e-acrdn-header .e-acrdn-header-content,
    [data-theme="dark"] .student-summary-analytics .e-acrdn-header .e-toggle-icon,
    [data-theme="dark"] .student-summary-analytics .e-acrdn-header .e-tgl-collapse-icon::before,
    [data-theme="dark"] .student-summary-analytics .e-acrdn-header h6.text-primary {
        color: var(--yb-text) !important;
    }

    /* Bootstrap utility chips (.bg-light) are white in dark mode — calm them */
    [data-theme="dark"] .student-summary-analytics .badge.bg-light {
        background: var(--yb-surface-2) !important;
        color: var(--yb-text-muted) !important;
        border-color: var(--yb-border) !important;
    }

    [data-theme="dark"] .student-summary-analytics .student-summary-card {
        background: var(--yb-card);
        border-color: var(--yb-border);
        color: var(--yb-text);
    }

    [data-theme="dark"] .student-summary-analytics .student-summary-card:hover {
        border-color: var(--yb-border-strong);
    }

/* ── from AnalyticsDetailsUnified.razor ────────────────────────────────────────── */
.student-detail-analytics .detail-grid-card {
        border: 1px solid var(--yb-border);
        border-radius: var(--yb-radius);
        box-shadow: var(--yb-shadow-sm);
        overflow: hidden;
    }

    .student-detail-analytics .detail-grid-card .card-body {
        padding: 0.25rem;
    }

    /* Density for the virtualized events grid — trim the global 0.55rem cell
       padding so the 40px sparkline sits comfortably inside the fixed row. */
    .student-detail-analytics .e-rowcell {
        padding-top: 0.35rem !important;
        padding-bottom: 0.35rem !important;
        padding-left: 0.6rem !important;
        padding-right: 0.6rem !important;
        vertical-align: middle;
    }

    .student-detail-analytics .e-headercell {
        vertical-align: middle;
    }

    /* The events grid pages instead of scrolling (AllowPaging), so it has no
       internal vertical scrollbar — that scrollbar was what reserved the white
       header-filler cell ("white patch") at the top-right corner. Header band
       recolor for any remaining scrolling grids stays global in ui-refinement.css. */

    /* Mini stress sparkline — same visual language as the summary trend */
    .student-detail-analytics .detail-sparkline {
        display: inline-flex;
        align-items: center;
        height: 40px;
        width: 120px;
        padding: 0;
        border: 0;
        background: none;
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
    }

    .student-detail-analytics .detail-sparkline:focus-visible {
        outline: 2px solid rgba(var(--yb-accent-rgb), 0.5);
        outline-offset: 2px;
        border-radius: var(--yb-radius-sm);
    }

    .student-detail-analytics .detail-sparkline__svg {
        display: block;
        width: 120px;
        height: 40px;
        overflow: visible;
    }

    .student-detail-analytics .detail-sparkline__band {
        fill: rgba(31, 157, 97, 0.10);
    }

    .student-detail-analytics .detail-sparkline__band-edge {
        stroke: rgba(31, 157, 97, 0.40);
        stroke-width: 1;
        stroke-dasharray: 4 3;
    }

    .student-detail-analytics .detail-sparkline__base {
        stroke: var(--yb-border);
        stroke-width: 1;
    }

    .student-detail-analytics .detail-sparkline__line {
        fill: none;
        stroke: var(--yb-danger);
        stroke-width: 1.5;
        stroke-linejoin: round;
        stroke-linecap: round;
        transition: stroke-width var(--yb-dur) var(--yb-ease);
    }

    .student-detail-analytics .detail-sparkline:hover .detail-sparkline__line {
        stroke-width: 2;
    }

    .student-detail-analytics .detail-pattern__empty {
        color: var(--yb-text-soft);
    }

    /* Stress Pattern cell: sparkline pinned left, optional chip pinned right */
    .student-detail-analytics .detail-pattern {
        width: 100%;
    }

    /* Counseling-on-date chip — accent language shared with the summary care nodes */
    .student-detail-analytics .detail-care-chip {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 22px;
        height: 22px;
        margin-left: auto;
        border-radius: 50%;
        background: rgba(var(--yb-accent-rgb), 0.12);
        color: var(--yb-accent-text);
        font-size: 0.72rem;
        flex: 0 0 auto;
    }

    /* Dark-mode parity for the normal-range band — brighter green like the summary trend */
    [data-theme="dark"] .student-detail-analytics .detail-sparkline__band {
        fill: rgba(45, 200, 130, 0.14);
    }

    [data-theme="dark"] .student-detail-analytics .detail-sparkline__band-edge {
        stroke: rgba(45, 200, 130, 0.45);
    }

    @media (prefers-reduced-motion: reduce) {
        .student-detail-analytics .detail-sparkline__line {
            transition: none;
        }
    }
