/* ================= THE STRIDE SETTINGS DESIGN SYSTEM =================
   Owns the one `.stg-*` visual language shared by every settings surface — Team settings
   (`#adminModal`/`.admin-pane` in team_board.html) and My Settings. Implements
   `_docs/_system/sys_stride-settings-design.md` §1-§5 and §8: the settings-only token layer,
   the concern colour system, the collapsible section-card component, the note/swatch
   components, THE DIALOG HEADER (§5), and the narrow-width header collapse. The header is
   shared deliberately — it is the single most visible chrome both dialogs have, and a header
   built twice is the duplication CLAUDE.md's "one canonical implementation" forbids. What
   differs between hosts is content only (team name+role vs "My Settings", eyebrow/subtitle
   present or not) — never the classes. Read the spec before changing anything here; its class
   and token names are a frozen contract.

   THIS FILE IS BYTE-IDENTICAL ACROSS TWO BRANCHES (`stride-configure-team-redesign` and
   `stride-my-settings-redesign`) PER THE SHARED-FILE PROTOCOL. Written ONCE, here, copied
   verbatim into the other branch — do not "improve" one side's copy; a divergence here is the
   defect the protocol exists to prevent, since Git can only merge an identical change on both
   branches without a conflict. A needed change after the branches are synced is a requirement
   for the orchestrator to re-sync both sides together, never an edit either lane makes alone.

   REUSE FIRST. `.a-card`, `.pref-row`/`.pref-copy`/`.pref-title`/`.pref-desc`, `.pref-switch`,
   `.a-check-l`, `.a-btn`, `.empty-state`, `.add-row`, `.role-badge` and `.a-chip` are NOT
   redefined here — general component vocabulary (`sys_design-system.md` §4b/§8/§14a), used
   unchanged inside `.stg-sec-body`. This file adds only what the spec's §4 marks "new."

   THEME. Dark is the default palette (on bare `.stg-shell`), light restated under
   `body.theme-light`/`:root.theme-light`, matching every other CSS/alt/ file. Both the
   compound form (`.stg-shell` IS the themed element) and the descendant form (nested inside a
   themed body) are covered below — alt-tokens.css already paid for the lesson that guessing
   wrong here means a theme rule silently never matches. */

.stg-shell{
  /* §1a. Brand constants — fixed, unthemed, unconfigurable. These three hexes match today's
     dark-theme `--accent`/`--accent-2`/`--green` but are LITERAL, never `var()`: a team's
     custom theme (JS/core/theme-custom.js) overrides those tokens at <html>, and the ribbon is
     the one thing on a settings dialog that must look identical on every team regardless. Do
     not refactor this into a role reference. */
  --stg-ribbon-from:#2f82ff;
  --stg-ribbon-via:#28a9e8;
  --stg-ribbon-to:#13b981;
  --stg-ribbon:linear-gradient(135deg,var(--stg-ribbon-from) 0%,var(--stg-ribbon-via) 40%,var(--stg-ribbon-to) 100%);
  --stg-ribbon-soft:linear-gradient(135deg,rgba(47,130,255,.22),rgba(19,185,129,.13));

  /* §1b. Structural roles, reused from the canonical --a-* ramp — settings-only NAMES pointing
     at roles alt-tokens.css already derived, so light theme and a custom team palette come free. */
  --stg-surface:var(--a-panel);
  --stg-surface-2:var(--a-raised);
  --stg-line:var(--a-line-soft);
  --stg-line-strong:var(--a-line-strong);
  --stg-text:var(--a-text);
  --stg-dim:var(--a-dim);
  --stg-faint:var(--a-faint);
  --stg-r:var(--a-r);
  --stg-r-lg:var(--a-r-lg);
  --stg-shadow:var(--a-shadow-sm);
  /* Larger than `.a-panel-ico`'s 22px because it's the section's primary identifier, not a
     supporting glyph beside an already-larger title. */
  --stg-tile-size:44px;
  --stg-tile-glyph:18px;

  /* §1c. Focus — reuse, not a second focus treatment for settings controls. */
  --stg-ring:var(--a-ring);

  /* §2. The concern colour system — four families, not thirteen. Rewritten on the product
     owner's report that the settings icons "seem random"; the full inventory and every
     measurement are in sys_stride-settings-design.md §2.
     WHAT WAS WRONG: the SCHEME, not drift. Ten distinct hexes resolved in dark, nine in light —
     `team` and `view` were byte-identical (#1c5fb8) in light, the two largest groups (25 and 23
     rows) painting the same colour. And thirteen categories is past what a reader can hold —
     five were used once or twice, `import`/`ai` were categories of one.
     THE FOUR FAMILIES, and the question each answers:
       BLUE    --stg-c-team       who is here, and which container this is           30 tiles
       PURPLE  --stg-c-taxonomy   how work is filed                                    7 tiles
       CYAN    --stg-c-view       what you see and how it looks                       23 tiles
       GOLD    --stg-c-email      anything leaving the product                        16 tiles
     Tallies are MEASURED (76 tiles/theme, both surfaces, settings-concern-colour-probe.py) and
     will drift as panes are added — the four families and the dE floor are the contract, the
     counts are not.
     MEASURED SEPARATION (CIE76 dE, minimum over every surviving pair): dark 27.4, light 24.4 —
     against 0.0 in both themes before this change. Blue/purple is the weakest pair in both
     themes — nothing collapses on a theme flip. Do not add a fifth family without re-running
     that minimum.
     PEOPLE AND TEAMS ARE ONE COLOUR ON THE OWNER'S OWN INSTRUCTION: "things related to users or
     teams, color them one colour" — overriding a tidier taxonomy that would have kept `Team
     admins` and `Team details` apart, the exact tile he flagged.
     Ten names survive as ALIASES, not deletions — every `data-concern` attribute already in the
     product stays valid, so no markup moved. A new concern is a new alias here, never a new hue. */

  /* The four canonical family colours — only these four carry a literal hex. */
  --stg-c-team:#69a8ff;
  --stg-c-taxonomy:#b99aff;
  /* Cyan is the one new value in this pass, replacing three tokens (`view`/`links`/`workspace`)
     — both existing candidates measured and failed (old `view` was byte-identical to team blue
     in light; old `links`/`workspace` were dE 3.9/11.6 from their neighbours). This value is
     dE >= 45.4 from every surviving family in both themes. */
  --stg-c-view:#2cc8dd;
  --stg-c-email:#ffc45d;

  /* The ten aliases — a concern name maps to a family, never carries its own hue.
     `people`/`okr`/`board`/`lock` -> BLUE: Team admins, Org Owners, Invite people, group cards,
     OKR access and Account rows are all "who is here"; a board is a container people belong to.
     NOTE THE INVERSION: `taxonomy` used to alias `board`; `board` now points at blue and
     `taxonomy` is its own canonical purple — no taxonomy row changed colour. */
  --stg-c-people:var(--stg-c-team);
  --stg-c-okr:var(--stg-c-team);
  --stg-c-board:var(--stg-c-team);
  /* `lock` was undefined and silently fell back to team blue through the tile's own
     `var(--stg-c, var(--stg-c-team))` — no console error, no failing test. Now blue ON PURPOSE
     (credentials are the reader's own access). The JS still spells it `lock` rather than
     `people` at JS/alt/alt-settings.js — a separate defect, reported rather than fixed here; do
     not remove this alias until that spelling changes. */
  --stg-c-lock:var(--stg-c-team);

  /* `import`/`ai`/`data` -> GOLD: all three cross the boundary the mail rows cross — content
     leaving the product, or being removed from it. AI is the substantive one: the reader's key
     and content go to a third party, the trust boundary sys_ai.md already draws. */
  --stg-c-import:var(--stg-c-email);
  --stg-c-ai:var(--stg-c-email);
  --stg-c-data:var(--stg-c-email);

  /* `time`/`links`/`workspace` -> CYAN. `time` was never about time: swimlane length, how long
     a finished task stays visible, the heavy-day alert, time zones and weather are all a
     display window or a widget — what this surface SHOWS, never something it sends anywhere. */
  --stg-c-time:var(--stg-c-view);
  --stg-c-links:var(--stg-c-view);
  --stg-c-workspace:var(--stg-c-view);

  /* "Locked" (no permission) is a status OVERRIDE, not one of the thirteen concerns — it
     REPLACES a concern's hue rather than competing with it, hence its own three-part token.
     Dark values are the kit's own `.wf-note.lock`; light values reuse the already-measured
     slate roles (--text-dim/--border/--panel-2) rather than inventing three unmeasured hexes. */
  --stg-c-locked:#95a8bb;
  --stg-c-locked-line:#334c66;
  --stg-c-locked-bg:#101d2a;
}

