/* ==========================================================================
   FL510 — INTERNAL PORTAL SHELL (FW6c, added 2026-08-06)
   --------------------------------------------------------------------------
   The internal estate's half of the accepted design
   (docs/prototype/internal-design-final.html, 3,910 lines; contract:
   docs/prototype/internal-design-build-spec.md).

   WHAT LIVES HERE AND WHAT DOES NOT. The two-tier chrome — rail, appbar,
   KPI strip, mobile :target sheet, scrim, module head, pane — is ALREADY a
   shared, multi-consumer component in `portal-shell.css` (`.portal-shell
   .ps-*`), proven on `_ExternalPortalLayout`. `_InternalPortalLayout` adopts
   that file verbatim by carrying `.internal-shell.portal-shell.ds`, so this
   file adds only the two things portal-shell.css cannot supply:

     1. the internal sheet/menu-button IDs (`#int-portal` / `#int-menuBtn`) —
        portal-shell.css hard-codes `#ext-portal` / `#ext-menuBtn` in five
        rules, and an ID selector cannot be generalised from the outside;
     2. the MODULE-BODY vocabulary the approved internal mock defines and the
        external portal never needed: `.section`, `.filters`, `.dtable`,
        `.wtile`, `.empty.good`, `.statgrid`, `.stackcard`, `.pill`, `.meters`,
        the pager and the chip-filter form.

   TOKENS — NO FORKED PALETTE. The mock's stylesheet is written against
   UNPREFIXED custom properties (`--surface`, `--ink-2`, `--warn-wash`, …).
   Rather than hand-retune every rule (which is how a translation drifts from
   the approved design), the `.internal-shell` block below ALIASES those exact
   names onto the `--ps-*` component locals portal-shell.css already defines,
   which themselves reference the semantic `--ds-*` tier in `tokens.css`. So
   light/dark AND the manual `[data-theme]` toggle still swap in ONE place,
   and the rules below can stay byte-faithful to the mock.
   The alias block is scoped to `.internal-shell`, never `:root`: custom
   properties inherit only into that subtree, so no other surface can see
   them. (Verified before writing: the only unprefixed custom properties
   anywhere in wwwroot/css are external-portal.css's `--ex-*`, which are
   prefixed — grep over every stylesheet in `wwwroot/css`. A literal comment-opener sequence is
   deliberately NOT written anywhere in this file, including inside prose, so the parse guard's
   opener/closer count stays a real signal rather than a thing that needs explaining away.)

   SCOPE CONTRACT: every selector below is under `.internal-shell`. No bare
   element is styled and no page that does not use `_InternalPortalLayout`
   can be reached by anything in this file. That scoping is also why `_Layout`
   may link this file unconditionally, exactly as it already links
   billing-modules.css, portal-shell.css and external-portal.css (8 stylesheet
   links, none conditional): a public page downloads this file's ~29 KB and can
   match none of it — which is also true today of external-portal.css (62,700
   bytes) and billing-modules.css (33,103 bytes) on that same page. Making the
   link conditional is a whole-head change across all four stylesheets, not a
   change this wave should make to one of them.

   ⚠ VOCABULARY SHIPPED AHEAD OF ITS MARKUP — MEASURED, NAMED, AND DELIBERATE.
   (No comment-opener sequence is written below either — see the parse-guard
   note; that is why the paths here carry no glob.)
   Of the 114 class names defined below, 33 are referenced by no .cshtml under
   Views, no script in wwwroot/js and no other stylesheet in wwwroot/css at
   this commit:
     critbar, dactions, dangerbtn, dc, dc-id, denied, dgo, dhead, dmeta,
     drailtail, drow, dsub, dtable, dv, fw6c-parse-sentinel, hl, linkbtn, neg,
     pagerbar, pgbtn, pgnum, pgwin, pos, recon, sl, slotgrid, slotline,
     statcell, statgrid, tb, trailitem, tw, warnbar
   (`fw6c-parse-sentinel` is unreferenced BY DESIGN — it is the tail guard
   below.) They are kept, not pruned, because the build spec §3 makes the
   extension-layer vocabulary the contract ("byte-copy them into
   wwwroot/css/portal-shell.css or successor") and §5 item 5 makes `.dtable` +
   `.pager` the REQUIREMENT for the row conversion that is still owed on these
   surfaces — 49a rule 2, never a shrunken desktop table. The honest statement
   is therefore: this file is the whole approved vocabulary, and batch C3
   converted the page frames (shell, header, filter bar, row summary, empty
   states) but NOT the rows or the pager. Do not read the presence of a
   `.dtable` rule as evidence that any surface renders one. Whoever converts
   the rows should shrink this list rather than grow it.

   ⚠ PARSE GUARD (docs/LANDMINES.md, the FW5c lesson: an unterminated comment
   silently killed six rules while 281 tests stayed green). This file ends
   with the sentinel rule `.internal-shell .fw6c-parse-sentinel` and
   `InternalPortalShellCssTests` asserts BOTH that comment openers equal
   comment closers / braces balance AND that the sentinel is the last rule —
   so a comment opened anywhere above cannot swallow the tail unnoticed.
   ========================================================================== */

.internal-shell {
    /* --- the mock's unprefixed names, aliased onto the shared shell locals --- */
    --bg: var(--ps-bg);
    --surface: var(--ps-surface);
    --surface-2: var(--ps-surface-2);
    --line: var(--ps-line);
    --line-strong: var(--ps-line-strong);
    --ink: var(--ps-ink);
    --ink-2: var(--ps-ink-2);
    --ink-3: var(--ps-ink-3);
    --ink-faint: var(--ps-ink-faint);
    --primary: var(--ps-primary);
    --primary-wash: var(--ps-primary-wash);
    --on-primary: var(--ps-primary-on);
    --good: var(--ps-good);
    --good-wash: var(--ps-good-wash);
    --warn: var(--ps-warn);
    --warn-wash: var(--ps-warn-wash);
    --crit: var(--ps-crit);
    --crit-wash: var(--ps-crit-wash);
    --info: var(--ps-info);
    --info-wash: var(--ps-info-wash);
    --radius: var(--ps-radius, 14px);
    --radius-sm: var(--ps-radius-sm, 9px);
    --mono: var(--ps-mono);
    --ease: var(--ps-ease);
    --shadow-card: var(--ps-shadow-card);
    --shadow-pop: var(--ps-shadow-pop);
}

/* ============ the internal mobile portal sheet + its opener ================
   Byte-equivalent to portal-shell.css's `#ext-portal` / `#ext-menuBtn` rules,
   re-pointed at the internal IDs. Kept here so portal-shell.css — a file four
   other surfaces depend on — is not edited by this wave at all. ============ */
.internal-shell #int-portal.ps-sheet {
    position: fixed; z-index: 50; left: 0; right: 0; bottom: 0; max-height: 90vh;
    border-radius: 20px 20px 0 0; box-shadow: var(--ps-shadow-sheet);
    transform: translateY(100%); visibility: hidden;
    transition: transform .34s var(--ease), visibility 0s linear .34s;
    will-change: transform;
}
.internal-shell #int-portal.ps-sheet.is-open,
.internal-shell #int-portal.ps-sheet:target {
    transform: translateY(0); visibility: visible;
    transition: transform .34s var(--ease), visibility 0s;
}
body:has(.internal-shell #int-portal:target) .internal-shell .ps-scrim { opacity: 1; visibility: visible; }
.internal-shell #int-portal .ps-sheet-body {
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    padding: 6px 2px calc(20px + env(safe-area-inset-bottom, 0px));
}

/* ============ module body — generic sections ============ */
.internal-shell .section { padding: 16px 0; display: flex; flex-direction: column; gap: 14px; }
.internal-shell .sectlbl {
    font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
    color: var(--ink-3); margin: 2px 0 -6px;
}
/* ⚠ THESE TWO CARRY REAL DISCLOSURE COPY AND THEY ARE UNDER THE SC 1.4.3 FLOOR.
   Both are normal-size text, so the floor is 4.5:1. Resolving the token chain by hand
   (internal-shell alias -> portal-shell `--ps-*` -> tokens.css `--ds-*`, then the
   color-mix, then WCAG relative luminance) against the pane background:

     class    token           px     LIGHT (#FFFFFF)      DARK (#12181D)
     .note    --ps-ink-3      12.5   #7A8388  3.8677:1    #889297  5.6257:1
     .hint    --ps-ink-faint  11.5   #A7ACB0  2.2898:1    #61696F  3.2011:1

   THREE OF THE FOUR FAIL. This is ARITHMETIC, NOT A BROWSER MEASUREMENT — no
   composited reading was taken, and mobile-design-standards.md section 8 asks for the
   browser. Treat the numbers as an indication to go measure, not as the measurement.

   NOT RE-TONED HERE, DELIBERATELY, AND THE PRECEDENT IS EXPLICIT. `--ink-3` and
   `--ink-faint` are two steps of the accepted template's own four-step text ramp, and
   section 2 of that doc makes the template's `:root` block LAW for values. Section 8
   already met this exact situation — four chrome elements below 4.5:1 on light — and
   filed them as BACKLOG 125 "with their measurements rather than re-toned inside a
   defect slice". Same call, same reason: a ramp step is a design decision for the
   operator's template, not something a fix commit quietly darkens, and three FW6c
   batches are converging on this vocabulary at once.

   WHAT CHANGED, AND WHY IT MATTERS MORE THAN IT DID: the tool pages' Purpose and
   Context copy now renders in these two classes, which puts a DESTRUCTIVE operation's
   scope disclosure (Import Rollback) and the wrong-record guard on Check Out / Check In
   into `.hint` at 2.29:1 on light. Measure and re-tone the ramp before this ships. */
