/**
 * Accessibility Layer CSS
 *
 * Reads the feature classes that UMM_Accessibility_Handler puts on <body> (in
 * wp-admin and on the member portal alike) plus two custom properties printed
 * inline in <head>: --umm-a11y-scale and --umm-a11y-saturation.
 *
 * THREE SCOPING RULES, all learned the hard way:
 *
 * 1. Selectors hang off `body.umm-a11y-*`, never off `#wpcontent`. `#wpcontent`
 *    exists only in wp-admin, so the previous build could not reach the member
 *    portal at all — and it also missed everything portaled to <body>
 *    (UMMDialog, UMMToast, UMMSelect menus, tooltips), which meant a member in
 *    high-contrast mode got a black page with a white modal on top of it.
 *
 * 2. Anything using `filter` or `zoom` is applied to `html`, via
 *    `html:has(body.umm-a11y-*)`. A filter on any other element makes that
 *    element the containing block for `position: fixed` descendants and opens a
 *    new stacking context — which broke every `.umm-member-panel` slide panel
 *    and every fixed mobile nav in the plugin. The document root element is
 *    explicitly exempt from that rule, so the root is the only safe target.
 *
 * 3. Interface scaling is ONE factor applied once at the root, not a per-element
 *    font-size. See the FONT / INTERFACE SCALING block.
 *
 * @package UnionMemberManagement
 * @version 2.0.0
 */

/* ==========================================================================
   0. TOKENS
   ========================================================================== */

:root {
    --umm-a11y-scale: 1;
    --umm-a11y-saturation: 1;

    /* High-contrast palette. Yellow/cyan on black is the convention users of
       this mode already expect from OS-level high contrast themes. */
    --umm-a11y-hc-bg: #000;
    --umm-a11y-hc-fg: #fff;
    --umm-a11y-hc-link: #ffff00;
    --umm-a11y-hc-link-active: #00ffff;
    --umm-a11y-hc-border: #fff;
    --umm-a11y-hc-surface: #111;
    --umm-a11y-hc-control: #333;
}

/* ==========================================================================
   1. FONT / INTERFACE SCALING
   ==========================================================================
   `zoom` on the root, not a font-size sweep.

   The plugin's stylesheets are written in px throughout, so there is no root
   font-size or rem chain that a scale could flow down. The previous build
   worked around that by walking the DOM, reading each element's computed
   font-size and writing it back multiplied with `!important` — which ran once
   at page load and therefore never reached a DataTables page, a slide panel or
   any AJAX-rendered view, i.e. most of the plugin. It also could not be
   overridden by anything afterwards.

   Root `zoom` scales text AND the boxes around it, which is what someone asking
   for a larger interface actually wants (bigger text in the same cramped
   container is not more readable), reflows narrower exactly like browser zoom
   so it stays usable on a phone, and covers content that appears later for
   free. On the root element it also does not create a containing block for
   fixed descendants.
   ========================================================================== */

html:has(body.umm-a11y-font-scaled) {
    zoom: var(--umm-a11y-scale, 1);
}

/* ==========================================================================
   2. COLOUR FILTERS — colour-blindness correction + saturation
   ==========================================================================
   Applied to the root so overlays portaled to <body> are filtered along with
   the page, and so no fixed-position descendant is re-parented. The SVG filter
   definitions are injected by accessibility-layer.js only when needed.
   ========================================================================== */

html:has(body.umm-a11y-saturation) {
    filter: saturate(var(--umm-a11y-saturation, 1));
}

html:has(body.umm-a11y-cb-deuteranopia) {
    filter: url('#umm-a11y-deuteranopia-filter');
}

html:has(body.umm-a11y-cb-protanopia) {
    filter: url('#umm-a11y-protanopia-filter');
}

html:has(body.umm-a11y-cb-tritanopia) {
    filter: url('#umm-a11y-tritanopia-filter');
}

/* Both at once — `filter` is one property, so the combination has to be spelled
   out rather than layered by two rules. */