:root.theme-light .stg-shell,
:root.theme-light.stg-shell,
body.theme-light .stg-shell,
body.theme-light.stg-shell{
  /* The ribbon does not invert by theme — a brand mark doesn't change hue because the page did
     — but the soft wash needs less alpha on a white ground or it reads as a grey smear. */
  --stg-ribbon-soft:linear-gradient(135deg,rgba(47,130,255,.14),rgba(19,185,129,.08));

  /* Only the four canonical hues are restated — every alias resolves through its family and so
     follows for free, which is what the suite's light/dark split check polices. Measured
     minimum pair dE here: 24.4 (blue/purple), against 0.0 before this change. */
  --stg-c-team:#1c5fb8;
  --stg-c-taxonomy:#6b4894;
  /* dE 45.4 from blue, 51.2 from purple, 67.3 from gold. White-glyph contrast on the tile's
     gradient is 6.11:1 at the start stop, 9.28:1 at the end — over the 3:1 WCAG 1.4.11 floor a
     control foreground needs, and over 4.5:1 besides. */
  --stg-c-view:#116b80;
  --stg-c-email:#6d4e00;

  /* The ten aliases are NOT repeated here, deliberately — each is `var(--stg-c-<family>)` in the
     dark block, re-resolving against whichever family value is in scope. Restating them would
     be a second place for light to disagree with dark. */

  /* Reused measured slate, not a fourth palette — see the dark block's own comment above. */
  --stg-c-locked:var(--a-dim);
  --stg-c-locked-line:var(--a-line);
  --stg-c-locked-bg:var(--a-raised);
}

/* ================= §5. THE SHELL HEADER — shared by BOTH dialogs =================
   Every settings dialog draws this once, at the top:
     [ribbon: 3px, --stg-ribbon, full width, top edge]
     [S-mark]  <eyebrow, Team settings only>            ×
               <Title>
               <Subtitle>
     [tab strip]
   ONE set of classes, TWO hosts, content-only difference: Team settings has the eyebrow
   "STRIDE · TEAM SETTINGS" present, title is the TEAM's own name (never STRIDE's, per
   sys_branding.md's product/team split), subtitle is "<role> · <team>". My Settings has no
   eyebrow (not team-scoped) — instead the mark and `stride-wordmark.svg` sit inline on one line
   before the title; no subtitle.
   `.stg-head` is a flex row; whichever piece a host omits is simply not in that host's markup —
   never present-and-hidden. `.stg-head-copy` grows to fill the space to the close button, so it
   lands flush right with no `margin-left:auto` on it.
   THE MARK IS ALWAYS stride-mark.svg/stride-wordmark.svg, NEVER A TEAM'S OWN UPLOADED MARK — a
   team's custom mark has its own place (the shell corner, the Team-mark settings row);
   substituting it here is the two-marks-fighting-for-one-slot defect sys_branding.md closes. */

.stg-head{
  position:relative;
  display:flex;
  align-items:center;
  gap:var(--a-3);
  padding:16px 18px 13px;
  border-bottom:1px solid var(--stg-line-strong);
  background:linear-gradient(180deg, var(--stg-surface-2), var(--stg-surface));
}
/* The one ribbon strip both dialogs share, 3px, full width — `.stg-head` must be the FIRST
   child inside the dialog card for this to read as the card's edge, not a rule under a gap. */
.stg-head::before{
  content:"";
  position:absolute; left:0; right:0; top:0; height:3px;
  background:var(--stg-ribbon);
}

/* The `[S]` mark, `stride-mark.svg`, 30×28 — see the file header on why never a team's mark. */
.stg-head-mark{
  flex:0 0 auto;
  display:block;
  width:30px; height:28px;
}
/* The wordmark, My Settings only, beside the mark — a SEPARATE element from `.stg-eyebrow`
   below even though both can say "STRIDE": this is the lockup wordmark, that is a small-caps
   label.
   LIVE TEXT, NOT AN IMAGE — there is no `stride-wordmark.svg` to point an <img> at. Mirrors
   `index.html`'s `.stride-lockup-word` (mark as <img>, word set in the display face) rather
   than inventing a second answer. Text themes, scales and translates; a raster does none of
   the three — do not "fix" this by adding a wordmark asset. */