.internal-shell .note { font-size: 12.5px; color: var(--ink-3); line-height: 1.5; }
.internal-shell .hint { font-size: 11.5px; color: var(--ink-faint); padding: 0 0 10px; line-height: 1.5; }
.internal-shell .stackcard {
    background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px; padding: 14px;
}
.internal-shell .stackcard h3 { margin: 0 0 3px; font-size: 14px; font-weight: 640; }
.internal-shell .stackcard.warnbar { box-shadow: inset 3px 0 0 var(--warn); }
.internal-shell .stackcard.critbar { box-shadow: inset 3px 0 0 var(--crit); }
.internal-shell .actrow { display: flex; gap: 8px; flex-wrap: wrap; }

.internal-shell .statgrid {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px;
    background: var(--line); border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
}
.internal-shell .statgrid.two { grid-template-columns: repeat(2, 1fr); }
.internal-shell .statgrid.four { grid-template-columns: repeat(2, 1fr); }
.internal-shell .statcell {
    background: var(--surface-2); padding: 13px 14px; display: flex; flex-direction: column; gap: 3px; min-width: 0;
}
.internal-shell .statcell .sl {
    font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3);
}
.internal-shell .statcell .sv {
    font-size: 20px; font-weight: 700; letter-spacing: -.02em; line-height: 1.15; font-variant-numeric: tabular-nums;
}
.internal-shell .statcell .sv small { font-size: 11px; font-weight: 600; color: var(--ink-3); letter-spacing: 0; }
.internal-shell .statcell.ok .sv { color: var(--good); }
.internal-shell .statcell.warn .sv { color: var(--warn); }
.internal-shell .statcell.crit .sv { color: var(--crit); }
.internal-shell .statcell a { text-decoration: none; }

/* ============ filter form (a real GET form — contract §4) ============ */
.internal-shell .filters {
    display: flex; gap: 9px; align-items: flex-end; flex-wrap: wrap;
    padding: 12px 14px; margin: 0 0 4px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
}
.internal-shell .filt { display: flex; flex-direction: column; gap: 4px; flex: none; min-width: 0; }
.internal-shell .filt > label {
    font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--ink-3); padding-left: 2px;
}
.internal-shell .filt.grow { flex: 1 0 200px; min-width: 200px; }
.internal-shell .filt select,
.internal-shell .filt input[type="text"],
.internal-shell .filt input[type="search"],
.internal-shell .filt input[type="date"] {
    /* 16px floor is the iOS no-zoom rule (mobile-design-standards.md rule 7); the class-level
       font-size must carry the max() itself or a smaller inherited rem wins the cascade. */
    font-family: inherit; font-size: max(16px, .95rem); font-weight: 600; color: var(--ink);
    background: var(--surface-2); border: 1px solid var(--line-strong); border-radius: 9px;
    padding: 9px 11px; min-height: 44px; width: 100%; min-width: 0;
}
.internal-shell .rowsummary {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 12px 0 6px; flex-wrap: wrap;
}
.internal-shell .rowsummary .n { font-size: 12px; color: var(--ink-3); font-weight: 600; }
.internal-shell .rowsummary .n b { color: var(--ink); font-weight: 700; }
.internal-shell .rowsummary .dim { color: var(--ink-faint); font-weight: 500; }
.internal-shell .linkbtn {
    font-size: 12px; font-weight: 650; color: var(--primary); background: none; border: 0;
    display: inline-flex; align-items: center; min-height: 44px; padding: 0 4px; text-decoration: none;
}

/* ============ buttons ============ */
.internal-shell .mbtn {
    font-size: 12.5px; font-weight: 600; padding: 10px 14px; border-radius: 9px; text-decoration: none;
    border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink);
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    min-height: 44px; min-width: 44px; transition: background .15s, border-color .15s;
}
.internal-shell .mbtn:hover { background: var(--surface-2); }
.internal-shell .mbtn.solid { background: var(--primary); color: var(--on-primary); border-color: transparent; }
.internal-shell .mbtn.solid:hover { filter: brightness(1.05); background: var(--primary); }
.internal-shell .dangerbtn {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px; flex: none;
    font-size: 12.5px; font-weight: 680; padding: 10px 15px; border-radius: 9px; text-decoration: none;
    min-height: 44px; min-width: 44px;
    background: var(--surface); color: var(--crit);
    border: 1px solid color-mix(in srgb, var(--crit) 38%, transparent);
    transition: background .15s;
}
.internal-shell .dangerbtn:hover { background: var(--crit-wash); }
.internal-shell .dangerbtn.solid { background: var(--crit); color: #fff; border-color: transparent; }

/* ============ status chips / pills ============ */
.internal-shell .chips { display: flex; flex-wrap: wrap; gap: 6px; }
.internal-shell .chip {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 11.5px; font-weight: 600; line-height: 1;
    padding: 5px 9px; border-radius: 999px;
    background: var(--surface-2); color: var(--ink-2); border: 1px solid var(--line);
}
.internal-shell .chip .n { font-variant-numeric: tabular-nums; color: var(--ink); font-weight: 700; }
.internal-shell .chip.hero { background: var(--good-wash); border-color: transparent; color: var(--good); }
.internal-shell .chip.hero .n { color: var(--good); }
.internal-shell .chip.attn { background: var(--warn-wash); border-color: transparent; color: var(--warn); }
.internal-shell .chip.attn .n { color: var(--warn); }
.internal-shell .chip.crit { background: var(--crit-wash); border-color: transparent; color: var(--crit); }
.internal-shell .chip.crit .n { color: var(--crit); }
.internal-shell .chip.info { background: var(--info-wash); border-color: transparent; color: var(--info); }
.internal-shell .chip.info .n { color: var(--info); }
.internal-shell .chip.zero { opacity: .72; }
.internal-shell .chip.dot::before {
    content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .85;
}
.internal-shell .pill {
    display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px; font-weight: 700;
    letter-spacing: .02em; padding: 3px 8px; border-radius: 999px; flex: none;
}
.internal-shell .pill.clean, .internal-shell .pill.released, .internal-shell .pill.ok {
    background: var(--good-wash); color: var(--good);
}
.internal-shell .pill.hold, .internal-shell .pill.p2 { background: var(--warn-wash); color: var(--warn); }
.internal-shell .pill.recon, .internal-shell .pill.p3, .internal-shell .pill.air {
    background: var(--info-wash); color: var(--info);
}
.internal-shell .pill.p1, .internal-shell .pill.down { background: var(--crit-wash); color: var(--crit); }
.internal-shell .pill.neutral, .internal-shell .pill.muted {
    background: var(--surface-2); color: var(--ink-3); box-shadow: inset 0 0 0 1px var(--line);
}
.internal-shell .pill.dot::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }

/* Chip filters as a REAL GET form (graft from Direction C — the buttons submit). */
.internal-shell .chipform { display: flex; gap: 6px; flex-wrap: wrap; margin: 0; padding: 0; border: 0; background: none; }
.internal-shell button.chip {
    cursor: pointer; min-height: 44px; transition: background .14s, border-color .14s, color .14s;
}
.internal-shell button.chip[aria-pressed="true"] {
    background: var(--primary-wash); border-color: transparent; color: var(--primary);
}
.internal-shell button.chip[aria-pressed="true"] .n { color: var(--primary); }

/* ============ data table at scale — phone card rows, desktop columns ======
   One markup, two layouts (spec §3): the meta wrapper is `display:contents`
   at >=900px so the same DOM promotes into a real column grid. NEVER a
   desktop table squeezed onto a phone (49a rule 2). ======================== */
