/* ==========================================================================
   design_system.css — the ONE owner of every restyle of a Bootstrap/AdminKit
   class. Created 2026-09-21 from the DS-alignment drafts (passes 2 and 3).

   THE CONTRACT (docs/design/archive/ds-alignment-2026-09/cascade.md §3)
   - Every selector is `body.mgx-restyle` + the selector it replaces, so the
     specificity band is (0,2,1), or (0,3,1) with a state or child. Extra
     context goes in :where() so it stays weightless.
   - NOT @layer: unlayered AdminKit would beat a layer, and layering AdminKit
     breaks the light/dark <link> swap.
   - This file READS theme variables and NEVER writes them. Colour belongs to
     the tenant theme, which is emitted after every stylesheet with !important.
     The 41 tenant-owned keys are never pinned here.
   - Load position: after the app's stylesheets, before theme_fonts and
     tenant_theme (application.html.erb). That is the whole design — after
     everything it must beat, before the theme it must not overwrite.

   WHERE EACH BLOCK CAME FROM
   Blocks 1-9 are pass 2 §3A (`overrides.DRAFT.css`), render-verified on a
   static specimen in light and dark. Blocks 10-12 are the owner options that
   won their decision on 2026-09-21 (`owner_options.DRAFT.css`). Block 5 is
   pass 3's C1 (`pass3/controls_overrides.DRAFT.css`), which SUPERSEDES pass 2's
   O5 — O5 themed the focus hue but kept a 55%-tint border at about 2:1 and
   never reached the picker engines. O5 is deliberately not in this file.

   DECISIONS THIS FILE IMPLEMENTS (src/docs/DESIGN_DECISIONS.md)
   6.3 control heights 30/38/48 · 6.4 bordered hairline cards ·
   6.15 underline tabs · 6.17 drawer actions pinned.
   6.8 (table header) chose SENTENCE CASE, which is today's behaviour, so the
   uppercase option is absent by design, not by omission.

   ADDED LATER THE SAME DAY: blocks 13-21 — C2-C6 (the picker engines, native
   file input, range track, segmented control, date pickers), the dark-mode
   scrim and side panels, the default wordmark in dark, readable rail labels,
   and the 768-991px overlay drawer. Each closes a row of the live-defect list.

   ADDED 2026-09-27: §22's dark branch and blocks 23-24 — the dark-theme
   contrast causes the Sites block census traced to the platform (Console
   #3997, #3999, #4034, #4036), fixed here once for every app. Their siblings
   live where each colour pairing is owned: #3998 and #4035 in
   color_text_fix.css, #4000 and #4001 in BusinessTheme.

   NOT YET HERE — each is tracked in the pass-3 work list, section 02:
   - The "one owner" extraction: the scattered overrides still in custom.css
     have NOT been moved here yet. They load before this file, so this file
     wins; the duplication is debt, not breakage. Locate them by CONTENT — the
     line numbers in the pass-2 plan have drifted (custom.css is 16,653 lines
     now, 16,626 when they were recorded).
   - 6.16's empty-state scale. The pass-2 note says "delete custom.css's Legacy
     empty states block", but that block's selector is `.card-body
     .text-center.py-5` — every card, not just widgets. The decision was "DS
     scale on PAGES, compact in WIDGETS", so the block must be NARROWED to
     widgets, not deleted. That needs a widget selector first.
   ========================================================================== */

/* ---------- 0 · Control tokens (pass 3) -----------------------------------
   Only the tokens the focus contract needs. --ctl-h is deliberately NOT set
   here: block 10 owns control height, per decision 6.3. */