html:has(body.umm-a11y-saturation.umm-a11y-cb-deuteranopia) {
    filter: url('#umm-a11y-deuteranopia-filter') saturate(var(--umm-a11y-saturation, 1));
}

html:has(body.umm-a11y-saturation.umm-a11y-cb-protanopia) {
    filter: url('#umm-a11y-protanopia-filter') saturate(var(--umm-a11y-saturation, 1));
}

html:has(body.umm-a11y-saturation.umm-a11y-cb-tritanopia) {
    filter: url('#umm-a11y-tritanopia-filter') saturate(var(--umm-a11y-saturation, 1));
}

/* ==========================================================================
   3. HIGH CONTRAST
   ==========================================================================
   Driven by neutralising backgrounds rather than by listing containers.

   There is no plugin-wide design-token layer to override — colours are declared
   literally in each module's stylesheet, and there are ~80 hardcoded dark
   `color:` declarations across them. The previous build forced white text on a
   dozen container selectors and left those 80 alone, so in many modules high
   contrast produced dark grey text on a black background: strictly worse than
   leaving the feature off.

   So: clear every background, force one foreground, and let the single black
   root show through. Media elements and the interactive controls below are put
   back deliberately.
   ========================================================================== */

body.umm-a11y-high-contrast {
    background: var(--umm-a11y-hc-bg) !important;
    color: var(--umm-a11y-hc-fg) !important;
}

body.umm-a11y-high-contrast *:not(img):not(svg):not(svg *):not(video):not(canvas):not(iframe):not(picture):not(source) {
    background-color: transparent !important;
    background-image: none !important;
    color: var(--umm-a11y-hc-fg) !important;
    border-color: var(--umm-a11y-hc-border) !important;
    box-shadow: none !important;
    text-shadow: none !important;
}

/* Generated content is content. `*` does not match ::before / ::after, so
   decorative bars, badges, chevrons and icon pseudo-elements kept their original
   colours over the black page — the one thing high contrast exists to prevent.
   Declared here, ahead of the deliberate exceptions below (the switch thumb,
   which is drawn with ::before and has to stay visible), so those still win. */
body.umm-a11y-high-contrast *::before,
body.umm-a11y-high-contrast *::after {
    background-color: transparent !important;
    background-image: none !important;
    color: var(--umm-a11y-hc-fg) !important;
    border-color: var(--umm-a11y-hc-border) !important;
    box-shadow: none !important;
    text-shadow: none !important;
}

/* Anything that floats over the page still needs an opaque backing, or the
   content underneath reads straight through it. */
body.umm-a11y-high-contrast .umm-member-panel,
body.umm-a11y-high-contrast .umm-slide-panel,
body.umm-a11y-high-contrast .umm-modal,
body.umm-a11y-high-contrast .umm-dialog,
body.umm-a11y-high-contrast .umm-dialog-box,
body.umm-a11y-high-contrast .umm-toast,
body.umm-a11y-high-contrast .umm-select-menu,
body.umm-a11y-high-contrast .umm-pill-menu,
body.umm-a11y-high-contrast .umm-tooltip,
body.umm-a11y-high-contrast [class*="umm-"][class*="-panel-body"],
body.umm-a11y-high-contrast [class*="umm-"][class*="-dropdown"] {
    background-color: var(--umm-a11y-hc-surface) !important;
    border: 2px solid var(--umm-a11y-hc-border) !important;
}

body.umm-a11y-high-contrast a {
    color: var(--umm-a11y-hc-link) !important;
    text-decoration: underline !important;
}

body.umm-a11y-high-contrast a:hover,
body.umm-a11y-high-contrast a:focus {
    color: var(--umm-a11y-hc-link-active) !important;
}

body.umm-a11y-high-contrast button,
body.umm-a11y-high-contrast .button,
body.umm-a11y-high-contrast [class*="umm-btn"],
body.umm-a11y-high-contrast [role="button"] {
    background-color: var(--umm-a11y-hc-control) !important;
    color: var(--umm-a11y-hc-fg) !important;
    border: 2px solid var(--umm-a11y-hc-border) !important;
}