.internal-shell .dtable { display: flex; flex-direction: column; }
.internal-shell .dhead { display: none; }
.internal-shell .drow {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
    column-gap: 11px; row-gap: 6px; align-items: center;
    padding: 12px 6px; border-bottom: 1px solid var(--line); border-radius: 10px;
    transition: background .12s;
}
.internal-shell .drow:last-child { border-bottom: none; }
.internal-shell .drow:hover { background: var(--surface-2); }
.internal-shell .drow.attn { box-shadow: inset 3px 0 0 var(--warn); }
.internal-shell .drow.crit { box-shadow: inset 3px 0 0 var(--crit); }
.internal-shell .dc { min-width: 0; }
.internal-shell .dc-id { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.internal-shell .dt {
    font-size: 14px; font-weight: 650; letter-spacing: -.01em; color: var(--ink); text-decoration: none;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.internal-shell a.dt { display: inline-flex; align-items: center; min-height: 44px; }
.internal-shell a.dt:hover { color: var(--primary); text-decoration: underline; }
.internal-shell .dsub { font-size: 11.5px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; }
.internal-shell .dsub.mono { font-family: var(--mono); font-size: 11px; }
.internal-shell .dmeta {
    grid-column: 2; display: flex; flex-wrap: wrap; align-items: center; gap: 5px 14px; min-width: 0;
}
.internal-shell .dmeta .dc[data-l]::before {
    content: attr(data-l); display: block;
    font-size: 9.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--ink-faint); margin-bottom: 1px;
}
.internal-shell .dv {
    font-size: 12.5px; font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums;
}
.internal-shell .dv.strong { color: var(--ink); font-weight: 700; }
.internal-shell .dv.pos { color: var(--good); }
.internal-shell .dv.neg { color: var(--crit); }
.internal-shell .dv.warn { color: var(--warn); }
.internal-shell .dv.mono { font-family: var(--mono); font-size: 12px; }
.internal-shell .dgo {
    color: var(--ink-faint); display: grid; place-items: center; width: 44px; height: 44px;
    text-decoration: none; flex: none; transition: transform .16s var(--ease), color .16s;
}
.internal-shell .dgo:hover { color: var(--primary); transform: translateX(2px); }
.internal-shell .dgo svg { width: 17px; height: 17px; }
.internal-shell .drailtail { width: 4px; border-radius: 4px; align-self: stretch; min-height: 34px; flex: none; }
.internal-shell .dactions { display: flex; gap: 6px; flex-wrap: wrap; }

/* ============ work item (the triage atom — always a link, never an action) */
.internal-shell .wlist { display: flex; flex-direction: column; gap: 9px; }
.internal-shell .wtile {
    position: relative; display: flex; gap: 10px; align-items: center; text-decoration: none; color: inherit;
    background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px;
    padding: 12px 13px 12px 16px; min-height: 44px; transition: border-color .14s, background .14s;
}
.internal-shell .wtile::before {
    content: ""; position: absolute; left: 0; top: 12px; bottom: 12px; width: 3px; border-radius: 3px;
    background: var(--info);
}
.internal-shell .wtile.t0::before { background: var(--crit); }
.internal-shell .wtile.t1::before { background: var(--warn); }
.internal-shell .wtile.t2::before { background: var(--info); }
.internal-shell .wtile.t3::before { background: var(--line-strong); }
.internal-shell .wtile:hover { border-color: var(--line-strong); background: var(--surface); }
.internal-shell .wtile .wbody { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.internal-shell .wl1 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.internal-shell .wsrc {
    font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3);
}
.internal-shell .wage {
    margin-left: auto; font-size: 11px; color: var(--ink-faint); font-weight: 650;
    font-variant-numeric: tabular-nums; flex: none;
}
.internal-shell .wt { font-size: 13.5px; font-weight: 650; letter-spacing: -.01em; color: var(--ink); line-height: 1.35; }
.internal-shell .wc { font-size: 12px; color: var(--ink-3); line-height: 1.5; }
.internal-shell .wc b { color: var(--ink-2); font-weight: 650; }
.internal-shell .wtile > .go { color: var(--ink-faint); flex: none; transition: transform .16s var(--ease), color .16s; }
.internal-shell .wtile:hover > .go { transform: translateX(3px); color: var(--primary); }
.internal-shell .wtile > .go svg { width: 17px; height: 17px; display: block; }

/* ============ empty states — filtered-to-nothing vs all-clear ==============
   Different FACTS, different rendering. `.empty.good` is the healthy queue. */
.internal-shell .empty {
    margin: 10px 0; padding: 28px 16px; text-align: center; color: var(--ink-3); font-size: 12.5px;
    border: 1.5px dashed var(--line-strong); border-radius: 12px;
}
.internal-shell .empty strong { color: var(--ink-2); display: block; font-size: 13.5px; font-weight: 650; margin-bottom: 4px; }
.internal-shell .empty .eact { display: block; margin-top: 11px; }
.internal-shell .empty.good { border-color: color-mix(in srgb, var(--good) 32%, transparent); color: var(--good); }
.internal-shell .empty.good strong { color: var(--good); }

/* ============ meters / bars (mx remaining, consumables, duty-rest) ============ */
.internal-shell .meters {
    display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px;
    background: var(--line); border: 1px solid var(--line); border-radius: 11px; overflow: hidden;
}
.internal-shell .meter {
    background: var(--surface-2); padding: 10px 12px; display: flex; flex-direction: column; gap: 3px; min-width: 0;
}
.internal-shell .meter .ml {
    font-size: 10px; font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3);
}
.internal-shell .meter .mv {
    font-family: var(--mono); font-size: 14px; font-weight: 750; letter-spacing: -.01em;
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
.internal-shell .meter .mv small { font-size: 10.5px; font-weight: 600; color: var(--ink-3); }
.internal-shell .bar { height: 7px; border-radius: 99px; background: var(--line); overflow: hidden; margin-top: 5px; }
.internal-shell .bar i { display: block; height: 100%; border-radius: 99px; background: var(--good); }
.internal-shell .bar.warn i { background: var(--warn); }
.internal-shell .bar.crit i { background: var(--crit); }

/* ============ slot rows (provider actions, scope lists) ============ */
.internal-shell .slotgrid { display: grid; grid-template-columns: 1fr; gap: 8px; }
.internal-shell .slotline {
    display: flex; align-items: center; gap: 11px; padding: 11px 13px;
    background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; flex-wrap: wrap;
}
.internal-shell .slotline .code {
    font-family: var(--mono); font-size: 12px; font-weight: 700; color: var(--ink); min-width: 38px;
}
.internal-shell .slotline .nm { font-size: 12.5px; color: var(--ink-2); flex: 1; min-width: 0; }

/* ============ audit / history trail ============ */
.internal-shell .trail { display: flex; flex-direction: column; gap: 0; padding: 2px 0; }
.internal-shell .trailitem { display: flex; gap: 11px; padding: 9px 0; border-bottom: 1px solid var(--line); }
.internal-shell .trailitem:last-child { border-bottom: none; }
.internal-shell .trailitem .tw {
    font-size: 11px; color: var(--ink-faint); font-variant-numeric: tabular-nums; flex: none; width: 74px; padding-top: 1px;
}
.internal-shell .trailitem .tb { font-size: 12.5px; color: var(--ink-2); line-height: 1.45; min-width: 0; }
.internal-shell .trailitem .tb b { color: var(--ink); font-weight: 650; }

/* ============ pagination window statement ============ */
.internal-shell .pager { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 14px 0 4px; }
.internal-shell .pagerbar { flex: 1 1 130px; min-width: 110px; display: flex; flex-direction: column; gap: 6px; }
.internal-shell .pgnum {
    font-size: 11.5px; color: var(--ink-3); font-weight: 600; font-variant-numeric: tabular-nums;
}
.internal-shell .pgnum b { color: var(--ink); font-weight: 700; }
.internal-shell .pgwin { position: relative; height: 5px; border-radius: 99px; background: var(--line); overflow: hidden; }
.internal-shell .pgwin i { position: absolute; top: 0; bottom: 0; border-radius: 99px; background: var(--primary); }
.internal-shell .pgbtn {
    flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 6px; text-decoration: none;
    font-size: 12px; font-weight: 650; padding: 10px 14px; border-radius: 9px; min-height: 44px;
    background: var(--surface); color: var(--ink); border: 1px solid var(--line-strong);
}
.internal-shell .pgbtn:hover { background: var(--surface-2); }
.internal-shell .pgbtn[aria-disabled="true"] { opacity: .42; pointer-events: none; }

/* ============ permission-denied (names the capability and who grants it) ==== */
.internal-shell .denied {
    margin: 14px 0; padding: 18px; border-radius: 13px; display: flex; gap: 13px; align-items: flex-start;
    background: var(--surface-2); border: 1px solid var(--line);
}
.internal-shell .denied h3 { margin: 0 0 4px; font-size: 14px; font-weight: 660; }
.internal-shell .denied p { margin: 0; font-size: 12.5px; color: var(--ink-3); line-height: 1.5; }
.internal-shell .denied.inline { margin: 0; }

.internal-shell .tnum { font-variant-numeric: tabular-nums; }
.internal-shell .mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* ============ DESKTOP >= 900px ============ */
@media (min-width: 900px) {
    .internal-shell #int-menuBtn { display: none; }
    .internal-shell #int-portal { display: none !important; }
    .internal-shell .section { padding: 18px 0; }
    .internal-shell .statgrid.four { grid-template-columns: repeat(4, 1fr); }
    .internal-shell .slotgrid { grid-template-columns: repeat(3, 1fr); }
    .internal-shell .meters { grid-template-columns: repeat(4, 1fr); }
    .internal-shell .dhead {
        display: grid; grid-template-columns: var(--cols); column-gap: 14px; align-items: center;
        padding: 9px 8px; border-bottom: 1.5px solid var(--line-strong); background: var(--surface);
    }
    .internal-shell .dhead .hl {
        font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3);
    }
    .internal-shell .drow { grid-template-columns: var(--cols); column-gap: 14px; row-gap: 0; padding: 11px 8px; }
    .internal-shell .dmeta { display: contents; }
    .internal-shell .dmeta .dc[data-l]::before { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .internal-shell * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

/* ==========================================================================
   LEGACY CONTENT HARMONIZATION — STRUCTURAL NEUTRALS ONLY
   --------------------------------------------------------------------------
   docs/AREAS/mobile-design-standards.md §8, the dark-mode trap: site.css has NO
   dark theme — every colour in it is a light-theme literal, which was harmless
   only while those classes rendered on the light-only `_Layout`. The moment a
   view is re-parented into a themed shell, its light literals land on a dark
   surface.

   portal-shell.css's own `.portal-shell .ps-panes` harmonization layer already
   covers the shared `contact-*` / `account-card` / `.btn` / form-control
   families, and this shell inherits it by carrying `.portal-shell`. What it
   does NOT cover is the ledger's own `.flight-log-table` and the alert banner,
   so those STRUCTURAL NEUTRALS — hairlines, header ink, banner surface — are
   re-pointed at the shell's semantic tokens here, which already carry both
   themes, so the fix cannot drift when a token changes.

   ⚠ HONEST SCOPE, AND THIS IS A LIMIT, NOT A CLAIM. This block covers
   structure. It does NOT cover the `flight-record-chip-*` status palette or the
   maintenance status colours, which remain light-theme literals in site.css:
   ~134 rules across the `.flight-record*` / `.flight-log*` / `.account-badge` /
   `.account-list` families carry roughly thirty hard-coded hexes between them.
   NO BROWSER MEASUREMENT OF EITHER THEME HAS BEEN RUN for this wave, so nothing
   here asserts a contrast ratio — §8's rule ("before re-parenting any
   site.css-classed view into a themed shell, MEASURE it in both themes") is
   recorded as owed, not as satisfied.
   ========================================================================== */
.internal-shell .ps-panes .flight-log-table th,
.internal-shell .ps-panes .flight-log-table td {
    border-bottom-color: var(--ps-line);
}
.internal-shell .ps-panes .flight-log-table th { color: var(--ps-ink); }
.internal-shell .ps-panes .flight-log-table { color: var(--ps-ink-2); }
.internal-shell .ps-panes .contact-alert {
    background: var(--ps-surface); border: 1px solid var(--ps-line); color: var(--ps-ink);
    border-radius: var(--radius-sm); padding: 12px 14px;
}
.internal-shell .ps-panes .contact-alert-success { border-color: color-mix(in srgb, var(--ps-good) 40%, transparent); }
.internal-shell .ps-panes .contact-alert-error { border-color: color-mix(in srgb, var(--ps-crit) 40%, transparent); }
.internal-shell .ps-panes .account-list { color: var(--ps-ink-2); }
.internal-shell .ps-panes .account-badge {
    background: var(--ps-surface-2); border: 1px solid var(--ps-line); color: var(--ps-ink-2);
}

/* ==========================================================================
   FW6c BATCH C4 (fw6c/config) — SETTINGS-GROUP MODULE VOCABULARY, ADDITIVE.
   --------------------------------------------------------------------------
   fw6c-wave integration note (accounts+billing+flightops merged first, this
   batch merged last): C4 built its own self-contained `--ip-*` token set and
   duplicated the shell chrome (rail/appbar/sheet) rather than reusing the
   `.ps-*` component `.internal-shell` above already carries. The chrome half
   of that duplicate is DEAD by integrator decision — _InternalPortalLayout.
   cshtml renders the `.ps-*` chrome only, so `.ip-app`/`.ip-rail`/`.ip-appbar`/
   `#ip-portal`/etc. below never match any element on this shell. Kept anyway,
   byte-faithful, rather than hand-pruned during the merge, because:
     1. the integration mandate for this wave is additive — keep both
        batches' rules rather than editorially cut one down mid-merge;
     2. InternalShellStylesheetParseGuardTests (FlightLevel510Website.Tests,
        added by this same batch) asserts the internal-shell rail selector
        below is still present in this exact file;
     3. deleting ~250 dead chrome lines is a real edit or a real page (choose
        one shell vocabulary and convert every Settings-family view to it) —
        recorded as owed, not silently done inside a merge.
   The MODULE-BODY half of this block (`.ip-note`, `.ip-stackcard`,
   `.ip-dtable`, `.ip-chip`, `.ip-wtile`, `.ip-denied`, the legacy site.css
   harmonization rules, …) is LIVE: Views/InternalConfiguration/Index.cshtml,
   InternalPermissions/Index.cshtml, InternalNotifications/Index.cshtml,
   InternalSignatures/Index.cshtml + DispatchAcknowledgmentChain.cshtml, and
   InternalDesignSystem/Index.cshtml all merged cleanly (C4 was the only
   batch to touch them) and render their bodies in this `.ip-*` vocabulary
   inside the `.ps-*`-chromed shell above — the two vocabularies coexist
   because neither shares a selector with the other (`.ip-note` vs `.note`,
   `.ip-chip` vs `.chip`, …), confirmed by grep before this merge landed.
   ========================================================================== */
/* ==========================================================================
   FL510 — INTERNAL PORTAL SHELL (FW6c conversion wave, 2026-08-06)
   --------------------------------------------------------------------------
   Generalizes the accepted /Portal/Billing shell (wwwroot/css/billing-modules.css)
   to every OTHER internal page: a two-tier portal nav (desktop persistent rail +
   mobile #ip-portal :target sheet), an appbar, and module content presented as
   in-flow panes (desktop) / full-viewport pages (mobile). Source of visual truth:
   docs/prototype/internal-design-final.html (the accepted final mock) + its
   "EXTENSION LAYER" (dtable / stackcard / confirm / wtile / denied / etc.) +
   docs/prototype/internal-design-build-spec.md §4 step 4.

   TOKEN RECONCILIATION (translation discipline, same rule billing-modules.css
   states): every colour/space/radius here derives from the EXISTING three-tier
   design system (wwwroot/css/tokens.css). No forked palette. The --ip-* locals
   below are COMPONENT-tier values that reference SEMANTIC --ds-* tokens, so
   light/dark (and the manual [data-theme] toggle) swap in ONE place.

   SCOPE: everything is under `.internal-shell` (which also carries `.ds`), so
   the opt-in contract holds — no bare element is styled, no other page is
   touched. DUPLICATED from billing-modules.css where the shape is identical
   (rail/appbar/sheet/scrim) rather than imported, mirroring that file's own
   documented reason: each shell is independently assertable and one shell's
   CSS can never silently depend on another's file existing.
   ========================================================================== */

.internal-shell {
    /* --- surfaces / ink (semantic tier) --- */
    --ip-bg: var(--ds-surface);
    --ip-surface: var(--ds-surface-raised);
    --ip-surface-2: color-mix(in srgb, var(--ds-surface-raised) 88%, var(--ds-line));
    --ip-line: var(--ds-line);
    --ip-line-strong: color-mix(in srgb, var(--ds-line) 55%, var(--ds-text-secondary));
    --ip-ink: var(--ds-text-primary);
    --ip-ink-2: var(--ds-text-secondary);
    --ip-ink-3: color-mix(in srgb, var(--ds-text-secondary) 78%, var(--ds-surface));
    --ip-ink-faint: color-mix(in srgb, var(--ds-text-secondary) 52%, var(--ds-surface));

    /* --- primary (accent) --- */
    --ip-primary: var(--ds-accent);
    --ip-primary-on: var(--ds-accent-on);
    --ip-primary-wash: color-mix(in srgb, var(--ds-accent) 15%, var(--ds-surface));

    /* --- semantic status + derived washes --- */
    --ip-good: var(--ds-ok);
    --ip-good-wash: color-mix(in srgb, var(--ds-ok) 16%, var(--ds-surface));
    --ip-warn: var(--ds-warn);
    --ip-warn-wash: color-mix(in srgb, var(--ds-warn) 18%, var(--ds-surface));
    --ip-crit: var(--ds-danger);
    --ip-crit-wash: color-mix(in srgb, var(--ds-danger) 16%, var(--ds-surface));
    --ip-info: var(--ds-accent);
    --ip-info-wash: color-mix(in srgb, var(--ds-accent) 12%, var(--ds-surface));

    /* --- geometry / elevation / motion --- */
    --ip-radius: var(--ds-radius-3);
    --ip-radius-sm: var(--ds-radius-2);
    --ip-shadow-card: var(--ds-shadow-1);
    --ip-shadow-pop: var(--ds-shadow-2);
    --ip-shadow-sheet: 0 -8px 40px color-mix(in srgb, var(--ds-text-primary) 22%, transparent);
    --ip-ease: var(--ds-ease);
    --ip-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

    background: var(--ip-bg);
    min-height: 100vh;
    min-height: 100svh;
    color: var(--ip-ink);
}

/* App frame: rail (desktop) + main column. */
.internal-shell .ip-app { min-height: 100vh; min-height: 100svh; }
.internal-shell .ip-main { min-width: 0; display: flex; flex-direction: column; }
.internal-shell .ip-rail { display: none; }
.internal-shell .tnum { font-variant-numeric: tabular-nums; }
.internal-shell .ip-mono { font-family: var(--ip-mono); font-variant-numeric: tabular-nums; }

/* ============ appbar: topbar + KPI strip ============ */
.internal-shell .ip-appbar {
    position: sticky; top: 0; z-index: 30;
    background: color-mix(in srgb, var(--ip-bg) 84%, transparent);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid var(--ip-line);
}
.internal-shell .ip-topbar {
    display: flex; align-items: center; gap: 12px;
    padding: calc(env(safe-area-inset-top, 0px) + 12px) 16px 10px;
}
.internal-shell .ip-brand { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.internal-shell .ip-eyebrow {
    font-size: 10.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--ip-ink-3);
}
.internal-shell .ip-brand h1 {
    margin: 0; font-size: 17px; font-weight: 650; letter-spacing: -.01em;
    display: flex; align-items: center; gap: 8px; line-height: 1.2;
}
.internal-shell .ip-livedot {
    width: 7px; height: 7px; border-radius: 50%; background: var(--ip-good);
    box-shadow: 0 0 0 3px var(--ip-good-wash); flex: none;
}
.internal-shell .ip-topbar .ip-spacer { flex: 1; }
.internal-shell .ip-iconbtn {
    width: 40px; height: 40px; border-radius: 10px; border: 1px solid var(--ip-line);
    background: var(--ip-surface); display: grid; place-items: center; color: var(--ip-ink-2);
    transition: background .15s var(--ip-ease), border-color .15s; flex: none; text-decoration: none;
}
.internal-shell .ip-iconbtn:hover { background: var(--ip-surface-2); border-color: var(--ip-line-strong); }
.internal-shell .ip-iconbtn svg { width: 18px; height: 18px; }

.internal-shell .ip-kpis {
    display: flex; align-items: center; gap: 8px;
    padding: 2px 16px 12px; overflow-x: auto; scrollbar-width: none; margin: 0;
}
.internal-shell .ip-kpis::-webkit-scrollbar { display: none; }
.internal-shell .ip-kpis .ip-plabel { flex: none; font-size: 12px; font-weight: 650; color: var(--ip-ink-2); }
.internal-shell .ip-kpi {
    flex: none; display: inline-flex; align-items: center; gap: 8px; text-decoration: none;
    padding: 7px 11px; border-radius: 10px; background: var(--ip-surface); border: 1px solid var(--ip-line);
    min-height: 40px; transition: border-color .15s, background .15s;
}
.internal-shell .ip-kpi:hover { border-color: var(--ip-line-strong); background: var(--ip-surface-2); }
.internal-shell .ip-kpi .ip-kl { font-size: 11px; font-weight: 600; color: var(--ip-ink-3); white-space: nowrap; }
.internal-shell .ip-kpi .ip-kv {
    font-size: 13px; font-weight: 750; letter-spacing: -.01em;
    font-variant-numeric: tabular-nums; color: var(--ip-ink); white-space: nowrap;
}
.internal-shell .ip-kpi.is-warn .ip-kv { color: var(--ip-warn); }
.internal-shell .ip-kpi.is-good .ip-kv { color: var(--ip-good); }

/* ============ portal nav (shared two-tier chrome) ============ */
.internal-shell .ip-pnav { display: flex; flex-direction: column; gap: 2px; padding: 6px 10px 2px; margin: 0; }
.internal-shell .ip-pitem {
    display: flex; align-items: center; gap: 10px; padding: 10px; border-radius: 10px; min-height: 44px;
    color: var(--ip-ink-2); text-decoration: none; font-size: 13px; font-weight: 600;
    transition: background .13s, color .13s;
}
.internal-shell .ip-pitem svg { width: 17px; height: 17px; flex: none; opacity: .8; }
.internal-shell .ip-pitem .ip-lbl { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.internal-shell .ip-pitem .ip-cnt {
    margin-left: auto; font-size: 10.5px; font-weight: 700; font-variant-numeric: tabular-nums;
    padding: 2px 7px; border-radius: 99px; background: var(--ip-surface-2); border: 1px solid var(--ip-line); color: var(--ip-ink-3);
}
.internal-shell .ip-pitem .ip-cnt.is-attn { color: var(--ip-warn); background: var(--ip-warn-wash); border-color: transparent; }
.internal-shell .ip-pitem:hover { background: var(--ip-surface-2); color: var(--ip-ink); }
.internal-shell .ip-pitem[aria-current="page"] { background: var(--ip-primary-wash); color: var(--ip-primary); }
.internal-shell .ip-pitem[aria-current="page"] svg { opacity: 1; }

/* tier-2 module rail group (mobile: a plain stacked nav under the tier-1 list on the #ip-portal sheet;
   desktop: its own labelled group under the rail). Only the ACTIVE section's group renders — server-picked,
   never a client :has() switch, because this is a real multi-page app, not the mock's one-document SPA. */
.internal-shell .ip-rail__group-label {
    display: block; font-size: 10px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
    color: var(--ip-ink-2); padding: 14px 10px 6px; margin-top: 4px; border-top: 1px solid var(--ip-line);
}
.internal-shell .ip-navitem {
    display: flex; align-items: center; gap: 10px; padding: 10px; border-radius: 10px; min-height: 44px;
    color: var(--ip-ink-2); text-decoration: none; font-size: 13px; font-weight: 600;
    transition: background .13s, color .13s;
}
.internal-shell .ip-navitem svg { width: 17px; height: 17px; flex: none; opacity: .85; }
.internal-shell .ip-navitem .ip-lbl { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.internal-shell .ip-navitem .ip-cnt {
    margin-left: auto; flex: none; font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
    padding: 2px 8px; border-radius: 99px; background: var(--ip-surface-2); border: 1px solid var(--ip-line); color: var(--ip-ink-2);
}
.internal-shell .ip-navitem .ip-cnt.is-attn { color: var(--ip-warn); background: var(--ip-warn-wash); border-color: transparent; }
.internal-shell .ip-navitem .ip-cnt.is-ok { color: var(--ip-good); background: var(--ip-good-wash); border-color: transparent; }
.internal-shell .ip-navitem:hover { background: var(--ip-surface-2); color: var(--ip-ink); }
.internal-shell .ip-navitem[aria-current="page"] { background: var(--ip-primary-wash); color: var(--ip-primary); }
.internal-shell .ip-navitem[aria-current="page"] svg { opacity: 1; }

/* Sign out — POST form, rendered in the desktop rail foot AND the mobile #ip-portal sheet (same reasoning
   and same contract as the billing shell's .bl-signout: suppressing _Layout's site-header removes the only
   sign-out control a shelled page has). 44px min-height is the repo touch standard. */
.internal-shell .ip-signout { margin: 0; padding: 6px 10px 2px; }
.internal-shell .ip-signout__btn {
    display: flex; align-items: center; gap: 10px; width: 100%; padding: 10px; border-radius: 10px;
    min-height: 44px; background: none; border: 0; cursor: pointer; text-align: left;
    color: var(--ip-ink-2); font: inherit; font-size: 13px; font-weight: 600;
    transition: background .13s, color .13s;
}
.internal-shell .ip-signout__btn svg { width: 17px; height: 17px; flex: none; opacity: .8; }
.internal-shell .ip-signout__btn:hover { background: var(--ip-surface-2); color: var(--ip-ink); }

/* ============ scrim + mobile portal sheet ============ */
.internal-shell .ip-scrim {
    position: fixed; inset: 0; z-index: 40; background: color-mix(in srgb, var(--ds-c-ink-900) 42%, transparent);
    opacity: 0; visibility: hidden; transition: opacity .3s var(--ip-ease), visibility .3s;
}
.internal-shell .ip-scrim.is-show { opacity: 1; visibility: visible; }

.internal-shell .ip-sheet {
    background: var(--ip-surface); display: flex; flex-direction: column;
}
.internal-shell #ip-portal.ip-sheet {
    position: fixed; z-index: 50; left: 0; right: 0; bottom: 0; max-height: 90vh;
    border-radius: 20px 20px 0 0; box-shadow: var(--ip-shadow-sheet);
    transform: translateY(100%); visibility: hidden;
    transition: transform .34s var(--ip-ease), visibility 0s linear .34s;
    will-change: transform;
}
.internal-shell #ip-portal.ip-sheet.is-open,
.internal-shell #ip-portal.ip-sheet:target {
    transform: translateY(0); visibility: visible;
    transition: transform .34s var(--ip-ease), visibility 0s;
}
body:has(.internal-shell #ip-portal:target) .internal-shell .ip-scrim { opacity: 1; visibility: visible; }
.internal-shell .ip-grip { width: 38px; height: 4px; border-radius: 99px; background: var(--ip-line-strong); margin: 9px auto 0; flex: none; }
.internal-shell .ip-sheet-head {
    display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--ip-line); flex: none;
}
.internal-shell .ip-sheet-head .ip-glyph {
    width: 32px; height: 32px; border-radius: 9px; flex: none; display: grid; place-items: center;
    background: var(--ip-primary-wash); color: var(--ip-primary);
}
.internal-shell .ip-sheet-head .ip-glyph svg { width: 17px; height: 17px; }
.internal-shell .ip-sheet-title { flex: 1; min-width: 0; }
.internal-shell .ip-sheet-title .ip-kicker { font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ip-ink-3); }
.internal-shell .ip-sheet-title h2 { margin: 1px 0 0; font-size: 17px; font-weight: 660; letter-spacing: -.01em; }
.internal-shell .ip-closebtn {
    width: 40px; height: 40px; border-radius: 9px; border: 1px solid var(--ip-line); background: var(--ip-surface);
    display: grid; place-items: center; color: var(--ip-ink-2); flex: none; text-decoration: none;
}
.internal-shell .ip-closebtn:hover { background: var(--ip-surface-2); }
.internal-shell .ip-closebtn svg { width: 16px; height: 16px; }
.internal-shell #ip-portal .ip-sheet-body { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 6px 2px calc(20px + env(safe-area-inset-bottom, 0px)); }

/* ============ module content pane (each route's body) ============ */
.internal-shell .ip-panes { padding: 8px 12px 60px; }
.internal-shell .ip-modulehead {
    display: flex; align-items: center; gap: 12px; padding: 14px 6px 8px;
}
.internal-shell .ip-modulehead .ip-glyph {
    width: 34px; height: 34px; border-radius: 9px; flex: none; display: grid; place-items: center;
    background: var(--ip-primary-wash); color: var(--ip-primary);
}
.internal-shell .ip-modulehead .ip-glyph svg { width: 18px; height: 18px; }
.internal-shell .ip-modulehead .ip-kicker { font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ip-ink-3); }
.internal-shell .ip-modulehead h1,
.internal-shell .ip-modulehead h2 { margin: 1px 0 0; font-size: 19px; font-weight: 660; letter-spacing: -.01em; }