body.mgx-restyle {
  --ctl-border: var(--control-border-color, #868e96);
  --ctl-bg: #fff;
  --ctl-ink: #495057;
  /* Focus colour: the brand in light (5.9:1 on white). In dark, the theme's
     readable brand tint — the dark --bs-primary is only 2.87:1. */
  --ctl-focus-rgb: var(--bs-primary-rgb);
  --ctl-focus-ring: 0 0 0 1px rgb(var(--ctl-focus-rgb)), 0 0 0 .25rem rgba(var(--ctl-focus-rgb), .2);
  --choice-focus-outline: 2px solid rgb(var(--ctl-focus-rgb));
}
:root[data-theme="dark"] body.mgx-restyle {
  --ctl-border: #767e86;          /* 3.07:1 on the #333 card, 3.4:1 on the control fill below; AdminKit's #4b4b4b is 1.58:1.
                                     Was #6f7780 until /pre-merge xr 2026-09-27: 2.78:1 on the card a control sits on. */
  /* The field is an INSET of the theme's own surfaces — the card mixed toward
     the page, the recess `.bg-light` / `.table-light` already take in dark
     (custom.css, "the surfaces AdminKit inverts") — a step darker than the card
     it sits in, the way a dark field reads. It was AdminKit's navy #222e3c: a
     second hue in a neutral palette, on every form in the product
     (Console #2831, decided 2026-10-02). Same luminance as the navy, so every
     ink and the boundary keep their measured contrast. */
  --ctl-bg: color-mix(in srgb, var(--bs-card-bg, #333) 40%, var(--bs-body-bg, #252526));
  /* The text a person types: the theme's body ink, read from the same tokens as
     the fill above so the two can never disagree (#7714). It was AdminKit's
     #bdc0c5 — 7.8:1, but within a hair of the placeholder (--bs-secondary-color,
     7.3:1 on this fill), so a filled field and an empty one showing its hint
     read alike. The body ink is ~10.8:1 and stands clear of the hint. */
  --ctl-ink: var(--bs-body-color);
  --ctl-focus-rgb: var(--bs-link-color-rgb, 161, 180, 211);
}
/* Dark: native controls get the same 3:1 boundary. AdminKit dark ships #4b4b4b. */
:root[data-theme="dark"] body.mgx-restyle :is(.form-control, .form-select, .input-group-text, .form-check-input:not(:checked)) {
  border-color: var(--ctl-border);
}
/* Dark: the native controls take that fill too — the picker engines (block 14)
   already read it. AdminKit paints each one a navy literal: the field and its
   focus state #222e3c, a disabled field #4e5863, the addon and the file button
   its --bs-tertiary-bg #384350. A disabled field is the theme's secondary
   ground (the light theme's grey-out); an addon is the card itself, a step off
   the field as #f8f9fa is beside white. The scope is `:where()` so each rule
   weighs what AdminKit's does and wins on load order alone: an app rule that
   makes ITS field transparent (a composer, a search in a bar) still wins. */
:where(:root[data-theme="dark"] body.mgx-restyle) :is(.form-control, .form-select),
:where(:root[data-theme="dark"] body.mgx-restyle) :is(.form-control, .form-select):focus {
  background-color: var(--ctl-bg);
}
/* The floating label's backing strip — AdminKit's rule is (0,3,2), so this one
   keeps its scope's weight. */
:root[data-theme="dark"] body.mgx-restyle .form-floating > :is(.form-control, .form-control-plaintext, .form-select) ~ label::after {
  background-color: var(--ctl-bg);
}
:where(:root[data-theme="dark"] body.mgx-restyle) :is(.form-control, .form-select):disabled {
  background-color: var(--bs-secondary-bg);
}
:where(:root[data-theme="dark"] body.mgx-restyle) .form-check-input { --bs-form-check-bg: var(--ctl-bg); }
/* The header's search capsule (shared/_navbar) sits on the NAVBAR, not a card:
   AdminKit fills it #222e3c in dark (#f3f6fa, a breath off the white bar, in
   light). In dark it is the theme's navbar colour lifted a step — the same
   breath off the bar, in the bar's own hue, whatever the tenant paints it. */
:where(:root[data-theme="dark"] body.mgx-restyle) .input-group-navbar :is(.btn, .form-control),
:where(:root[data-theme="dark"] body.mgx-restyle) .input-group-navbar :is(.btn, .form-control):focus {
  background: color-mix(in srgb, var(--navbar-bg, #262626) 92%, #fff);
}
:where(:root[data-theme="dark"] body.mgx-restyle) .input-group-text,
:where(:root[data-theme="dark"] body.mgx-restyle) .form-control::file-selector-button {
  background-color: var(--bs-card-bg, #333);
}
/* Dark: the controls' INK, from this layer like their fill (#7714). AdminKit
   writes a control's text as a literal per sheet — #495057 in light.css,
   #bdc0c5 in dark.css — while the fill above is keyed on data-theme. The dark
   sheet was an overlay that loaded only after data-theme flipped (until #7776
   linked the reader's sheet in <head>), so on every dark first paint, every
   switch to dark, and for good when the overlay failed to load, typed text, a
   select's value and an addon were #495057 on the dark field: 1.74:1, a
   disabled field 1.17:1. Reading the ink here keeps the controls independent of
   whichever AdminKit sheet is active. Same
   `:where()` weight as the fill: an app rule that inks ITS field still wins.
   The light theme is untouched — light.css's #495057 is --ctl-ink's light value. */
:where(:root[data-theme="dark"] body.mgx-restyle) :is(.form-control, .form-select, .input-group-text),
:where(:root[data-theme="dark"] body.mgx-restyle) :is(.form-control, .form-select):focus,
:where(:root[data-theme="dark"] body.mgx-restyle) .form-control::file-selector-button {
  color: var(--ctl-ink);
}
/* Firefox draws a focused select's value as a text-shadow; AdminKit's is the light ink. */
:where(:root[data-theme="dark"] body.mgx-restyle) .form-select:-moz-focusring { text-shadow: 0 0 0 var(--ctl-ink); }
/* ...and the select's chevron, light.css's #343a40 on the dark field (1.4:1). */
:where(:root[data-theme="dark"] body.mgx-restyle) .form-select { --bs-form-select-bg-img: var(--ctl-chevron); }
/* A floated label (and a disabled field's) is AdminKit's body ink at 65% —
   3.33:1 on the white strip behind it in light.css (#7777), 4.2:1 on the dark
   field, and #a7abb1 when disabled in dark. Both themes take the theme's
   secondary ink: rgba(73,80,87,.85) in light, 5.45:1 on that strip (a disabled
   field's label sits on the same white strip); ~7.3:1 on the field in dark.
   Unscoped (no data-theme) so it is one rule for both; (0,4,2) beats
   AdminKit's (0,3,1) floated-label rules in either sheet. */
body.mgx-restyle .form-floating > :is(.form-control:focus, .form-control:not(:placeholder-shown), .form-control:-webkit-autofill, .form-control-plaintext, .form-select, :disabled) ~ label {
  color: var(--bs-secondary-color);
}
/* Grouped options. custom.css gives every optgroup a light band (#212529 on
   #f8f9fa, !important, for the light list) and its options inherit the
   #212529 — 1.08:1 on the dark list wherever the browser paints the list
   itself (Chrome and Edge on Windows, Linux and ChromeOS; Firefox). The band
   is the card, a step off the field like the addon; the options take the
   control's ink. */
:root[data-theme="dark"] body.mgx-restyle optgroup {
  color: var(--ctl-ink) !important;
  background-color: var(--bs-card-bg, #333) !important;
}
:root[data-theme="dark"] body.mgx-restyle optgroup > option { color: var(--ctl-ink); }
/* The picker engines type into raw inputs of their own (Select2's inline
   search in a multi-select, Choices, Tom Select), so their hint is the
   browser's #757575 — 3.09:1 on the dark field. The hint every .form-control
   shows: the theme's secondary ink. */
:root[data-theme="dark"] body.mgx-restyle :is(.select2-search__field, .choices__input, .ts-control > input)::placeholder {
  color: var(--bs-secondary-color);
}

/* ---------- 1 · Card inset — the header aligns with the body ---------------
   The adapter's `.card > .card-header { padding: 14px 18px }` puts every card
   title 4px left of the body text under it (measured: title x=19, body x=23).
   Flush tables follow the same inset. */
body.mgx-restyle .card > .card-header {
  /* --mgx-card-cap-py: the theme's card density (EXP-3c) — unset is 14px. */
  padding: var(--mgx-card-cap-py, 14px) var(--bs-card-cap-padding-x, 1.25rem);
}
body.mgx-restyle :is(.card-body.p-0, .card) > .table > * > tr > :first-child,
body.mgx-restyle :is(.card-body.p-0, .card) > .table-responsive > .table > * > tr > :first-child {
  padding-left: var(--bs-card-cap-padding-x, 1.25rem);
}
body.mgx-restyle :is(.card-body.p-0, .card) > .table > * > tr > :last-child,
body.mgx-restyle :is(.card-body.p-0, .card) > .table-responsive > .table > * > tr > :last-child {
  padding-right: var(--bs-card-cap-padding-x, 1.25rem);
}

/* ---------- 2 · The approved type scale, second pass ----------------------
   PAGE_COMPOSITION_STANDARDS §5A, owner-approved 2026-09-19. Controls take the
   tenant's body size (font_size_base), never a pinned 15px. */
body.mgx-restyle :where(.btn:not(.btn-sm, .btn-lg, .btn-group-sm > .btn, .btn-group-lg > .btn)),
body.mgx-restyle :where(.form-control:not(.form-control-sm, .form-control-lg), .form-select:not(.form-select-sm, .form-select-lg)),
body.mgx-restyle :where(.input-group:not(.input-group-sm, .input-group-lg) > .input-group-text) {
  font-size: var(--bs-body-font-size);
}
body.mgx-restyle .form-control-sm,
body.mgx-restyle .form-select-sm,
body.mgx-restyle .input-group-sm > :is(.form-control, .form-select, .input-group-text) {
  font-size: var(--type-small);
}
/* A searchable (Tom Select) small select draws its text in the inner
   .ts-control, which custom.css sizes in rem — 15.4px beside the 13px native
   .form-select-sm next to it (measured on the Power Tables rule editor,
   2026-10-03). Same token as the native control. */
body.mgx-restyle :is(.ts-wrapper.form-select-sm, .ts-wrapper.form-control-sm) .ts-control {
  font-size: var(--type-small);
}
body.mgx-restyle .dropdown-menu { --bs-dropdown-font-size: var(--bs-body-font-size); }
body.mgx-restyle .pagination:not(.pagination-sm):not(.pagination-lg) { --bs-pagination-font-size: var(--bs-body-font-size); }
@media (min-width: 576.02px) {
  body.mgx-restyle .breadcrumb { font-size: var(--bs-body-font-size); }
}
/* A badge is never larger than the text it sits beside (decision 6.21, owner
   2026-10-01): 0.85 of its context, between the type floor (12) and the small
   step (13) — 13 beside 15–16px text, 12 in a dense 14px row or a table. Pinned
   at 13 it read bigger than the meta lines, table cells and dense rows it
   annotates: bold and padded, at a larger size than the words around it. */
body.mgx-restyle .badge { --bs-badge-font-size: clamp(var(--type-caption), 0.85em, var(--type-small)); }
/* Weights are 400/500/600 — the UA's bold `th` (700) is off the scale. */
body.mgx-restyle .table th { font-weight: 600; }
/* Stat value (shared/_dashboard_stat_card): the display step, 28/600. */
body.mgx-restyle .stat-card-text > .h2 { font-size: var(--type-display); font-weight: 600; }
/* The same step as a variable: the narrow-tile rule (custom.css,
   `@container dashboard-stat-card`) scales the value DOWN from it. */
body.mgx-restyle .stat-card-text { --stat-value-size: var(--type-display); }
/* Modal and drawer titles are titles: 16/600 (modal was 15.4/400, drawer 15.4/600). */
body.mgx-restyle :is(.modal-title, .offcanvas-title) { font-size: var(--type-title); font-weight: 600; }

/* ---------- 3 · Underline tabs — decision 6.15 ----------------------------
   Restyles `.nav-tabs` (127 files + 46 card-header-tabs + enhanced-tabs) to the
   values the product's own underline tabs render. Markup unchanged.
   The rule and the bar are INSET SHADOWS, not borders with a -1px overhang: a
   strip that scrolls sideways must not overflow vertically. The !importants
   answer custom.css's "selected tab white" rule. */
body.mgx-restyle .nav-tabs {
  gap: 1.5rem;
  border-bottom: 0;
  box-shadow: inset 0 -1px 0 var(--bs-border-color);
}
body.mgx-restyle .nav-tabs .nav-link {
  margin-bottom: 0;
  padding: .5rem 0;
  font-size: var(--bs-body-font-size);
  color: var(--bs-secondary-color);
  background-color: transparent;
  border: 0;
  border-radius: 0;
}
body.mgx-restyle .nav-tabs .nav-link:hover {
  color: var(--bs-body-color);
  box-shadow: inset 0 -2px 0 var(--bs-border-color);
}
body.mgx-restyle .nav-tabs .nav-link.active,
body.mgx-restyle .nav-tabs .nav-item.show .nav-link {
  color: var(--bs-link-color, var(--bs-primary));
  font-weight: 600;
  background-color: transparent !important;
  border-color: transparent !important;
  box-shadow: inset 0 -2px 0 currentColor;
}
/* In a card header the tabs sit on the header's own rule, at the header's inset. */
body.mgx-restyle .card-header > .nav-tabs.card-header-tabs {
  margin: 0 0 -15px;
  box-shadow: none;
}

/* ---------- 4 · Input-group addon: boundary colour and control radius ------
   The addon kept #dee2e6 / 8px while the input beside it is #868e96 / 6px. */
:where(:root:not([data-theme="dark"])) body.mgx-restyle .input-group-text {
  border-color: var(--control-border-color);
}
body.mgx-restyle .input-group-text { border-radius: var(--mgx-ctl-radius); }

/* ---------- 5 · ONE focus indicator (pass 3, C1) --------------------------
   Supersedes pass 2's O5. Fourteen focus treatments across 31 focusable
   controls become two: text entry gets a brand edge plus a soft halo; a
   button-like choice gets a 2px outline with a 2px gap. Measured on the
   specimen: ring edge 1.36-1.90:1 -> 5.91:1 light, 6.55:1 dark.
   The !importants answer custom.css:1102-1111, which sets #80bdff !important.
   The engine selectors are included so the picker engines stop drawing their
   own rings even before their geometry rules (C2) land. */
body.mgx-restyle :is(.form-control, .form-select):focus,
body.mgx-restyle .ts-wrapper.focus,
body.mgx-restyle .select2-container--focus .select2-selection,
body.mgx-restyle .select2-container--open .select2-selection,
body.mgx-restyle .choices.is-focused .choices__inner,
body.mgx-restyle .choices.is-open .choices__inner {
  border-color: rgb(var(--ctl-focus-rgb)) !important;
  box-shadow: var(--ctl-focus-ring) !important;
  outline: 0;
}
body.mgx-restyle .ts-wrapper.focus .ts-control { box-shadow: none; border-color: transparent; }
/* Invalid keeps its own colour — this sits after the rule above on purpose. */
body.mgx-restyle .form-control.is-invalid:focus,
body.mgx-restyle .form-select.is-invalid:focus {
  border-color: var(--bs-form-invalid-border-color) !important;
  box-shadow: 0 0 0 1px var(--bs-form-invalid-border-color), 0 0 0 .25rem rgba(var(--bs-danger-rgb), .2) !important;
}
body.mgx-restyle .btn-check:focus-visible + .btn,
body.mgx-restyle .input-group > .btn:focus-visible,
body.mgx-restyle .star-rating [role="radio"]:focus-visible,
body.mgx-restyle .star-radio:focus-visible + .star-icon,
body.mgx-restyle .form-check-input:focus-visible {
  outline: var(--choice-focus-outline) !important;
  outline-offset: 2px;
  box-shadow: none !important;
  z-index: 5;
}

/* ---------- 6 · Status-badge fills derive from the tenant's colours --------
   …except the neutral tag, one fixed grey (below; decision S6).
   Bootstrap 5.3's own rule: the tone mixed 20% into white. AdminKit compiled
   these from its own palette, so a tenant's brand never reached the fill while
   the theme DID recolour the ink. Inks stay the theme's contrast-checked
   on-subtle values. Light only; dark keeps custom.css's rgba tints. */
:root:not([data-theme="dark"]) body.mgx-restyle {
  --bs-primary-bg-subtle: color-mix(in srgb, var(--bs-primary) 20%, #fff);
  --bs-secondary-bg-subtle: color-mix(in srgb, var(--bs-secondary) 20%, #fff);
  --bs-success-bg-subtle: color-mix(in srgb, var(--bs-success) 20%, #fff);
  --bs-info-bg-subtle: color-mix(in srgb, var(--bs-info) 20%, #fff);
  --bs-warning-bg-subtle: color-mix(in srgb, var(--bs-warning) 20%, #fff);
  --bs-danger-bg-subtle: color-mix(in srgb, var(--bs-danger) 20%, #fff);
}
/* The neutral status tag is ONE grey on every tenant (decision S6, owner
   2026-10-21): a status never wears a tenant colour. It painted the PAGE colour
   first — invisible on the page, 1.07:1 on a card; 284 files hand-add `border`
   to see it — then a tint of the tenant's SECONDARY, so on a green-secondary
   tenant every Draft, Cancelled and Required tag read as a green "done", and
   OfficeChat's #00a8e1 made them the info tone's light blue. Bootstrap's
   `text-bg-light` is the same tag spelled the other way (~110 sites); the
   legacy `badge bg-secondary` (StatusBadgeHelper.bootstrap_color) is block 22's.
   The fill and the muted ink are GENERATED (DesignTokens.surface(:neutral_tag),
   BusinessTheme#neutral_tag_colors): the platform grey 20% into white, as the
   default theme already painted and the phone's grey status paints. The neutral
   BUTTON still follows the secondary colour (S2). */
:root:not([data-theme="dark"]) body.mgx-restyle {
  /* design-tokens:neutral-tag:begin */
  --mgx-neutral-tag-bg: #e2e3e5;
  --mgx-neutral-tag-ink: #575f66;
  /* design-tokens:neutral-tag:end */
}
:root:not([data-theme="dark"]) body.mgx-restyle .badge:is(.bg-light, .text-bg-light) {
  background-color: var(--mgx-neutral-tag-bg) !important;
}
/* The ink is whatever the tag carries; over 300 badges pair it with a tone
   utility, clamped against the card and the page only, which the grey is not:
   "AI mode: Off" (`text-muted`) read 4.34:1, `text-secondary` 3.96–4.40:1 on five
   presets, `text-primary` 4.30:1 on Sunset (preset sweep, 2026-10-02), and
   `text-success` 3.5:1 on the default theme. `text-dark` (#212529, 13:1) and
   `text-bg-light` (#000) need nothing. A muted ink is the grey measured for the
   fill; a tone's is the tenant's tone measured on it
   (BusinessTheme#neutral_tag_on_color_tokens), so a mention or a step number
   keeps its brand colour and reads. */
:root:not([data-theme="dark"]) body.mgx-restyle .badge.bg-light:is(.text-muted, .text-secondary, .text-body-secondary) {
  color: var(--mgx-neutral-tag-ink) !important;
}
:root:not([data-theme="dark"]) body.mgx-restyle .badge.bg-light.text-primary {
  color: var(--bs-on-neutral-tag-primary, var(--bs-on-subtle-primary, var(--bs-primary-text-emphasis))) !important;
}
:root:not([data-theme="dark"]) body.mgx-restyle .badge.bg-light.text-success {
  color: var(--bs-on-neutral-tag-success, var(--bs-on-subtle-success, var(--bs-success-text-emphasis))) !important;
}
:root:not([data-theme="dark"]) body.mgx-restyle .badge.bg-light.text-danger {
  color: var(--bs-on-neutral-tag-danger, var(--bs-on-subtle-danger, var(--bs-danger-text-emphasis))) !important;
}
:root:not([data-theme="dark"]) body.mgx-restyle .badge.bg-light.text-warning {
  color: var(--bs-on-neutral-tag-warning, var(--bs-on-subtle-warning, var(--bs-warning-text-emphasis))) !important;
}
:root:not([data-theme="dark"]) body.mgx-restyle .badge.bg-light.text-info {
  color: var(--bs-on-neutral-tag-info, var(--bs-on-subtle-info, var(--bs-info-text-emphasis))) !important;
}
/* Dark: AdminKit fills it navy (#2d3846 — a second hue among the theme's
   neutral greys, Console #2831, decided 2026-10-02). It is the CARD lifted one
   step toward white: a raised neutral chip off the card, as the tone chips
   (block 22) are tone washes over it. Not the secondary wash light uses: that
   carries the tenant's secondary hue, and is light enough that a `text-muted`
   tag fell to 4.43:1 on it (the lifted card keeps it at 5:1). */
:root[data-theme="dark"] body.mgx-restyle .badge:is(.bg-light, .text-bg-light) {
  background-color: color-mix(in srgb, var(--bs-card-bg, #333) 94%, #fff) !important;
}
/* The fill above is lifted, the ink was not: the neutral StatusBadge
   (`bg-light text-dark`, StatusBadgeHelper#status_badge_classes) kept
   #212529 on it — about 1.5:1, unreadable on every dark page drawing a
   neutral status (idea #394's "Not available" badge found it, 2026-10-09). */
:root[data-theme="dark"] body.mgx-restyle .badge.bg-light.text-dark {
  color: var(--bs-body-color) !important;
}
/* Its muted ink is neutral too (S6): `text-muted` and `text-secondary` are the
   tenant's muted text and secondary colours lightened, so the tag's text came
   out purple on Midnight (#caa0ed) and green on Forest (#95bcaa). The body ink
   at 80% stays muted beside a `text-dark` tag. */
:root[data-theme="dark"] body.mgx-restyle .badge.bg-light:is(.text-muted, .text-secondary, .text-body-secondary) {
  color: color-mix(in srgb, var(--bs-body-color) 80%, transparent) !important;
}

/* ---------- 7 · Menus float ------------------------------------------------
   AdminKit defines --bs-dropdown-box-shadow but never paints it. */
body.mgx-restyle .dropdown-menu { box-shadow: var(--mgx-menu-shadow); }

/* ---------- 8 · The overflow toggle is square at its height ----------------
   shared/_row_actions is icon-only fa-ellipsis-v: 23x29 -> 29x29 in a row.
   min-width, so a labelled button is never squeezed. */
body.mgx-restyle .btn:has(> .fa-ellipsis-v:only-child) {
  min-width: calc(1.5em + 2 * var(--bs-btn-padding-y) + 2 * var(--bs-btn-border-width));
}

/* ---------- 9 · Tenant page colour reaches the canvas and the modal body ---
   AdminKit paints `.main` with a literal (#f5f7fb light, #19222c navy dark), so
   page_bg was inert in the content area and dark mode showed the theme's #333
   cards on AdminKit navy. The modal-body tint was the same literal. */
body.mgx-restyle .main { background: var(--bs-body-bg); }
:root:not([data-theme="dark"]) body.mgx-restyle .modal-body { background-color: var(--bs-body-bg) !important; }

/* ---------- 10 · Control heights 30 / 38 / 48 — decision 6.3 ---------------
   Reached with PADDING, not a fixed height, so a wrapped label still grows
   instead of clipping. This block owns --ctl-h. */
body.mgx-restyle :where(.btn, .form-control, .form-select, .page-link, .input-group-text) { --ctl-h: 38px; }
body.mgx-restyle :where(.btn-sm, .btn-group-sm > .btn, .form-control-sm, .form-select-sm, .input-group-sm > *) { --ctl-h: 30px; }
body.mgx-restyle :where(.btn-lg, .btn-group-lg > .btn, .form-control-lg, .form-select-lg, .input-group-lg > *) { --ctl-h: 48px; }
/* A picker engine (block 14) draws its box as the select's NEXT SIBLING, which
   inherits nothing from it: a Select2 on a small select took 38px beside 30px
   inputs and lifted its label above its neighbours' (Lone Worker's alerts filter,
   /design-pass 2026-10-02). The box takes its select's size. */
body.mgx-restyle :where(.form-select-sm, .form-control-sm) + .select2-container { --ctl-h: 30px; }
body.mgx-restyle :where(.form-select-lg, .form-control-lg) + .select2-container { --ctl-h: 48px; }
body.mgx-restyle .btn { --bs-btn-padding-y: calc((var(--ctl-h) - 2px - 1.5em) / 2); }
body.mgx-restyle :is(.form-control, .form-select, .input-group-text):not(textarea) {
  padding-top: calc((var(--ctl-h) - 2px - 1.5em) / 2);
  padding-bottom: calc((var(--ctl-h) - 2px - 1.5em) / 2);
  min-height: 0;
}
body.mgx-restyle .pagination { --bs-pagination-padding-y: calc((var(--ctl-h, 38px) - 2px - 1.5em) / 2); }

/* ---------- 11 · Bordered hairline cards — decision 6.4 -------------------
   `.border-0` is an !important utility that 1,724 files opt out with, so this
   is the one place the layer answers a utility with !important. The repo rules
   that currently mandate `border-0 shadow-sm` change with this. */
body.mgx-restyle .card.border-0 { border: 1px solid var(--mgx-card-edge, var(--mgx-card-border)) !important; }

/* ---------- 12 · Drawer actions pinned to the bottom edge — decision 6.17 --
   Left-flowing order was already settled; the pinning is what was decided.

   z-index, added for ISS-20260922-601-25E845: the bar pinned with `z-index:
   auto`, which paints in the SAME layer as ordinary drawer content and LOSES
   to any positioned element in the body carrying a positive z-index. A drawer
   body is a scroll container, so anything a form pins to its floor lands in
   this bar's band — Live Boards' sticky "Live preview" card (z-index: 3) sat
   on top of Save and Cancel and swallowed the clicks at every scroll position
   but the very last. The bar owns the drawer floor: it is the only way out of
   the form, so it outranks whatever the form pins beside it. Kept well under
   the Bootstrap overlay bands (dropdown 1000, modal 1055) — those open ABOVE
   the bar and still must. */
body.mgx-restyle .offcanvas-body .form-actions {
  position: sticky;
  bottom: calc(-1 * var(--bs-offcanvas-padding-y));
  z-index: 5;
  margin: 1rem calc(-1 * var(--bs-offcanvas-padding-x)) calc(-1 * var(--bs-offcanvas-padding-y));
  padding: .75rem var(--bs-offcanvas-padding-x);
  background: var(--bs-offcanvas-bg);
  border-top: 1px solid var(--bs-border-color);
}

/* ==========================================================================
   Blocks 13-19 — added 2026-09-21 to close the live-defect list. Same
   contract as above: body.mgx-restyle + the selector it replaces, theme
   variables read never written, dark twins on :root[data-theme="dark"].
   ========================================================================== */

/* ---------- 13 · Picker-engine tokens (pass 3, C2-C6) ------------------
   The engines paint their own chevrons, so the form-select glyph is restated
   here scoped to them. --ctl-h is owned by block 10. */
body.mgx-restyle {
  --token-bg: rgba(var(--bs-primary-rgb), .12);
  --token-ink: var(--bs-on-subtle-primary, #2959a1);
  --ctl-chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");
}
:root[data-theme="dark"] body.mgx-restyle {
  --token-bg: rgba(var(--bs-primary-rgb), .28);
  --token-ink: #e4ebf5;
  --ctl-chevron: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23bdc0c5' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");
}

/* ---------- 14 · C2: every picker engine takes the control's geometry ---
   select2.min.css is appended by application.js AFTER every stylesheet, so
   equal-specificity rules lose to it on order alone; the !importants here
   answer legacy !importants in custom.css:1036-1227 and win on weight. In
   dark mode these engines painted WHITE boxes with light ink (1.06-1.73:1,
   ~210 files). */
body.mgx-restyle .select2-container--default .select2-selection--single,
body.mgx-restyle .user-searchable-select + .select2-container--default .select2-selection--single {
  height: var(--ctl-h, 38px) !important;
  border: 1px solid var(--ctl-border) !important;
  border-radius: var(--mgx-ctl-radius, 6px) !important;
  background-color: var(--ctl-bg);
  font-size: var(--bs-body-font-size, 15px);
}
body.mgx-restyle .select2-container--default .select2-selection--single .select2-selection__rendered,
body.mgx-restyle .user-searchable-select + .select2-container--default .select2-selection--single .select2-selection__rendered {
  line-height: calc(var(--ctl-h, 38px) - 2px) !important;
  color: var(--ctl-ink) !important;
  padding-left: .85rem !important;
}
body.mgx-restyle .select2-container--default .select2-selection--single .select2-selection__arrow { height: calc(var(--ctl-h, 38px) - 2px) !important; }
body.mgx-restyle .select2-container--default .select2-selection--multiple {
  min-height: var(--ctl-h, 38px);
  border: 1px solid var(--ctl-border) !important;
  border-radius: var(--mgx-ctl-radius, 6px);
  background-color: var(--ctl-bg);
}
body.mgx-restyle .select2-container--default .select2-selection--multiple .select2-selection__choice {
  background-color: var(--token-bg); color: var(--token-ink); border: 0; border-radius: calc(var(--mgx-ctl-radius, 6px) - 2px);
}
body.mgx-restyle .select2-dropdown { background-color: var(--ctl-bg); color: var(--ctl-ink); border-color: var(--ctl-border); border-radius: var(--mgx-ctl-radius, 6px); }
body.mgx-restyle .select2-container--default .select2-results__option--highlighted[aria-selected],
body.mgx-restyle .select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
  background-color: rgb(var(--bs-primary-rgb)); color: var(--bs-on-primary, #fff);
}
body.mgx-restyle .select2-container--default.select2-container--focus .select2-selection,
body.mgx-restyle .select2-container--default.select2-container--open .select2-selection,
body.mgx-restyle .user-searchable-select + .select2-container--default.select2-container--focus .select2-selection--single,
body.mgx-restyle .user-searchable-select + .select2-container--default.select2-container--open .select2-selection--single {
  border-color: rgb(var(--ctl-focus-rgb)) !important;
  box-shadow: var(--ctl-focus-ring) !important;
}
body.mgx-restyle .select2-container--default .select2-search--dropdown .select2-search__field { border-color: var(--ctl-border); background: var(--ctl-bg); color: var(--ctl-ink); }

body.mgx-restyle .choices__inner {
  min-height: var(--ctl-h, 38px);
  border: 1px solid var(--ctl-border);
  border-radius: var(--mgx-ctl-radius, 6px);
  background-color: var(--ctl-bg);
  color: var(--ctl-ink);
  font-size: var(--bs-body-font-size, 15px);
  line-height: 1.5;
  padding: calc((var(--ctl-h, 38px) - 2px - 1.5em) / 2) .85rem;
}
body.mgx-restyle .choices[data-type*=select-one] .choices__inner { padding-bottom: calc((var(--ctl-h, 38px) - 2px - 1.5em) / 2); }
body.mgx-restyle .choices__list--single { padding: 0 1.75rem 0 0; }
body.mgx-restyle .choices[data-type*=select-one]::after {
  border: 0; width: 16px; height: 12px; margin-top: -6px; right: .75rem;
  background: var(--ctl-chevron) no-repeat center / 16px 12px;
}
body.mgx-restyle .choices__list--multiple .choices__item {
  background-color: var(--token-bg); color: var(--token-ink); border: 0; border-radius: calc(var(--mgx-ctl-radius, 6px) - 2px);
  font-size: .8125rem; font-weight: 500;
}
body.mgx-restyle .choices[data-type*=select-multiple] .choices__button { filter: invert(.55); border-left-color: rgba(0,0,0,.25); }
:root[data-theme="dark"] body.mgx-restyle .choices[data-type*=select-multiple] .choices__button { filter: none; border-left-color: rgba(255,255,255,.3); }
body.mgx-restyle .choices__list--dropdown, body.mgx-restyle .choices__list[aria-expanded] { background-color: var(--ctl-bg); color: var(--ctl-ink); border-color: var(--ctl-border); }
body.mgx-restyle .choices__input { background-color: transparent; color: var(--ctl-ink); }

body.mgx-restyle .ts-wrapper.multi .ts-control > div { background: var(--token-bg); color: var(--token-ink); border-radius: calc(var(--mgx-ctl-radius, 6px) - 2px); }
:root[data-theme="dark"] body.mgx-restyle .ts-dropdown { background: var(--ctl-bg); color: var(--ctl-ink); border-color: var(--ctl-border); }

/* colour swatch in an input-group: a fixed square at control height (was 120x38) */
body.mgx-restyle .input-group > .form-control-color {
  flex: 0 0 var(--ctl-h, 38px); width: var(--ctl-h, 38px); height: var(--ctl-h, 38px); padding: 0; border-color: var(--ctl-border);
  overflow: hidden; cursor: pointer;
}
/* ...and the chosen colour fills that square edge to edge: the browser's own
   swatch keeps an inner padding and a grey border, which drew a small chip
   floating inside a white box. The control's border and corners frame it. */
body.mgx-restyle .input-group > .form-control-color::-webkit-color-swatch-wrapper { padding: 0; }
body.mgx-restyle .input-group > .form-control-color::-webkit-color-swatch { border: 0; border-radius: 0; }
body.mgx-restyle .input-group > .form-control-color::-moz-color-swatch { border: 0; border-radius: 0; }

/* ---------- 15 · C3: the native file input is a control, not a drop zone -
   enhanced_field_types.css:123-140 drew it as a 40.3px dashed box on #f8f9fa
   that dark mode never recoloured (1.73:1). */
body.mgx-restyle .form-control[type="file"] {
  border: 1px solid var(--ctl-border);
  background-color: var(--ctl-bg);
  color: var(--ctl-ink);
  padding: .3rem .85rem;
}
body.mgx-restyle .form-control[type="file"]:hover:not(:focus) { background-color: var(--ctl-bg); border-color: var(--ctl-border); }
/* ...and when it is invalid, it says so. The two rules above sit at (0,3,1)/(0,4,1)
   and outranked Bootstrap's `.form-control.is-invalid` border, so EVERY invalid file
   input on the platform stayed grey while its text-field siblings turned red — the
   error summary was the only visible signal (found on the Sites asset upload,
   2026-09-23). The hover twin, because the hover rule above resets border-color. */
body.mgx-restyle .form-control[type="file"].is-invalid,
body.mgx-restyle .form-control[type="file"].is-invalid:hover:not(:focus) { border-color: var(--bs-form-invalid-border-color); }

/* ---------- 16 · C4: a range track you can see (was 1.02-1.05:1) --------
   The disabled-thumb fix is in BusinessTheme (:enabled on the emitter). */
body.mgx-restyle .form-range::-webkit-slider-runnable-track { height: .3rem; background-color: var(--ctl-border); }
body.mgx-restyle .form-range::-moz-range-track { height: .3rem; background-color: var(--ctl-border); }
body.mgx-restyle .form-range::-moz-range-progress { height: .3rem; background-color: rgb(var(--bs-primary-rgb)); }
body.mgx-restyle .form-range::-webkit-slider-thumb { width: 1.125rem; height: 1.125rem; margin-top: -.4125rem; border: 2px solid var(--bs-card-bg, #fff); }
body.mgx-restyle .form-range:focus::-webkit-slider-thumb { box-shadow: none; }
body.mgx-restyle .form-range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 2px var(--bs-card-bg, #fff), 0 0 0 4px rgb(var(--ctl-focus-rgb)); }
body.mgx-restyle .form-range:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 2px var(--bs-card-bg, #fff), 0 0 0 4px rgb(var(--ctl-focus-rgb)); }

/* ---------- 17 · C5: one selected look for the segmented control ---------
   shared/_segmented_control painted :radio mode grey (#6c757d) and :link mode
   brand — same partial, two looks. The look is the NEUTRAL one (decision,
   deferred-findings #3127, 2026-10-22): a selected view is a state, not an
   action, and the design system's own segmented control draws it neutral
   (design-system/decisions/tabs.html option B) — filled brand beside a page's
   primary button made a second, equally loud primary (Workspace List/Timeline,
   Schedule List/Calendar, Board Kanban/List), and ~25 view toggles already drew
   it neutral with aria-current="true" + .active. So the selected outline-secondary
   segment — checked radio, aria-current="page" link or .active alike — takes the
   tone's own active fill (the tenant theme's measured --bs-btn-active-*). An
   option the author drew as a PRIMARY tone (btn-outline-primary / btn-primary)
   stays brand: that is the author's choice of tone, not the control's. */
body.mgx-restyle .btn-group > .btn-outline-secondary[aria-current="page"] {
  background-color: var(--bs-btn-active-bg); border-color: var(--bs-btn-active-border-color); color: var(--bs-btn-active-color);
}
body.mgx-restyle .btn-group > .btn-check:checked + .btn-outline-primary,
body.mgx-restyle .btn-group > .btn-primary[aria-current="page"] {
  background-color: rgb(var(--bs-primary-rgb)); border-color: rgb(var(--bs-primary-rgb)); color: var(--bs-on-primary, #fff);
}

/* ---------- 18 · C6: pickers that paint their own blues take the brand ---
   flatpickr #3b7ddd, daterangepicker #08c/#357ebd, repainted #0d6efd. */
body.mgx-restyle .flatpickr-day.selected, body.mgx-restyle .flatpickr-day.selected:hover,
body.mgx-restyle .flatpickr-day.startRange, body.mgx-restyle .flatpickr-day.endRange {
  background: rgb(var(--bs-primary-rgb)); border-color: rgb(var(--bs-primary-rgb)); color: var(--bs-on-primary, #fff);
}
body.mgx-restyle .flatpickr-day.today:not(.selected) { border-color: rgb(var(--bs-primary-rgb)); }
/* AdminKit fills a hovered "today" with #adb5bd (light) / #959ea9 (dark) under white
   ink: 2.07:1 / 2.71:1. One grey that carries white in both modes (4.69:1). Never on a
   today that is also picked: the brand fill above must survive the pointer and focus. */
body.mgx-restyle .flatpickr-day.today:not(.selected, .startRange, .endRange):hover,
body.mgx-restyle .flatpickr-day.today:not(.selected, .startRange, .endRange):focus {
  background: #6c757d; border-color: #6c757d; color: #fff;
}
/* AdminKit recolours Quill's code block to the page's own grey and keeps the ink
   Quill drew on its dark block — #f8f9fa on #f8f9fa light, #384350 on #384350 dark:
   1.00:1, a code block nobody can read (finding 4342). The theme's ink on its
   tertiary ground, in both modes. */
body .ql-snow .ql-editor pre.ql-syntax, body .ql-bubble .ql-editor pre.ql-syntax {
  background-color: var(--bs-tertiary-bg, #f8f9fa); color: var(--bs-body-color, #212529);
}
body.mgx-restyle .daterangepicker .ranges li.active,
body.mgx-restyle .daterangepicker td.active, body.mgx-restyle .daterangepicker td.active:hover {
  background-color: rgb(var(--bs-primary-rgb)); color: var(--bs-on-primary, #fff);
}
body.mgx-restyle .daterangepicker td.in-range:not(.active) { background-color: var(--token-bg); color: inherit; }
:root[data-theme="dark"] body.mgx-restyle .daterangepicker { background-color: var(--bs-card-bg, #333); border-color: var(--ctl-border); color: var(--ctl-ink); }
:root[data-theme="dark"] body.mgx-restyle .daterangepicker .calendar-table { background-color: transparent; border-color: transparent; }
:root[data-theme="dark"] body.mgx-restyle .daterangepicker td.off { background-color: transparent; color: #6c757d; }
:root[data-theme="dark"] body.mgx-restyle .daterangepicker td.available:hover,
:root[data-theme="dark"] body.mgx-restyle .daterangepicker .ranges li:hover { background-color: rgba(255, 255, 255, .08); }
:root[data-theme="dark"] body.mgx-restyle .daterangepicker select { background: var(--ctl-bg); color: var(--ctl-ink); border: 1px solid var(--ctl-border); }
:root[data-theme="dark"] body.mgx-restyle .daterangepicker::after { border-bottom-color: var(--bs-card-bg, #333); }

/* ---------- 19 · Dark mode: the scrim, the two side panels, the wordmark -
   AdminKit dark.css sets --bs-backdrop-bg:#fff, so every modal and drawer
   dimmed the page WHITE in dark mode. help_sidepanel.css and the profile
   panel's inline style carry no [data-theme] rule at all (1.15-1.34:1). */
:root[data-theme="dark"] body.mgx-restyle :is(.modal-backdrop, .offcanvas-backdrop) {
  --bs-backdrop-bg: #0b0d10;
  --bs-backdrop-opacity: .6;
}
:root[data-theme="dark"] body.mgx-restyle .help-sidepanel {
  --ai-assistant-bg-color: var(--bs-card-bg, #333);
  --ai-assistant-header-bg: var(--bs-tertiary-bg, #2b2b2b);
  color: var(--bs-body-color);
}
:root[data-theme="dark"] body.mgx-restyle .profile-sidepanel-container { background-color: var(--bs-card-bg, #333); color: var(--bs-body-color); }
:root[data-theme="dark"] body.mgx-restyle .profile-sidepanel-header { background-color: var(--bs-tertiary-bg, #2b2b2b); border-bottom-color: var(--bs-border-color); }
:root[data-theme="dark"] body.mgx-restyle .profile-sidepanel-job-title { color: var(--bs-secondary-color); }
/* The DEFAULT MangoApps wordmark is dark ink on a transparent PNG; on the dark
   navbar it vanished. This lifts only that asset — a tenant's own logo never
   carries .navbar-default-logo and is never filtered. */
:root[data-theme="dark"] body.mgx-restyle .navbar-default-logo { filter: brightness(0) invert(1); }

/* ---------- 20 · Rail labels you can read (pass 3, J5) -------------------
   custom.css:2649-2668 set 0.5625rem (9.9px) and 0.4375rem (7.7px); axe
   flagged all 11 as serious. 11px/500, two lines max. The colour half of the
   fix is BusinessTheme's sidebar_rail_text default (#d8ebe1 -> #ffffff).
   A label wraps first. A word too long for one line at 11px was clipped mid-
   word, so rail_label_fit_controller.js now steps that label down (inline
   font-size, floor 7px) until the whole word fits and marks it
   .rail-label-sm. Only a word that still does not fit at the floor breaks
   across lines (.rail-label-break) — every letter visible beats half a word.
   A rail link has a tooltip with its full name (.rail-label-tooltip) only
   where the label does not already show it at full size — shrunk, broken,
   clipped, or a short rail name (ISS-20261005-524-7BBB42). */
body.mgx-restyle .sidebar-rail-label {
  font-size: 11px;
  font-weight: 500;
  line-height: 1.2;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
body.mgx-restyle .sidebar-rail-label.rail-label-break { overflow-wrap: anywhere; }
/* One line: the 200px default wrapped "Compensation Management" in two. */
.tooltip.rail-label-tooltip { --bs-tooltip-font-size: 0.875rem; --bs-tooltip-max-width: none; white-space: nowrap; }
/* The tenant's rail colours, a shade deeper, not Bootstrap's black — set on
   :root by rail_label_fit_controller.js from whatever the rail is painted with,
   held to 4.5:1 text contrast. */
.tooltip.rail-label-tooltip {
  --bs-tooltip-bg: var(--rail-tip-bg, var(--bs-emphasis-color));
  --bs-tooltip-color: var(--rail-tip-ink, var(--bs-body-bg));
  --bs-tooltip-opacity: 1;
}
.tooltip.rail-label-tooltip .tooltip-inner { box-shadow: 0 2px 8px rgba(11, 13, 16, .18); }

/* ---------- 21 · Navigation at 768-991px (pass 3, J1) --------------------
   custom.css:3397-3409 forces the sidebar wrapper to width 0 below 992 while
   the phone drawer is d-md-none, so in this band there was NO app or admin
   navigation. The panel becomes an overlay drawer beside the rail, opened by
   the hamburger or the rail's Apps/Admin buttons (modules/sidebar.js and
   sidebar_rail_controller add body.sidebar-overlay-open only in this band).
   The offsets are the shell's own: 56px navbar, 96px with the trial strip. */
@media (min-width: 768px) and (max-width: 991.98px) {
  body.mgx-restyle.sidebar-overlay-open .sidebar-rail ~ #sidebar-wrapper {
    position: fixed;
    top: 56px;
    bottom: 0;
    left: 64px;
    width: 220px !important;
    min-width: 220px !important;
    z-index: 1031;
    overflow-y: auto;
    background: var(--bs-body-bg);
    box-shadow: 0 8px 24px rgba(11, 13, 16, .26);
  }
  body.mgx-restyle.sidebar-overlay-open.has-trial-strip .sidebar-rail ~ #sidebar-wrapper { top: 96px; }
  body.mgx-restyle.sidebar-overlay-open .sidebar-rail ~ #sidebar-wrapper .sidebar {
    width: 220px !important;
    min-width: 220px !important;
    max-width: none !important;
    overflow: visible;
  }
  body.mgx-restyle.sidebar-overlay-open::after {
    content: "";
    position: fixed;
    inset: 56px 0 0 0;
    background: rgba(11, 13, 16, .36);
    z-index: 1000;
  }
  body.mgx-restyle.sidebar-overlay-open.has-trial-strip::after { top: 96px; }
}

/* ---------- 22 · Soft status badges (decision 6.14) ------------------------
   The majority markup, `badge bg-{tone}` (about 3,000 files, helpers and JS
   included), renders the settled soft look with no markup change: the tone's
   subtle fill, tenant-derived in light (block 6) and re-tinted in dark
   (custom.css), under `--bs-on-subtle-{tone}` — the ink BusinessTheme clamps
   for contrast against exactly those fills, in both modes. The settled form
   `shared/_status_badge` writes (`bg-{tone}-subtle text-{tone}-emphasis`) takes
   the same ink, so a helper-made badge and a hand-written one are identical.
   Stays solid: counters (`rounded-pill`), positioned notification dots
   (`position-absolute`), `bg-dark`, and Bootstrap's explicit `text-bg-{tone}`.
   !important because `.bg-{tone}` and `.text-dark` are !important utilities and
   color_text_fix.css re-inks solid fills with !important. Never a bare
   `.bg-{tone}` — always compounded with `.badge`. The modern skin (decision S0)
   comes after this and changes the badge's shape, not its colours. */
body.mgx-restyle .badge.bg-primary:not(.rounded-pill, .position-absolute),
body.mgx-restyle .badge.bg-primary-subtle {
  background-color: var(--bs-primary-bg-subtle) !important;
  color: var(--bs-on-subtle-primary, var(--bs-primary-text-emphasis)) !important;
}
/* Secondary is the neutral status's legacy spelling (StatusBadgeHelper
   .bootstrap_color: neutral → "secondary"), so it is the neutral tag's fixed
   grey, never the tenant's secondary (decision S6; block 6 defines the pair in
   light, the dark wash is below). */
body.mgx-restyle .badge.bg-secondary:not(.rounded-pill, .position-absolute),
body.mgx-restyle .badge.bg-secondary-subtle {
  background-color: var(--mgx-neutral-tag-bg, var(--bs-secondary-bg-subtle)) !important;
  color: var(--mgx-neutral-tag-ink, var(--bs-on-subtle-secondary, var(--bs-secondary-text-emphasis))) !important;
}
body.mgx-restyle .badge.bg-success:not(.rounded-pill, .position-absolute),
body.mgx-restyle .badge.bg-success-subtle {
  background-color: var(--bs-success-bg-subtle) !important;
  color: var(--bs-on-subtle-success, var(--bs-success-text-emphasis)) !important;
}
body.mgx-restyle .badge.bg-danger:not(.rounded-pill, .position-absolute),
body.mgx-restyle .badge.bg-danger-subtle {
  background-color: var(--bs-danger-bg-subtle) !important;
  color: var(--bs-on-subtle-danger, var(--bs-danger-text-emphasis)) !important;
}
body.mgx-restyle .badge.bg-warning:not(.rounded-pill, .position-absolute),
body.mgx-restyle .badge.bg-warning-subtle {
  background-color: var(--bs-warning-bg-subtle) !important;
  color: var(--bs-on-subtle-warning, var(--bs-warning-text-emphasis)) !important;
}
body.mgx-restyle .badge.bg-info:not(.rounded-pill, .position-absolute),
body.mgx-restyle .badge.bg-info-subtle {
  background-color: var(--bs-info-bg-subtle) !important;
  color: var(--bs-on-subtle-info, var(--bs-info-text-emphasis)) !important;
}
/* A remove control inside a soft badge. Markup written for the old solid fill
   carries `.btn-close-white`, whose filter turns the glyph white — on the pale
   fill above that is a white cross on a near-white chip, and the only way to
   remove the chip cannot be seen (six sites on 2026-10-21: Jurisdiction Mapping,
   Service Desk's requester chip, AI Sheets' filter chip and condition values,
   Interview Scheduler's selected jobs, media tags). Dropping the filter leaves
   the theme's own glyph: dark in light, and the dark stylesheet's white
   `.btn-close` in dark — the chip's ink in both. */
body.mgx-restyle .badge:is(.bg-primary, .bg-secondary, .bg-success, .bg-danger, .bg-warning, .bg-info):not(.rounded-pill, .position-absolute) .btn-close-white,
body.mgx-restyle .badge:is(.bg-primary-subtle, .bg-secondary-subtle, .bg-success-subtle, .bg-danger-subtle, .bg-warning-subtle, .bg-info-subtle) .btn-close-white {
  filter: none;
}
/* In the dark theme each tone's subtle fill is an 18% TRANSLUCENT wash
   (custom.css, "Re-tint the Bootstrap subtle tokens"), while the ink above,
   --bs-on-subtle-{tone}, is measured against that wash over the CARD
   (BusinessTheme#subtle_on_color_tokens). A translucent chip takes on whatever
   is behind it, so a badge in an alert, on a card header or on a secondary
   panel sat on a wash over a wash: 3.6-4.4:1 across Policy Hub, Recognition,
   Forms, Scheduling, Tasks, the dashboard, the app marketplace and chat
   mentions (Console #3999). So the chip is laid over the card surface its ink
   was measured on, and reads the same wherever it sits. `dark` is the seventh
   tone and the one AdminKit's dark palette gets wrong outright: it fills
   `bg-dark-subtle` with an OPAQUE mid grey (#7a828a) under
   `text-dark-emphasis` (#bdc0c5), 2.14:1 (#4036). It becomes the same wash,
   of the dark theme's own `dark` (#e9eaec), inked with that tone the way the
   other tones are (6.3:1). Light is untouched: there the fills are opaque
   (block 6) and AdminKit's light `dark` pair reads 7:1. */
:root[data-theme="dark"] body.mgx-restyle .badge:is(.bg-primary:not(.rounded-pill, .position-absolute), .bg-primary-subtle) { --mgx-chip-wash: var(--bs-primary-bg-subtle); }
/* Secondary — the neutral status (decision S6) — is the neutral tag's dark
   form, the card lifted one step toward white with the body ink (block 6's
   `bg-light`), not a wash of the tenant's secondary. */
:root[data-theme="dark"] body.mgx-restyle .badge:is(.bg-secondary:not(.rounded-pill, .position-absolute), .bg-secondary-subtle) {
  --mgx-chip-wash: rgba(255, 255, 255, .06);
  color: var(--bs-body-color) !important;
}
:root[data-theme="dark"] body.mgx-restyle .badge:is(.bg-success:not(.rounded-pill, .position-absolute), .bg-success-subtle) { --mgx-chip-wash: var(--bs-success-bg-subtle); }
:root[data-theme="dark"] body.mgx-restyle .badge:is(.bg-danger:not(.rounded-pill, .position-absolute), .bg-danger-subtle) { --mgx-chip-wash: var(--bs-danger-bg-subtle); }
:root[data-theme="dark"] body.mgx-restyle .badge:is(.bg-warning:not(.rounded-pill, .position-absolute), .bg-warning-subtle) { --mgx-chip-wash: var(--bs-warning-bg-subtle); }
:root[data-theme="dark"] body.mgx-restyle .badge:is(.bg-info:not(.rounded-pill, .position-absolute), .bg-info-subtle) { --mgx-chip-wash: var(--bs-info-bg-subtle); }
:root[data-theme="dark"] body.mgx-restyle .badge.bg-dark-subtle {
  --mgx-chip-wash: rgba(233, 234, 236, .18);
  color: #e9eaec !important;
}
:root[data-theme="dark"] body.mgx-restyle .badge:is(.bg-primary, .bg-secondary, .bg-success, .bg-danger, .bg-warning, .bg-info):not(.rounded-pill, .position-absolute),
:root[data-theme="dark"] body.mgx-restyle .badge:is(.bg-primary-subtle, .bg-secondary-subtle, .bg-success-subtle, .bg-danger-subtle, .bg-warning-subtle, .bg-info-subtle, .bg-dark-subtle) {
  background: linear-gradient(var(--mgx-chip-wash), var(--mgx-chip-wash)), var(--bs-card-bg, #333) !important;
}

/* ---------- 23 · A filled outline button's label is the one measured for it
   AdminKit's light.css AND dark.css paint every hovered or pressed outline
   button's label a LITERAL white (`.btn-outline-*:hover:not(:disabled):not(.disabled)`,
   `…:active`, `….active`, 0,4,0) over the `--bs-btn-hover-color` /
   `--bs-btn-active-color` the tenant theme measured for each fill
   (BusinessTheme#component_scope_overrides: on_color of the fill). Wherever
   the fill is light the label vanished: the "Not now" button on every page and
   the List/Board view toggles in Tasks and Workspace (outline-secondary on the
   tenant's pale accent) 2.3:1 light / 1.94:1 dark, outline-warning 1.89:1 /
   1.66:1, outline-dark 1.2:1 in dark (Console #4034). Bootstrap's own `.btn`
   rules read the variable; this puts that back at AdminKit's own weight
   (0,4,0 — `:where()` keeps the body scope weightless) and wins on load order,
   so every rule that already beat AdminKit on purpose (a coloured card header,
   BusinessTheme#component_style_css; the chat composer's paperclip) still wins. */
:where(body.mgx-restyle) :is(.btn-outline-primary, .btn-outline-secondary, .btn-outline-success, .btn-outline-info, .btn-outline-warning, .btn-outline-danger, .btn-outline-dark, .btn-outline-light):is(:hover, .hover):not(:disabled):not(.disabled) {
  color: var(--bs-btn-hover-color);
}
:where(body.mgx-restyle) :is(.btn-outline-primary, .btn-outline-secondary, .btn-outline-success, .btn-outline-info, .btn-outline-warning, .btn-outline-danger, .btn-outline-dark, .btn-outline-light):not(:disabled):not(.disabled):is(:active, .active) {
  color: var(--bs-btn-active-color);
}

/* ---------- 24 · Dark: `btn-dark` takes AdminKit's own dark label ----------
   AdminKit's dark palette inverts `.btn-dark` into a light grey (#e9eaec) and
   declares its label dark (--bs-btn-color #222e3c), but its combined solid
   rule (`.btn-danger, …, .btn-dark… { color: #fff }`) paints the label a
   literal white over it: 1.2:1 on Service Desk's "Close request", Guest Pass's
   badge and every other btn-dark (Console #3997). The label reads the
   variables again, 11.4:1. `btn-light` keeps AdminKit's fills and labels — a
   dark slate with a light label (8:1), the dark twin of the light theme's
   #f5f7fb button — and takes an edge in block 25. The `bg-dark` / `bg-black` UTILITIES are a
   different question with a different answer: they stay dark
   (color_text_fix.css, "Dark background"). */
:root[data-theme="dark"] body.mgx-restyle .btn-dark { color: var(--bs-btn-color); }
:root[data-theme="dark"] body.mgx-restyle .btn-dark:is(:hover, .hover, :focus-visible):not(:disabled):not(.disabled) { color: var(--bs-btn-hover-color); }
:root[data-theme="dark"] body.mgx-restyle .btn-dark:is(:active, .active, .show),
:root[data-theme="dark"] body.mgx-restyle .show > .btn-dark.dropdown-toggle { color: var(--bs-btn-active-color); }

/* ---------- 25 · `btn-light` has an edge (Console #4107) -----------------
   X1 (cross-app contrast, 2026-09-27; owner decision the same day). AdminKit
   draws `btn-light` with its fill as its border in both sheets (#f5f7fb light,
   #2d3846 dark), so on a white card it was a floating word at 1.07:1 and on the
   dark #333 card 1.06:1. It takes the CONTROL boundary, --ctl-border (block 0) —
   the edge a text input already draws, 3.32:1 on white / 3.1:1 on the #f5f7fb
   shell light, 3.07:1 on the #333 card dark — in every state and both themes
   (owner decision 2026-09-27, /pre-merge xr). The theme hairline it took first
   (--bs-border-color) is a decorative divider, 1.3:1 light / 1.45:1 dark, and
   AdminKit's light hover/pressed borders (#c4c6c9 / #b8b9bc) are 1.71 / 1.96:1.
   Variables only, at AdminKit's own weight (`:where()` keeps the scope
   weightless) — every button rule reads them. The twin for the layouts that
   load color_text_fix.css but not this file is there. */
:where(body.mgx-restyle) .btn-light {
  --bs-btn-border-color: var(--ctl-border);
  --bs-btn-hover-border-color: var(--ctl-border);
  --bs-btn-active-border-color: var(--ctl-border);
  --bs-btn-disabled-border-color: var(--ctl-border);
}

/* ---------- 26 · A card title outside a header takes its card's ink --------
   X1 (cross-app contrast, 2026-09-27). AdminKit's light sheet paints every
   `.card-title` a literal #939ba2 (after its own var() rule, so the variable
   cannot reach it): 2.81:1 on a white card. A heading title is rescued by the
   theme's `h1…h6` rule and a header title by the mgx header rule, but a
   `span` / `div` / `p` title in a card body kept the grey — Company Store's
   product names (Console #4086). It inherits instead: the card's ink, or a
   solid fill's measured label (color_text_fix.css), whichever it sits in.
   Light only — AdminKit's dark title (#d3d5d8) reads 9:1. Weight 0,1,0 (the
   scope is `:where()`), so every rule that already colours a title still wins. */
:where(:root:not([data-theme="dark"]) body.mgx-restyle) .card-title { color: inherit; }

/* ---------- 27 · The nav panel has an edge --------------------------------
   The 220px panel beside the rail had no edge in the product, while Theme
   Settings' preview (admin/theme_settings/_preview_frame) and the design
   system's navigation shell (design-system/preview/navigation.html) both draw
   a 1px hairline in the theme's border_color. A white panel on a tinted
   page_bg read as unfinished. Logical, so it lands on the page side in RTL.
   The panel collapses to width 0 (Home zone, hamburger, AdminKit's
   margin-left collapse, and every width below 992px unless block 21's overlay
   is open; custom.css's rail block) without leaving the box, so those states
   drop the edge, or a 1px line stays beside the rail. Same weight as the edge
   rule (the extra context is `:where()`), later wins. */
body.mgx-restyle .sidebar-rail ~ #sidebar-wrapper .sidebar {
  border-inline-end: 1px solid var(--bs-border-color, #dee2e6);
}
body.mgx-restyle:where(.sidebar-toggled) .sidebar-rail ~ #sidebar-wrapper .sidebar,
body.mgx-restyle .sidebar-rail ~ #sidebar-wrapper:where([data-sidebar-zone="home"]) .sidebar,
body.mgx-restyle .sidebar-rail ~ #sidebar-wrapper .sidebar:where(.collapsed, [style*="margin-left"]) {
  border-inline-end: 0;
}
@media (max-width: 991.98px) {
  body.mgx-restyle:where(:not(.sidebar-overlay-open)) .sidebar-rail ~ #sidebar-wrapper .sidebar {
    border-inline-end: 0;
  }
}

/* ---------- 28 · A count inside a button follows the button ---------------
   `.btn-count` is the number on a button ("Nudge 1"). It is drawn from the
   button's own variables, so it reads on every state: on an outline button
   it is a chip of the button's colour with the hover label colour inside,
   and turns into the label colour with the fill colour inside once the button
   fills (hover, focus, pressed); on a solid button it is the label colour
   with the fill inside. A fixed `bg-white` chip vanished into a white
   outline button and only showed its frame on hover (Onboarding tester
   round 1). */
.btn > .btn-count {
  background-color: var(--bs-btn-color);
  color: var(--bs-btn-bg);
}
.btn:is(:hover, :focus-visible, :active, .active) > .btn-count {
  background-color: var(--bs-btn-hover-color);
  color: var(--bs-btn-hover-bg);
}
.btn:is([class*="btn-outline-"]) > .btn-count {
  color: var(--bs-btn-hover-color);
}
.btn:is([class*="btn-outline-"]):is(:hover, :focus-visible, :active, .active) > .btn-count {
  color: var(--bs-btn-hover-bg);
}

/* ==========================================================================
   Style family: Bold (src/docs/DESIGN_DECISIONS.md F1–F4)

   The tenant's family is data-style-family on <body> (ApplicationHelper#
   current_style_family). Bold is the expressive family: heavy page and card
   titles, roomier cards, 8px heavy buttons, large white Quick Action tiles,
   icons in tinted chips and a gentle hover lift on what can be clicked. Its
   corner radius, card style and density come from BusinessTheme::FAMILY_SHAPES
   through the tenant theme block, its chrome colours from the Style card
   (BusinessTheme#family_form_config). Every colour here is a theme token, so
   dark mode and the tenant's brand carry through. Classic emits none of this.
   ========================================================================== */

/* Page title, and the title fallback: a hand-written <h1> inside the page
   content gets the family's size too, unless it asked for a size of its own. */
body[data-style-family="bold"] h1.h3,
body.mgx-restyle[data-style-family="bold"] h1.h3,
body.mgx-restyle[data-style-family="bold"] .content h1:not(.h3):not(.h4):not(.h5):not(.h6):not([class*="display-"]):not(.visually-hidden) {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

/* As specific as custom.css's card-header title rule, which it must beat. */
body[data-style-family="bold"] .card-title,
body.mgx-restyle[data-style-family="bold"] .card-title,
body.mgx-restyle[data-style-family="bold"] .card > .card-header .card-title {
  font-size: 18px;
  font-weight: 700;
}

body[data-style-family="bold"] .card {
  --bs-card-spacer-y: 1.25rem;
  --bs-card-spacer-x: 1.4rem;
  --bs-card-cap-padding-y: 1rem;
  --bs-card-cap-padding-x: 1.4rem;
}

body[data-style-family="bold"] .btn {
  --bs-btn-border-radius: 8px;
  --bs-btn-font-weight: 700;
}

body[data-style-family="bold"] .sidebar-rail-icon.active {
  border-radius: 12px;
}

/* Card header icons in a brand-tinted chip (F4: brand chips wherever the
   icon's app is not known). */
body[data-style-family="bold"] .card-header > i:first-child,
body[data-style-family="bold"] .card-header .card-title > i:first-child {
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--bs-primary) 12%, transparent);
  font-size: 15px;
  margin-right: 0.6rem !important;
}

/* Quick Actions as large white tiles with a 40px chip. A tile whose app is
   known gets its domain wash inline (DomainToneHelper); the rest a brand chip. */
body[data-style-family="bold"] .quick-action-btn {
  background-color: var(--bs-card-bg) !important;
  border-color: var(--bs-border-color) !important;
  border-radius: 12px !important;
  min-height: 104px;
  padding: 16px 12px !important;
}

body[data-style-family="bold"] .quick-action-icon {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--bs-primary) 12%, transparent);
  margin-bottom: 10px !important;
}

body[data-style-family="bold"] .quick-action-label {
  font-size: 15px !important;
  font-weight: 600 !important;
}

/* Domain-toned tiles (only Bold renders them): the inline style paints the
   wash, so the tile's own brand wash steps aside. */
.quick-action-icon--toned {
  border-radius: 50%;
}

.launcher-tile-icon--toned {
  border-radius: 0.6rem;
}

.launcher-tile-icon--toned .launcher-tile-glyph {
  background-color: transparent;
}

/* F3: Bold lifts what can be clicked, and only when motion is welcome. */
@media (prefers-reduced-motion: no-preference) {
  body[data-style-family="bold"] :is(.quick-action-btn, .launcher-tile, a.card) {
    transition: transform 0.15s ease, box-shadow 0.15s ease;
  }

  body[data-style-family="bold"] :is(.quick-action-btn, .launcher-tile, a.card):hover {
    transform: translateY(-2px);
    box-shadow: var(--bs-box-shadow);
  }
}

/* ---------- 29 · A launcher's caption in a menu starts under its label -----
   shared/live_assist/_launch_button draws its menu item with the mode's icon
   (`fa-fw me-2`, like the menu's other items); its caption — who it invites,
   and the AI-recording line — starts where the label does, past the icon. */
.dropdown-item-text.live-assist-caption {
  /* the icon is `fa-fw` (1.25em of the ITEM's size, not this smaller caption's) + me-2 */
  padding-inline-start: calc(var(--bs-dropdown-item-padding-x, 1rem) + 1.25 * var(--bs-dropdown-font-size, 1rem) + 0.5rem);
}

/* ---------- 30 · A menu's section heading reads as a heading --------------
   `.dropdown-header` titles the items under it ("Add to newsletter" above the
   newsletters). The theme drew it at .75rem and regular weight, smaller and
   lighter than the items it names, so it read as a footnote (Communications
   tester round 10). It takes the items' size and the body ink, semibold,
   lined up with the items' text. `:where()` keeps it at one class, so a menu that styles
   its own headings on purpose (the navigation tabs' small capitals,
   components/navigation_dropdown_tabs.css) keeps them. */
:where(.dropdown-menu) .dropdown-header {
  font-size: var(--bs-dropdown-font-size, 0.875rem);
  font-weight: 600;
  color: var(--bs-body-color);
  padding: 0.5rem var(--bs-dropdown-item-padding-x, 1rem) 0.25rem;
}
/* On a phone mobile_optimizations.css sets every item to 1rem type with 1rem
   side padding (!important, for the finger); the heading follows them. */
@media (max-width: 575.98px) {
  :where(.dropdown-menu) .dropdown-header {
    font-size: 1rem;
    padding-inline: 1rem;
  }
}

/* ---------- 31 · An inline-edited title reads as a field -----------------
   A record's own title — and a line under it — edited where the page shows
   it: the newsletter composer's subject and preview text, the correction
   composer's title (REUSABLE_COMPONENTS §5 "Inline edit"):
     div.inline-edit
       › input.form-control.inline-edit__control#x (+ the title's type, fw-bold fs-4)
       › label.inline-edit__icon[for=x] › i.fas.fa-pen[aria-hidden=true]
   At rest it draws no box, so the title reads as the page's title; on hover
   it shows the control's edge, and on focus the ONE focus ring (§5, whose
   !important it leaves alone). The pencil is a label, so a click focuses the
   field with no script; the field keeps its aria-label as its name. It was
   `border-0 bg-transparent shadow-none` — no edge, no focus ring — and read
   as plain text (Communications tester round 10, row 2). Where the browser
   sizes a field to its words (field-sizing) the pencil sits right after
   them; elsewhere the field takes the line. The padding is taken back by a
   negative margin, so the words line up with the page's left edge. */
.inline-edit {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  min-width: 0;
  max-width: 100%;
}
body.mgx-restyle .inline-edit > .form-control.inline-edit__control,
.inline-edit > .form-control.inline-edit__control {
  flex: 0 1 auto;
  width: auto;
  min-width: 10ch;
  max-width: 100%;
  field-sizing: content;
  padding-inline: 0.5rem;
  margin-inline-start: calc(-0.5rem - var(--bs-border-width, 1px));
}
@supports not (field-sizing: content) {
  body.mgx-restyle .inline-edit > .form-control.inline-edit__control,
  .inline-edit > .form-control.inline-edit__control {
    flex: 1 1 auto;
  }
}
/* (0,5,1): beats the dark theme's control edge, (0,4,1) in block 0. A
   subject longer than the line ends in "…" at rest, not cut mid-letter;
   focused, the field scrolls to show all of it. */
body.mgx-restyle .inline-edit > .form-control.inline-edit__control:not(:focus),
.inline-edit > .form-control.inline-edit__control:not(:focus) {
  border-color: transparent;
  background-color: transparent;
  box-shadow: none;
  text-overflow: ellipsis;
}
body.mgx-restyle .inline-edit:hover > .form-control.inline-edit__control:not(:focus),
.inline-edit:hover > .form-control.inline-edit__control:not(:focus) {
  border-color: var(--bs-border-color);
}
.inline-edit__icon {
  flex: none;
  margin: 0;
  padding: 0.25rem;
  font-size: 0.8125rem;
  line-height: 1;
  color: var(--bs-secondary-color);
  cursor: pointer;
}
.inline-edit:is(:hover, :focus-within) > .inline-edit__icon {
  color: var(--bs-body-color);
}

/* Onboarding round 2 — analytics
   Executive Analytics' Performance cards (apps/onboarding_hub/executive_analytics):
   a completion bar with its target marked on it, so a reader sees how far the
   average is from the target the "Challenges and next steps" list judges it by;
   the change from the previous period beside each figure; and the list's rows
   divided like a list. */
.onboarding-analytics-meter {
  position: relative;
  max-width: 16rem;
}
.onboarding-analytics-meter__target {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 2px;
  margin-left: -1px;
  background: var(--bs-body-color, #212529);
  opacity: 0.55;
}
.onboarding-analytics-change {
  cursor: default;
}
.onboarding-analytics-findings > .onboarding-analytics-finding + .onboarding-analytics-finding {
  border-top: 1px solid var(--bs-border-color, #dee2e6);
}
.onboarding-analytics-findings > .onboarding-analytics-finding:first-child {
  padding-top: 0 !important;
}
.onboarding-analytics-findings > .onboarding-analytics-finding:last-child {
  padding-bottom: 0 !important;
}