.stg-head-word{
  flex:0 0 auto;
  font-family:var(--display); font-weight:700; font-size:15px;
  letter-spacing:.01em; color:var(--stg-text);
  line-height:1;
}

/* The text stack — eyebrow (optional) / title / subtitle (optional) — the flexible member that
   pushes a trailing close button right by growing, not by margin on the button. */
.stg-head-copy{
  min-width:0;
  flex:1 1 auto;
}

/* `STRIDE · TEAM SETTINGS` — Team settings only. A brand constant, same rule as §1a: fixed,
   unthemed, never a concern colour. Reads as a THIRD colour distinct from the ribbon because it
   sits on dark chrome where the ribbon's own colours are already at full saturation above it. */
.stg-eyebrow{
  display:block;
  margin-bottom:2px;
  font-size:9px;
  font-weight:800;
  letter-spacing:.15em;
  text-transform:uppercase;
  color:#6ed7c5;
}

.stg-head-t{
  margin:0;
  font-size:18px;
  line-height:1.15;
  font-weight:750;
  letter-spacing:-.015em;
  color:var(--stg-text);
}

.stg-head-sub{
  margin-top:1px;
  font-size:11px;
  line-height:1.35;
  color:var(--stg-dim);
}

/* ================= §3. THE SECTION CARD COMPONENT =================
   `.admin-pane`'s current flat `.pref-row` list, wrapped and re-sectioned — this IS
   `sys_design-system.md` §6's collapsible-section rule (chevron left, whole header row is the
   hit target, header keeps a state summary, toggle persists), the concrete anatomy for
   settings, not a competing pattern.
   Markup (this file styles it, does not generate it):
     <section class="a-card stg-sec" data-concern="okr">
       <button type="button" class="stg-sec-h" aria-expanded="false" aria-controls="stg-body-okr">
         <svg class="stg-chev" aria-hidden="true">…</svg>
         <span class="stg-sec-ico" data-concern="okr" aria-hidden="true">…</span>
         <span class="stg-sec-copy">
           <span class="stg-sec-t">Title</span>
           <span class="stg-sec-d">Description</span>
         </span>
         <span class="stg-sec-state">Enabled</span>
       </button>
       <div class="stg-sec-body" id="stg-body-okr" hidden>…</div>
     </section>
   `aria-expanded` on the button is the single source of truth for open/closed (spec §7);
   `.is-open` is a MIRROR a host's toggle may also set on `.stg-sec` for engines without
   `:has()` — never an independently tracked class. Both forms are written below. */

.stg-sec{
  /* `.a-card` already supplies background/border/radius — this adds the accent edge's room, the
     stacking context under it, and the gap between cards. */
  position:relative;
  overflow:hidden;
  /* NEVER SHRINK. `.admin-pane.active` is a flex COLUMN, so every card is a flex item, and
     `overflow:hidden` above removes a flex item's automatic minimum size — with the default
     `flex-shrink:1` the browser crushes all six cards to fit the pane's visible height instead
     of overflowing, so each collapses to a ~16px sliver AND the pane never scrolls (no overflow
     to scroll). Measured: scrollHeight 618px against clientHeight 617.8px — exactly zero. Both
     halves of the report ("too tight", no scrollbar) were this one fact. */
  flex-shrink:0;
  margin-bottom:10px;
  box-shadow:var(--stg-shadow);
  transition:border-color var(--a-quick) var(--a-ease);
}
/* THE GAP BELONGS TO THE CONTAINER, because the container is a flex column — `margin-bottom`
   on `.stg-sec` is the only thing separating cards, so a sibling that is NOT a `.stg-sec` (the
   Team Insights launcher, the Import pane's dropzone block) contributes no spacing at all and
   sits flush against its neighbour. A `margin-top` would not fix it: flex items don't collapse
   margins, so every existing 10px gap would become 20px. The container owns the spacing
   instead, spacing every child whatever it is, with the card's own margin dropped where the gap
   now applies. My Settings already works this way (`.a-drawer-b`'s `row-gap:12px`). */
.alt-app #adminModal .admin-pane.active{ row-gap:10px; }
.alt-app #adminModal .admin-pane.active > .stg-sec{ margin-bottom:0; }
/* A little more than the card gap under the pane head — zeroing it entirely left Expand
   all/Collapse all the same 10px off the first card as two cards sit off each other, reading as
   though the controls belong to the card below rather than the pane. 6px on top of the
   container's row-gap gives 16px. */
.alt-app #adminModal .admin-pane.active > .stg-pane-head{ margin-bottom:6px; }

/* ================= MY SETTINGS' OWN PANE HEAD — THE SAME TWO CLASSES, A DIFFERENT SCOPE =====
   `.stg-pane-head`/`.stg-pane-actions`/`.stg-fold-mount` already exist as alt-team.css's
   `#adminModal`-scoped rules, for Configure Team's twelve admin-panes. My Settings draws the
   identical markup (altRenderSettings(), JS/alt/alt-settings.js — "provide a expand and collapse
   all using the SAME style and button location used in the configure team") inside
   `#altSettings` instead, which `#adminModal`'s selectors never reach — the same component under
   a different root, not a fork. The button needs no dressing here: this dialog already speaks
   `.a-btn` throughout (unlike `#adminModal`'s `.btn` vocabulary), so the shared, unscoped
   `.a-btn.a-fold-all[aria-pressed]` rule (alt-components.css) paints both states for free.
   Outside `.a-drawer-b`'s scroll region — sys_stride-settings-design.md §3 rule 5 ("Expand
   all/Collapse all live in the pane head, outside the scrolling region"), same as Configure
   Team's copy. No `.pane-intro` here (no per-tab intro copy), so the row holds one child and is
   right-aligned with `flex-end` rather than `space-between`, which has no effect on one item. */
#altSettings .stg-pane-head{
  display:flex; align-items:center; justify-content:flex-end;
  padding:10px 12px 0;
}
#altSettings .stg-pane-actions{ display:flex; gap:8px; flex:0 0 auto; }
/* Generates no box, identically to `#adminModal .stg-fold-mount` — the mount is deliberately
   ABSENT (not merely empty) when the active tab has no foldable card, and `display:contents` is
   what keeps an empty mount from holding an 8px gap open around nothing. */
#altSettings .stg-fold-mount{ display:contents; }