/* ============ generic module sections (mock's "EXTENSION LAYER" vocabulary) ============ */
.internal-shell .ip-section { padding: 8px 6px 18px; display: flex; flex-direction: column; gap: 14px; }
.internal-shell .ip-sectlbl { font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ip-ink-3); margin: 2px 0 -6px; }
.internal-shell .ip-note { font-size: 12.5px; color: var(--ip-ink-3); line-height: 1.5; margin: 0; }
.internal-shell .ip-stackcard { background: var(--ip-surface-2); border: 1px solid var(--ip-line); border-radius: 12px; padding: 14px; }
.internal-shell .ip-stackcard h3 { margin: 0 0 3px; font-size: 14px; font-weight: 640; color: var(--ip-ink); }

.internal-shell .ip-statgrid {
    display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px;
    background: var(--ip-line); border: 1px solid var(--ip-line); border-radius: 12px; overflow: hidden;
}
.internal-shell .ip-statgrid.four { grid-template-columns: repeat(2, 1fr); }
.internal-shell .ip-statcell { background: var(--ip-surface-2); padding: 13px 14px; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.internal-shell .ip-statcell .ip-sl { font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ip-ink-3); }
.internal-shell .ip-statcell .ip-sv { font-size: 20px; font-weight: 700; letter-spacing: -.02em; line-height: 1.15; font-variant-numeric: tabular-nums; color: var(--ip-ink); }
.internal-shell .ip-statcell .ip-sv small { font-size: 11px; font-weight: 600; color: var(--ip-ink-3); }
.internal-shell .ip-statcell.ok .ip-sv { color: var(--ip-good); }
.internal-shell .ip-statcell.warn .ip-sv { color: var(--ip-warn); }
.internal-shell .ip-statcell.crit .ip-sv { color: var(--ip-crit); }