body.umm-a11y-high-contrast button:hover,
body.umm-a11y-high-contrast .button:hover,
body.umm-a11y-high-contrast [class*="umm-btn"]:hover,
body.umm-a11y-high-contrast button:focus-visible,
body.umm-a11y-high-contrast .button:focus-visible,
body.umm-a11y-high-contrast [class*="umm-btn"]:focus-visible {
    background-color: #555 !important;
    outline: 3px solid var(--umm-a11y-hc-link) !important;
}

body.umm-a11y-high-contrast input,
body.umm-a11y-high-contrast textarea,
body.umm-a11y-high-contrast select {
    background-color: var(--umm-a11y-hc-surface) !important;
    color: var(--umm-a11y-hc-fg) !important;
    border: 2px solid #aaa !important;
}

body.umm-a11y-high-contrast input:focus,
body.umm-a11y-high-contrast textarea:focus,
body.umm-a11y-high-contrast select:focus {
    border-color: var(--umm-a11y-hc-link) !important;
    outline: 3px solid var(--umm-a11y-hc-link) !important;
}

/* A switch whose track and thumb are both white reads as "no switch at all". */
body.umm-a11y-high-contrast .umm-a11y-slider,
body.umm-a11y-high-contrast [class*="umm-switch"] > span,
body.umm-a11y-high-contrast [class*="-slider"] {
    background-color: var(--umm-a11y-hc-control) !important;
    border: 2px solid var(--umm-a11y-hc-border) !important;
}

body.umm-a11y-high-contrast input:checked + .umm-a11y-slider,
body.umm-a11y-high-contrast input:checked + [class*="-slider"] {
    background-color: var(--umm-a11y-hc-link) !important;
}

body.umm-a11y-high-contrast input:checked + .umm-a11y-slider::before,
body.umm-a11y-high-contrast input:checked + [class*="-slider"]::before {
    background-color: var(--umm-a11y-hc-bg) !important;
}

/* Photographs stay recognisable; only their contrast is nudged. */
body.umm-a11y-high-contrast img:not([class*="icon"]):not([class*="logo"]) {
    filter: brightness(0.92) contrast(1.15);
}

/* ==========================================================================
   3b. HIGH CONTRAST — 'auto', resolved before JavaScript runs
   ==========================================================================
   `high_contrast: auto` means "do what the operating system asks". Only the
   browser knows the answer, so the server ships a marker class
   (`umm-a11y-high-contrast-auto`) and the runtime upgrades it to the real class
   once it can read the media query.

   The runtime cannot do that before <body> exists, i.e. not before first paint:
   a member whose system asks for high contrast watched the whole page render
   white and then flip to black. The media query answers the same question with
   no JavaScript at all, so the first paint is already correct — and it also
   covers the portal's login screen, where there is no signed-in actor and
   therefore no personal settings to read.

   This is deliberately a SUBSET of section 3, not a copy of it: it only has to
   stop the flash. The full treatment (panels, switches, image handling) arrives
   milliseconds later with the real class, and the two never conflict because
   they declare the same values. The marker is removed as soon as the runtime
   resolves it, so this block stops matching at that point.
   ========================================================================== */

@media (prefers-contrast: more) {

    body.umm-a11y-high-contrast-auto {
        background: var(--umm-a11y-hc-bg) !important;
        color: var(--umm-a11y-hc-fg) !important;
    }

    body.umm-a11y-high-contrast-auto *:not(img):not(svg):not(svg *):not(video):not(canvas):not(iframe):not(picture):not(source) {
        background-color: transparent !important;
        background-image: none !important;
        color: var(--umm-a11y-hc-fg) !important;
        border-color: var(--umm-a11y-hc-border) !important;
        box-shadow: none !important;
        text-shadow: none !important;
    }

    body.umm-a11y-high-contrast-auto a {
        color: var(--umm-a11y-hc-link) !important;
        text-decoration: underline !important;
    }

    body.umm-a11y-high-contrast-auto button,
    body.umm-a11y-high-contrast-auto .button,
    body.umm-a11y-high-contrast-auto [class*="umm-btn"],
    body.umm-a11y-high-contrast-auto [role="button"] {
        background-color: var(--umm-a11y-hc-control) !important;
        color: var(--umm-a11y-hc-fg) !important;
        border: 2px solid var(--umm-a11y-hc-border) !important;
    }

    body.umm-a11y-high-contrast-auto input,
    body.umm-a11y-high-contrast-auto textarea,
    body.umm-a11y-high-contrast-auto select {
        background-color: var(--umm-a11y-hc-surface) !important;
        color: var(--umm-a11y-hc-fg) !important;
        border: 2px solid #aaa !important;
    }
}

