/* ===========================================================================
   BGL-3569 - contrast fixes that are NOT dark-mode-specific
   ===========================================================================

   bg-dark.css is scoped entirely to html.bg-dark-mode, so it can only ever fix
   the dark theme. Everything here is either light-mode-only or applies to both,
   which is why it is a separate file rather than more of that one.

   Two rules for reading this file:

   1. Anything light-specific is scoped `html:not(.bg-dark-mode)`. The dark
      theme has been measured screen by screen and every value in it is
      accounted for; nothing here is allowed to move it.
   2. Colours come from the brand guide (Battleground Brand Colours, April
      2024), not from picking a darker shade until a number passed:

        Victory    #00a886     Earth    #ac937d     Sky        #a7d3d3
        Grass      #e6ecd1     Clarity  #fbf6ea     Steel      #5e8a8a
        Rich Black #000104     AI Pink  #FF57BE

      The guide says plainly that **Rich Black is the primary font colour**,
      and that core colours may carry text "for headlines and callouts" - i.e.
      large text, where 1.4.3 asks 3:1 rather than 4.5:1.

      That single line resolves most of what follows. The light theme had white
      text sitting on brand fills - white on Victory is 3.02:1, on the teal
      badge 2.30:1, on the danger red 3.37:1 - and the fix is not to darken the
      brand colour but to use the ink the brand already specifies. Rich Black
      clears AA on every core colour:

        Victory 6.88   Earth 7.13   Steel 5.42   AI Pink 7.31
        Sky, Grass, Clarity all far higher

      The dark theme reached the same answer independently: --bg-on-brand is
      #000104, which is Rich Black. The two halves agree.

   The one place the guide does not answer is brand colour used as SMALL text on
   a light ground - Victory is 3.06:1 on white, fine for a headline and short of
   AA for a link. Rather than invent a shade, this reuses the darkened Victory
   the dark theme already carries as --bg-teal-nav (#007e65), which is 5.05:1 on
   white. Same hue, and a value already in the codebase rather than a fourth
   copy of the teal.
   =========================================================================== */

:root {
    --bg-rich-black: #000104;
    --bg-victory: #00a886;
    /* Victory darkened for small text on a light ground. Same value the dark
       theme uses for the nav fill, deliberately - see the note above. */
    --bg-victory-text: #007e65;
    /* The same tone doing the other job: the fill of an INTERACTIVE element -
       a filled button, a badge - chosen so white ink clears AA on it (5.05:1).
       Named separately from --bg-victory-text because they are two different
       decisions that happen to land on one value today; if the text tone ever
       moves, the button tone should not follow it by accident. */
    --bg-victory-action: #007e65;
    /* The hover step for that fill, and it has to be a DIFFERENT value.
       An earlier version pinned both the resting fill and the hover fill to
       --bg-victory-action, so every dark green button in the app stopped
       responding to the pointer - correct contrast, no feedback, which is its
       own kind of broken. Darker rather than lighter because white has to stay
       on it: 6.68:1 here, where a lighter step would have dropped to 3.60:1. */
    --bg-victory-action-hover: #006854;
    /* Metronic's danger red darkened in its own hue until white clears AA:
       #F4516C is 3.37:1 against white, this is 5.57:1. */
    --bg-danger-action: #c0304a;
    /* A neutral that clears AA on the light chrome. Metronic's own greys here
       (#a9a9aa, #a4a2bb, #a7a9c1) are 2.2-2.5:1 and were never adjusted.
       Pitched just past the 4.5:1 line rather than well past it - these are
       secondary text and secondary icons, and the first value here was 5.05:1,
       which made them louder than the content.

       "Just past" measured against the surface they actually sit on. The value
       before this one was #757577, chosen off a calculation against WHITE and
       landing at 4.41:1 on the footer's #FAFAFA - under the line, by a margin
       small enough that only the measurement caught it. This is 4.75:1 there
       and 4.94:1 on white. */
    --bg-muted-ink: #707072;
    /* Steel as small TEXT. The palette Steel (#5e8a8a) is 3.67:1 on #fafafa and
       3.83:1 under white; this is the same hue three steps darker, 4.86:1 on
       #fafafa and 5.1:1 on white. Fills that carry white ink use #527a7a. */
    --bg-steel-text: #4f7575;
}

/* ---------------------------------------------------------------------------
   1. Focus visible - BOTH themes (WCAG 2.1 AA, 2.4.7)

   Metronic ships `html a, html button { outline: none !important }`, so until
   now nothing in the app drew a focus ring except the dark-mode toggle, which
   restored one for itself. Keyboard users had no visible focus anywhere.

   The shape follows the toggle's, which is the house pattern and already
   reviewed: paint the ring on :focus, then remove it again on
   :focus:not(:focus-visible). A browser without :focus-visible support keeps
   the first rule and shows a ring on mouse clicks - visually noisy, but it
   fails SAFE rather than failing invisible, which is the right way round.

   Ring colours are checked against 1.4.11's 3:1 for the surfaces they land on:
   #007e65 is 5.05:1 on white and 4.86:1 on #FAFAFA; #14be9c is 6.8:1 on the
   dark card. Full Victory was measured first and is 2.90:1 on #FAFAFA - it
   would have been a focus indicator that itself failed the criterion it exists
   to satisfy.
--------------------------------------------------------------------------- */
html a:focus,
html button:focus,
html summary:focus,
html [tabindex]:focus,
html [role="button"]:focus,
html [role="tab"]:focus,
html [role="link"]:focus,
html [role="menuitem"]:focus,
html [role="checkbox"]:focus,
html [role="option"]:focus {
    outline: 2px solid var(--bg-victory-text) !important;
    outline-offset: 2px !important;
}

html a:focus:not(:focus-visible),
html button:focus:not(:focus-visible),
html summary:focus:not(:focus-visible),
html [tabindex]:focus:not(:focus-visible),
html [role="button"]:focus:not(:focus-visible),
html [role="tab"]:focus:not(:focus-visible),
html [role="link"]:focus:not(:focus-visible),
html [role="menuitem"]:focus:not(:focus-visible),
html [role="checkbox"]:focus:not(:focus-visible),
html [role="option"]:focus:not(:focus-visible) {
    outline: none !important;
}

html.bg-dark-mode a:focus,
html.bg-dark-mode button:focus,
html.bg-dark-mode input:focus,
html.bg-dark-mode select:focus,
html.bg-dark-mode textarea:focus,
html.bg-dark-mode summary:focus,
html.bg-dark-mode [tabindex]:focus,
html.bg-dark-mode [role="button"]:focus,
html.bg-dark-mode [role="tab"]:focus,
html.bg-dark-mode [role="link"]:focus,
html.bg-dark-mode [role="menuitem"]:focus,
html.bg-dark-mode [role="checkbox"]:focus,
html.bg-dark-mode [role="option"]:focus {
    outline-color: #14be9c !important;
}

/* ENTRY FIELDS GET NO RING. Chosen deliberately by Craig on 2026-08-31 after
   seeing it: "the borders around all entry fields is not good... we don't need
   them."

   The ring stays on links, buttons and anything with a tabindex or a widget
   role, so keyboard focus is still visible on everything you can activate. What
   it costs is 2.4.7 on the fields themselves - a keyboard user tabbing into a
   text input now has only the caret and Metronic's own focus border to tell
   them where they are, which is weaker than a ring but not nothing.

   Written as an explicit override rather than by deleting the selectors from the
   list above, so the decision is visible instead of looking like an omission.
   Reversing it is deleting this block. */
html input:focus,
html select:focus,
html textarea:focus,
html input:focus-visible,
html select:focus-visible,
html textarea:focus-visible,
html .select2-container--focus .select2-selection,
html .select2-container--open .select2-selection {
    outline: none !important;
}

/* select2 hides a real <input> inside the control - ten pixels wide on a
   multi-select, sitting among the chips - and ringing THAT drew a small box
   inside the field around nothing, which is what "a box around the text area
   inside the placeholder" was.

   An earlier version of this file solved that by moving the ring onto
   `.select2-selection`. That is now moot: entry fields get no ring at all, per
   the block above. This rule stays because select2's own stylesheet can still
   put an outline on the inner input, and there is no reason to let it. */
html .select2-container .select2-search__field:focus,
html .select2-search--inline .select2-search__field:focus,
html .select2-search--dropdown .select2-search__field:focus {
    outline: none !important;
}

/* ...and the control does not recolour its EDGE on focus either.

   Reported in dark mode as "the thick green border at input is still there".
   It was not the ring - that had gone - it was bg-dark.css painting
   `.select2-container--focus .select2-selection--multiple` with --bg-teal
   (#00A886) against a #7E8188 resting edge, which on a dark card reads as a
   heavy green box appearing round the field. Metronic does the same thing in
   light with its stock indigo #716ACA.

   An earlier version of this rule answered the indigo by swapping it for brand
   teal - which was the same idea, just on-palette, and is exactly what the
   instruction not to put borders on entry fields rules out. So both themes now
   hold the field's own resting edge through focus and open: no colour change,
   nothing appearing, and no indigo either.

   Plain inputs already behaved this way - `.form-control:focus` measured
   #7E8188 in dark, the same as at rest - so this brings select2 into line with
   the rest of the form rather than inventing a new behaviour for it. */
html:not(.bg-dark-mode) .select2-container--default.select2-container--open .select2-selection--single,
html:not(.bg-dark-mode) .select2-container--default.select2-container--open .select2-selection--multiple,
html:not(.bg-dark-mode) .select2-container--default.select2-container--focus .select2-selection--single,
html:not(.bg-dark-mode) .select2-container--default.select2-container--focus .select2-selection--multiple {
    border-color: #ebedf2 !important;
}

html.bg-dark-mode .select2-container--default.select2-container--open .select2-selection--single,
html.bg-dark-mode .select2-container--default.select2-container--open .select2-selection--multiple,
html.bg-dark-mode .select2-container--default.select2-container--focus .select2-selection--single,
html.bg-dark-mode .select2-container--default.select2-container--focus .select2-selection--multiple,
html.bg-dark-mode .form-control:focus {
    border-color: var(--bg-field-edge) !important;
}

/* ---------------------------------------------------------------------------
   2. Light mode - move the TONE, not the ink

   The first version of this section flipped white ink to Rich Black wherever
   white failed on a brand fill, and cited the brand guide's "Rich Black should
   be used as primary font colour" for it. That was the wrong reading, and the
   result was a light theme that had quietly become a high-contrast theme:
   black labels on teal buttons, black on the tan pills, black on the red chip.
   Reported as "light mode isn't as nice as it was", which it wasn't.

   Two corrections.

   The guide's line is about body copy. Its own artwork puts WHITE on Victory -
   the tagline lockup is white on a Victory bar - so the brand plainly does
   reverse text out of its own fills.

   And the arithmetic is kinder than it looked. White on Victory is 3.02:1,
   which PASSES 1.4.3 for large text and fails only below 24px (or 18.66px
   bold). So the defect was never "white on Victory"; it was "white on Victory
   at 13px button-label size". Fixing that at the ink end was fixing the wrong
   end.

   What every mature system does instead: the brand hex stays the brand hex for
   headlines and fills, and the INTERACTIVE role gets a derived, darker tone
   picked so white clears AA on it. Material, Carbon, Lightning and GOV.UK all
   work this way. So white ink comes back, and the fill moves to
   --bg-victory-action (#007e65) - which is not a new colour: it is the tone
   this app already uses for the active nav item, carrying white at 5.03:1.

   The exception, and it is a real one: a fill that is genuinely LIGHT cannot
   carry white at any tone. Earth (#AC937D) is 2.91:1 against white and would
   have to stop being Earth to fix that. Those keep Rich Black - see section 3.
--------------------------------------------------------------------------- */

/* The notification count on the topbar bell: white on #34BFA3 was 2.30:1.
   Also brings the badge onto Victory rather than Metronic's own off-brand
   teal, which it should arguably have been all along. */
html:not(.bg-dark-mode) .m-badge--new,
html:not(.bg-dark-mode) .m-topbar .m-topbar__nav .m-nav__item .m-nav__link .badge,
html:not(.bg-dark-mode) #bell_badge {
    background-color: var(--bg-victory-action) !important;
    color: #ffffff !important;
}

/* Metronic's danger badge - every status pill that uses it: white on #F4516C
   was 3.37:1. Darkened in its own hue so it still reads as the same red, and
   white returns at 5.57:1.

   The "LOCAL" environment chip used to be covered here too. It no longer wears
   `.m-badge--danger` (BGL-3569): borrowing pill classes is what let a pill rule
   in bg-dark.css wash its fill out in dark mode, so it carries `.bg-env-badge`
   and its own colours now. The value below is the one it took from here.

   11px BOLD, which is worth stating because bold only counts as large text at
   18.66px and up - so this needs the full 4.5:1, not 3:1. */
html:not(.bg-dark-mode) .m-badge.m-badge--danger,
html:not(.bg-dark-mode) .m-badge--wide.m-badge--danger {
    background-color: var(--bg-danger-action) !important;
}

html:not(.bg-dark-mode) .m-badge.m-badge--danger,
html:not(.bg-dark-mode) .m-badge.m-badge--danger a,
html:not(.bg-dark-mode) .m-badge.m-badge--danger span,
html:not(.bg-dark-mode) .m-badge--wide.m-badge--danger {
    color: #ffffff !important;
}

