/**
 * Solon Targets Page — Chrome & Tokens
 *
 * @version 1.2.0 — Phase 19.1 follow-up. Switcher settled: ONE centred row of nine
 *   chips in a pill that hugs its content, with a hairline dividing the three
 *   portfolio scopes from the six brands. Halves the switcher's height (105px → 54px)
 *   and removes the dead space two earlier attempts only framed. Chosen from five
 *   rendered options; B (aligned label grid), D (segmented) and E (full-width) are
 *   recorded in the phase SUMMARY as considered and not taken.
 * @version 1.1.1 — Phase 19.1 follow-up (superseded). The switcher became a centred bar:
 *   both rows centre on the page axis inside a bordered surface whose edges align
 *   with the Core KPIs card. Centring the rows alone was not enough — three
 *   portfolio chips adrift in 1280px still read as empty space; the enclosing
 *   surface is what makes the width look intentional.
 * @version 1.1.0 — Phase 19.1 follow-up. Scope-switcher redesign: labelled Portfolio /
 *   Brands rows, and an active chip carried by FIVE channels (fill, border, ring, text
 *   colour, weight) with idle chips deliberately receded. The previous active state
 *   was a tint of --scope-accent alone, which reads fine for a brand's green or red
 *   but collapsed for the three group scopes — their accent is neutral slate, the same
 *   family as the chip surface, so "active" was slate on slate.
 * @version 1.0.0 — Phase 19.1 (T10). Page shell, header, scope head, and the two
 *   custom properties css/targets.css needs but css/group-dashboard.css never defines.
 *
 * Loads AFTER css/group-dashboard.css (whose slate/gold palette and light-theme
 * surface overrides this page inherits wholesale) and BEFORE css/targets.css (which
 * reads the tokens defined here). That order is locked in targets.html's <head>.
 *
 * This sheet owns the page CHROME only. It deliberately restates nothing that
 * css/targets.css already owns — in particular its ≤900px and ≤640px blocks are not
 * overridden, so the section keeps one responsive story across all the surfaces that
 * render it.
 *
 * Locked Decision #14 applies throughout: every rule that sets display/flex/grid on
 * an element that can also carry [hidden] is scoped :not([hidden]).
 */

/* ----------------------------------------------------------------------- */
/*  Tokens css/targets.css reads that css/group-dashboard.css does not own  */
/*                                                                         */
/*  --text-dim is used UNGUARDED in .targets-week, .targets-tier-ref,       */
/*  .targets-chart-formula, .targets-wow--none and .targets-forecast-method.*/
/*  An undefined var() with no fallback is invalid at computed-value time,  */
/*  so without this those five would silently inherit --text and lose their */
/*  de-emphasis entirely. Values lifted verbatim from css/dashboard.css.    */
/* ----------------------------------------------------------------------- */
:root {
    --text-dim: #6B7A90;
    --r-lg: 14px;

    /* Rewritten on #targets-page by js/targets-page.js on every scope change AND
       on every theme change — one write, every accent consumer follows. NEVER a
       text colour: it appears only as the active chip's border/tint, the
       scope-head rule and the chart series line, which is what holds it to WCAG
       1.4.11's 3:1 NON-TEXT bar rather than 4.5:1. Defaults are the group slate,
       which is also what the three group scopes keep. */
    --scope-accent: #64748B;
    --scope-accent-rgb: 100, 116, 139;
}

[data-theme="light"] {
    --text-dim: #94A3B8;
    --scope-accent: #475569;
    --scope-accent-rgb: 71, 85, 105;
}

/* -------------------------------------------------------------------------
   SCOPE-ACCENT CONTRAST — measured, not assumed (UI-CONTRACT §4.3, §6 A-6)

   Every --scope-accent measured against its own theme's --card-bg
   (light #F7FAFD, dark #0F172A). The accent is non-text only, so the bar is
   3:1 (WCAG 1.4.11), not 4.5:1. Mirrors the css/targets.css:112-122 precedent.

     Scope          Light on #F7FAFD        Dark on #0F172A
     -----------------------------------------------------------------
     CRC Northern   #00965E   3.63:1  PASS  #00B871   6.88:1  PASS
     NHCC           #2B9EB3   3.02:1  PASS  #3DB6CC   7.45:1  PASS
     MagicMan       #1E3A5F  10.98:1  PASS  #4A90D9   5.34:1  PASS
     MA Assist      #2596B4   3.29:1  PASS  #2BA8C9   6.42:1  PASS
     Revival        #2C5F8D   6.41:1  PASS  #4A8BC4   4.91:1  PASS
     Virtus         #E5202E   4.38:1  PASS  #E5202E   3.89:1  PASS
     MAGCS/MAGPC/
     MA Group       #475569   7.23:1  PASS  #64748B   3.75:1  PASS

   TWO ADJUSTMENTS were required; both are departures from UI-CONTRACT §4.3's
   table, made under its own verification duty rather than left at "looks fine":

     MA Assist, light. The brand Primary #2BA8C9 measures 2.66:1 on #F7FAFD —
     under the bar. Darkened one step to #2596B4 (3.29:1). MA Assist is the one
     brand whose Primary and glow are the same hex, so the light side had no
     darker variant of its own to fall back on.

     Group slate, dark. #475569 measures 2.36:1 on #0F172A — the worst pair of
     the twelve, and the most consequential, since it is the default accent and
     the one all three group scopes use. Lightened one step to #64748B (3.75:1),
     which is the next stop on the same slate ramp, so the page chrome stays
     neutral as D11 requires.

   NHCC light (3.02:1) clears the bar with almost nothing to spare. It is left
   at the brand Primary deliberately — it passes, and changing a brand's own
   colour to buy margin is a brand decision, not a stylesheet one — but any
   future darkening of --card-bg on the light theme will break it first.
   ------------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*  Page wrapper — a clone of #group-page (css/group-dashboard.css:107-117)  */