/* ================= WORKSPACE AND TASKS, IN TWO COLUMNS =================
   PRODUCT OWNER: "the workspace tab sections and task tab sections should be layed out in a two
   column design... Follow the same design style as implemented in the configure team tabs."
   `[data-stg-tab]` is stamped on `#altSettingsBody` by altRenderSettings() every time a tab
   renders — a data attribute rather than a class this function would have to strip on every
   OTHER tab (several hand-built, never asked to become a grid).
   Reuses Configure Team's two-column pane component (`#adminModal #teamPane.active`,
   alt-team.css) rather than reinventing it, and the three-rule crush fix that pane found
   travels with it: `.stg-sec` carries `overflow:hidden` (§3), which removes a GRID item's
   automatic minimum size exactly as it removes a flex item's — `flex-shrink:0` is a no-op once
   the container is `display:grid`.
   THE PRECONDITION IS PRESENT HERE, MEASURED: `#altSettingsCard` (`.a-modal`) gets a DEFINITE
   height from alt-shell.css, and `#altSettingsBody` (`.a-drawer-b`) inherits `flex:1 1 auto;
   min-height:0; overflow:auto` from it — the same "scroll instead of pushing taller" shape that
   crushed on `#teamPane.active`. So `min-height:min-content` (opts cards back into content-based
   sizing despite `overflow:hidden`) and `grid-auto-rows:min-content` (stops implicit rows
   defaulting to ~30px) both still apply, verified with every card forced open via
   `stgSectionSetOpen()` (JS/features/team-pane.js) — every card defaults collapsed, so a check
   that never opens one proves nothing, exactly as it didn't the first time this bug was found.
   THE THIRD RULE IS `align-items:stretch`, NOT `start` — PRODUCT OWNER, twice, one per tab:
   "make the tile in my settings, workspace the same size as your theme color" and "make the
   folds the same size as the how the task page opens." A pair sharing a row must be the SAME
   height. `start` was the fix for a real, photographed defect — a two-line card stretched to
   match a many-hundred-line neighbour — but that neighbour (Task fields) is no longer a
   neighbour: the FULL-WIDTH SPAN revision below made it (and every long, structurally different
   card) a declared full-width row spanning alone, so nothing pairs with it any more and
   `stretch`'s only remaining effect is on the four declared PAIRS, where the owner now wants it.
   WHY `stretch` DOES NOT REOPEN THE CRUSH: the crush makes an item SHORTER than its content;
   `stretch` only ever makes one TALLER. `min-height:min-content` plus `grid-auto-rows:min-content`
   still guarantee a stretched item is `>= the tallest pair member's content >= its own content` —
   padded, never clipped.
   THE REAL COST, MEASURED: `stretch` can make the shorter member of a pair visibly taller once
   both are open — the worst case (Workspace's Appearance/Focus row) leaves an open Focus card
   with ~439px of empty space beneath it. A real trade the owner has not seen (his screenshots
   are the COLLAPSED pane, where the pair differs by ~11px and stretch changes nothing
   perceptible) — recorded here, not decided here; see settings-pane-crush-probe.py for current
   numbers on every pair, both states. */
#altSettings #altSettingsBody[data-stg-tab="workspace"],
#altSettings #altSettingsBody[data-stg-tab="tasks"]{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  grid-auto-rows:min-content;
  align-items:stretch;
  /* `column-gap` only — `.a-drawer-b`'s own `gap` (alt-tasks.css) still supplies `row-gap` at
     the same specificity fight `#teamPane.active`'s `row-gap:10px` settles for Configure Team:
     this rule wins the property it sets (id beats class), leaving the row rhythm untouched.
     14px matches the team pane's own column gap rather than inventing a second number. */
  column-gap:14px;
}
/* Kept deliberately, measured still necessary after switching the third rule to `stretch`: with
   `stretch` in place an item's height is dictated by the stretch algorithm from the row's track
   size, never from `height:auto` — the specific mechanism `overflow:hidden`'s "automatic minimum
   size of 0" acts on. `align-items:start` (the value this replaced) DID depend on that
   mechanism, which is why this line mattered before; it stays anyway at zero cost, in case
   `align-items` ever changes again for some other reason. */
#altSettings #altSettingsBody[data-stg-tab="workspace"] .stg-sec,
#altSettings #altSettingsBody[data-stg-tab="tasks"] .stg-sec{
  min-height:min-content;
}
/* THE FULL-WIDTH SPAN — one class, one shared JS rule for both tabs, since the owner's second
   (Tasks) revision turned out to be the same shape as Workspace's first: a fixed set of cards,
   named by identity, always spans the full row alone; every other card pairs up sequentially in
   DOM order, a lone leftover spanning full width rather than drifting to pair with whatever
   comes next. `stgSettingsGridRepaint(host, fullIds)` (JS/alt/alt-settings.js) replaced two
   separate tab-specific functions once the owner's revisions made clear they were one rule —
   per his own note not to maintain "a per-tab list of which card spans" twice. Neither
   function's answer is ever a static id: unlike Configure Team's cards, these panes rebuild
   their whole body from scratch on every render, so there is nothing for a stale class to
   survive between. */
#altSettings #altSettingsBody[data-stg-tab="workspace"] .stg-grid-solo,
#altSettings #altSettingsBody[data-stg-tab="tasks"] .stg-grid-solo{
  grid-column:1 / -1;
}
/* Below 880px — this codebase's established breakpoint for every other settings-pane grid
   (alt-team.css's People/Topics grids, and its own copy of this rule) — both panes stack to
   one column. */
@media (max-width: 880px){
#altSettings #altSettingsBody[data-stg-tab="workspace"],
#altSettings #altSettingsBody[data-stg-tab="tasks"]{
  grid-template-columns:1fr;
}
}

/* AND THE TAB PANEL IS A THIRD LEVEL THE CONTAINER GAP NEVER REACHES — PRODUCT OWNER: "add a
   bit of padding between how import works and the import button."
   THE RULE ABOVE FIXES DIRECT CHILDREN OF THE PANE, AND THAT IS WHERE IT STOPS. Bulk Import puts
   its two tabs in their own panels, so the run-button block (`#importControls`) and the "How
   import works" card are siblings inside `#importSubTasks` — one level deeper than
   `.admin-pane.active`, whose `row-gap:10px` spaces the PANEL, not what's inside it. A plain
   block, so nothing separated the Import button from the card below it.
   `margin-top` is safe here, unlike on the direct children above — that warning was about flex
   items (margins don't collapse there); these are blocks in a block container with no gap of
   their own, so 14px IS the gap.
   Scoped to the ADJACENCY, not the card — `#importReferenceSec` also renders when the reader may
   not import at all (the block above it is hidden in that state), and a rule on the card alone
   would leave a stray gap at the panel's top in that case. */