/* The sidebar item under the pointer fills with Victory and kept white text at
   3.02:1. The ACTIVE item is a different case and is left alone: it fills with
   Victory darkened 25%, where white is 5.03:1 and already passes - which is
   also what keeps hover and active telling apart.

   The selector has to out-specify bog.css, which sets the white. Its rule is

     .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__item
       :not(--parent):not(--open):not(--expanded):not(--active):hover
       > .m-menu__link .m-menu__link-text        { color: #fff !important }

   and each `:not()` argument counts, so it scores eleven classes. A short,
   readable `.m-aside-menu .m-menu__item:hover .m-menu__link-text` scores seven,
   carries !important, looks correct in the source and does nothing at all -
   which is exactly how the first version of this rule behaved. So the chain is
   mirrored, and `html:not(.bg-dark-mode)` supplies the margin.

   The second selector covers the ACTIVE item, which bog.css deliberately
   excludes and which therefore keeps white on Victory when hovered. */
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__item:not(.m-menu__item--parent):not(.m-menu__item--open):not(.m-menu__item--expanded):not(.m-menu__item--active):hover > .m-menu__link .m-menu__link-text,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__item:not(.m-menu__item--parent):not(.m-menu__item--open):not(.m-menu__item--expanded):not(.m-menu__item--active):hover > .m-menu__link .m-menu__link-icon,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__item:not(.m-menu__item--parent):not(.m-menu__item--open):not(.m-menu__item--expanded):not(.m-menu__item--active):hover > .m-menu__link .m-menu__ver-arrow,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__item.m-menu__item--active:hover > .m-menu__link .m-menu__link-text,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__item.m-menu__item--active:hover > .m-menu__link .m-menu__link-icon,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__item.m-menu__item--active:hover > .m-menu__link .m-menu__ver-arrow,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav .m-menu__submenu .m-menu__item:not(.m-menu__item--active):hover > .m-menu__link .m-menu__link-text {
    color: #ffffff !important;
}

/* ...and the states that chain deliberately excludes. An OPEN parent and the
   `--parent` item inside its submenu are outside bog.css's `:not()` list, so
   nothing there sets their hover ink and the low-specificity
   `.m-menu__link:hover > .m-menu__link-text` (two classes) supplies the white
   instead. Keyed on the hovered LINK rather than on the item's state, so it
   holds whatever combination of --open / --parent / --expanded the item is in.
   Eight classes is enough to beat that rule and not enough to disturb the
   chain above, which is what should win for an ordinary item. */
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav .m-menu__item > .m-menu__link:hover .m-menu__link-text,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav .m-menu__item > .m-menu__link:hover .m-menu__link-icon,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav .m-menu__item > .m-menu__link:hover .m-menu__ver-arrow,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav .m-menu__item > .m-menu__link:hover .m-menu__link-bullet > span {
    color: #ffffff !important;
}

/* The bullet dot is drawn as a filled SPAN, so it needs `background-color`
   rather than `color` - and that declaration belongs ONLY to the bullet.
   Putting it on the block above, which also lists .m-menu__link-text and
   .m-menu__link-icon, painted every hovered LABEL with a white background:
   white text on a white box, 1:1, on the row under the pointer. Adding a
   declaration to a shared selector list gives it to every selector in the
   list, which is obvious written down and was not obvious while typing it. */
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav .m-menu__item > .m-menu__link:hover .m-menu__link-bullet > span {
    background-color: #ffffff !important;
}

/* The fill those white inks sit on.

   style.blade.php fills a hovered item with Victory at full strength, where
   white is 3.02:1. Pinned to the same --bg-victory-action the ACTIVE item
   already uses, so white returns at 5.03:1 and the sidebar has one teal rather
   than two.

   That does make a hovered item the same colour as the active one. It is not a
   loss worth solving with a third tone: the active item is still teal when your
   pointer is elsewhere, and the one under the cursor is the one that moves with
   it. If the two ever need separating, the answer is a left edge or a weight
   change rather than another shade of Victory to keep in step. */
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__item:not(.m-menu__item--parent):not(.m-menu__item--open):not(.m-menu__item--expanded):not(.m-menu__item--active):hover,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__item:not(.m-menu__item--parent):not(.m-menu__item--open):not(.m-menu__item--expanded):not(.m-menu__item--active):hover > .m-menu__link,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav .m-menu__submenu .m-menu__item:not(.m-menu__item--parent):not(.m-menu__item--open):not(.m-menu__item--expanded):not(.m-menu__item--active):hover,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav .m-menu__submenu .m-menu__item:not(.m-menu__item--parent):not(.m-menu__item--open):not(.m-menu__item--expanded):not(.m-menu__item--active):hover > .m-menu__link,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav .m-menu__item > .m-menu__link:hover {
    background-color: var(--bg-victory-action-hover) !important;
}

/* The bullet dot on the ACTIVE submenu item, which is drawn in full Victory on
   that item's darker Victory fill: 1.66:1, so it reads as a missing bullet on
   the one row that has a fill. Not a 1.4.11 failure - every row has a bullet,
   so it carries no state of its own and losing it costs no information - but it
   looks like a rendering fault, and white matches the label beside it. */
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav .m-menu__submenu .m-menu__item.m-menu__item--active > .m-menu__link .m-menu__link-bullet > span,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__item.m-menu__item--active > .m-menu__link .m-menu__link-bullet > span {
    background-color: #ffffff !important;
}

/* The secondary button's hover is handled with the rest of the buttons below,
   by deepening the fill rather than darkening the ink - its Steel fill is too
   dark for Rich Black. */

/* Action buttons on a brand fill - the "BIA List" / "Audit" pair at the top of
   a record, and every button that shares their classes.

   The first version of this rule set the ICON and forgot the LABEL, so the
   buttons rendered with a near-black glyph beside white text and looked
   broken - reported, correctly, as looking odd. A button is one object; its
   glyph and its label have to agree, and the way to write that is to set
   `color` on the button and let the icon inherit rather than to name the icon
   separately.

   White is not an option here, on any of them. It fails on every core colour
   in the brand palette, not just these two:

     Victory #00a886  3.02:1     Steel  #5e8a8a  3.83:1
     Earth   #ac937d  2.91:1     Sky, Grass, Clarity  far lower

   ...at FULL STRENGTH. That is the sentence the first version of this rule was
   missing, and it concluded from the table that no white-text version of these
   buttons could pass, so the ink had to go dark. Both of those buttons then
   rendered as black-on-brand and light mode read as a high-contrast theme.

   The table is right and the conclusion was wrong: the fill does not have to
   stay at full strength. Darkening the tone of an interactive element until
   white clears AA is what design systems do, and it leaves the brand hex
   untouched everywhere it is actually a brand mark. So these split by the only
   question that matters - can this fill carry white at ANY tone of itself?

     .btn-success / .btn-primary / .btn-accent  Victory family, mid-tone.
         Yes. The fill moves to --bg-victory-action (5.05:1 with white), which
         is the tone the active nav item already uses. This is the pair the
         "New BIA" button was reported on.

     .btn-default (m-btn--air)                  Earth, #AC937D, genuinely light.
         No. White is 2.91:1 on Earth and every tone of Earth light enough to
         still be Earth is worse. Keeps Rich Black at 7.18:1. Next to a filled
         primary this reads as an ordinary primary/secondary pair rather than
         as two high-contrast buttons.

   .btn-danger, .btn-warning and .btn-info are deliberately left out: their
   fills are not brand colours, bg-dark.css records that near-black on them is
   wrong once a theme has neutralised them, and they have not been measured
   here. */
html:not(.bg-dark-mode) .btn.btn-success,
html:not(.bg-dark-mode) .btn.btn-primary,
html:not(.bg-dark-mode) .btn.btn-accent {
    background-color: var(--bg-victory-action) !important;
    border-color: var(--bg-victory-action) !important;
}

html:not(.bg-dark-mode) .btn.btn-success,
html:not(.bg-dark-mode) .btn.btn-success i,
html:not(.bg-dark-mode) .btn.btn-success span,
html:not(.bg-dark-mode) .btn.btn-primary,
html:not(.bg-dark-mode) .btn.btn-primary i,
html:not(.bg-dark-mode) .btn.btn-primary span,
html:not(.bg-dark-mode) .btn.btn-accent,
html:not(.bg-dark-mode) .btn.btn-accent i,
html:not(.bg-dark-mode) .btn.btn-accent span {
    color: #ffffff !important;
}

html:not(.bg-dark-mode) .btn.btn-default,
html:not(.bg-dark-mode) .btn.btn-default i,
html:not(.bg-dark-mode) .btn.btn-default span {
    color: var(--bg-rich-black) !important;
}

/* ---------------------------------------------------------------------------
   2b. Every OTHER button fill

   The rules above were written from the buttons that happened to be on the
   pages being swept - primary, success, accent, default, secondary - and the
   comment even recorded danger, warning and info as "not measured here". They
   still were not, and Craig reported the obvious consequence: most of the app's
   buttons were still on the old pairings.

   So they were enumerated properly instead. Every button class in the templates
   was collected, rendered together, and measured in one pass rather than found
   a page at a time. Against white, at 13px:

     btn-info / btn-save / btn-autoplay-auto / btn-outline-focus
                            Victory  #00A886  3.02:1
     btn-warning            amber    #ED880B  2.58:1
     btn-danger             red      #ED2052  4.26:1
     btn-metal              grey     #C4C5D6  1.71:1
     btn-ai                 AI Pink  #FF57BE  2.85:1
     btn-autoplay-manual    Earth    #AC937D  2.91:1
     btn-from-participant   Steel    #5E8A8A  3.83:1

   Same test as before: can the fill carry white at some tone of itself? Victory
   and the danger red can, so they take a darker tone and keep white. Amber,
   Earth, Steel, metal and AI Pink cannot - they are light-to-mid colours where
   no usable tone saves white - so they take Rich Black, which clears AA on all
   of them (8.08, 7.18, 5.45, 12.23, 7.31).

   `.btn-default` above also lost its `.m-btn--air` qualifier. That class was in
   the selector because the "Audit" button happens to carry it; 65 templates use
   btn-default without it, and every one of them was still white on Earth.
--------------------------------------------------------------------------- */

/* Victory-filled buttons: darken the tone, keep white. Same treatment and same
   value as .btn-primary / .btn-success / .btn-accent above. */
html:not(.bg-dark-mode) .btn.btn-info,
html:not(.bg-dark-mode) .btn.btn-save,
html:not(.bg-dark-mode) .btn.btn-autoplay-auto,
html:not(.bg-dark-mode) .btn.btn-outline-focus {
    background-color: var(--bg-victory-action) !important;
    border-color: var(--bg-victory-action) !important;
}

html:not(.bg-dark-mode) .btn.btn-info,
html:not(.bg-dark-mode) .btn.btn-info i,
html:not(.bg-dark-mode) .btn.btn-info span,
html:not(.bg-dark-mode) .btn.btn-save,
html:not(.bg-dark-mode) .btn.btn-save i,
html:not(.bg-dark-mode) .btn.btn-save span,
html:not(.bg-dark-mode) .btn.btn-autoplay-auto,
html:not(.bg-dark-mode) .btn.btn-autoplay-auto i,
html:not(.bg-dark-mode) .btn.btn-autoplay-auto span,
html:not(.bg-dark-mode) .btn.btn-outline-focus,
html:not(.bg-dark-mode) .btn.btn-outline-focus i,
html:not(.bg-dark-mode) .btn.btn-outline-focus span {
    color: #ffffff !important;
}

/* Danger keeps being red with white on it, which is the convention worth
   keeping - so the red deepens to the same tone the danger badge uses. */
html:not(.bg-dark-mode) .btn.btn-danger {
    background-color: var(--bg-danger-action) !important;
    border-color: var(--bg-danger-action) !important;
}

html:not(.bg-dark-mode) .btn.btn-danger,
html:not(.bg-dark-mode) .btn.btn-danger i,
html:not(.bg-dark-mode) .btn.btn-danger span {
    color: #ffffff !important;
}

/* Fills that cannot carry white at any tone of themselves. */
html:not(.bg-dark-mode) .btn.btn-warning,
html:not(.bg-dark-mode) .btn.btn-warning i,
html:not(.bg-dark-mode) .btn.btn-warning span,
html:not(.bg-dark-mode) .btn.btn-metal,
html:not(.bg-dark-mode) .btn.btn-metal i,
html:not(.bg-dark-mode) .btn.btn-metal span,
html:not(.bg-dark-mode) .btn.btn-ai,
html:not(.bg-dark-mode) .btn.btn-ai i,
html:not(.bg-dark-mode) .btn.btn-ai span,
html:not(.bg-dark-mode) .btn.btn-autoplay-manual,
html:not(.bg-dark-mode) .btn.btn-autoplay-manual i,
html:not(.bg-dark-mode) .btn.btn-autoplay-manual span,
html:not(.bg-dark-mode) .btn.btn-from-participant,
html:not(.bg-dark-mode) .btn.btn-from-participant i,
html:not(.bg-dark-mode) .btn.btn-from-participant span {
    color: var(--bg-rich-black) !important;
}

/* ---------------------------------------------------------------------------
   2c. The wizard step markers

   The BIA wizard draws seven circles, and six of them carried a WHITE glyph on
   the #E2E5EC pending fill: 1.26:1. Not a regression - it is the same invisible
   icon this whole ticket is about, on a screen nobody had swept, and the ghost
   shapes are visible in any screenshot of the wizard once you look for them.

   The current step keeps white and moves its fill to the action tone, both to
   clear 1.4.11 with room (3.02:1 to 5.05:1) and so the wizard agrees with the
   buttons two inches above it.
   The pending glyph is a step darker than --bg-muted-ink, because the pending
   circle DEEPENS to #BDC3D4 on hover and the lighter grey falls to 2.81:1
   there. Measured against the hovered fill rather than the resting one, which
   is the state that fails: 5.19:1 at rest, 3.67:1 hovered, and still reading as
   a pending step rather than a filled one.
--------------------------------------------------------------------------- */
html:not(.bg-dark-mode) .m-wizard__step .m-wizard__step-number > span > i,
html:not(.bg-dark-mode) .m-wizard__step .m-wizard__step-number i {
    color: #5f6163 !important;
}