/* ----------------------------------------------------------------------- */
main#targets-page {
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-width: 1280px;
    margin: 0 auto;
    padding: 16px;
}
@media (min-width: 1024px) {
    main#targets-page { padding: 24px; gap: 20px; }
}

/* ----------------------------------------------------------------------- */
/*  Header                                                                 */
/* ----------------------------------------------------------------------- */
header#targets-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    padding-block: 12px;
    border-bottom: 1px solid var(--border);
    /* js/theme.js fixes its toggle at top:14px; right:14px. Reserve that corner
       so the toggle never sits on top of the header's own content (§6 A-13). */
    padding-right: 56px;
}

.targets-header__title {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
}
.targets-header__title h1 {
    margin: 0;
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--text);
}
.targets-version-chip {
    font-family: var(--mono);
    font-size: 0.68rem;
    font-weight: 500;
    color: var(--text-muted);
}

/* Phase 22 (T23, D4/C2) — the standing statement that this surface is
   interest-free by definition. Deliberately NOT [hidden]-scoped: it is always
   visible, because this page cannot read the Statutory Charges toggle at all.
   flex-basis 100% so it drops to its own line under the title + chip. */
.targets-basis-note {
    flex-basis: 100%;
    margin: 2px 0 0;
    font-size: 0.72rem;
    font-style: italic;
    line-height: 1.4;
    color: var(--text-muted);
}

/* ----------------------------------------------------------------------- */
/*  Scope head — which scope, which tier, which week, on what basis         */
/* ----------------------------------------------------------------------- */
#targets-scope-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 8px 12px;
    padding-bottom: 8px;
    border-bottom: 2px solid var(--scope-accent);
}

.targets-scope-name {
    font-size: 1.35rem;
    font-weight: 700;
    letter-spacing: -0.025em;
    color: var(--text);
}

.targets-scope-tier {
    font-family: var(--mono);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.targets-scope-week {
    font-family: var(--mono);
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--text-dim);
}

/* The active scope's basis, spelled out rather than offered as a toggle (D2). */
.targets-scope-basis {
    flex-basis: 100%;
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--text-muted);
}

/* ----------------------------------------------------------------------- */
/*  Scope switcher (T19; UI-CONTRACT §5.1)                                 */
/*                                                                         */
/*  Active state is carried by THREE channels — aria-pressed, fill and font */
/*  weight — so it never depends on hue alone (§6 A-4).                     */
/* ----------------------------------------------------------------------- */
/* ONE centred row inside a pill that HUGS its content (width: fit-content).
   Two earlier attempts are worth recording as rejected:
     - two left-aligned labelled rows: the chips sat hard left with a large dead
       right-hand side;
     - the same rows centred inside a full-width bar: each row centred on its own,
       so the two legends landed at different x positions — which reads as an
       accident — and the border merely drew a frame around the empty space.
   Hugging is the fix: there is no empty space to frame. The grouping the word
   legends used to carry is now carried by the divider, and by the ordering
   (three portfolio scopes, then the six brands). The role="group" labels remain
   on both halves, so a screen reader still hears the distinction.
   js/viewport-fit.js zooms this page to fit its 1280 canvas rather than
   reflowing it, so in practice this stays a single row. */
#targets-switcher {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 8px;
    width: fit-content;
    max-width: 100%;
    margin: 0 auto;
    padding: 10px 14px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: rgba(148, 163, 184, 0.03);
}

.targets-scope-group {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
}

/* Portfolio scopes | brand scopes. */
.targets-scope-divider {
    flex: 0 0 auto;
    width: 1px;
    align-self: stretch;
    min-height: 22px;
    margin: 0 4px;
    background: var(--border);
}

/* IDLE chips deliberately RECEDE. The active state used to be carried entirely by a
   tint of --scope-accent, which works for a brand's green or red but collapses for
   the three group scopes: their accent is neutral slate, the same family as the
   chip surface itself, so active read as slate-on-slate. Dropping the idle chip's
   weight is what makes the active one legible without touching D11's neutral
   chrome. */