.internal-shell .ip-slotgrid { display: grid; grid-template-columns: 1fr; gap: 8px; }
.internal-shell .ip-slotline { display: flex; align-items: center; gap: 11px; padding: 11px 13px; background: var(--ip-surface-2); border: 1px solid var(--ip-line); border-radius: 10px; }
.internal-shell .ip-slotline .ip-code { font-family: var(--ip-mono); font-size: 12px; font-weight: 700; color: var(--ip-ink); min-width: 38px; }
.internal-shell .ip-slotline .ip-nm { font-size: 12.5px; color: var(--ip-ink-2); flex: 1; }
.internal-shell .ip-slotline .ip-ok { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 650; color: var(--ip-good); }
.internal-shell .ip-slotline .ip-ok svg { width: 14px; height: 14px; }

.internal-shell .ip-fieldrow { display: grid; grid-template-columns: 1fr; gap: 11px; }
.internal-shell .ip-field { display: flex; flex-direction: column; gap: 5px; }
.internal-shell .ip-field > label { font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ip-ink-3); }
.internal-shell .ip-help { font-size: 11.5px; color: var(--ip-ink-faint); line-height: 1.45; }

.internal-shell .ip-radioset { display: flex; flex-direction: column; gap: 8px; }
.internal-shell .ip-radioline { display: flex; gap: 10px; align-items: flex-start; padding: 11px 12px; background: var(--ip-surface-2); border: 1px solid var(--ip-line); border-radius: 10px; cursor: pointer; }
.internal-shell .ip-radioline input { margin-top: 2px; accent-color: var(--ip-primary); width: 17px; height: 17px; flex: none; }
.internal-shell .ip-radioline b { font-size: 13px; font-weight: 660; display: block; color: var(--ip-ink); }
.internal-shell .ip-radioline .ip-help { display: block; margin-top: 2px; }
.internal-shell .ip-radioline:has(input:checked) { border-color: transparent; background: var(--ip-primary-wash); }
.internal-shell .ip-radioline:has(input:checked) b { color: var(--ip-primary); }