/* The step labels under the circles - "Initial information", "Key Processes" -
   are #898B96 on white, 3.39:1. */
html:not(.bg-dark-mode) .m-wizard__step .m-wizard__step-title,
html:not(.bg-dark-mode) .m-wizard__step-title {
    color: var(--bg-muted-ink) !important;
}

html:not(.bg-dark-mode) .m-wizard__step.m-wizard__step--current .m-wizard__step-number > span,
html:not(.bg-dark-mode) .m-wizard__step.m-wizard__step--done .m-wizard__step-number > span {
    background-color: var(--bg-victory-action) !important;
}

html:not(.bg-dark-mode) .m-wizard__step.m-wizard__step--current .m-wizard__step-number > span > i,
html:not(.bg-dark-mode) .m-wizard__step.m-wizard__step--current .m-wizard__step-number i,
html:not(.bg-dark-mode) .m-wizard__step.m-wizard__step--done .m-wizard__step-number > span > i,
html:not(.bg-dark-mode) .m-wizard__step.m-wizard__step--done .m-wizard__step-number i {
    color: #ffffff !important;
}

/* ---------------------------------------------------------------------------
   2d. The Rich-Black buttons, on HOVER

   Every button in the app swings to a Victory fill on hover - style.blade.php
   sets `.btn:hover { background-color: victory }` for all of them - so the
   buttons that carry Rich Black at rest cannot keep it through hover: the
   surface under the ink stops being Earth or amber.

   `.btn-default` was already handled that way. The rest were not, and the Clone
   button is what it looked like: Rich Black on amber at rest, then on hover a
   WHITE label at 3.02:1 next to a BLACK icon, because the rest rule's
   `.btn-warning i { … !important }` outranks the general `.btn i { inherit }`.
   Failing and disagreeing with itself at the same time.

   So the fill is pinned to the action tone and the ink - button, icon and label
   together - goes white. Same pair of values as every other filled button on
   hover, which is the point: one hover appearance for all of them rather than
   one per class.
--------------------------------------------------------------------------- */
html:not(.bg-dark-mode) .btn.btn-warning:hover,
html:not(.bg-dark-mode) .btn.btn-warning:focus,
html:not(.bg-dark-mode) .btn.btn-metal:hover,
html:not(.bg-dark-mode) .btn.btn-metal:focus,
html:not(.bg-dark-mode) .btn.btn-ai:hover,
html:not(.bg-dark-mode) .btn.btn-ai:focus,
html:not(.bg-dark-mode) .btn.btn-autoplay-manual:hover,
html:not(.bg-dark-mode) .btn.btn-autoplay-manual:focus,
html:not(.bg-dark-mode) .btn.btn-from-participant:hover,
html:not(.bg-dark-mode) .btn.btn-from-participant:focus {
    background-color: var(--bg-victory-action-hover) !important;
    border-color: var(--bg-victory-action-hover) !important;
}

html:not(.bg-dark-mode) .btn.btn-warning:hover,
html:not(.bg-dark-mode) .btn.btn-warning:hover i,
html:not(.bg-dark-mode) .btn.btn-warning:hover span,
html:not(.bg-dark-mode) .btn.btn-warning:focus,
html:not(.bg-dark-mode) .btn.btn-warning:focus i,
html:not(.bg-dark-mode) .btn.btn-warning:focus span,
html:not(.bg-dark-mode) .btn.btn-metal:hover,
html:not(.bg-dark-mode) .btn.btn-metal:hover i,
html:not(.bg-dark-mode) .btn.btn-metal:hover span,
html:not(.bg-dark-mode) .btn.btn-metal:focus,
html:not(.bg-dark-mode) .btn.btn-metal:focus i,
html:not(.bg-dark-mode) .btn.btn-metal:focus span,
html:not(.bg-dark-mode) .btn.btn-ai:hover,
html:not(.bg-dark-mode) .btn.btn-ai:hover i,
html:not(.bg-dark-mode) .btn.btn-ai:hover span,
html:not(.bg-dark-mode) .btn.btn-ai:focus,
html:not(.bg-dark-mode) .btn.btn-ai:focus i,
html:not(.bg-dark-mode) .btn.btn-ai:focus span,
html:not(.bg-dark-mode) .btn.btn-autoplay-manual:hover,
html:not(.bg-dark-mode) .btn.btn-autoplay-manual:hover i,
html:not(.bg-dark-mode) .btn.btn-autoplay-manual:hover span,
html:not(.bg-dark-mode) .btn.btn-autoplay-manual:focus,
html:not(.bg-dark-mode) .btn.btn-autoplay-manual:focus i,
html:not(.bg-dark-mode) .btn.btn-autoplay-manual:focus span,
html:not(.bg-dark-mode) .btn.btn-from-participant:hover,
html:not(.bg-dark-mode) .btn.btn-from-participant:hover i,
html:not(.bg-dark-mode) .btn.btn-from-participant:hover span,
html:not(.bg-dark-mode) .btn.btn-from-participant:focus,
html:not(.bg-dark-mode) .btn.btn-from-participant:focus i,
html:not(.bg-dark-mode) .btn.btn-from-participant:focus span {
    color: #ffffff !important;
}

/* An icon takes the ink of the button it is in, always.

   This is the half-and-half defect stated once as a rule instead of patched
   per button. Metronic recolours `.btn … i` on its own in a dozen places, and
   every one of them is a chance for a glyph to disagree with the label beside
   it - which is what shipped on the Audit button, and again on New BIA in dark
   mode. `inherit` cannot drift; a repeated colour value can. */
html .btn i,
html .btn .la,
html .btn [class^="flaticon-"],
html .btn [class*=" flaticon-"] {
    color: inherit !important;
}

/* .btn-secondary is NOT in that list, and the reason is worth keeping.

   It was, briefly. style.css pins it to a Steel background, but a DARK one -
   #507676, not the #5e8a8a from the palette - and on that fill white is
   already 5.00:1 while Rich Black is only 4.17:1. Adding it here made the
   Column Chooser / Excel / Delete / Archive row WORSE than it started, which
   is precisely the trap bg-dark.css warns about a few hundred lines up: this
   treatment is only right while the fill is still a light brand colour.

   Its hover is the one real failure: the fill goes to #00876C and white lands
   at 4.49:1, which is short of AA by a rounding error and still short. Fixed by
   deepening the hover along the same Steel hue rather than flipping the ink,
   so the button does not change ink colour halfway through an interaction. */
html:not(.bg-dark-mode) .btn.btn-secondary:hover,
html:not(.bg-dark-mode) .btn.btn-secondary:focus,
html:not(.bg-dark-mode) .btn.btn-secondary:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-secondary:focus:not(:disabled):not(.active) {
    background-color: #3f5c5c !important;
    color: #ffffff !important;
}

html:not(.bg-dark-mode) .btn.btn-secondary:hover i,
html:not(.bg-dark-mode) .btn.btn-secondary:hover span,
html:not(.bg-dark-mode) .btn.btn-secondary:focus i,
html:not(.bg-dark-mode) .btn.btn-secondary:focus span,
html:not(.bg-dark-mode) .btn.btn-secondary:hover:not(:disabled):not(.active) i,
html:not(.bg-dark-mode) .btn.btn-secondary:hover:not(:disabled):not(.active) span {
    color: #ffffff !important;
}

/* Hover and focus, where every one of these buttons ends up on a Victory tone
   and so takes white ink - see the fill rule below this one. The job of this
   rule is to make the ink agree across the whole control, and to beat
   Metronic's own :hover rules, which would otherwise recolour the icon alone
   and put the button back into the half-and-half state.

   The `:not(:disabled):not(.active)` chain is Metronic's, mirrored rather than
   copied for neatness. Its rule is

     .btn.m-btn--air.btn-default:hover:not(:disabled):not(.active) i
       { color: #fff !important }

   and both `:not()` arguments count, so it scores six classes to the five that
   `html:not(.bg-dark-mode) …:hover i` scores. Without the chain this rule reads
   as correct, carries !important, and loses - the icon went white again on
   hover while the label stayed dark, which is the same half-and-half state one
   interaction later. Second time this file has been caught by a Metronic
   `:not()` chain; the menu rules further up were the first. */
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:hover,
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:hover i,
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:hover span,
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:hover:not(:disabled):not(.active) i,
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:hover:not(:disabled):not(.active) span,
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:focus,
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:focus i,
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:focus span,
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:focus:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:focus:not(:disabled):not(.active) i,
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:focus:not(:disabled):not(.active) span,
html:not(.bg-dark-mode) .btn.btn-success:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-success:hover:not(:disabled):not(.active) i,
html:not(.bg-dark-mode) .btn.btn-success:hover:not(:disabled):not(.active) span,
html:not(.bg-dark-mode) .btn.btn-primary:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-primary:hover:not(:disabled):not(.active) i,
html:not(.bg-dark-mode) .btn.btn-primary:hover:not(:disabled):not(.active) span,
html:not(.bg-dark-mode) .btn.btn-accent:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-accent:hover:not(:disabled):not(.active) i,
html:not(.bg-dark-mode) .btn.btn-accent:hover:not(:disabled):not(.active) span,
html:not(.bg-dark-mode) .btn.btn-success:hover,
html:not(.bg-dark-mode) .btn.btn-success:hover i,
html:not(.bg-dark-mode) .btn.btn-success:hover span,
html:not(.bg-dark-mode) .btn.btn-success:focus,
html:not(.bg-dark-mode) .btn.btn-success:focus i,
html:not(.bg-dark-mode) .btn.btn-success:focus span,
html:not(.bg-dark-mode) .btn.btn-primary:hover,
html:not(.bg-dark-mode) .btn.btn-primary:hover i,
html:not(.bg-dark-mode) .btn.btn-primary:hover span,
html:not(.bg-dark-mode) .btn.btn-primary:focus,
html:not(.bg-dark-mode) .btn.btn-primary:focus i,
html:not(.bg-dark-mode) .btn.btn-primary:focus span,
html:not(.bg-dark-mode) .btn.btn-accent:hover,
html:not(.bg-dark-mode) .btn.btn-accent:hover i,
html:not(.bg-dark-mode) .btn.btn-accent:hover span,
html:not(.bg-dark-mode) .btn.btn-accent:focus,
html:not(.bg-dark-mode) .btn.btn-accent:focus i,
html:not(.bg-dark-mode) .btn.btn-accent:focus span {
    color: #ffffff !important;
}

/* ...and the fill they are white ON.

   Every one of these buttons - Earth included - already swings to a Victory
   tone on hover, because style.blade.php sets
   `.btn:hover { background-color: adjustBrightness(victory, -0.2) }` for all of
   them. That hue change on hover is existing behaviour and not something this
   file introduces; what it does mean is that the Earth button cannot keep Rich
   Black through hover, because the surface under it stops being Earth.

   So the hover fill is pinned to the same --bg-victory-action as the filled
   buttons at rest, and the ink is white throughout. Victory darkened 20% would
   have carried white at 4.55:1 - passing, but by half a point, and dependent on
   a tenant's configured Victory. Pinning the tone puts it at 5.05:1 and makes
   it the same colour the primary buttons already are. */
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:hover,
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:focus,
html:not(.bg-dark-mode) .btn.m-btn--air.btn-default:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-success:hover,
html:not(.bg-dark-mode) .btn.btn-success:focus,
html:not(.bg-dark-mode) .btn.btn-success:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-primary:hover,
html:not(.bg-dark-mode) .btn.btn-primary:focus,
html:not(.bg-dark-mode) .btn.btn-primary:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-accent:hover,
html:not(.bg-dark-mode) .btn.btn-accent:focus,
html:not(.bg-dark-mode) .btn.btn-accent:hover:not(:disabled):not(.active) {
    background-color: var(--bg-victory-action-hover) !important;
    border-color: var(--bg-victory-action-hover) !important;
}

/* The tag pills in a register - business unit, geography, department. They fill
   with Earth and carried white text at 2.91:1, ten to a screen. Same treatment
   and same reason as the buttons above; --bg-on-brand in dark mode already
   inks them this way.

   These only surfaced once a table had rows in it. An audit of an empty grid is
   an audit of nothing, which is a lesson this ticket has now taught twice. */
html:not(.bg-dark-mode) .m-badge--metal,
html:not(.bg-dark-mode) .m-badge--metal a,
html:not(.bg-dark-mode) span.m-badge.m-badge--metal,
html:not(.bg-dark-mode) td .m-badge.m-badge--wide {
    color: var(--bg-rich-black) !important;
}

/* Hovering a register row fills it with Victory and left the cell text white at
   3.02:1 - a whole row of data, and only while the pointer is on it. The dark
   theme hit the identical defect on expired rows. The fill is tenant-driven
   (`table_row_hover_bg`), so the ink moves, not the fill. */
html:not(.bg-dark-mode) .dataTables_wrapper table tbody tr:hover,
html:not(.bg-dark-mode) .dataTables_wrapper table tbody tr:hover td,
html:not(.bg-dark-mode) .dataTables_wrapper table tbody tr:hover td a,
html:not(.bg-dark-mode) .dataTables_wrapper table tbody tr:hover td span,
html:not(.bg-dark-mode) .m-datatable__row:hover .m-datatable__cell,
html:not(.bg-dark-mode) .m-datatable__row:hover .m-datatable__cell span {
    color: var(--bg-rich-black) !important;
}

/* The sorted column heading is Steel on the #F0F0F0 header strip: 3.36:1.
   Steel is a brand colour but this is small body text, so it takes the same
   darkened treatment as Victory does elsewhere in this file. */
html:not(.bg-dark-mode) .m-datatable__cell.sorting_asc,
html:not(.bg-dark-mode) .m-datatable__cell.sorting_desc,
html:not(.bg-dark-mode) th.m-datatable__cell.sorting_asc span,
html:not(.bg-dark-mode) th.m-datatable__cell.sorting_desc span,
html:not(.bg-dark-mode) th.m-datatable__cell.sorting_asc,
html:not(.bg-dark-mode) th.m-datatable__cell.sorting_desc {
    color: #3f5c5c !important;
}