/* ==========================================================================
   4. DYSLEXIA FONT
   ==========================================================================
   Icon fonts are excluded: dashicons and Font Awesome map glyphs to private
   code points, so re-pointing them at OpenDyslexic replaces every icon in the
   interface with a blank box.
   ========================================================================== */

body.umm-a11y-dyslexia-font,
body.umm-a11y-dyslexia-font *:not(.dashicons):not([class*="dashicons-"]):not(.material-icons):not([class*="fa-"]):not(.umm-icon) {
    font-family: 'OpenDyslexic', sans-serif !important;
}

/* ==========================================================================
   5. FOCUS INDICATORS (WCAG 2.4.7, 2.4.11)
   ========================================================================== */

body.umm-a11y-focus-indicators *:focus-visible {
    outline: 3px solid #7c3aed !important;
    outline-offset: 2px !important;
    box-shadow: 0 0 0 5px rgba(124, 58, 237, 0.25) !important;
}

body.umm-a11y-high-contrast.umm-a11y-focus-indicators *:focus-visible {
    outline-color: var(--umm-a11y-hc-link) !important;
    box-shadow: 0 0 0 5px rgba(255, 255, 0, 0.3) !important;
}

/* ==========================================================================
   6. LINK UNDERLINES (WCAG 1.4.1)
   ========================================================================== */

body.umm-a11y-link-underlines a {
    text-decoration: underline !important;
    text-underline-offset: 3px !important;
    text-decoration-thickness: 2px !important;
}

body.umm-a11y-link-underlines a:hover {
    text-decoration-thickness: 3px !important;
}

/* Buttons and nav items that happen to be anchors are controls, not prose —
   underlining them just makes the interface look broken. */
body.umm-a11y-link-underlines a.button,
body.umm-a11y-link-underlines a[class*="umm-btn"],
body.umm-a11y-link-underlines a[role="button"],
body.umm-a11y-link-underlines a[class*="-nav-item"],
body.umm-a11y-link-underlines a[class*="-tab"] {
    text-decoration: none !important;
}

/* ==========================================================================
   7. REDUCE MOTION (WCAG 2.3.3)
   ==========================================================================
   Animations are SLOWED, not annihilated. Setting duration to ~0 with a single
   iteration freezes every spinner mid-rotation, so a loading state becomes
   indistinguishable from a crashed one. Long, calm loops keep the "something is
   happening" signal while removing the motion that causes the problem.
   ========================================================================== */

body.umm-a11y-reduce-motion *,
body.umm-a11y-reduce-motion *::before,
body.umm-a11y-reduce-motion *::after {
    animation-duration: 2.4s !important;
    animation-delay: 0s !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0s !important;
}

body.umm-a11y-reduce-motion {
    scroll-behavior: auto !important;
}

/* Decorative, non-informative motion has no reason to continue at all. */
body.umm-a11y-reduce-motion [class*="-marquee"],
body.umm-a11y-reduce-motion [class*="-ticker"],
body.umm-a11y-reduce-motion [class*="-parallax"],
body.umm-a11y-reduce-motion [class*="-pulse"],
body.umm-a11y-reduce-motion [class*="-bounce"] {
    animation: none !important;
}