.internal-shell .ip-trail { display: flex; flex-direction: column; gap: 0; padding: 2px 0; }
.internal-shell .ip-trailitem { display: flex; gap: 11px; padding: 9px 0; border-bottom: 1px solid var(--ip-line); }
.internal-shell .ip-trailitem:last-child { border-bottom: none; }
.internal-shell .ip-trailitem .ip-tw { font-size: 11px; color: var(--ip-ink-faint); font-variant-numeric: tabular-nums; flex: none; width: 74px; padding-top: 1px; }
.internal-shell .ip-trailitem .ip-tb { font-size: 12.5px; color: var(--ip-ink-2); line-height: 1.45; min-width: 0; }
.internal-shell .ip-trailitem .ip-tb b { color: var(--ip-ink); font-weight: 650; }

.internal-shell .ip-actrow { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.internal-shell .ip-floorline { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; font-size: 12.5px; color: var(--ip-ink-2); }
.internal-shell .ip-floorline .ip-pin {
    display: inline-flex; align-items: center; gap: 6px; font-weight: 650; color: var(--ip-ink);
    background: var(--ip-surface-2); border: 1px solid var(--ip-line); border-radius: 7px; padding: 4px 9px;
    font-variant-numeric: tabular-nums;
}
.internal-shell .ip-floorline .ip-pin svg { width: 13px; height: 13px; color: var(--ip-good); }
.internal-shell .ip-hint { font-size: 11.5px; color: var(--ip-ink-faint); padding: 0 6px 10px; line-height: 1.5; }

.internal-shell .ip-rowsummary { display: flex; align-items: center; justify-content: space-between; padding: 6px 6px 6px; gap: 10px; flex-wrap: wrap; }
.internal-shell .ip-rowsummary .n { font-size: 12px; color: var(--ip-ink-3); font-weight: 600; }
.internal-shell .ip-rowsummary .n b { color: var(--ip-ink); font-weight: 700; }
.internal-shell .ip-rowsummary .dim { color: var(--ip-ink-faint); font-weight: 500; }

/* ---------- DATA TABLE AT SCALE (phone stacked card -> desktop columns) ---------- */
.internal-shell .ip-dtable { display: flex; flex-direction: column; padding: 0; }
.internal-shell .ip-dhead { display: none; }
.internal-shell .ip-drow {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
    column-gap: 11px; row-gap: 6px; align-items: center;
    padding: 12px 6px; border-bottom: 1px solid var(--ip-line); border-radius: 10px;
    transition: background .12s;
}
.internal-shell .ip-drow:last-child { border-bottom: none; }
.internal-shell .ip-drow:hover { background: var(--ip-surface-2); }
.internal-shell .ip-drow.attn { box-shadow: inset 3px 0 0 var(--ip-warn); }
.internal-shell .ip-drow.crit { box-shadow: inset 3px 0 0 var(--ip-crit); }
.internal-shell .ip-dc { min-width: 0; }
.internal-shell .ip-dc-id { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.internal-shell .ip-dt { font-size: 14px; font-weight: 650; letter-spacing: -.01em; color: var(--ip-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.internal-shell .ip-dsub { font-size: 11.5px; color: var(--ip-ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.internal-shell .ip-dmeta { grid-column: 2; display: flex; flex-wrap: wrap; align-items: center; gap: 5px 14px; min-width: 0; }
.internal-shell .ip-dmeta .ip-dc[data-l]::before {
    content: attr(data-l); display: block;
    font-size: 9.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ip-ink-faint);
    margin-bottom: 1px;
}
.internal-shell .ip-dv { font-size: 12.5px; font-weight: 600; color: var(--ip-ink-2); font-variant-numeric: tabular-nums; }
.internal-shell .ip-dv.strong { color: var(--ip-ink); font-weight: 700; }
.internal-shell .ip-dv.pos { color: var(--ip-good); }
.internal-shell .ip-dv.neg { color: var(--ip-crit); }
.internal-shell .ip-dv.mono { font-family: var(--ip-mono); font-size: 12px; }
.internal-shell .ip-dgo { color: var(--ip-ink-faint); display: grid; place-items: center; width: 28px; height: 28px; text-decoration: none; flex: none; transition: transform .16s var(--ip-ease), color .16s; }
.internal-shell .ip-dgo:hover { color: var(--ip-primary); transform: translateX(2px); }
.internal-shell .ip-dgo svg { width: 17px; height: 17px; }
.internal-shell .ip-drailtail { width: 4px; border-radius: 4px; align-self: stretch; min-height: 34px; flex: none; }

/* ---------- DESTRUCTIVE-ACTION CONFIRMATION ---------- */
.internal-shell .ip-dangerbtn {
    display: inline-flex; align-items: center; gap: 7px; flex: none;
    font-size: 12.5px; font-weight: 680; padding: 9px 15px; border-radius: 9px;
    background: var(--ip-surface); color: var(--ip-crit); border: 1px solid color-mix(in srgb, var(--ip-crit) 38%, transparent);
    transition: background .15s; text-decoration: none;
}
.internal-shell .ip-dangerbtn:hover { background: var(--ip-crit-wash); }
.internal-shell .ip-dangerbtn.solid { background: var(--ip-crit); color: #fff; border-color: transparent; box-shadow: 0 4px 14px color-mix(in srgb, var(--ip-crit) 34%, transparent); }
.internal-shell .ip-dangerbtn.solid:hover { filter: brightness(1.06); background: var(--ip-crit); }
.internal-shell .ip-confirm { position: fixed; inset: 0; z-index: 60; display: none; align-items: flex-end; justify-content: center; }
.internal-shell .ip-confirm:target { display: flex; }
.internal-shell .ip-confirm .ip-cscrim { position: absolute; inset: 0; background: rgba(10, 15, 26, .55); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); }
.internal-shell .ip-confirm .ip-ccard {
    position: relative; z-index: 1; width: 100%; max-width: 470px;
    background: var(--ip-surface); border: 1px solid var(--ip-line-strong);
    border-radius: 20px 20px 0 0; box-shadow: var(--ip-shadow-pop);
    padding: 18px 18px calc(18px + env(safe-area-inset-bottom, 0px));
    display: flex; flex-direction: column; gap: 13px; max-height: 92vh; overflow-y: auto;
}
.internal-shell .ip-confirm .ip-chead { display: flex; gap: 12px; align-items: flex-start; }
.internal-shell .ip-confirm .ip-cicon { width: 38px; height: 38px; border-radius: 11px; flex: none; display: grid; place-items: center; background: var(--ip-crit-wash); color: var(--ip-crit); }
.internal-shell .ip-confirm .ip-cicon svg { width: 19px; height: 19px; }
.internal-shell .ip-confirm h3 { margin: 0; font-size: 16px; font-weight: 670; letter-spacing: -.01em; color: var(--ip-ink); }
.internal-shell .ip-confirm .ip-cwhat { font-size: 12.5px; color: var(--ip-ink-3); margin-top: 2px; line-height: 1.45; }
.internal-shell .ip-conseq { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.internal-shell .ip-conseq li { display: flex; gap: 9px; font-size: 12.5px; color: var(--ip-ink-2); line-height: 1.45; }
.internal-shell .ip-conseq li::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--ip-crit); flex: none; margin-top: 7px; }
.internal-shell .ip-conseq li.keep::before { background: var(--ip-good); }
.internal-shell .ip-conseq b { color: var(--ip-ink); font-weight: 680; }
.internal-shell .ip-cfoot { display: flex; gap: 9px; align-items: center; padding-top: 3px; }
.internal-shell .ip-cfoot .sp { flex: 1; }

/* ---------- EMPTY / DENIED STATES ---------- */
.internal-shell .ip-empty { margin: 10px 0; padding: 28px 16px; text-align: center; color: var(--ip-ink-3); font-size: 12.5px; border: 1.5px dashed var(--ip-line-strong); border-radius: 12px; }
.internal-shell .ip-empty strong { color: var(--ip-ink-2); display: block; font-size: 13.5px; font-weight: 650; margin-bottom: 4px; }
.internal-shell .ip-empty.good { border-color: color-mix(in srgb, var(--ip-good) 32%, transparent); color: var(--ip-good); }
.internal-shell .ip-empty.good strong { color: var(--ip-good); }
.internal-shell .ip-denied { margin: 0; padding: 18px; border-radius: 13px; display: flex; gap: 13px; align-items: flex-start; background: var(--ip-surface-2); border: 1px solid var(--ip-line); }
.internal-shell .ip-denied .ip-dicon { width: 36px; height: 36px; border-radius: 10px; flex: none; display: grid; place-items: center; background: var(--ip-warn-wash); color: var(--ip-warn); }
.internal-shell .ip-denied .ip-dicon svg { width: 18px; height: 18px; }
.internal-shell .ip-denied h3 { margin: 0 0 4px; font-size: 14px; font-weight: 660; color: var(--ip-ink); }
.internal-shell .ip-denied p { margin: 0; font-size: 12.5px; color: var(--ip-ink-3); line-height: 1.5; }
.internal-shell .ip-denied p + p { margin-top: 7px; }
.internal-shell .ip-denied code { font-family: var(--ip-mono); font-size: 11px; background: var(--ip-surface); border: 1px solid var(--ip-line); padding: 1px 6px; border-radius: 6px; color: var(--ip-ink-2); }

/* ---------- VERDICT / CHIP / PILL / MBTN ---------- */
.internal-shell .ip-verdict { display: flex; gap: 10px; padding: 11px 12px; border-radius: 11px; background: var(--ip-good-wash); border: 1px solid color-mix(in srgb, var(--ip-good) 22%, transparent); }
.internal-shell .ip-verdict .ip-vicon { color: var(--ip-good); flex: none; margin-top: 1px; }
.internal-shell .ip-verdict .ip-vicon svg { width: 16px; height: 16px; display: block; }
.internal-shell .ip-verdict .ip-vtext { font-size: 12.5px; line-height: 1.5; color: var(--ip-ink); }
.internal-shell .ip-verdict .ip-vtext b { font-weight: 700; color: var(--ip-good); }
.internal-shell .ip-verdict.warn { background: var(--ip-warn-wash); border-color: color-mix(in srgb, var(--ip-warn) 26%, transparent); }
.internal-shell .ip-verdict.warn .ip-vicon, .internal-shell .ip-verdict.warn .ip-vtext b { color: var(--ip-warn); }
.internal-shell .ip-verdict.info { background: var(--ip-info-wash); border-color: color-mix(in srgb, var(--ip-info) 24%, transparent); }
.internal-shell .ip-verdict.info .ip-vicon, .internal-shell .ip-verdict.info .ip-vtext b { color: var(--ip-info); }

.internal-shell .ip-chip {
    display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 600; line-height: 1;
    padding: 5px 9px; border-radius: 999px; background: var(--ip-surface-2); color: var(--ip-ink-2); border: 1px solid var(--ip-line);
    /* Every current .ip-chip is the _InboxChips.cshtml filter anchor — an actual tap target, not a static
       label. 44px min-height is the repo touch standard (see the sign-out control comment above); box-sizing
       keeps the 1px border inside that box rather than growing past it. text-decoration:none because this
       chip is an <a>, unlike most .ip-* idioms below which are buttons and already borderless. */
    min-height: 44px; box-sizing: border-box; text-decoration: none;
}
.internal-shell .ip-chip .n { font-variant-numeric: tabular-nums; color: var(--ip-ink); font-weight: 700; }
.internal-shell .ip-chip.hero { background: var(--ip-good-wash); border-color: transparent; color: var(--ip-good); }
.internal-shell .ip-chip.hero .n { color: var(--ip-good); }
.internal-shell .ip-chip.attn { background: var(--ip-warn-wash); border-color: transparent; color: var(--ip-warn); }
.internal-shell .ip-chip.attn .n { color: var(--ip-warn); }
.internal-shell .ip-chip.crit { background: var(--ip-crit-wash); border-color: transparent; color: var(--ip-crit); }
.internal-shell .ip-chip.info { background: var(--ip-info-wash); border-color: transparent; color: var(--ip-info); }
.internal-shell .ip-chip.zero { opacity: .72; }
.internal-shell .ip-chip.dot::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .85; margin-right: 1px; }

.internal-shell .ip-pill {
    display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px; font-weight: 700; letter-spacing: .02em;
    padding: 3px 8px; border-radius: 999px; flex: none;
}
.internal-shell .ip-pill.ok, .internal-shell .ip-pill.clean, .internal-shell .ip-pill.released { background: var(--ip-good-wash); color: var(--ip-good); }
.internal-shell .ip-pill.hold { background: var(--ip-warn-wash); color: var(--ip-warn); }
.internal-shell .ip-pill.recon, .internal-shell .ip-pill.info { background: var(--ip-info-wash); color: var(--ip-info); }
.internal-shell .ip-pill.p1 { background: var(--ip-crit-wash); color: var(--ip-crit); }
.internal-shell .ip-pill.p2 { background: var(--ip-warn-wash); color: var(--ip-warn); }
.internal-shell .ip-pill.p3 { background: var(--ip-info-wash); color: var(--ip-info); }
.internal-shell .ip-pill.neutral, .internal-shell .ip-pill.muted { background: var(--ip-surface-2); color: var(--ip-ink-3); box-shadow: inset 0 0 0 1px var(--ip-line); }
.internal-shell .ip-pill.dot::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }

.internal-shell .ip-mbtn {
    font-size: 12px; font-weight: 600; padding: 8px 12px; border-radius: 8px; text-decoration: none;
    border: 1px solid var(--ip-line-strong); background: var(--ip-surface); color: var(--ip-ink);
    display: inline-flex; align-items: center; gap: 6px;
    transition: background .15s, border-color .15s;
}
.internal-shell .ip-mbtn:hover { background: var(--ip-surface-2); }
.internal-shell .ip-mbtn.solid { background: var(--ip-primary); color: var(--ip-primary-on); border-color: transparent; }
.internal-shell .ip-mbtn.solid:hover { filter: brightness(1.05); background: var(--ip-primary); }
.internal-shell .ip-mbtn svg { width: 14px; height: 14px; }

/* ---------- WORK ITEM (Operations inbox tiles) ---------- */
.internal-shell .ip-wlist { display: flex; flex-direction: column; gap: 9px; }
.internal-shell .ip-wtile {
    position: relative; display: flex; gap: 10px; align-items: center; text-decoration: none; color: inherit;
    background: var(--ip-surface-2); border: 1px solid var(--ip-line); border-radius: 12px;
    padding: 12px 13px 12px 16px; transition: border-color .14s, background .14s;
}
.internal-shell .ip-wtile::before { content: ""; position: absolute; left: 0; top: 12px; bottom: 12px; width: 3px; border-radius: 3px; background: var(--ip-info); }
.internal-shell .ip-wtile.t0::before { background: var(--ip-crit); }
.internal-shell .ip-wtile.t1::before { background: var(--ip-warn); }
.internal-shell .ip-wtile.t2::before { background: var(--ip-info); }
.internal-shell .ip-wtile.t3::before { background: var(--ip-line-strong); }
.internal-shell .ip-wtile:hover { border-color: var(--ip-line-strong); background: var(--ip-surface); }
.internal-shell .ip-wtile .ip-wbody { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.internal-shell .ip-wl1 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.internal-shell .ip-wsrc { font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ip-ink-3); }
.internal-shell .ip-wage { margin-left: auto; font-size: 11px; color: var(--ip-ink-faint); font-weight: 650; font-variant-numeric: tabular-nums; flex: none; }
.internal-shell .ip-wt { font-size: 13.5px; font-weight: 650; letter-spacing: -.01em; color: var(--ip-ink); line-height: 1.35; }
.internal-shell .ip-wc { font-size: 12px; color: var(--ip-ink-3); line-height: 1.5; }
.internal-shell .ip-wc b { color: var(--ip-ink-2); font-weight: 650; }
.internal-shell .ip-wtile > .go { color: var(--ip-ink-faint); flex: none; transition: transform .16s var(--ip-ease), color .16s; }
.internal-shell .ip-wtile:hover > .go { transform: translateX(3px); color: var(--ip-primary); }
.internal-shell .ip-wtile > .go svg { width: 17px; height: 17px; display: block; }

/* ---------- CHIP FILTERS AS A REAL GET FORM ---------- */
/* _InboxChips.cshtml renders these as <a class="ip-chip"> inside a <nav> (a real GET-addressable link per
   chip, not a <form>+<button> submit) — so these rules are unqualified by element, matching the anchor.
   The 44px touch-target min-height lives on the shared .ip-chip base rule above. */
.internal-shell .ip-chipform { display: flex; gap: 6px; flex-wrap: wrap; margin: 0; padding: 0; border: 0; background: none; }
.internal-shell .ip-chip { cursor: pointer; transition: background .14s, border-color .14s, color .14s; }
.internal-shell .ip-chip[aria-pressed="true"] { background: var(--ip-primary-wash); border-color: transparent; color: var(--ip-primary); }
.internal-shell .ip-chip[aria-pressed="true"] .n { color: var(--ip-primary); }

/* ============ DESKTOP >= 900px — persistent rail + content pane ============ */
@media (min-width: 900px) {
    .internal-shell .ip-app { display: flex; align-items: stretch; }
    .internal-shell .ip-rail {
        display: flex; flex-direction: column; width: 240px; flex: none;
        position: sticky; top: 0; align-self: flex-start; height: 100vh; height: 100svh;
        background: var(--ip-surface); border-right: 1px solid var(--ip-line); z-index: 35; overflow-y: auto;
    }
    .internal-shell .ip-rail__label {
        font-size: 10px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--ip-ink-3); padding: 18px 20px 8px;
    }
    .internal-shell .ip-rail__nav { display: flex; flex-direction: column; gap: 3px; padding: 0 10px 10px; }
    .internal-shell .ip-rail .ip-pnav { padding: 6px 10px 2px; }
    .internal-shell .ip-rail__spacer { flex: 1; }
    .internal-shell .ip-rail__foot {
        position: sticky; bottom: 0; z-index: 1; background: var(--ip-surface);
        border-top: 1px solid var(--ip-line); padding: 8px 16px;
    }
    .internal-shell .ip-rail__foot .ip-signout { padding: 0; }
    .internal-shell .ip-rail__foot .ip-signout__btn { padding: 8px 10px; margin-left: -10px; }

    .internal-shell .ip-main { flex: 1; min-width: 0; }
    .internal-shell .ip-topbar { padding: 18px 28px 10px; }
    .internal-shell .ip-kpis { padding: 2px 28px 14px; }
    .internal-shell #ip-menuBtn { display: none; }
    .internal-shell .ip-panes { padding: 18px 28px 60px; max-width: 1140px; width: 100%; }
    .internal-shell .ip-scrim { display: none !important; }
    /* #ip-portal is MOBILE-ONLY chrome (mirrors the billing shell's identical #bl-portal rule and the
       identical pre-existing defect it fixed: without this, a desktop viewport on a URL still carrying
       #ip-portal paints the sheet over the rail). */
    .internal-shell #ip-portal { display: none !important; }

    .internal-shell .ip-statgrid.four { grid-template-columns: repeat(4, 1fr); }
    .internal-shell .ip-radioset { flex-direction: row; }
    .internal-shell .ip-radioset .ip-radioline { flex: 1; }
    .internal-shell .ip-fieldrow { grid-template-columns: 1fr 1fr; }
    .internal-shell .ip-fieldrow .wide { grid-column: 1 / -1; }
    .internal-shell .ip-slotgrid { grid-template-columns: repeat(3, 1fr); }
    .internal-shell .ip-confirm { align-items: center; padding: 24px; }
    .internal-shell .ip-confirm .ip-ccard { border-radius: 16px; padding: 22px; }
    .internal-shell .ip-dtable { padding: 0; }
    .internal-shell .ip-dhead {
        display: grid; grid-template-columns: var(--cols); column-gap: 14px; align-items: center;
        padding: 9px 8px; border-bottom: 1.5px solid var(--ip-line-strong); background: var(--ip-surface);
    }
    .internal-shell .ip-dhead .ip-hl { font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ip-ink-3); }
    .internal-shell .ip-drow { grid-template-columns: var(--cols); column-gap: 14px; row-gap: 0; padding: 11px 8px; }
    .internal-shell .ip-dmeta { display: contents; }
    .internal-shell .ip-dmeta .ip-dc[data-l]::before { display: none; }
}