.alt-app #adminModal #importControls + .stg-sec{ margin-top:14px; }

.stg-sec:hover{ border-color:var(--stg-line-strong); }

/* The accent edge — a 2px left border, filled with the brand ribbon, appears only while open.
   The one place the brand gradient marks user content rather than chrome, reserved so it keeps
   meaning "you opened this." A pseudo-element rather than `border-left` so it sits flush
   against `.stg-sec`'s `overflow:hidden` and is clipped at the corners for free. */
.stg-sec::before{
  content:"";
  position:absolute; left:0; top:0; bottom:0; width:2px;
  background:transparent;
}
.stg-sec:has(.stg-sec-h[aria-expanded="true"])::before,
.stg-sec.is-open::before{
  background:var(--stg-ribbon);
}
.stg-sec:has(.stg-sec-h[aria-expanded="true"]),
.stg-sec.is-open{
  border-color:var(--stg-line-strong);
  box-shadow:0 8px 24px rgba(0,0,0,.13);
}

/* THE HEADER IS A REAL <button>, NEVER A <div> WITH A CLICK HANDLER — native keyboard
   activation and `:focus-visible` with no script (§3 rule 2: the whole row is the hit target).
   Every property below undoes a browser's own default button chrome — which is exactly why
   this element must stay a `<button>`: swap the tag and every rule here goes from "undoing a
   default" to "asserting nothing," invisible to a review that only checks the visual result. */
.stg-sec-h{
  all:unset;
  box-sizing:border-box;
  /* The spec's four tracks: chevron / icon tile / copy / state.
     GRID, NOT FLEX — flex seemed right because the chevron is OPTIONAL, but a fixed four-track
     recipe can't absorb a missing child under flex: the remaining three auto-place into tracks
     1-3 and the tile lands in the chevron's slot. Measured at 1440px: tiles staggered at 290 on
     static headers, 320 on collapsible ones, 337 on Widgets — a column of tiles that doesn't
     line up. The fix is to place each child EXPLICITLY (below), so a missing chevron leaves its
     track empty instead of shifting everything left. */
  display:grid;
  grid-template-columns:20px var(--stg-tile-size) minmax(0, 1fr) auto;
  align-items:center;
  gap:14px;
  min-height:66px;
  width:100%;
  padding:13px 16px;
  background:var(--stg-surface-2);
  border-bottom:1px solid var(--stg-line);
  cursor:pointer;
  text-align:left;
  font:inherit;
  color:inherit;
  -webkit-appearance:none;
  appearance:none;
  border:0;
  background:transparent;
  border-radius:var(--stg-r-lg);
  transition:background var(--a-quick) var(--a-ease);
}
/* Explicit tracks — naming the column for each child makes the row's shape independent of
   which children exist. */
.stg-sec-h > .stg-chev{ grid-column:1; }
.stg-sec-h > .stg-sec-ico{ grid-column:2; }
.stg-sec-h > .stg-sec-copy{ grid-column:3; }
.stg-sec-h > .stg-sec-state{ grid-column:4; }

.stg-sec-h:hover{ background:var(--stg-surface-2); }
.stg-sec-h:focus-visible{ outline:2px solid var(--stg-ring); outline-offset:-2px; }
.stg-sec-h[aria-expanded="true"]{
  background:var(--stg-surface-2);
  border-bottom:1px solid var(--stg-line-strong);
}

.stg-chev{
  flex:0 0 auto;
  display:inline-flex; align-items:center; justify-content:center;
  color:var(--stg-faint);
  transition:transform var(--a-quick) var(--a-ease), color var(--a-quick) var(--a-ease);
}
.stg-chev svg{ width:16px; height:16px; }
/* A turning chevron, not a swapped glyph — sys_design-system.md §6b's convention.
   RESTING STATE IS ROTATED, NOT BARE — `chev` is a down glyph, so with no base transform a
   COLLAPSED card pointed down (the universal "I am open" signal) and expanding turned it LEFT,
   meaning nothing. Correct: collapsed points RIGHT (-90deg), expanded points DOWN (0deg); only
   the two angles changed, the turning-not-swapping convention is preserved. */
.stg-chev{ transform:rotate(-90deg); }
.stg-sec-h[aria-expanded="true"] .stg-chev{
  transform:rotate(0deg);
  color:var(--stg-dim);
}

/* ---- The icon tile ---- */
/* A FILLED TILE, NOT AN OUTLINED ONE — the approved sheet draws every section badge as a solid
   rounded square carrying its concern colour as a GRADIENT with a WHITE glyph; the tile is the
   strongest identifying mark on the panel. The first build inverted this (dark fill, coloured
   glyph, 1px border) and read as an outline of the design rather than the design. */