/* ==========================================================================
   7b. REDUCE MOTION — 'auto', resolved before JavaScript runs
   ==========================================================================
   Same reasoning as 3b, and here the timing is the whole point: an animation
   that has already played cannot be un-played. Waiting for the runtime to
   resolve the marker meant the member who asked their system for reduced motion
   watched the entrance animation first and got the setting applied afterwards.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {

    body.umm-a11y-reduce-motion-auto *,
    body.umm-a11y-reduce-motion-auto *::before,
    body.umm-a11y-reduce-motion-auto *::after {
        animation-duration: 2.4s !important;
        animation-delay: 0s !important;
        transition-duration: 0.001ms !important;
        transition-delay: 0s !important;
    }

    body.umm-a11y-reduce-motion-auto {
        scroll-behavior: auto !important;
    }

    body.umm-a11y-reduce-motion-auto [class*="-marquee"],
    body.umm-a11y-reduce-motion-auto [class*="-ticker"],
    body.umm-a11y-reduce-motion-auto [class*="-parallax"],
    body.umm-a11y-reduce-motion-auto [class*="-pulse"],
    body.umm-a11y-reduce-motion-auto [class*="-bounce"] {
        animation: none !important;
    }
}

/* ==========================================================================
   8. TEXT SPACING (WCAG 1.4.12)
   ==========================================================================
   Applied to text-bearing block elements only. WCAG 1.4.12 is about text
   content; letter-spacing every element in the interface pushes toolbar chips,
   pills and button rows past their containers — the press/news toolbars are
   even regression-tested for staying on one line.
   ========================================================================== */

body.umm-a11y-text-spacing p,
body.umm-a11y-text-spacing li,
body.umm-a11y-text-spacing dd,
body.umm-a11y-text-spacing dt,
body.umm-a11y-text-spacing blockquote,
body.umm-a11y-text-spacing figcaption,
body.umm-a11y-text-spacing td,
body.umm-a11y-text-spacing th,
body.umm-a11y-text-spacing h1,
body.umm-a11y-text-spacing h2,
body.umm-a11y-text-spacing h3,
body.umm-a11y-text-spacing h4,
body.umm-a11y-text-spacing h5,
body.umm-a11y-text-spacing h6 {
    line-height: 1.8 !important;
    letter-spacing: 0.12em !important;
    word-spacing: 0.16em !important;
}

body.umm-a11y-text-spacing p {
    margin-bottom: 2em !important;
}

/* ==========================================================================
   9. LARGE CURSOR
   ==========================================================================
   Deliberately NOT `* { cursor: … !important }`. That form outranks
   `cursor: grab / move / col-resize / ns-resize`, so it silently removes the
   drag and resize affordances in the events calendar, the forms builder and
   every resizable table — taking away a motor-accessibility cue inside a
   motor-accessibility feature. Only the default and pointer cursors are
   replaced; anything that declares a meaningful cursor keeps it.
   ========================================================================== */

body.umm-a11y-large-cursor,
body.umm-a11y-large-cursor div,
body.umm-a11y-large-cursor span,
body.umm-a11y-large-cursor p,
body.umm-a11y-large-cursor li,
body.umm-a11y-large-cursor td,
body.umm-a11y-large-cursor th,
body.umm-a11y-large-cursor h1,
body.umm-a11y-large-cursor h2,
body.umm-a11y-large-cursor h3,
body.umm-a11y-large-cursor h4,
body.umm-a11y-large-cursor section,
body.umm-a11y-large-cursor article,
body.umm-a11y-large-cursor main,
body.umm-a11y-large-cursor aside,
body.umm-a11y-large-cursor nav,
body.umm-a11y-large-cursor table {
    cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M5 2l18 14h-10l6 12-4 2-6-12-4 8z' fill='%23000' stroke='%23fff' stroke-width='1.5'/%3E%3C/svg%3E") 5 2, auto;
}

body.umm-a11y-large-cursor a,
body.umm-a11y-large-cursor button,
body.umm-a11y-large-cursor label,
body.umm-a11y-large-cursor [role="button"],
body.umm-a11y-large-cursor input[type="submit"],
body.umm-a11y-large-cursor input[type="button"],
body.umm-a11y-large-cursor input[type="checkbox"],
body.umm-a11y-large-cursor input[type="radio"],
body.umm-a11y-large-cursor .button {
    cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M10 4v16l4-4 3 7 3-1-3-7h5z' fill='%23000' stroke='%23fff' stroke-width='1.5'/%3E%3C/svg%3E") 10 4, pointer;
}