/* ---------------------------------------------------------------------------
   3. RAiDAR - AI Pink, in BOTH themes

   `#fdf2f8` on `#FF57BE` is 2.61:1. The dark theme already inks this surface
   with Rich Black at 7.31:1; light mode was still on the near-white and had
   simply never been measured. Unscoped, so the two agree by construction.
--------------------------------------------------------------------------- */
.global-raidar-chat-button,
.global-raidar-chat-button .m-nav__link-text,
.global-raidar-chat-button i,
.global-raidar-chat-button svg {
    color: var(--bg-rich-black) !important;
}

/* The button carries its edge at REST, not only on hover.

   bog.css gives it `border: 0` and then paints an AI Pink border on :hover, so
   the control had no boundary at all until the pointer found it and then grew
   one - which reads as the button appearing rather than responding. The edge is
   now always there in the brand pink, and hover deepens it, so the hover state
   still says something.

   Light theme only. In dark the button is a solid AI Pink pill and already
   carries an edge at rest (rgba(0,0,0,.25) from bg-dark.css); a pink border on
   a pink fill would be invisible, so that half is left as it is. */
html:not(.bg-dark-mode) .m-nav .m-nav__item > .m-nav__link.global-raidar-chat-button,
html:not(.bg-dark-mode) .global-raidar-chat-button {
    border: 1px solid #ff57be !important;
}

html:not(.bg-dark-mode) .m-nav .m-nav__item > .m-nav__link.global-raidar-chat-button:hover,
html:not(.bg-dark-mode) .m-nav .m-nav__item > .m-nav__link.global-raidar-chat-button:focus,
html:not(.bg-dark-mode) .global-raidar-chat-button:hover,
html:not(.bg-dark-mode) .global-raidar-chat-button:focus {
    border-color: #d9369c !important;
}

/* ---------------------------------------------------------------------------
   The RAiDAR chat tabs

   Reported as "chat 1 has no edges... they are tabs". bog.css gives
   `.global-raidar-chat-tab` a border of `1px solid transparent` and fills only
   the active one, so an inactive tab is bare text on the tab bar with nothing to
   say it is a tab at all - you cannot tell it is clickable, and you cannot see
   where one ends and the next begins.

   An edge on every tab, brand pink on the active one. Also a 1.4.11 point in its
   own right: a tab is a control, and a control needs a boundary you can see.
--------------------------------------------------------------------------- */
html:not(.bg-dark-mode) .global-raidar-chat-tab {
    border: 1px solid #e3d4dd !important;
}

html:not(.bg-dark-mode) .global-raidar-chat-tab:hover {
    border-color: #d9369c !important;
}

html:not(.bg-dark-mode) .global-raidar-chat-tab.is-active {
    border-color: #d9369c !important;
}

/* The active tab fills with a pale pink (#FFD0EC), and its label was inheriting
   the panel's pink - pink on pink. Rich Black on that fill is 15.9:1. */
html:not(.bg-dark-mode) .global-raidar-chat-tab.is-active,
html:not(.bg-dark-mode) .global-raidar-chat-tab.is-active span,
html:not(.bg-dark-mode) .global-raidar-chat-tab.is-active .global-raidar-chat-tab-title {
    color: var(--bg-rich-black) !important;
}

/* ---------------------------------------------------------------------------
   The RAiDAR outline buttons - "RAiDAR Debrief", "Build exercise with RAiDAR",
   "RAiDAR tools" (.wp-ai-build-btn)

   Two things were wrong, and the second is the one that gets noticed: on hover
   they turned GREEN and kept their pink outline. Nothing had styled their hover
   at all, so they fell through to style.blade.php's `.btn:hover { background:
   victory }`, which every button in the app inherits - and a RAiDAR control
   going Victory green with an AI Pink border reads as a mistake, because it is
   one. It also landed on 4.49:1, under the line by a hundredth.

   At rest they were AI Pink text on white: 2.85:1. AI Pink is a fill colour,
   not an ink for a white ground - #FF57BE only ever reaches 2.85:1 there, and
   the darkened #D9369C only 4.23:1, so the ink has to go deeper still.

   So they become a proper outline button in the brand's own colour: pink text
   and a pink edge at rest, and on hover they FILL with AI Pink and take Rich
   Black - which is exactly what the RAiDAR chat button does, so the two RAiDAR
   controls on the same screen now behave alike.

   Not scoped to light mode: the green hover is theme-independent, because the
   rule it falls through to is. */
.btn.wp-ai-build-btn,
.btn.wp-ai-build-btn i,
.btn.wp-ai-build-btn span {
    color: #c22b86 !important;
}

.btn.wp-ai-build-btn {
    border: 1px solid #ff57be !important;
}

.btn.wp-ai-build-btn:hover,
.btn.wp-ai-build-btn:focus,
.btn.wp-ai-build-btn:hover:not(:disabled):not(.active),
.btn.wp-ai-build-btn:focus:not(:disabled):not(.active) {
    background-color: #ff57be !important;
    border-color: #d9369c !important;
}

/* KNOWN AA EXCEPTION, chosen deliberately by Craig on 2026-08-31.

   Hover is white on AI Pink #FF57BE: 2.85:1, which fails 1.4.3 for these 13px
   labels (the large-text 3:1 allowance does not reach them). The alternatives
   were white on a deepened #C22B86 at 5.28:1, or Rich Black on the true AI Pink
   at 7.31:1 - both compliant, both offered, and the all-white-on-brand-pink
   look was preferred over either.

   Recorded here rather than left to be rediscovered: this is the one pairing in
   this file that knowingly does not meet AA, and it is a design decision, not a
   miss. If the buttons ever grow to 18.66px bold or 24px they pass as large
   text at 3:1 and the exception disappears on its own. */
.btn.wp-ai-build-btn:hover,
.btn.wp-ai-build-btn:hover i,
.btn.wp-ai-build-btn:hover span,
.btn.wp-ai-build-btn:focus,
.btn.wp-ai-build-btn:focus i,
.btn.wp-ai-build-btn:focus span,
.btn.wp-ai-build-btn:hover:not(:disabled):not(.active),
.btn.wp-ai-build-btn:hover:not(:disabled):not(.active) i,
.btn.wp-ai-build-btn:hover:not(:disabled):not(.active) span {
    color: #ffffff !important;
}

/* The icon is a PNG (/img/raidar-ai-small.png), so `color` cannot reach it -
   which is exactly why it stayed pale while the label went dark, and why the
   button read as black-wording-with-a-white-icon. A filter is the only way to
   move a raster image: brightness(0) crushes it to black, invert(1) lifts it to
   white, so it matches the label rather than disagreeing with it. */
.btn.wp-ai-build-btn:hover img,
.btn.wp-ai-build-btn:focus img,
.btn.wp-ai-build-btn:hover:not(:disabled):not(.active) img {
    filter: brightness(0) invert(1) !important;
}

/* In dark mode the resting ground is a card, not white, so the ink lifts rather
   than deepens - the same AI Pink text tone the dark theme already uses. */
html.bg-dark-mode .btn.wp-ai-build-btn,
html.bg-dark-mode .btn.wp-ai-build-btn i,
html.bg-dark-mode .btn.wp-ai-build-btn span {
    color: #ff9ecb !important;
}

.global-raidar-chat-refresh-icon svg,
.global-raidar-chat-refresh-icon svg *,
.global-raidar-chat-settings-icon svg,
.global-raidar-chat-settings-icon svg * {
    stroke: currentColor !important;
}

.global-raidar-chat-settings-icon svg [fill]:not([fill='none']),
.global-raidar-chat-refresh-icon svg [fill]:not([fill='none']) {
    fill: currentColor !important;
}

/* ---------------------------------------------------------------------------
   4. Light mode - Metronic's own greys, which were never retuned

   These are stock Metronic values sitting on Battleground's lighter chrome
   (#FAFAFA rather than Metronic's white), so they read a little worse here than
   they did in the theme they shipped with. All three are secondary text or
   secondary icons; --bg-muted-ink keeps them secondary and clears AA.
--------------------------------------------------------------------------- */
html:not(.bg-dark-mode) .m-footer .m-footer__copyright,
html:not(.bg-dark-mode) .m-footer .m-footer__copyright a:not(.m-link) {
    color: var(--bg-muted-ink) !important;
}

html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__section .m-menu__section-icon {
    color: var(--bg-muted-ink) !important;
}

html:not(.bg-dark-mode) .m-list-search .m-list-search__form .m-list-search__form-input-wrapper .m-list-search__form-icon,
html:not(.bg-dark-mode) .m-input-icon .m-input-icon__icon i,
html:not(.bg-dark-mode) .la-search {
    color: var(--bg-muted-ink) !important;
}

/* ---------------------------------------------------------------------------
   5. Light mode - Victory as small text

   `.m-link` is the footer's "Battleground" link and a general link class:
   2.90:1 on #FAFAFA. Headline use of Victory is untouched, which is the use the
   brand guide actually sanctions.
--------------------------------------------------------------------------- */
html:not(.bg-dark-mode) .m-link,
html:not(.bg-dark-mode) a.m-link {
    color: var(--bg-victory-text) !important;
}

/* The same colour doing the same job on the profile tab strip - "Update
   Profile", "Security", "Appearance", "Two Factor Authentication" - which go
   Victory on hover at 3.02:1. Found only once the profile page itself was
   swept, which happened because the appearance control moved there: a page
   nobody had audited had its own instance of the defect the rest of this file
   is about. */
html:not(.bg-dark-mode) .m-tabs__link:hover,
html:not(.bg-dark-mode) a.m-tabs__link:hover,
html:not(.bg-dark-mode) .m-tabs-line .m-tabs__link:hover,
html:not(.bg-dark-mode) .nav.nav-tabs .nav-link:hover {
    color: var(--bg-victory-text) !important;
}

/* Form help text - "All mobile numbers should start with...". Metronic's
   `m--font-info` resolves to Victory here, so it is the same 3.02:1 as every
   other use of the brand teal at body size. */
html:not(.bg-dark-mode) .m-form__help.m--font-info,
html:not(.bg-dark-mode) .m-form__help,
html:not(.bg-dark-mode) .m--font-info {
    color: var(--bg-victory-text) !important;
}

/* ---------------------------------------------------------------------------
   6. Light mode - two more the profile page turned up

   Both pre-existing, and both found only because the appearance control moved
   to this page and it got swept for the first time.
--------------------------------------------------------------------------- */

/* select2's placeholder, #9699A2 on the #F4F5F8 field: 2.61:1. A placeholder is
   text and 1.4.3 applies to it. */
html:not(.bg-dark-mode) .select2-selection__placeholder,
html:not(.bg-dark-mode) .select2-container--default .select2-selection__placeholder {
    color: var(--bg-muted-ink) !important;
}

/* Metronic's form section headings - "1. Personal Details" - are #7B7E8A on
   white, 4.04:1. Under the line, and not large enough to qualify for the 3:1
   that would have excused it. Kept deliberately soft rather than promoted to
   ink: it was a muted heading by design and --bg-muted-ink is 4.94:1, so the
   character survives and the contrast clears. */
html:not(.bg-dark-mode) .m-form__section,
html:not(.bg-dark-mode) h3.m-form__section {
    color: var(--bg-muted-ink) !important;
}

/* The SCIM notice - "Your profile details are under management by your
   organisation" - is white on Steel at 3.83:1. Steel is a core colour and the
   fill stays; Rich Black on it is 5.42:1, which is the figure from the brand
   table. bg-dark.css already inks this notice with --bg-on-brand in dark mode,
   so this is the light half of a decision already taken. */
html:not(.bg-dark-mode) .bg-scim-notice,
html:not(.bg-dark-mode) .bg-scim-notice a,
html:not(.bg-dark-mode) .bg-scim-notice span {
    color: var(--bg-rich-black) !important;
}

/* Metronic paints hovered nav text its stock indigo #716ACA - 4.36:1 on the
   light footer, 3.62:1 on the dark one. Off-palette in both, and short of AA in
   both. Dark mode answers this in bg-dark.css; this is the light half.
   The RAiDAR button is excluded - it carries a brand fill and its own ink. */
html:not(.bg-dark-mode) .m-footer .m-nav .m-nav__item:hover > .m-nav__link:not(.global-raidar-chat-button) .m-nav__link-text,
html:not(.bg-dark-mode) .m-topbar .m-nav .m-nav__item:hover > .m-nav__link:not(.global-raidar-chat-button) .m-nav__link-text {
    color: var(--bg-victory-text) !important;
}

/* Victory on the pale teal wash the topbar buttons use for hover and focus is
   2.63:1. The wash is a tint of the brand and worth keeping, so the ink moves
   instead: Rich Black on #E4F2F2 is 17.8:1. */
html:not(.bg-dark-mode) .m-topbar .m-nav .bg-feedback-btn:hover,
html:not(.bg-dark-mode) .m-topbar .m-nav .bg-feedback-btn:focus,
html:not(.bg-dark-mode) .bg-feedback-btn:hover,
html:not(.bg-dark-mode) .bg-feedback-btn:focus,
html:not(.bg-dark-mode) .bg-feedback-btn:hover i,
html:not(.bg-dark-mode) .bg-feedback-btn:focus i,
html:not(.bg-dark-mode) .bg-feedback-btn:hover .bg-feedback-btn__label,
html:not(.bg-dark-mode) .bg-feedback-btn:focus .bg-feedback-btn__label {
    color: var(--bg-rich-black) !important;
}