.stg-sec-ico{
  position:relative;
  width:var(--stg-tile-size); height:var(--stg-tile-size);
  flex:0 0 auto;
  display:inline-flex; align-items:center; justify-content:center;
  border-radius:12px;
  /* A plain fill first, then the gradient — `color-mix()` is unsupported before Safari 16.2/
     Chrome 111, and an engine that doesn't know it discards the WHOLE declaration, so without
     this the tile would have no background at all on those versions. The flat concern colour
     is the right fallback: the gradient's own start stop, so the tile loses depth, not
     identity. cross-browser-check.py exists for exactly this and caught it. */
  background:var(--stg-c, var(--stg-c-team));
  background:linear-gradient(150deg,
             var(--stg-c, var(--stg-c-team)) 0%,
             color-mix(in srgb, var(--stg-c, var(--stg-c-team)) 62%, #0b1b34) 100%);
  color:#fff;
  border:0;
  box-shadow:0 2px 8px rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.22);
  overflow:hidden;
}
.stg-sec-ico svg{ width:22px; height:22px; stroke-width:2; }
/* The ribbon wash behind every glyph reuses the already-themed `--stg-ribbon-soft` token
   rather than a second literal gradient, so it survives light theme for free. */
.stg-sec-ico::before{
  content:"";
  position:absolute; inset:0;
  background:var(--stg-ribbon-soft);
  opacity:.95;
}
/* The diagonal ribbon sliver, at the kit's own 38% opacity — the one other place (besides the
   accent edge) the full-strength brand gradient appears inside a page rather than the shell
   header. */
.stg-sec-ico::after{
  content:"";
  position:absolute; left:-8px; bottom:3px;
  width:30px; height:5px;
  border-radius:999px;
  background:var(--stg-ribbon);
  transform:rotate(-28deg);
  opacity:.38;
}
.stg-sec-ico svg{
  position:relative; z-index:1;
  width:var(--stg-tile-glyph); height:var(--stg-tile-glyph);
  stroke-width:1.9;
}

/* Every concern is the same colour everywhere it appears (§3 rule 7) — one attribute selector
   per concern, never a generic tinted chip with no semantic meaning. The concern feeds the
   FILL, not the glyph: each rule sets `--stg-c`, which the tile's gradient reads; the glyph is
   white on every concern, clearing contrast on all thirteen with no per-concern pass. */
.stg-sec-ico[data-concern="team"]{ --stg-c:var(--stg-c-team); }
.stg-sec-ico[data-concern="board"]{ --stg-c:var(--stg-c-board); }
.stg-sec-ico[data-concern="people"]{ --stg-c:var(--stg-c-people); }
.stg-sec-ico[data-concern="okr"]{ --stg-c:var(--stg-c-okr); }
.stg-sec-ico[data-concern="email"]{ --stg-c:var(--stg-c-email); }
.stg-sec-ico[data-concern="taxonomy"]{ --stg-c:var(--stg-c-taxonomy); }
.stg-sec-ico[data-concern="import"]{ --stg-c:var(--stg-c-import); }
.stg-sec-ico[data-concern="view"]{ --stg-c:var(--stg-c-view); }
.stg-sec-ico[data-concern="time"]{ --stg-c:var(--stg-c-time); }
.stg-sec-ico[data-concern="links"]{ --stg-c:var(--stg-c-links); }
.stg-sec-ico[data-concern="ai"]{ --stg-c:var(--stg-c-ai); }
.stg-sec-ico[data-concern="data"]{ --stg-c:var(--stg-c-data); }
.stg-sec-ico[data-concern="workspace"]{ --stg-c:var(--stg-c-workspace); }
/* `lock` — the Account tab's two rows. Had no rule or token until this pass, so it fell through
   the tile's own fallback and painted team blue with no error of any kind. Blue ON PURPOSE now
   (credentials are the reader's own access) — the JS spelling is the remaining half, reported
   not fixed here. */
.stg-sec-ico[data-concern="lock"]{ --stg-c:var(--stg-c-lock); }

/* ---- Status overrides — apply AFTER a concern colour, never instead of the icon glyph ---- */
/* Disabled/quiet: a real utility, not a token, layered on top of whichever concern is present
   (kit's own `.wf-sec-ico.quiet`). */
.stg-sec-ico.quiet{ filter:saturate(.45); opacity:.72; }
/* Warning/danger reuse the canonical status roles rather than inventing settings-only ones. */
.stg-sec-ico.warn  { color:var(--a-amber); border-color:var(--a-amber); background:var(--a-amber-soft); }
.stg-sec-ico.danger{ color:var(--a-red);   border-color:var(--a-red);   background:var(--a-red-soft); }

/* The one context exception (§3): a solid ribbon fill with a white glyph, overriding whichever
   concern colour the tile would otherwise carry — at most one tile per pane. Same specificity
   as the `[data-concern]` rules, so it must come AFTER them to win on source order. A
   highlight, never a substitute for `aria-expanded`/`.is-open` — independent of open/closed. */
.stg-sec-ico.is-context{
  background:var(--stg-ribbon);
  color:#fff;
  border-color:rgba(255,255,255,.4);
  box-shadow:0 5px 18px rgba(0,0,0,.2);
}
.stg-sec-ico.is-context::before{ opacity:0; }

/* A COLUMN, NOT TWO INLINE SPANS. `.stg-sec-t`/`.stg-sec-d` are <span>s, inline by default, so
   with only `min-width:0` they flowed into ONE line ("Time zonesShown in the rail in this
   order") and every truncation/margin rule on them was INERT on an inline box. Making the
   wrapper a flex column blockifies both children, which is what makes those rules take effect
   at all. NOTHING IN THE SUITE COULD SEE THIS — every assertion matched source text; none
   rendered a card and measured it. A stylesheet can be entirely present and entirely inert. */
.stg-sec-copy{
  flex:1 1 auto;
  display:flex;
  flex-direction:column;
  justify-content:center;
  min-width:0;
}
.stg-sec-copy > *{ min-width:0; }
.stg-sec-t{
  font-size:15px; font-weight:700; color:var(--stg-text); letter-spacing:-.008em;
  line-height:1.25;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* Truncates to one line under width pressure rather than wrapping and pushing the state
   summary off-baseline — the spec's own instruction for `.stg-sec-copy` under narrowing. */
/* THE DESCRIPTION WRAPS TO TWO LINES RATHER THAN TRUNCATING — these are full sentences, and an
   ellipsis on the first line hides the half that explains the setting. The header is 66px tall
   with no fixed height, so a second line costs nothing. */
.stg-sec-d{
  margin-top:3px; font-size:12px; color:var(--stg-faint); line-height:1.4;
  /* No clamp — a two-line clamp was cutting real sentences mid-clause, reading as broken
     rather than tidy. */
  white-space:normal;
}

/* No `flex:0 0 auto; margin-left:auto` here any more — leftover from when this header was a
   flex row; in a grid they actively broke the narrow-width rule (an auto left margin shrinks a
   grid item to its content), so the summary sat at the column's right edge instead of starting
   under the title. Track 4 is already `auto`-sized, so nothing is lost dropping them. */
.stg-sec-state{
  padding-left:12px;
  font-size:11px; color:var(--stg-dim); white-space:nowrap; text-align:right;
}
/* Sub-modifiers for the collapsed-state summary, mirroring the kit's own `.wf-sec-state
   .muted/.warn/.none` — "every shut card states its current value" (§3 rule 1) can say more
   than one thing: a plain count, a warning, or "off". */
.stg-sec-state .muted, .stg-sec-state.muted{ color:var(--stg-faint); }
.stg-sec-state .warn,  .stg-sec-state.warn { color:var(--a-amber); }
.stg-sec-state .none,  .stg-sec-state.none { color:var(--stg-faint); }
.stg-sec-state .good,  .stg-sec-state.good { color:var(--a-green); }

.stg-sec-body{ padding:14px; background:rgba(7,17,31,.03); }
/* A body with no chrome of its own (a full-bleed table, e.g. People's roster) uses this instead
   of fighting the default padding with overrides on every child. */
.stg-sec-body.flush{ padding:0; }

/* ================= §4. SUPPORTING COMPONENTS — genuinely new only =================
   Everything reusable (`.pref-row`, `.pref-switch`, `.a-check-l`, `.a-btn`, `.empty-state`,
   `.add-row`, `.role-badge`, `.a-chip`, the drag-handle pattern, the admin grid header row) is
   NOT here — existing vocabulary, used unchanged inside `.stg-sec-body`. */

/* ---- Note block: info / warn / lock / danger ---- */
.stg-note{
  display:flex; align-items:flex-start; gap:10px;
  padding:10px 12px;
  border-radius:9px;
  border:1px solid var(--stg-line);
  background:var(--stg-surface-2);
  color:var(--stg-dim);
  font-size:11px; line-height:1.5;
}
.stg-note-ico{
  display:inline-flex; flex:0 0 24px; width:24px; height:24px;
  align-items:center; justify-content:center;
  border-radius:7px;
  background:var(--stg-surface);
  color:var(--a-blue-text);
}
.stg-note-ico svg{ width:14px; height:14px; }

/* Breathing room only when something follows. `.stg-sec-body` is `padding:14px` with no flex
   gap, so children stack flush — the Swimlanes note sat directly on the lane list below it.
   12px is the rhythm this dialog already uses between siblings (alt-team.css's add-row rule).
   `:not(:last-child)` is the whole rule: a note that ENDS its section must not add dangling
   space below itself, so the gap appears only where there is something to separate FROM. */
.stg-note:not(:last-child){ margin-bottom:12px; }

.stg-note.info{ border-color:var(--a-blue); background:var(--a-blue-soft); }
.stg-note.info .stg-note-ico{ color:var(--a-blue-text); }

.stg-note.warn{ border-color:var(--a-amber); background:var(--a-amber-soft); color:var(--stg-text); }
.stg-note.warn .stg-note-ico{ background:var(--a-amber-soft); color:var(--a-amber); }

.stg-note.danger{ border-color:var(--a-red); background:var(--a-red-soft); color:var(--stg-text); }
.stg-note.danger .stg-note-ico{ background:var(--a-red-soft); color:var(--a-red); }

/* Desaturated, not tinted, per §2's Locked status override — a locked tile (or note) must never
   read as "some other concern," it must read as "off limits." */
.stg-note.lock{
  border-color:var(--stg-c-locked-line);
  background:var(--stg-c-locked-bg);
  color:var(--stg-c-locked);
}
.stg-note.lock .stg-note-ico{ background:var(--stg-c-locked-line); color:var(--stg-c-locked); }

/* ---- Swatch — small colour square, e.g. a tag's colour dot ----
   Checked before adding: no generic swatch class existed yet in this codebase, so this is
   genuinely new rather than a duplicate of something reusable. */
.stg-swatch{
  display:inline-block;
  width:18px; height:18px;
  border-radius:5px;
  border:1px solid rgba(255,255,255,.22);
  flex:0 0 auto;
}

/* ================= §8. RESPONSIVE SPEC =================
   Scoped to what this file owns — the section-card header grid. Dialog framing (width, height,
   tab-strip overflow) belongs to each host's own shell chrome. Breakpoint matches the
   wireframe kit's own `@media(max-width:900px)`. */
@media (max-width:900px){
  .stg-sec-h{
    grid-template-columns:18px 34px minmax(0,1fr);
  }
  /* The state summary drops to its own line under the title rather than being clipped, per the
     spec. Written as `.stg-sec-h > .stg-sec-state` to match the explicit placement above — a
     media query adds no specificity, so a bare `.stg-sec-state` here would lose to §3's child
     rule and the summary would stay in a column-4 this three-track grid doesn't have. */
  .stg-sec-h > .stg-sec-state{
    grid-column:3;
    text-align:left;
    padding-left:0;
    padding-top:2px;
    white-space:normal;
  }
}

/* No separate prefers-reduced-motion block — every transition above is
   `<property> var(--a-quick) var(--a-ease)`, and alt-tokens.css already zeroes `--a-quick` on
   `.alt-app` (which every page mounting `.stg-shell` also wears) under that media query. A
   second override here would just set the same custom property to the same value again. */


/* ============================================================================================
   §3b. THE PANEL BODY AND ITS ROWS — the anatomy the approved sheet actually draws.
   A ROW IS LABEL-AND-DESCRIPTION ON THE LEFT, CONTROL ON THE RIGHT — the first build emitted
   the label as a micro-caps heading, the control full-bleed beneath it, and the description as
   a separate line UNDER the control: three stacked bands where the sheet draws one two-column
   row, orphaning the description from the label it explains.
   Rows are separated by a hairline, not margin, so a panel of settings reads as one object with
   several parts. Last row has none: a divider above the panel's own bottom edge is a double
   rule. */
/* THE KIT'S OWN 14px, NOT 2px/6px — this rule's §3b copy had quietly overridden §3's matching
   declaration to `2px 16px 6px` (to avoid stacking the body's padding on `.stg-row`'s own 13px),
   but the compensation landed on EVERY body, including ones holding prose or a note rather than
   rows (Team mark's content sat 2px off the panel edge). Sides stay at 16px; the ends go back
   to standard, and the doubling is cancelled instead at the first/last row, where it actually
   happens. */
.stg-sec-body{ padding:14px 16px; }
.stg-sec-body.flush{ padding:0; }
.stg-sec-body > .stg-row:first-child{ padding-top:4px; }
.stg-sec-body > .stg-row:last-child{ padding-bottom:4px; }

/* "Add a group" is a row's neighbour, not its continuation — the Notes Groups card draws the
   list then this button with nothing between, reading as a fourth group rather than the action
   that makes one. */
.stg-shell #sNoteGroupAdd{ margin-top:12px; }

/* THE SAME DEFECT, ON BOTH SIDES. "Back to the default set" is a bare button an `{html:...}`
   row hands to altRows() as one opaque blob — the row-spacing system above only ever sees
   `.stg-row` siblings, so an html-row's content is invisible to it in both directions: it sat
   flush against the checklist above AND the ordinary `.stg-row` below. 12px is the same rhythm
   this dialog already uses between siblings, applied on both edges since this button has
   neighbours on both. */
.stg-shell #sQuickReset{ margin:12px 0; }

.stg-row{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,auto);
  align-items:center;
  gap:16px;
  padding:13px 0;
  border-bottom:1px solid var(--stg-line);
}
.stg-row:last-child{ border-bottom:0; }
/* The same bug as `.stg-sec-copy`, one component away: a <span> is inline until told otherwise,
   so `.stg-row-t`/`.stg-row-d` ran together and `.stg-row-d`'s `margin-top` was inert. */
.stg-row-copy{
  display:flex;
  flex-direction:column;
  justify-content:center;
  min-width:0;
}
.stg-row-copy > *{ min-width:0; }
.stg-row-t{
  font-size:13px; font-weight:650; color:var(--stg-text); line-height:1.3;
}
.stg-row-d{
  margin-top:3px; font-size:12px; color:var(--stg-faint); line-height:1.45;
}
/* The control column is CAPPED, not content-sized — a <select> whose longest option is "STRIDE
   Default — modern" would otherwise set the column and shove every other row's control out of
   alignment; the sheet draws every control in one right-hand column of equal width. */
.stg-row-ctl{
  min-width:0;
  flex:0 0 auto;
  display:flex; align-items:center; justify-content:flex-end; gap:8px;
}
.stg-row-ctl > select,
.stg-row-ctl > input[type="text"],
.stg-row-ctl > input[type="number"]{ min-width:0; width:clamp(140px,22vw,240px); }

/* A row whose control belongs under its copy rather than beside it — a checkbox group, a list,
   a drag-ordered set. The sheet draws these as a full-width inset well below the label. */
.stg-row.stacked{ grid-template-columns:minmax(0,1fr); }
.stg-row.stacked .stg-row-ctl{ justify-content:flex-start; margin-top:10px; }

/* ================= YOUR TAGS — FOUR COLUMNS, EVERY TRACK FIXED =================
   sys_design-system.md §7, "an admin list with per-row controls is a grid, and every track is
   fixed" — restated here because `#sTagList`'s rows were the exact failure mode: `.a-tagrow`
   (alt-shell.css) is `display:flex` with only the swatch pinned to 44px, so the name field's
   `flex:1 1 auto` absorbed whatever the count text did NOT need — a track sized to its own
   content, independently, on every row, so two tags drew their counts starting at two different
   x positions.
   SCOPED TO `#sTagList` ONLY — `.a-tagrow` also renders a single checkbox, a label-only row and
   other shapes elsewhere in this file, where a four-column template would misplace every one.
   The Notes Groups list does NOT reuse this row at all — it draws `.stg-row` below instead. */
.stg-shell #sTagList.a-tagrow,
.stg-shell #sTagList .a-tagrow{
  display:grid;
  grid-template-columns:44px minmax(0,1fr) 92px auto;
}
/* The count text's own COLUMN, not its own width — "on 999 items" and "unused" both fit inside
   92px; the fixed track is what keeps the text starting at the same x on every row. */