.targets-scope-chip {
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 500;
    line-height: 1;
    padding: 9px 15px;
    border-radius: 999px;
    border: 1px solid rgba(148, 163, 184, 0.14);
    background: rgba(148, 163, 184, 0.04);
    color: var(--text-secondary);
    cursor: pointer;
    transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease;
}
.targets-scope-chip:hover {
    background: rgba(148, 163, 184, 0.12);
    border-color: rgba(var(--scope-accent-rgb), 0.55);
    color: var(--text);
}
.targets-scope-chip:focus-visible {
    outline: 2px solid var(--group-accent);
    outline-offset: 2px;
}

/* FOUR channels, so the active chip never rests on hue alone (§6 A-4): a strong
   accent fill, a full-strength accent border, an outer ring, and the only
   full-weight full-contrast text in the switcher. */
.targets-scope-chip[aria-pressed="true"] {
    background: rgba(var(--scope-accent-rgb), 0.22);
    border-color: var(--scope-accent);
    box-shadow: 0 0 0 1px rgba(var(--scope-accent-rgb), 0.30);
    color: var(--text);
    font-weight: 600;
}
.targets-scope-chip[aria-pressed="true"]:hover {
    background: rgba(var(--scope-accent-rgb), 0.30);
}

@media (max-width: 640px) {
    /* Below the zoom-to-fit floor the row does wrap; soften the pill into a
       rounded block and drop the divider, which would otherwise strand itself
       at the end of a line. */
    #targets-switcher { width: auto; border-radius: var(--r-lg); padding: 12px; }
    .targets-scope-divider { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .targets-scope-chip { transition: none; }
}

/* ----------------------------------------------------------------------- */
/*  Notice strips (T17)                                                    */
/*                                                                         */
/*  .group-banner-strip itself is reused verbatim from                      */
/*  css/group-dashboard.css:709-750 — only the :empty collapse is added,    */
/*  following the #group-banner-region precedent.                          */
/* ----------------------------------------------------------------------- */
#targets-notice-region {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
#targets-notice-region:empty {
    display: none;
}

/* ----------------------------------------------------------------------- */
/*  Stage-B chart skeleton (T16, I5)                                       */
/*                                                                         */
/*  Static, no shimmer: an animated placeholder implies progress this page  */
/*  cannot measure. .targets-chart-canvas-wrap keeps its css/targets.css    */
/*  height in EVERY stage — deliberately NOT overridden here — so the table */
/*  never shifts when the charts land (A13).                               */
/* ----------------------------------------------------------------------- */
.targets-chart-skeleton {
    display: flex;
    align-items: flex-end;
    height: 100%;
    padding-bottom: 4px;
    font-size: 0.68rem;
    color: var(--text-dim);
    border-bottom: 1px solid var(--border);
}

/* While the history is in flight, hide the two texts that would otherwise
   read "Showing 0 of 13 weeks" and "Insufficient data" — both are honest
   statements about data that has ARRIVED, and neither has yet.

   The #targets-section prefix is REQUIRED, not decoration. css/targets.css
   loads after this sheet, and its `.targets-shortfall:not([hidden])` and
   `.targets-forecast-value:not([hidden])` rules carry the same specificity as
   a two-class selector would — so on source order they would win and these
   rules would silently never apply. The ID lifts specificity above them. */
#targets-section.targets-page--history-pending .targets-shortfall,
#targets-section.targets-page--history-pending .targets-forecast,
#targets-section.targets-page--history-pending .targets-forecast-value,
#targets-section.targets-page--history-pending .targets-forecast-insufficient,
#targets-section.targets-page--history-pending .targets-forecast-method {
    display: none;
}

/* ----------------------------------------------------------------------- */
/*  Empty and error states (T18; §3.2, §3.5)                               */
/*                                                                         */
/*  Locked Decision #14: both are [hidden]-toggled, so every display rule   */
/*  here is :not([hidden])-scoped. ID specificity beats the UA [hidden]     */
/*  rule, so an unscoped rule would leak them on every page load.           */
/* ----------------------------------------------------------------------- */
#targets-empty:not([hidden]),
#targets-error:not([hidden]) {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    padding: 1.1rem 1.2rem;
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    background: var(--card-bg);
}

.targets-empty__headline,
.targets-error__headline {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--text);
}
.targets-empty__body,
.targets-error__body {
    font-size: 0.85rem;
    color: var(--text-muted);
    max-width: 60ch;
}

.targets-retry {
    margin-top: 6px;
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    padding: 7px 16px;
    border-radius: 999px;
    border: 1px solid var(--scope-accent);
    background: rgba(var(--scope-accent-rgb), 0.16);
    color: var(--text);
    cursor: pointer;
    transition: background-color 120ms;
}
.targets-retry:hover {
    background: rgba(var(--scope-accent-rgb), 0.28);
}
.targets-retry:focus-visible {
    outline: 2px solid var(--group-accent);
    outline-offset: 1px;
}

/* ----------------------------------------------------------------------- */
/*  Utilities                                                              */
/*                                                                         */
/*  .sr-only lives in styles.css and css/dashboard.css, neither of which    */
/*  this page loads, so the live region needs its own copy.                 */
/* ----------------------------------------------------------------------- */
.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;
}