/* ...and the same two buttons at REST, which the block above does not cover.
   Victory on the topbar's #FBFBFB is 2.93:1 - short for the label at 4.5:1 and,
   by a hair, for the glyph at 3:1 too. Fixing only hover and focus was the
   first pass here; resting state is the one a user actually looks at. */
html:not(.bg-dark-mode) .bg-feedback-btn,
html:not(.bg-dark-mode) .bg-feedback-btn i,
html:not(.bg-dark-mode) .bg-feedback-btn .bg-feedback-btn__label,
html:not(.bg-dark-mode) .m-topbar .m-nav .bg-feedback-btn {
    color: var(--bg-victory-text) !important;
}

/* The pale mint chip behind a module icon: Victory on #DBF3EE is 2.60:1. An
   icon needs 3:1, and the darkened Victory gives 4.18:1 while still reading as
   teal-on-teal rather than as a black mark.

   Scoped to the CHIP, never to the glyph class. The first version of this rule
   listed `.flaticon-layers` on its own, which is an icon-font class and says
   nothing about what the icon is sitting on. It caught the BIA wizard's current
   step - same glyph, but on a full Victory circle - and painted it #007e65 on
   #00a886: 1.35:1, dark teal on teal, reported as "a funny colour icon". An
   icon-font class is a shape, not a context; contrast belongs to the context. */
html:not(.bg-dark-mode) .m-widget4__icon i,
html:not(.bg-dark-mode) .m-widget-icon i {
    color: var(--bg-victory-text) !important;
}

/* ---------------------------------------------------------------------------
   Solid alert icons - the coloured square at the left of an alert
--------------------------------------------------------------------------- */

/* The m-alert--icon-solid modifier fills that square with the alert's own
   accent colour and drops a white glyph on it. Four of the nine accents are
   too light to carry white at the 3:1 that 1.4.11 asks of a non-text graphic:

     metal    #C4C5D6   1.71:1
     accent   #00C5DC   2.10:1
     success  #34BFA3   2.30:1
     info     #36A3F7   2.71:1

   The remaining five pass (brand 4.55, primary 4.77, focus 5.59, danger 3.37,
   and warning already at 10.91 because Metronic itself gives the yellow square
   a dark glyph).

   So the fix follows the precedent Metronic set for its own lightest fill
   rather than inventing one: keep the accent, darken the glyph. Rich Black
   gives 12.08, 9.85, 9.06 and 7.74 respectively, and the four squares now
   match the warning square that was always drawn this way.

   Not theme-scoped. The accents come from style.bundle.css and are the same in
   both modes, so the failure and the fix are the same in both. The info square
   is the one on screen most often - it carries the "this table allows
   re-ordering of rows" notice on every checklist and datatable page.

   The selectors mirror Metronic's own rule EXACTLY, four classes deep, rather
   than the shorter `.m-alert--icon-solid.alert-info .m-alert__icon i` that
   would seem to say the same thing. It does not: the square is only filled when
   m-alert--outline is present as well. Without it the square is transparent and
   the glyph sits on the alert's own body, which in dark mode is #262A38 - and
   the shorter selector put Rich Black on that at 1.47:1. The incident edit
   screen carries both shapes at once, three filled and two transparent, so it
   showed the regression immediately. A rule that recolours a foreground has to
   match the same elements as the rule that set the background, or it is
   guessing at what is behind the text. */
.alert.m-alert--outline.alert-metal.m-alert--icon-solid .m-alert__icon i,
.alert.m-alert--outline.alert-accent.m-alert--icon-solid .m-alert__icon i,
.alert.m-alert--outline.alert-success.m-alert--icon-solid .m-alert__icon i,
.alert.m-alert--outline.alert-info.m-alert--icon-solid .m-alert__icon i {
    color: var(--bg-rich-black) !important;
}

/* ---------------------------------------------------------------------------
   The selected item in the left menu, light theme
--------------------------------------------------------------------------- */

/* The worst single number in the light theme, and it is on the one row a user
   is guaranteed to be looking at: the CURRENTLY SELECTED submenu item.
   White label on pale Steel, 1.63:1.

   Two rules that were never written with each other in mind:

       style.css  .m-menu__item--open                     { background: #A7D3D3 !important }
       bog.css    ...m-menu__item--active > .m-menu__link
                     .m-menu__link-text                   { color: #FFF !important }

   White on Steel works on the Steel the brand guide actually shows, which is
   the full-strength #5E8A8A. #A7D3D3 is a tint of it, light enough to be a
   background - and once it is a background, white stops being ink.

   Rich Black is the answer the brand guide gives directly ("Rich Black should
   be used as primary font colour") and it measures 12.81:1 here. The fill
   stays exactly as it is, so the selected row still reads as selected in the
   pale Steel the product has chosen for it.

   The chain is written out to the same depth as bog.css's, which is what it
   has to outrank; a shorter selector loses even with !important behind it,
   because bog.css already has !important of its own. Light theme only: dark
   mode paints this row in the teal from bg-dark.css and was measured clean.

   :not(:hover) because the row does not keep the pale Steel when the pointer is
   on it - it goes to the dark green #006854, where Rich Black is 3.09:1. The
   first version of this rule left the ink pinned through hover and so traded a
   1.63:1 resting state for a 3.09:1 hovered one. Excluding hover hands the row
   back to bog.css's white, which is 6.68:1 on that green, and each state ends
   up with the ink that suits the fill it actually has.

   Keyed on --open, NOT on --active, and that distinction is the whole rule.
   The pale Steel comes from the --open declaration quoted above, so --open is
   exactly the set of rows that have it. A selected row that is NOT also open -
   which is what the incident LIST page shows, where the same menu entry
   carries only m-menu__item--active - keeps the darkened Victory #007E65 from
   the inline colours block, and there white is 5.05:1 while Rich Black is
   4.15:1. The first version of this rule named both classes, fixed the pale
   Steel row and broke the Victory one: same menu entry, same label, two fills
   depending on whether its submenu happens to be expanded. Ink follows the
   fill, so the selector has to name the fill's own condition. */
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__item .m-menu__submenu .m-menu__item.m-menu__item--open > .m-menu__link:not(:hover) .m-menu__link-text,
html:not(.bg-dark-mode) .m-menu__item--open > .m-menu__link:not(:hover) .m-menu__link-text {
    color: var(--bg-rich-black) !important;
}

/* The bullet beside that label is left alone, deliberately.
 *
 * It is the brand Victory at 1.86:1 on the pale Steel, and a darkened Victory
 * would have read 3.10:1. A rule to do that was written and then removed,
 * because it never applied: the winning declaration is not in any stylesheet
 * but in the inline <style> block that inc/style.blade.php renders, where the
 * bullet colour comes from `enee.template-metronic.style.colours` -
 *
 *     ...m-menu__item--active > .m-menu__link .m-menu__link-bullet span
 *         { background: #00a886 !important }
 *
 * That block is emitted after every <link>, carries !important, and runs a
 * class deeper than the rule above it, so it wins on all three counts. Beating
 * it would mean an even longer chain aimed at a colour the tenant is meant to
 * be able to configure - fragility bought for a 4px dot.
 *
 * And the dot is decoration: 1.4.11 exempts it, the label beside it now reads
 * 12.82:1, and nothing is conveyed by the bullet that the label does not say.
 * A rule that provably does nothing is worse than no rule, so this is a note
 * rather than a selector. */

/* Every select2 control in the light theme, not just the one first noticed.
   Metronic's select2 ink #6F727D on the #F4F5F8 control is 4.39:1, which fails
   1.4.3 by a hundredth and a half.

   Rich Black rather than a nudged grey. A grey chosen to clear 4.5 by a
   whisker is a number nobody can maintain: the next change to either colour
   silently breaks it again, and there is no way to tell from reading it that
   it was ever deliberate. These are chosen VALUES - the tenant name, a filter
   set to "Active" - which is content rather than chrome, so the brand's primary
   font colour is right on its own terms, and it is 12.35:1.

   Scoped to the control by class, not by the one id that turned it up. The
   first version named #select2-team_switcher-container and the top bar, because
   the team switcher was the instance the profile page happened to show. The
   incident list then produced three more of exactly the same failure in its
   filter row, which is what a per-instance fix always does next.

   The placeholder is deliberately excluded. It fails the same measurement, and
   darkening it would be the wrong repair: a placeholder that reads as strongly
   as a value tells the user the field is filled when it is empty. If it needs
   fixing it needs a different answer, not this one. */
html:not(.bg-dark-mode) .select2-selection__rendered {
    color: var(--bg-rich-black) !important;
}

html:not(.bg-dark-mode) .select2-selection__rendered .select2-selection__placeholder {
    color: var(--bg-muted-ink) !important;
}

/* ---------------------------------------------------------------------------
   Page headings, light theme
--------------------------------------------------------------------------- */

/* bog.css opens with two unqualified element rules that reach every heading in
   the product:

       h1 { color: #AC937D; font-weight: 700 !important }    Earth
       h2 { color: #00A886; font-weight: 500 !important }    Victory

   Both fail 1.4.3 on a light page: Earth is 2.91:1 on white, Victory 2.90:1 on
   the #FAFAFA the app uses behind most content. Neither is rescued by the
   large-text allowance of 3:1 - they do not reach it either, and the h2 is
   19.5px at weight 500, which is not large text by any reading of the rule
   (that needs 24px, or 18.66px AND bold).

   Dark mode has covered these since the first pass, where h1 through h6 all
   take --bg-ink. Light mode never did, which is why "RAiDAR Insights" was still
   sitting at 2.90:1 - and it is a page title, not an ornament.

   Tone moved, hue kept, which is the approach this whole branch settled on
   after the first attempt made light mode into a high-contrast theme. Victory
   goes to the darkened Victory already used for small brand text elsewhere in
   this file (4.82:1 on #FAFAFA, 5.05:1 on white). Earth goes to #856D56, the
   same brown carried down until white clears 4.5 (4.86:1 on white, 4.66:1 on
   #FAFAFA) - still unmistakably Earth, and the guide's own words are that the
   core colours are for "headlines and callouts", not that they are for
   headlines at any tint.

   Excluded from anything sitting ON a brand fill. A darkened brand colour on
   the full-strength version of itself is the failure mode this branch has
   already produced once: a rule aimed at a glyph class painted the BIA wizard's
   current step #007E65 on #00A886, 1.35:1, and it was reported as a funny
   colour. CSS cannot ask what is behind an element, so the containers that
   carry a fill are named instead. */
html:not(.bg-dark-mode) h2:not(.text-white):not(.m-alert__title) {
    color: var(--bg-victory-text) !important;
}

html:not(.bg-dark-mode) h1:not(.text-white):not(.m-alert__title) {
    color: #856d56 !important;
}

/* The named exceptions: a heading inside a filled surface keeps whatever ink
   that surface gives it, because the fill is what it has to contrast against
   and the fill is not the page. */
html:not(.bg-dark-mode) .bg-primary h1,
html:not(.bg-dark-mode) .bg-primary h2,
html:not(.bg-dark-mode) .btn h1,
html:not(.bg-dark-mode) .btn h2,
html:not(.bg-dark-mode) .m-alert h1,
html:not(.bg-dark-mode) .m-alert h2,
html:not(.bg-dark-mode) [class*="--brand"] h1,
html:not(.bg-dark-mode) [class*="--brand"] h2,
html:not(.bg-dark-mode) .m-widget4__icon h1,
html:not(.bg-dark-mode) .m-widget4__icon h2 {
    color: inherit !important;
}


/* ---------------------------------------------------------------------------
   The "new data" tab highlight
--------------------------------------------------------------------------- */

/* When a new incident log entry or task arrives, JS adds .newdatatab to the
   tab so it turns amber and asks for attention. style.scss gives it:

       .newdatatab   { background: $warning !important; color: white !important;
                       padding-left: 8px; padding-right: 8px;
                       border-top-left-radius: 10px; ... }
       .newdatatab a { color: white !important }
       .newdatatab i { color: white !important }

   Two problems, and they were reported together.

   THE INK. The fill is #ED880B. Measured on the live tab, the label came out
   at 1.17:1 and 1.12:1 depending on which tab, and the glyph at 2.58:1 - so
   the attention state is the least readable thing on the screen. White, which
   is what the rules above intend, is only 1.74:1 there; it never worked. Worse,
   in dark mode the brand teal from this branch's own nav rules wins over
   `.newdatatab a`, which is how the label ended up teal-on-orange at 1.17:1 -
   my rules made a bad number worse.

   Rich Black is 8.07:1 on that amber, and it is what the rest of the app
   already does with amber: Metronic's own warning alert square carries a dark
   glyph, and .btn-outline-warning:hover goes to #111111. Amber is a fill
   colour in this palette, never an ink background for white.

   THE MOVEMENT. This is the horizontal shift reported after the vertical shake
   was fixed, and it is not a hover effect at all - which is why hovering every
   button and tab on the screen measured perfectly still. The padding above adds
   8px to each side, so the moment a log entry lands the tab grows 16px and
   every tab to its right jumps 16px sideways. On the incident screen new
   entries arrive live over Firestore, so they land while the pointer is moving
   across the tabs and it reads as the tabs moving under the cursor.

   The padding is dropped rather than offset. Offsetting it with -8px margins
   was tried first and measured WORSE: these tabs wrap onto two rows, and
   changing a tab's outer width by 16px moves the wrap point, so the neighbour
   went from jumping +16px to jumping -35px. A layout fix that only holds while
   nothing wraps is not a fix. Removing the padding leaves the box exactly as it
   was, which is the only version that measures 0.

   The amber fill and the rounded top corners carry the signal on their own; the
   8px was making the pill slightly wider than the tab, which is decoration and
   not worth a reflow.

   A notification must not reflow the thing it is notifying you about. */