.stg-shell #sTagList .a-tagrow .use{ text-align:left; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* Buttons in a grid cell must be told not to stretch to fill their track (sys_design-system.md
   §7) — `justify-items` defaults to `stretch`, which would draw Delete as a full-width bar. */
.stg-shell #sTagList .a-tagrow .danger{ justify-self:start; }

/* An inset well — the bordered group the sheet draws around checkbox lists (the four widget
   ticks, the event switches). A container, not a card: no icon, no header, one hairline
   between items, sits INSIDE a panel body. */
.stg-well{
  border:1px solid var(--stg-line);
  border-radius:10px;
  background:var(--stg-surface);
  overflow:hidden;
}
.stg-well > *{ border-bottom:1px solid var(--stg-line); }
.stg-well > *:last-child{ border-bottom:0; }
.stg-well .a-check-l,
.stg-well .stg-well-row{
  display:flex; align-items:center; gap:11px;
  padding:11px 13px; margin:0; font-size:13px;
}

/* A static panel header. `.stg-sec-h` is a <button> when the panel discloses; one that never
   folds uses a <div> with the same class, so the geometry is declared once — `all:unset` is
   inert on a div, and the cursor/hover belong only to the interactive form. */
div.stg-sec-h{ cursor:default; }
div.stg-sec-h:hover{ background:var(--stg-surface-2); }
.stg-sec-h:not(button) .stg-chev{ display:none; }
/* No second column recipe: the header is flex, so an absent chevron simply takes no space. */