/* Text-entry fields keep the I-beam: it is the only cue for where the caret
   will land. */
body.umm-a11y-large-cursor input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]),
body.umm-a11y-large-cursor textarea,
body.umm-a11y-large-cursor [contenteditable="true"] {
    cursor: text;
}

/* ==========================================================================
   10. SKIP-TO-CONTENT
   ========================================================================== */

.umm-skip-link {
    position: absolute;
    top: -9999px;
    left: -9999px;
    z-index: 2147483000;
    padding: 12px 24px;
    background: #7c3aed;
    color: #fff;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    border-radius: 0 0 8px 0;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.umm-skip-link:focus {
    top: 0;
    left: 0;
    outline: 3px solid #ffff00;
}

/* ==========================================================================
   11. READING GUIDE
   ==========================================================================
   Two shapes, chosen in the settings: a ruler bar, or a focus band that dims
   everything outside the line being read. The band is built from two fixed
   overlays (above and below the cursor) so no wrapper element is needed and
   nothing in the page has to be re-parented.
   ========================================================================== */

.umm-a11y-reading-guide-bar {
    position: fixed;
    left: 0;
    right: 0;
    height: 8px;
    background: rgba(124, 58, 237, 0.35);
    pointer-events: none;
    z-index: 2147482000;
    border-radius: 4px;
    box-shadow: 0 0 12px rgba(124, 58, 237, 0.2);
}

.umm-a11y-reading-shade {
    position: fixed;
    left: 0;
    right: 0;
    background: rgba(0, 0, 0, 0.55);
    pointer-events: none;
    z-index: 2147482000;
}

.umm-a11y-reading-shade--top    { top: 0; }
.umm-a11y-reading-shade--bottom { bottom: 0; }

/* The guide follows the pointer, so it must never be the thing that animates. */
body.umm-a11y-reduce-motion .umm-a11y-reading-guide-bar,
body.umm-a11y-reduce-motion .umm-a11y-reading-shade {
    transition: none !important;
}

/* ==========================================================================
   12. IMAGE DESCRIPTIONS — alt text as a visible overlay
   ========================================================================== */

body.umm-a11y-img-descriptions img[alt]:not([alt=""]) {
    outline: 2px dashed rgba(124, 58, 237, 0.4);
}

.umm-a11y-img-parent {
    position: relative;
}

.umm-a11y-img-desc-overlay {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 6px 10px;
    background: rgba(0, 0, 0, 0.8);
    color: #fff;
    font-size: 11px;
    line-height: 1.4;
    pointer-events: none;
    z-index: 10;
    border-radius: 0 0 4px 4px;
}

/* ==========================================================================
   13. SCREEN READER UTILITIES
   ==========================================================================
   Note what is NOT here any more: a `[aria-label]::after { content: attr(…) }`
   rule that visually hid a copy of every label. Hidden from sight is not hidden
   from a screen reader — it put the label into the accessibility tree a second
   time, so every labelled control was announced twice. Screen-reader support is
   a job for correct ARIA (accessibility-layer.js), not for generated content.
   ========================================================================== */

.umm-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;
}

/* ==========================================================================
   14. KEYBOARD NAVIGATION
   ========================================================================== */

/* With keyboard navigation on, tab stops are always visible — not only in the
   browser's own :focus-visible heuristic. */
body.umm-a11y-keyboard-nav a:focus,
body.umm-a11y-keyboard-nav button:focus,
body.umm-a11y-keyboard-nav input:focus,
body.umm-a11y-keyboard-nav select:focus,
body.umm-a11y-keyboard-nav textarea:focus,
body.umm-a11y-keyboard-nav [tabindex]:focus {
    outline: 3px solid #7c3aed !important;
    outline-offset: 2px !important;
}

/* ==========================================================================
   15. FORCED-COLORS / PRINT
   ========================================================================== */