/* BGL-3693: scoped to light mode, which is the only place it was ever right.

   Rich Black is correct ON the solid #ED880B fill, and dark mode no longer has
   that fill - BGL-3693 replaces it with an amber wash, because a lit orange
   block on the dark tab strip was reported as overwhelming. On that wash Rich
   Black is unreadable.

   This rule reaches it because it was written unscoped and leans on the tab
   ids, which puts it at 1,2,1 - above anything bg-dark.css can say without
   ids of its own. The file's own convention is that light-only rules carry
   `html:not(.bg-dark-mode)` precisely so they cannot reach the dark theme; this
   one was missing it. Nothing about light mode changes. */
html:not(.bg-dark-mode) .newdatatab,
html:not(.bg-dark-mode) .newdatatab > a,
html:not(.bg-dark-mode) .newdatatab > a.nav-link,
html:not(.bg-dark-mode) .newdatatab > a.m-tabs__link,
html:not(.bg-dark-mode) .newdatatab > a > i,
html:not(.bg-dark-mode) .newdatatab i,
html:not(.bg-dark-mode) #tab_incident_log.newdatatab > a.nav-link,
html:not(.bg-dark-mode) #tab_incident_log.newdatatab > a.m-tabs__link > i,
html:not(.bg-dark-mode) #tab_tasks.newdatatab > a.nav-link,
html:not(.bg-dark-mode) #tab_tasks.newdatatab > a.m-tabs__link > i,
html:not(.bg-dark-mode) #tab_incident_log:has(.newdatatab) > a.nav-link:hover,
html:not(.bg-dark-mode) #tab_incident_log:has(.newdatatab) > a.m-tabs__link:hover > i,
html:not(.bg-dark-mode) #tab_tasks:has(.newdatatab) > a.nav-link:hover,
html:not(.bg-dark-mode) #tab_tasks:has(.newdatatab) > a.m-tabs__link:hover > i,
html:not(.bg-dark-mode) #tab_incident_log.newdatatab > a.nav-link:hover,
html:not(.bg-dark-mode) #tab_incident_log.newdatatab > a.m-tabs__link:hover > i,
html:not(.bg-dark-mode) #tab_tasks.newdatatab > a.nav-link:hover {
    color: var(--bg-rich-black) !important;
}

/* The 8px either side, taken back off, so the tab occupies exactly the space it
   occupied before the class landed. */
.newdatatab {
    padding-left: 0 !important;
    padding-right: 0 !important;
}

/* ---------------------------------------------------------------------------
   Toasts
--------------------------------------------------------------------------- */

/* Measured by firing all four toastr types and reading the settled values. In
   DARK mode:

       error     #ED2052 / #000104   4.90:1   passes
       success   #00A886 / #000104   6.90:1   passes
       warning   #ED880B / #FFFFFF   2.58:1   FAILS
       info      #00A886 / #FFFFFF   3.02:1   FAILS

   Error and success already carried Rich Black there, so the convention
   existed and the other two had simply never been given it - info most
   obviously, since it sits on the very same #00A886 as success and read at less
   than half the contrast.

   Fixing those two and then re-running the same probe in LIGHT mode turned up
   the other half of the problem: the Rich Black on error and success comes from
   bg-dark.css, so in light mode those two were still white -

       error     #ED2052 / #FFFFFF   4.26:1   FAILS
       success   #00A886 / #FFFFFF   3.02:1   FAILS

   which is the same defect the other way round, and would have shipped if the
   check had stopped at the theme the report came from. Toastr's fills are its
   own and identical in both modes, so the ink should be too: all four types
   take Rich Black here, unscoped, and the two themes stop disagreeing. 8.08,
   6.90, 6.90 and 4.90 respectively.

   Applied to the title, the message and the close button together - the close
   button is a glyph on the same fill, 1.4.11 asks 3:1 of it, and at 2.58:1 it
   was failing that too. */
.toast-warning,
.toast-warning .toast-title,
.toast-warning .toast-message,
.toast-warning .toast-close-button,
.toast-info,
.toast-info .toast-title,
.toast-info .toast-message,
.toast-info .toast-close-button,
.toast-success,
.toast-success .toast-title,
.toast-success .toast-message,
.toast-success .toast-close-button,
.toast-error,
.toast-error .toast-title,
.toast-error .toast-message,
.toast-error .toast-close-button {
    color: var(--bg-rich-black) !important;
}


/* ---------------------------------------------------------------------------
   The light-theme button matrix
--------------------------------------------------------------------------- */

/* Found by asking the question that had not been asked: had EVERY button
   variant been checked, in both themes, in every state? It had not. Dark mode
   had been swept variant by variant with a real cursor; light mode had only
   ever been swept page by page, which covers the buttons that happen to be on
   the pages you visit and nothing else.

   Rendering all 35 btn-* variants in three forms each - plain, m-btn--air, and
   the m-btn--air.m-btn--pill combination the BIA wizard uses - and measuring
   rest, focus and active in light mode returned 69 failures. A screenshot
   confirmed them: several of these buttons render as blank white boxes with no
   visible label at all.

   Two separate causes.

   FIRST, style.css carries `.btn { color: white }` for every button in the app.
   On a variant with a coloured fill that is fine. On one with a white or
   transparent fill it is a white label on white - 1.00:1, literally invisible.
   That is btn-cancel, btn-link, btn-preview, btn-outline-dark,
   btn-outline-light and btn-outline-secondary, and they are not obscure: the
   templates use btn-link 20 times, btn-cancel 15, btn-outline-light 15 and
   btn-preview 9.

   SECOND, the outline variants ink themselves in their own accent, and several
   of those accents are far too light to be text on white:

       btn-outline-metal    #C4C5D6   1.71:1
       btn-outline-warning  #FFB822   1.73:1
       btn-outline-accent   #00C5DC   2.10:1
       btn-outline-success  #34BFA3   2.30:1
       btn-outline-danger   #F4516C   3.37:1   (34 uses - the most common)

   btn-outline-brand (4.55) and btn-outline-primary (4.77) clear the line and
   are deliberately left alone.

   The tones below are the same hue carried down until white clears 4.5:1, and
   the border takes the ink colour with it - an outline button's border IS its
   boundary, and 1.4.11 asks 3:1 of that, which #EBEDF2 at 1.17:1 and a white
   border at 1.00:1 were never going to give. Where the brand already has an
   answer this uses it rather than inventing a second one: success takes the
   darkened Victory, danger takes --bg-danger-action. */

/* Invisible labels: a fill this light cannot carry white ink. Rich Black is
   20.87:1 on white, and the brand guide names it the primary font colour. */
html:not(.bg-dark-mode) .btn.btn-cancel,
html:not(.bg-dark-mode) .btn.btn-cancel i,
html:not(.bg-dark-mode) .btn.btn-cancel span,
html:not(.bg-dark-mode) .btn.btn-preview,
html:not(.bg-dark-mode) .btn.btn-preview i,
html:not(.bg-dark-mode) .btn.btn-preview span,
html:not(.bg-dark-mode) .btn.btn-outline-light,
html:not(.bg-dark-mode) .btn.btn-outline-light i,
html:not(.bg-dark-mode) .btn.btn-outline-light span,
html:not(.bg-dark-mode) .btn.btn-outline-secondary,
html:not(.bg-dark-mode) .btn.btn-outline-secondary i,
html:not(.bg-dark-mode) .btn.btn-outline-secondary span {
    color: var(--bg-rich-black) !important;
}

/* btn-link is a link wearing a button's markup, so it takes the colour this
   file already gives brand-coloured links rather than body ink: 5.05:1. */
html:not(.bg-dark-mode) .btn.btn-link,
html:not(.bg-dark-mode) .btn.btn-link i,
html:not(.bg-dark-mode) .btn.btn-link span {
    color: var(--bg-victory-text) !important;
}

/* btn-outline-dark already owns a usable ink - its own border, #343A40 at
   11.51:1. It was only failing because the white from .btn was winning. */
html:not(.bg-dark-mode) .btn.btn-outline-dark,
html:not(.bg-dark-mode) .btn.btn-outline-dark i,
html:not(.bg-dark-mode) .btn.btn-outline-dark span {
    color: #343a40 !important;
}

/* The two whose BOUNDARY is invisible as well as their label: a white border
   on white is 1.00:1 and #EBEDF2 is 1.17:1, where 1.4.11 asks 3:1 of the edge
   of a control. #767a86 is 4.35:1 on white and still reads as chrome. */
html:not(.bg-dark-mode) .btn.btn-outline-light,
html:not(.bg-dark-mode) .btn.btn-outline-secondary {
    border-color: #767a86 !important;
}

/* Accents too light to be ink, carried down the same hue until white clears
   4.5:1. Border comes with them so the boundary clears 3:1 too. */