/* ============================================================================================
   §3c. EVERY ICON INSIDE A BUTTON IS SIZED. THIS IS NOT A REFINEMENT.
   `altIcon()` emits `<svg viewBox="0 0 24 24">` with NO width/height — by design, so each host
   sizes it. The settings surfaces only ever sized the `.icon-only` variants, so a button with
   an icon AND a label got `flex:0 0 auto` and nothing else — an SVG with a viewBox and no
   intrinsic size falls back to the replaced-element default and stretches to its container.
   Measured live before this rule: six icons at 112x112, five at 84x84, five at 58x58 — THAT is
   what made rows look "too tight" and read as overlapping text, not padding and not the row
   markup, which was correct.
   Scoped to the two settings surfaces and to `> svg`, so it cannot reach the 44px
   `.stg-sec-ico` tile or `.stg-chev`, both of which size their own child. */
.stg-shell button > svg,
.stg-shell a.a-btn > svg,
.stg-shell a.btn > svg,
.alt-app #adminModal button > svg,
.alt-app #adminModal a.btn > svg,
.alt-app #adminModal a.a-btn > svg{
  width:15px; height:15px; flex:0 0 auto;
}
/* And icons not inside a button at all — the rule above scopes to `button`/`a.btn`, but the
   Import-people DROPZONE draws its upload arrow into a plain <div>, inheriting nothing and
   rendering at 907x907px, filling the entire pane. Same root cause, different host — the
   button-scoped selector could never have caught it. Deliberately larger than a button's icon:
   a dropzone glyph is the target, not a label's decoration. */
.alt-app #adminModal .import-dropzone > svg,
.stg-shell .import-dropzone > svg,
.alt-app #adminModal .a-dropzone > svg,
.stg-shell .a-dropzone > svg{ width:34px; height:34px; flex:0 0 auto; }

/* An icon-only control keeps the slightly larger glyph its own rules already give it. */
.stg-shell button.icon-only > svg,
.alt-app #adminModal button.btn.icon-only > svg,
.alt-app #adminModal a.btn.icon-only > svg{ width:16px; height:16px; }