/* ============ legacy site.css content harmonization ============
   Several converted pages keep dense EXISTING account-card/flight-log-table/contact-form markup rather than
   re-authoring every field into the .ip-dtable pattern (proportionate effort for this pass — recorded in the
   wave's openQuestions). site.css is light-only (mobile-design-standards.md §8, the dark-mode-trap rule), so
   its literal colours are re-pointed at this shell's semantic tokens here, scoped to .internal-shell, exactly
   the pattern billing-modules.css already established for the same classes. A page carrying the same class
   OUTSIDE this shell (still on _Layout) is byte-for-byte unaffected. */
.internal-shell .account-card {
    background: var(--ip-surface); border: 1px solid var(--ip-line); border-radius: var(--ip-radius);
    box-shadow: var(--ip-shadow-card); color: var(--ip-ink);
}
.internal-shell .account-card h2, .internal-shell .account-card h3 { color: var(--ip-ink); }
.internal-shell .account-stat { color: var(--ip-ink); }
.internal-shell .account-field-help { color: var(--ip-ink-3); }
.internal-shell .account-field-value { color: var(--ip-ink); }
.internal-shell .account-badge { background: var(--ip-good-wash); border-color: transparent; color: var(--ip-good); }
.internal-shell .contact-heading { color: var(--ip-ink); }
.internal-shell .contact-copy { color: var(--ip-ink-2); }
.internal-shell .contact-input, .internal-shell .contact-textarea {
    background: var(--ip-surface-2); border: 1px solid var(--ip-line-strong); color: var(--ip-ink);
}
.internal-shell .configuration-toggle { background: var(--ip-surface-2); border-color: var(--ip-line); }
.internal-shell .configuration-toggle-group { color: var(--ip-ink); }
.internal-shell .contact-alert-success { background: var(--ip-good-wash); color: var(--ip-good); border-color: color-mix(in srgb, var(--ip-good) 34%, transparent); }
.internal-shell .contact-alert-error, .internal-shell .contact-alert-danger { background: var(--ip-crit-wash); color: var(--ip-crit); border-color: color-mix(in srgb, var(--ip-crit) 34%, transparent); }
.internal-shell .contact-alert-info, .internal-shell .contact-alert-warning { background: var(--ip-info-wash); color: var(--ip-info); border-color: color-mix(in srgb, var(--ip-info) 34%, transparent); }
.internal-shell .flight-log-table-wrap { overflow-x: auto; }
.internal-shell .flight-log-table { width: 100%; border-collapse: collapse; }
.internal-shell .flight-log-table th { color: var(--ip-ink-3); text-align: left; white-space: nowrap; font-weight: 700; }
.internal-shell .flight-log-table td, .internal-shell .flight-log-table th { border-color: var(--ip-line); border-bottom: 1px solid var(--ip-line); padding: 0.6rem 0.6rem; vertical-align: top; }
.internal-shell .account-detail-list dt { color: var(--ip-ink-3); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; margin-top: 10px; }
.internal-shell .account-detail-list dd { color: var(--ip-ink); margin: 2px 0 0; }
.internal-shell .btn {
    min-height: 44px; border-radius: var(--ip-radius-sm); font-weight: 600;
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.internal-shell .btn-primary { background: var(--ip-primary); border-color: transparent; color: var(--ip-primary-on); }
.internal-shell .btn-primary:hover { filter: brightness(1.05); color: var(--ip-primary-on); }
.internal-shell .btn-secondary { background: var(--ip-surface); border-color: var(--ip-line-strong); color: var(--ip-ink); }
.internal-shell .btn-secondary:hover { background: var(--ip-surface-2); border-color: var(--ip-primary); color: var(--ip-primary); }

@media (prefers-reduced-motion: reduce) {
    .internal-shell * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

/* PARSE SENTINEL — must remain the LAST rule in this file. See the header. */
.internal-shell .fw6c-parse-sentinel { display: none; }