html:not(.bg-dark-mode) .btn.btn-outline-metal,
html:not(.bg-dark-mode) .btn.btn-outline-metal i,
html:not(.bg-dark-mode) .btn.btn-outline-metal span {
    color: #6c6e80 !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-metal {
    border-color: #6c6e80 !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-warning,
html:not(.bg-dark-mode) .btn.btn-outline-warning i,
html:not(.bg-dark-mode) .btn.btn-outline-warning span {
    color: #8a6100 !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-warning {
    border-color: #8a6100 !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-accent,
html:not(.bg-dark-mode) .btn.btn-outline-accent i,
html:not(.bg-dark-mode) .btn.btn-outline-accent span {
    color: #00707e !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-accent {
    border-color: #00707e !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-success,
html:not(.bg-dark-mode) .btn.btn-outline-success i,
html:not(.bg-dark-mode) .btn.btn-outline-success span {
    color: var(--bg-victory-text) !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-success {
    border-color: var(--bg-victory-text) !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-danger,
html:not(.bg-dark-mode) .btn.btn-outline-danger i,
html:not(.bg-dark-mode) .btn.btn-outline-danger span {
    color: var(--bg-danger-action) !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-danger {
    border-color: var(--bg-danger-action) !important;
}


/* The two outline variants that fail against the REAL page ground.
 *
 * Measured against #FFFFFF these read 4.55 and 4.77 and looked safe. The body
 * of this app is #F2F3F8, not white, and on that they are 4.10:1 and 4.31:1 -
 * both under the line. Measuring an ink against the colour you assume is
 * behind it rather than the colour actually behind it is how a passing number
 * hides a failing control; the ground has to come from the page. Carried down
 * the same hue to 4.88:1 and 4.82:1, borders with them for 1.4.11. */
html:not(.bg-dark-mode) .btn.btn-outline-brand,
html:not(.bg-dark-mode) .btn.btn-outline-brand i,
html:not(.bg-dark-mode) .btn.btn-outline-brand span {
    color: #655dbb !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-brand {
    border-color: #655dbb !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-primary,
html:not(.bg-dark-mode) .btn.btn-outline-primary i,
html:not(.bg-dark-mode) .btn.btn-outline-primary span {
    color: #5361c9 !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-primary {
    border-color: #5361c9 !important;
}

/* ---------------------------------------------------------------------------
   The .active state, light theme
--------------------------------------------------------------------------- */

/* .active was never checked before this pass - not in either theme - and it is
   not a rare state: Metronic puts it on toggle buttons, on the selected member
   of a button group, and on a dropdown toggle while its menu is open.
 *
 * On an outline variant .active FLOODS the button with the accent it was only
 * outlining, so the resting ink - which is that same accent, or a darkened
 * version of it - lands on top of itself. btn-outline-dark was the extreme
 * case at exactly 1.00:1, ink and fill the identical #343A40, and the fix
 * earlier in this file made it so: giving the resting label the border colour
 * was right for rest and wrong the moment the fill became that colour.
 *
 * So the ink has to be chosen per fill - and the fills are NOT what Bootstrap's
 * own .active rules say they are. Bootstrap wants to flood each outline variant
 * with its accent, and for most of them something in this app's stylesheets
 * overrides that back to transparent, so the button keeps the page ground.
 * Reading Bootstrap's intent instead of the computed value sends the ink the
 * wrong way; these are the measured fills:
 *
 *     btn-outline-accent   transparent (#F2F3F8)  black 18.84  -> black
 *     btn-outline-danger   transparent (#F2F3F8)  black 18.84  -> black
 *     btn-outline-metal    transparent (#F2F3F8)  black 18.84  -> black
 *     btn-outline-success  transparent (#F2F3F8)  black 18.84  -> black
 *     btn-outline-warning  transparent (#F2F3F8)  black 18.84  -> black
 *     btn-outline-info     #507676 Steel   white 5.01  black 4.17  -> white
 *     btn-secondary        #507676 Steel   white 5.01  black 4.17  -> white
 *
 * btn-outline-dark is deliberately absent from both lists. Its active fill is
 * transparent too, so it simply keeps the #343A40 this file gives it at rest,
 * which is 10.38:1 on the page ground. An earlier version of this block put
 * WHITE on it - reasoning from Bootstrap's #343A40 fill that never actually
 * applies - and measured 1.11:1, another invisible label. Two of these take
 * white and five take Rich Black, which is the argument against a single
 * blanket rule for a state like this. */
html:not(.bg-dark-mode) .btn.btn-outline-accent.active,
html:not(.bg-dark-mode) .btn.btn-outline-accent.active i,
html:not(.bg-dark-mode) .btn.btn-outline-accent.active span,
html:not(.bg-dark-mode) .btn.btn-outline-danger.active,
html:not(.bg-dark-mode) .btn.btn-outline-danger.active i,
html:not(.bg-dark-mode) .btn.btn-outline-danger.active span,
html:not(.bg-dark-mode) .btn.btn-outline-metal.active,
html:not(.bg-dark-mode) .btn.btn-outline-metal.active i,
html:not(.bg-dark-mode) .btn.btn-outline-metal.active span,
html:not(.bg-dark-mode) .btn.btn-outline-success.active,
html:not(.bg-dark-mode) .btn.btn-outline-success.active i,
html:not(.bg-dark-mode) .btn.btn-outline-success.active span,
html:not(.bg-dark-mode) .btn.btn-outline-warning.active,
html:not(.bg-dark-mode) .btn.btn-outline-warning.active i,
html:not(.bg-dark-mode) .btn.btn-outline-warning.active span {
    color: var(--bg-rich-black) !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-info.active,
html:not(.bg-dark-mode) .btn.btn-outline-info.active i,
html:not(.bg-dark-mode) .btn.btn-outline-info.active span,
html:not(.bg-dark-mode) .btn.btn-secondary.active,
html:not(.bg-dark-mode) .btn.btn-secondary.active i,
html:not(.bg-dark-mode) .btn.btn-secondary.active span {
    color: #ffffff !important;
}


/* ---------------------------------------------------------------------------
   One button box, whatever the variant
--------------------------------------------------------------------------- */

/* The last of the alignment defects, and the only one left after the templates
   were normalised: buttons in the same row still differed by 2px in height
   because some variants carry a 1px border and some carry none.
 *
 * Measured across the catalogue: 74 of the 105 have a 1px resting border and 31
 * do not. The 31 are the seven filled brand variants in their three forms -
 * btn-primary, btn-success, btn-accent, btn-save, btn-cancel,
 * btn-from-participant and btn-outline-focus. So "New BIA" (btn-success, no
 * border, 38.3px) sat beside "Audit" (btn-default, 1px border, 40.3px), and no
 * amount of padding matching could close a gap that came from the box model.
 *
 * The border is given to the seven rather than taken from the seventy-four,
 * because that is the smaller change and because the 1px edge is doing real
 * work: in dark mode it is what gives an unfilled control the 3:1 boundary
 * 1.4.11 asks for. Transparent, so nothing looks different - a filled button
 * shows its fill right to the edge exactly as before - and the box is now the
 * same 40.3px for every variant.
 *
 * DARK ONLY, and that was learned the hard way. The 74/31 split was measured in
 * the catalogue and assumed to hold in both themes. It does not: in light,
 * btn-default has no border either, so light toolbars were already even at 0px.
 * Applying this there raised the seven to 1px and produced the very mismatch it
 * was meant to remove - New BIA 40.3px beside Audit 38.3px, the same defect
 * inverted. Each theme is equalised to its own majority: 1px in dark, untouched
 * in light. */
html.bg-dark-mode .btn.btn-primary,
html.bg-dark-mode .btn.btn-success,
html.bg-dark-mode .btn.btn-accent,
html.bg-dark-mode .btn.btn-save,
html.bg-dark-mode .btn.btn-cancel,
html.bg-dark-mode .btn.btn-from-participant,
html.bg-dark-mode .btn.btn-outline-focus {
    border-width: 1px !important;
    border-style: solid !important;
    border-color: transparent !important;
}

/* ...and those same seven pinned through hover and focus, for the reason the
   other twenty-eight were pinned in bg-dark.css: style.css strips borders on
   hover with the `border` shorthand, which resets border-style to none and the
   width to 0. Before this block they had no resting border and so nothing to
   lose. Now that they have one, they would shrink 2px on hover and shove their
   neighbours along - the exact defect that fix was for, reintroduced by this
   one. Both halves have to land together.

   Border COLOUR is deliberately not set here, so each variant keeps whatever
   colour it already had - transparent for the filled ones. */
html.bg-dark-mode .btn.btn-primary:hover,
html.bg-dark-mode .btn.btn-primary:focus,
html.bg-dark-mode .btn.btn-success:hover,
html.bg-dark-mode .btn.btn-success:focus,
html.bg-dark-mode .btn.btn-accent:hover,
html.bg-dark-mode .btn.btn-accent:focus,
html.bg-dark-mode .btn.btn-save:hover,
html.bg-dark-mode .btn.btn-save:focus,
html.bg-dark-mode .btn.btn-cancel:hover,
html.bg-dark-mode .btn.btn-cancel:focus,
html.bg-dark-mode .btn.btn-from-participant:hover,
html.bg-dark-mode .btn.btn-from-participant:focus,
html.bg-dark-mode .btn.btn-outline-focus:hover,
html.bg-dark-mode .btn.btn-outline-focus:focus,
html.bg-dark-mode .btn.btn-primary:hover:not(:disabled):not(.active),
html.bg-dark-mode .btn.btn-success:hover:not(:disabled):not(.active),
html.bg-dark-mode .btn.btn-accent:hover:not(:disabled):not(.active),
html.bg-dark-mode .btn.btn-save:hover:not(:disabled):not(.active),
html.bg-dark-mode .btn.btn-cancel:hover:not(:disabled):not(.active),
html.bg-dark-mode .btn.btn-from-participant:hover:not(:disabled):not(.active),
html.bg-dark-mode .btn.btn-outline-focus:hover:not(:disabled):not(.active) {
    border-width: 1px !important;
    border-style: solid !important;
    border-color: transparent !important;
}


/* The same equalisation for the light theme, with light's own class list.
 *
 * The dark block above was scoped to dark after applying it to both themes
 * broke light. That was the right correction but only half the job: light has
 * the same problem with a different membership. Measured there, 50 of the 70
 * catalogue entries carry a 1px border and 20 do not, and the 20 are not the
 * same seven as in dark - btn-default and btn-warning have no border in light
 * but do in dark, and btn-danger and btn-success differ by FORM, carrying one
 * in the plain form and none in the m-btn--icon/air/pill form the toolbars use.
 *
 * That is what left "Request QR Code" (btn-accent, no border) 2px shorter than
 * "Disable 2FA" (btn-outline-danger, 1px) once their padding was matched: the
 * padding fix made the remaining difference visible rather than causing it.
 *
 * Light's majority is 1px, so the nine filled variants are brought up to it
 * with a transparent border - same reasoning as dark, opposite membership.
 *
 * btn-outline-focus and btn-outline-info ARE here, and the reason is worth
 * writing down because the first pass got it backwards on the strength of their
 * names. They were held back as outline variants whose visible edge a
 * transparent border would erase. Measuring them says otherwise: in this app
 * both are solid FILLED buttons - btn-outline-focus is #007E65 with white ink,
 * btn-outline-info is #507676 with white ink - and both carry 0px in all four
 * forms, plain, air, canonical and pill. There is no edge to erase because
 * there has never been one.
 *
 * Compare a real outline variant measured beside them: btn-outline-danger has a
 * transparent fill, a 1px #C0304A border and matching ink; btn-outline-success
 * the same in #007E65. That is what the name is supposed to mean, and these two
 * were overridden away from it somewhere in the app's own stylesheets long ago.
 *
 * So they take the same transparent border as the other filled variants, and
 * for the same reason. A class name is a label, not a measurement. */
html:not(.bg-dark-mode) .btn.btn-outline-focus,
html:not(.bg-dark-mode) .btn.btn-outline-info,
html:not(.bg-dark-mode) .btn.btn-outline-focus:hover,
html:not(.bg-dark-mode) .btn.btn-outline-focus:focus,
html:not(.bg-dark-mode) .btn.btn-outline-info:hover,
html:not(.bg-dark-mode) .btn.btn-outline-info:focus,
html:not(.bg-dark-mode) .btn.btn-outline-focus:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-outline-info:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-primary,
html:not(.bg-dark-mode) .btn.btn-success,
html:not(.bg-dark-mode) .btn.btn-accent,
html:not(.bg-dark-mode) .btn.btn-save,
html:not(.bg-dark-mode) .btn.btn-cancel,
html:not(.bg-dark-mode) .btn.btn-danger,
html:not(.bg-dark-mode) .btn.btn-default,
html:not(.bg-dark-mode) .btn.btn-warning,
html:not(.bg-dark-mode) .btn.btn-from-participant,
html:not(.bg-dark-mode) .btn.btn-primary:hover,
html:not(.bg-dark-mode) .btn.btn-primary:focus,
html:not(.bg-dark-mode) .btn.btn-success:hover,
html:not(.bg-dark-mode) .btn.btn-success:focus,
html:not(.bg-dark-mode) .btn.btn-accent:hover,
html:not(.bg-dark-mode) .btn.btn-accent:focus,
html:not(.bg-dark-mode) .btn.btn-save:hover,
html:not(.bg-dark-mode) .btn.btn-save:focus,
html:not(.bg-dark-mode) .btn.btn-cancel:hover,
html:not(.bg-dark-mode) .btn.btn-cancel:focus,
html:not(.bg-dark-mode) .btn.btn-danger:hover,
html:not(.bg-dark-mode) .btn.btn-danger:focus,
html:not(.bg-dark-mode) .btn.btn-default:hover,
html:not(.bg-dark-mode) .btn.btn-default:focus,
html:not(.bg-dark-mode) .btn.btn-warning:hover,
html:not(.bg-dark-mode) .btn.btn-warning:focus,
html:not(.bg-dark-mode) .btn.btn-from-participant:hover,
html:not(.bg-dark-mode) .btn.btn-from-participant:focus,
html:not(.bg-dark-mode) .btn.btn-primary:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-success:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-accent:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-save:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-cancel:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-danger:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-default:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-warning:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-from-participant:hover:not(:disabled):not(.active) {
    border-width: 1px !important;
    border-style: solid !important;
    border-color: transparent !important;
}


/* ---------------------------------------------------------------------------
   The glow that would not leave - BOTH themes

   Bootstrap gives every .btn variant a `box-shadow: 0 0 0 .2rem rgba(...)`
   halo on :focus - style.bundle.css ships 192 of them - and a clicked button
   HOLDS :focus until something else takes it. So every click left a coloured
   ring sitting on the page, reported as "the glow shadow sticks". The outline
   focus ring at the top of this file already does the right dance (paint on
   :focus, remove on :focus:not(:focus-visible)); these halos are the same
   idea implemented 192 times without the second half. This is the second
   half. Keyboard focus keeps both the halo and the outline ring; a mouse
   click keeps neither, which is what 2.4.7 actually asks for - focus VISIBLE
   when focus is how you got there. */
html .btn:focus:not(:focus-visible),
html .btn.focus:not(:focus-visible) {
    box-shadow: none !important;
}

/* ---------------------------------------------------------------------------
   Toggle switches - the light theme's share

   Dark mode's switch treatment lives in bg-dark.css; two of its defects were
   never dark-specific and are fixed here for both themes.

   1. Metronic's checked-state glow is tinted to ITS demo brand purple -
      rgba(113,106,202,.41), 20px of it - underneath a knob the tenant block
      paints Victory green. A purple halo around a green control looked wrong
      in light mode too; it was simply louder in dark. The knob keeps a small
      NEUTRAL shadow in light so it still reads as sitting on the track, and
      the track's own pale glow goes entirely.

   2. Keyboard focus: the switch <input> is opacity:0 and 999px off-canvas, so
      the focus ring this file gives every control lands on nothing anyone can
      see. The ring is painted on the visible span instead, same colours and
      geometry as the house ring, same :focus-visible dance. m-checkbox and
      m-radio hide their inputs the same way and get the same treatment. */
.m-switch input:checked ~ span:before {
    box-shadow: none !important;
}

/* The light switch's own colours, measured in the cascade harness once the
   glow was out of the way: an OFF knob of #DFE2EA sitting on a #EBEDF2 track
   is 1.10:1 - the knob is not there - and the track itself is 1.24:1 against
   a white card, so the control has no edge either. The ON knob, Victory on
   the same pale track, is 2.55:1.

   Same design as dark, in light's own tones: the OFF track keeps its pale
   fill but gains the field-edge border (3.91:1 on white) and a knob in the
   same edge grey (3.33:1 on the track); ON flips the track to the action teal
   the active menu item and every primary button already use, under a white
   knob at 5.03:1. A switch that is on and a menu item that is current are the
   same statement in both themes now. The knob keeps a small neutral shadow so
   it still reads as sitting on the track.

   html:not(.bg-dark-mode) lifts these to (0,3,3), one class over the tenant
   block's `.m-switch input:checked ~ span:after { background !important }`,
   which is what had been painting the knob Victory. */
html:not(.bg-dark-mode) .m-switch input:empty ~ span:before {
    border: 1px solid var(--bg-field-edge, #7e8188) !important;
}

html:not(.bg-dark-mode) .m-switch input:empty ~ span:after {
    background-color: #7e8188 !important;
    color: #ffffff !important;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25) !important;
}

html:not(.bg-dark-mode) .m-switch input:checked ~ span:before {
    background-color: var(--bg-victory-action) !important;
    border-color: var(--bg-victory-action) !important;
}

html:not(.bg-dark-mode) .m-switch input:checked ~ span:after {
    background-color: #ffffff !important;
    color: var(--bg-victory-action) !important;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25) !important;
}

html .m-switch input:focus ~ span,
html .m-checkbox > input:focus ~ span,
html .m-radio > input:focus ~ span {
    outline: 2px solid var(--bg-victory-text) !important;
    outline-offset: 2px !important;
}

html .m-switch input:focus:not(:focus-visible) ~ span,
html .m-checkbox > input:focus:not(:focus-visible) ~ span,
html .m-radio > input:focus:not(:focus-visible) ~ span {
    outline: none !important;
}

html.bg-dark-mode .m-switch input:focus ~ span,
html.bg-dark-mode .m-checkbox > input:focus ~ span,
html.bg-dark-mode .m-radio > input:focus ~ span {
    outline-color: #14be9c !important;
}

/* ---------------------------------------------------------------------------
   Light theme: what the cascade harness found

   Every production stylesheet, in production order, rendered into headless
   Chrome with :hover / :focus / :focus-visible rewritten to classes of the
   same weight, so the engine resolves the real cascade for each state. Three
   findings in light, all pre-existing, none of them visible from a rest-state
   sweep.

   1. btn-secondary in its m-btn--air form loses its 1px border on hover and
      focus - style.css sends it to Earth with `border: none !important`, and
      the shorthand resets border-style to none and the width to 0. That is
      the 2px "horizontal movement" defect this branch fixed for 28 classes in
      dark and 20 in light; btn-secondary/air was not in the light list
      because its resting border was measured, not its hovered one. The
      selectors mirror style.css's exactly and add the theme scope, so they
      out-rank it by one class.

   2. The tenant block's `.btn:hover { background: #00876C !important }`
      floods every button green on hover, including the outline family, whose
      resting inks were chosen for a transparent fill: #655DBB on the green is
      1.22:1, #5361C9 1.19:1, #C0304A 1.24:1, #007E65 1.12:1, and
      btn-outline-info's white 4.49:1 - under the line by a hundredth. These
      join section 2d: hover fill pinned to --bg-victory-action-hover, ink
      white at 6.74:1, so an outline button hovers to exactly what a filled
      one hovers to. Hover only - focus is handled next.

   3. On focus, Metronic floods btn-outline-brand / -primary / -danger /
      -success with their full accent (#716ACA, #5867DD, #F4516C, #34BFA3)
      while the resting ink stays: 1.20:1, 1.12:1, 1.66:1, 2.19:1. Same
      answer as the dark theme gave the first two: hold the fill transparent
      when focus is not also hover, and let the focus ring say what focus is.
      A clicked button therefore returns to its resting look, which is also
      what stops the fill sticking after a mouse click.
--------------------------------------------------------------------------- */
html:not(.bg-dark-mode) .btn.m-btn--air.btn-secondary.focus,
html:not(.bg-dark-mode) .btn.m-btn--air.btn-secondary:focus,
html:not(.bg-dark-mode) .btn.m-btn--air.btn-secondary:hover:not(:disabled):not(.active) {
    border-width: 1px !important;
    border-style: solid !important;
    border-color: transparent !important;
}

html:not(.bg-dark-mode) .btn.btn-link:hover,
html:not(.bg-dark-mode) .btn.btn-outline-brand:hover,
html:not(.bg-dark-mode) .btn.btn-outline-primary:hover,
html:not(.bg-dark-mode) .btn.btn-outline-danger:hover,
html:not(.bg-dark-mode) .btn.btn-outline-success:hover,
html:not(.bg-dark-mode) .btn.btn-outline-info:hover,
html:not(.bg-dark-mode) .btn.btn-link:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-outline-brand:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-outline-primary:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-outline-danger:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-outline-success:hover:not(:disabled):not(.active),
html:not(.bg-dark-mode) .btn.btn-outline-info:hover:not(:disabled):not(.active) {
    background-color: var(--bg-victory-action-hover) !important;
    border-color: var(--bg-victory-action-hover) !important;
}

html:not(.bg-dark-mode) .btn.btn-link:hover,
html:not(.bg-dark-mode) .btn.btn-link:hover i,
html:not(.bg-dark-mode) .btn.btn-link:hover span,
html:not(.bg-dark-mode) .btn.btn-outline-brand:hover,
html:not(.bg-dark-mode) .btn.btn-outline-brand:hover i,
html:not(.bg-dark-mode) .btn.btn-outline-brand:hover span,
html:not(.bg-dark-mode) .btn.btn-outline-primary:hover,
html:not(.bg-dark-mode) .btn.btn-outline-primary:hover i,
html:not(.bg-dark-mode) .btn.btn-outline-primary:hover span,
html:not(.bg-dark-mode) .btn.btn-outline-danger:hover,
html:not(.bg-dark-mode) .btn.btn-outline-danger:hover i,
html:not(.bg-dark-mode) .btn.btn-outline-danger:hover span,
html:not(.bg-dark-mode) .btn.btn-outline-success:hover,
html:not(.bg-dark-mode) .btn.btn-outline-success:hover i,
html:not(.bg-dark-mode) .btn.btn-outline-success:hover span,
html:not(.bg-dark-mode) .btn.btn-outline-info:hover,
html:not(.bg-dark-mode) .btn.btn-outline-info:hover i,
html:not(.bg-dark-mode) .btn.btn-outline-info:hover span {
    color: #ffffff !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-brand:focus:not(:hover),
html:not(.bg-dark-mode) .btn.btn-outline-primary:focus:not(:hover),
html:not(.bg-dark-mode) .btn.btn-outline-danger:focus:not(:hover),
html:not(.bg-dark-mode) .btn.btn-outline-success:focus:not(:hover) {
    background-color: transparent !important;
}

/* ---------------------------------------------------------------------------
   Skip to main content - BOTH themes (WCAG 2.4.1 Bypass Blocks)

   The layout puts this link first in <body>. It sits off-canvas until it
   has keyboard focus, then drops into the top-left corner over everything
   else, so a sighted keyboard user sees where they are and a screen-reader
   user hears it first. Off-canvas rather than display:none, because a hidden
   link is not focusable and the whole point is that it is.

   White on the action teal is 5.03:1; in dark the link takes the theme's
   text teal under Rich Black at 8.82:1, the same pair every primary button
   uses. The target's own focus outline is suppressed: it is a content
   column, not a control, and the ring would draw a box round the page.
--------------------------------------------------------------------------- */
.bg-skip-link {
    position: absolute;
    left: 12px;
    top: -200px;
    z-index: 100000;
    padding: 10px 16px;
    background: #007e65;
    color: #ffffff !important;
    font-weight: 500;
    border-radius: 3px;
    text-decoration: none;
    transition: none;
}

.bg-skip-link:focus,
.bg-skip-link:focus-visible {
    top: 12px;
    outline: 2px solid #ffffff !important;
    outline-offset: 2px !important;
}

html.bg-dark-mode .bg-skip-link {
    background: #14be9c;
    color: #000104 !important;
}

html.bg-dark-mode .bg-skip-link:focus,
html.bg-dark-mode .bg-skip-link:focus-visible {
    outline-color: #ffffff !important;
}

#main-content:focus {
    outline: none !important;
}


/* ==========================================================================
   Accessibility additions, second pass (BGL-3569 audit). Behavioural hooks
   for the layer at the end of app.js, plus the last contrast tones.
   ========================================================================== */

/* 1.4.13 - a tooltip that can be dismissed. balloon.css draws the bubble as
   pseudo-elements on the trigger, shown on hover and focus; app.js sets this
   class on Escape and clears it when the pointer or focus leaves. */
html.bg-tooltips-dismissed [aria-label][data-balloon-pos]::before,
html.bg-tooltips-dismissed [aria-label][data-balloon-pos]::after {
    opacity: 0 !important;
    pointer-events: none !important;
}

/* 2.3.3 - reduced motion. The class comes from the profile Motion setting or
   the OS preference, resolved before first paint in inc/head.blade.php, and is
   painted into the Angular iframe the same way dark mode is. Every feature
   stays; only the movement stops. Near-zero durations rather than `none`, so
   anything waiting on transitionend or animationend still hears it. */
html.bg-reduce-motion *,
html.bg-reduce-motion *::before,
html.bg-reduce-motion *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
}

/* 1.4.10 - reflow. Register tables carry ten or more columns and cannot fold
   to 320px; the WCAG allowance for data tables is two-dimensional scrolling
   within the table's own container, so the column that holds the table
   scrolls sideways while the page itself does not. Scoped to the table's
   column rather than the DataTables wrapper, because the wrapper also holds
   the button dropdowns, and an overflow rule on it would clip those. */
@media screen and (max-width: 767px) {
    .m-content {
        overflow-x: hidden;
    }

    .dataTables_wrapper > .row > [class*="col-"]:has(> table.dataTable),
    .dataTables_wrapper > .row > [class*="col-"]:has(> table.m-datatable__table),
    .dataTables_wrapper > .row > [class*="col-"]:has(> form > table.dataTable),
    .dataTables_wrapper > .row > [class*="col-"]:has(> form > table.m-datatable__table) {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    .m-portlet .m-portlet__head {
        flex-wrap: wrap;
        height: auto;
        min-height: 0;
        padding-top: 8px;
        padding-bottom: 8px;
    }

    .m-portlet .m-portlet__head .m-portlet__head-tools {
        flex-wrap: wrap;
        max-width: 100%;
    }

    .m-content img,
    .m-content svg,
    .m-content canvas,
    .m-content iframe,
    .m-content video {
        max-width: 100%;
    }

    .m-subheader .m-subheader__title,
    .m-subheader .m-subheader__breadcrumbs {
        max-width: 100%;
        white-space: normal;
    }
}

/* 1.4.3 / 1.4.11 - the last Steel fills that carry WHITE ink. Steel #5e8a8a
   under white is 3.83:1; #527a7a is the same hue two steps darker and 4.75:1.
   Where it still appeared: the secondary button, the info outline button at
   rest (style.css fills it with Steel and leaves the ink white), and the
   light-mode active menu row. Dark mode has its own menu treatment in
   bg-dark.css and is not touched.

   .btn-warning is deliberately NOT here. The rules above this block give it
   Rich Black ink on the light brand fill, and Rich Black on #5e8a8a is 5.4:1
   while on #527a7a it would be 4.40:1 - the harness caught exactly that when
   this rule first included it. Darken only what carries white. */
html:not(.bg-dark-mode) .btn.btn-secondary,
html:not(.bg-dark-mode) .btn.btn-outline-info,
html:not(.bg-dark-mode) .btn.btn-outline-info:focus,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__item.m-menu__item--active > .m-menu__link,
html:not(.bg-dark-mode) .m-aside-menu.m-aside-menu--skin-dark .m-menu__nav > .m-menu__item .m-menu__submenu .m-menu__item.m-menu__item--active > .m-menu__link {
    background-color: #527a7a !important;
}

html:not(.bg-dark-mode) .btn.btn-outline-info,
html:not(.bg-dark-mode) .btn.btn-outline-info:focus {
    border-color: #527a7a !important;
    color: #ffffff !important;
}

/* The #34bfa3 success tone under white ink is 2.30:1, and it is the fill on
   success badges, the "new" pill and the Dropzone tick. Rich Black on the
   same fill is 9.1:1, so the ink flips rather than the brand tone. The
   Dropzone tick is an icon, and its fill goes to the action teal instead so
   the white glyph reaches 3:1 (1.4.11). */
html:not(.bg-dark-mode) .m-badge.m-badge--success,
html:not(.bg-dark-mode) .m-badge--new,
html:not(.bg-dark-mode) .badge-success {
    color: #000104 !important;
}

html:not(.bg-dark-mode) .m-badge.m-badge--success a,
html:not(.bg-dark-mode) .m-badge.m-badge--success span,
html:not(.bg-dark-mode) .m-badge--new a,
html:not(.bg-dark-mode) .m-badge--new span {
    color: #000104 !important;
}

html:not(.bg-dark-mode) .dz-success-mark {
    background: #007e65 !important;
}

/* Visually hidden text for the labels app.js adds to select2 comboboxes.
   Bootstrap 4 ships .sr-only; this is the same rule, present in case a page
   loads without the reboot. */
.sr-only {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}


/* Third pass - what axe found on the served branch once the second pass was in.

   Breadcrumb trail: Metronic's #898b96 on the #fafafa subheader is 3.24:1 at
   13px. The muted-ink token was pitched for exactly this surface. */
html:not(.bg-dark-mode) .m-subheader .m-subheader__breadcrumbs .m-nav__item > .m-nav__link:not(:hover) .m-nav__link-text,
html:not(.bg-dark-mode) .m-subheader .m-subheader__breadcrumbs .m-nav__item > .m-nav__link:not(:hover) .m-nav__link-icon,
html:not(.bg-dark-mode) .m-subheader .m-subheader__breadcrumbs .m-nav__separator {
    color: var(--bg-muted-ink) !important;
}

/* Read-only fields still show a value the reader has to read - the profile of
   anyone whose details are managed by their organisation is nothing but
   these. Metronic's #6f727d on the #f4f5f8 fill is 4.39:1; this is 5.55:1.
   Disabled fields are exempt under 1.4.3 and are left alone. */
html:not(.bg-dark-mode) .form-control[readonly]:not(:disabled) {
    color: #616266 !important;
}

/* Tab strips: the inactive label is Steel #5e8a8a on #fafafa, 3.67:1; the
   same hue three steps darker is 4.86:1 there and 5.1:1 on white. The active
   label is untouched. */
html:not(.bg-dark-mode) .m-tabs-line .m-tabs__link:not(.active):not(.newdatatab),
html:not(.bg-dark-mode) .m-tabs-line > .nav-item > .nav-link:not(.active):not(.newdatatab) {
    color: var(--bg-steel-text);
}

/* The "new data" amber (#ED880B) still carried white on the dashboard domain
   tabs, where the class sits on the anchor itself rather than the <li> the
   rule further up expects. White on that amber is 2.58:1; Rich Black is 8.1:1.
   The amber stays - it is the signal. */
html:not(.bg-dark-mode) a.newdatatab,
html:not(.bg-dark-mode) a.newdatatab.nav-link,
html:not(.bg-dark-mode) a.newdatatab.m-tabs__link,
html:not(.bg-dark-mode) a.newdatatab i {
    color: var(--bg-rich-black) !important;
}

/* TouchBase "EXPIRED": was inline pure red, 3.99:1 on white. The danger
   action tone is 5.57:1; the dark-mode value is 5.8:1 on the #262c31 card. */
.bg-status-expired {
    color: var(--bg-danger-action);
    font-weight: 500;
}

html.bg-dark-mode .bg-status-expired {
    color: #ff7b8d;
}


/* The subheader title is now the page's <h1> (it was an <h3>, and no page had
   a level-one heading). The class sets the size but not the weight, so the
   browser's bold h1 default would have changed the look; pinned to the weight
   the h3 rendered at. !important because bog.css pins h1 to 700 the same way. */
.m-subheader .m-subheader__title {
    font-weight: 500 !important;
}