@media (forced-colors: active) {
    .umm-a11y-slider {
        border: 2px solid ButtonText;
    }

    .umm-a11y-slider::before {
        background: ButtonText;
    }

    .umm-skip-link {
        border: 2px solid LinkText;
    }

    .umm-a11y-reading-guide-bar {
        background: Highlight;
    }

    .umm-a11y-img-desc-overlay {
        border: 1px solid CanvasText;
    }
}

@media print {

    /* Overlays and filters are screen aids; on paper they only waste ink. */
    .umm-a11y-reading-guide-bar,
    .umm-a11y-reading-shade,
    .umm-a11y-img-desc-overlay,
    .umm-skip-link,
    #umm-a11y-svg-filters {
        display: none !important;
    }

    html:has(body.umm-a11y-saturation),
    html:has(body.umm-a11y-cb-deuteranopia),
    html:has(body.umm-a11y-cb-protanopia),
    html:has(body.umm-a11y-cb-tritanopia) {
        filter: none !important;
    }

    body.umm-a11y-high-contrast,
    body.umm-a11y-high-contrast *:not(img):not(svg):not(svg *) {
        background: #fff !important;
        color: #000 !important;
        border-color: #000 !important;
    }
}

/* ==========================================================================
   16. FALLBACK FOR BROWSERS WITHOUT :has()
   ==========================================================================
   Root-level features are keyed on `html:has(body…)` because the root is the
   only element where `filter` and `zoom` are safe. Where :has() is missing, the
   runtime copies the same classes onto <html> itself and these rules take over.
   ========================================================================== */

html.umm-a11y-font-scaled          { zoom: var(--umm-a11y-scale, 1); }
html.umm-a11y-saturation           { filter: saturate(var(--umm-a11y-saturation, 1)); }
html.umm-a11y-cb-deuteranopia      { filter: url('#umm-a11y-deuteranopia-filter'); }
html.umm-a11y-cb-protanopia        { filter: url('#umm-a11y-protanopia-filter'); }
html.umm-a11y-cb-tritanopia        { filter: url('#umm-a11y-tritanopia-filter'); }

html.umm-a11y-saturation.umm-a11y-cb-deuteranopia {
    filter: url('#umm-a11y-deuteranopia-filter') saturate(var(--umm-a11y-saturation, 1));
}

html.umm-a11y-saturation.umm-a11y-cb-protanopia {
    filter: url('#umm-a11y-protanopia-filter') saturate(var(--umm-a11y-saturation, 1));
}

html.umm-a11y-saturation.umm-a11y-cb-tritanopia {
    filter: url('#umm-a11y-tritanopia-filter') saturate(var(--umm-a11y-saturation, 1));
}

/* ==========================================================================
   17. READ ALOUD
   ==========================================================================
   A small fixed control, deliberately not a full-width bar: it has to stay
   reachable on a phone without covering the text it is reading. Bottom-left,
   because the portal's own mobile navigation owns the bottom-centre strip and
   the notification bell the top-right.
   ========================================================================== */

.umm-a11y-read-bar {
    position: fixed;
    left: 12px;
    bottom: 76px;
    z-index: 2147481000;
    display: flex;
    gap: 4px;
    padding: 5px;
    background: #1e293b;
    border-radius: 999px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.28);
}

.umm-a11y-read-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: #7c3aed;
    color: #fff;
    cursor: pointer;
}

.umm-a11y-read-btn:hover,
.umm-a11y-read-btn:focus-visible {
    background: #6d28d9;
    outline: 3px solid #fff;
    outline-offset: 1px;
}

.umm-a11y-read-btn[hidden] {
    display: none;
}

.umm-a11y-read-btn .dashicons {
    font-size: 22px;
    width: 22px;
    height: 22px;
    /* base.css gives every `button .dashicons` a right margin, which knocks an
       icon-only round button's glyph off centre. */
    margin: 0;
}

/* wp-admin has no bottom navigation to clear. */
.wp-admin .umm-a11y-read-bar {
    bottom: 20px;
}

@media print {
    .umm-a11y-read-bar { display: none !important; }
}
