/* ==========================================================================
   Accessibility bar
   Markup : app/Views/components/accessibility-bar.php
   Script : assets/theme/js/accessibility-bar.js

   1. The bar            4. The tools: what each choice does to the page
   2. The two menus         4.1 Select Colors      4.5 Text size
   3. Narrow screens        4.2 High contrast      4.6 Spacing, line height
                            4.3 Invert, saturation 4.7 Hide images
                            4.4 Highlight links    4.8 Big cursor

   Shared by both layouts, so nothing here leans on Bootstrap or on either
   theme's own stylesheet; the bar's own elements are sized and coloured in
   full, because both themes style bare h2 / a / button.

   The script only marks the reader's choices on <html> (data-a11y-*). Every
   effect in part 4 is keyed on those marks.
   ========================================================================== */

:root {
    --a11y-bar-h: 40px;
}


/* 1. The bar
   ========================================================================== */

.a11y-bar {
    /* The Portal's own colour on every page, the public ones included
       (KVS HQ, 29-09-2026: the landing and sign-in pages are to match the
       signed-in dashboard). */
    --a11y-bar-bg: var(--color-primary, #632765);
    --a11y-bar-fg: #ffffff;
    --a11y-bar-focus: #ffe600;
    --a11y-pad: 12px;

    position: relative;
    z-index: 1040;   /* over the header and its menus, under Bootstrap's modals */
    background: var(--a11y-bar-bg);
    color: var(--a11y-bar-fg);
    font-family: "Segoe UI", "Nirmala UI", "Noto Sans Devanagari", system-ui, -apple-system, Roboto, Arial, sans-serif;
    font-size: 13px;
    font-weight: 400;
    line-height: 1.2;
    letter-spacing: 0;
    text-transform: none;
    text-align: left;
}

.a11y-bar *,
.a11y-bar *::before,
.a11y-bar *::after {
    box-sizing: border-box;
}

.a11y-bar__inner {
    position: relative;   /* the menus hang from here, not from their icons */
    display: flex;
    align-items: stretch;
    justify-content: space-between;
    gap: 12px;
    /* Full width, as on the signed-in dashboard: Government of India at the
       left edge, the icons at the right edge, on every page. */
    max-width: none;
    min-height: var(--a11y-bar-h);
    margin: 0 auto;
    padding: 0 var(--a11y-pad);
    white-space: nowrap;
}

/* Public layout (templates/main.php). Its site header is fixed to the top of
   the window, so the bar is fixed above it and the header moved down by the
   bar's height. The slot holds that height in the page flow, which is what
   keeps the content clear of the bar on every public page, whatever padding
   the page's own stylesheet gives <body> (the landing page 120px, the sign-in
   pages none). The bar is outside .site-header because the sign-in pages hide
   that element whole. */
.a11y-bar-slot {
    height: var(--a11y-bar-h);
}

.a11y-bar-slot .a11y-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 9999;
}

.a11y-bar-slot ~ .site-header .header-wrapper {
    top: var(--a11y-bar-h);
}

/* The sign-in pages fill the window exactly; give back the bar's share so
   they do not start to scroll. */
.a11y-bar-slot ~ .lg-page {
    min-height: calc(100vh - var(--a11y-bar-h));
}

/* Left: Government of India ------------------------------------------------ */

.a11y-bar__gov {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    font-weight: 600;
}

.a11y-bar__gov-sep {
    width: 1px;
    height: 14px;
    background: currentColor;
    opacity: .55;
}

/* Right: the three icons ---------------------------------------------------- */

.a11y-bar__tools {
    display: flex;
    align-items: stretch;
    flex: 0 0 auto;
}

.a11y-menu {
    display: block;
    position: static;
}

.a11y-tool,
.a11y-tool:hover,
.a11y-tool:visited {
    color: var(--a11y-bar-fg);
    text-decoration: none;
}

.a11y-tool {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: var(--a11y-bar-h);
    min-width: 46px;
    margin: 0;
    padding: 0 14px;
    border-left: 1px solid rgba(255, 255, 255, .18);
    cursor: pointer;
    list-style: none;
    -webkit-user-select: none;
    user-select: none;
}

.a11y-menu:last-child > .a11y-tool {
    border-right: 1px solid rgba(255, 255, 255, .18);
}

summary.a11y-tool::-webkit-details-marker {
    display: none;
}

summary.a11y-tool::marker {
    content: "";
}

.a11y-tool:hover {
    background: rgba(255, 255, 255, .12);
}

.a11y-menu[open] > .a11y-tool {
    background: rgba(255, 255, 255, .2);
}

.a11y-bar .a11y-tool:focus-visible {
    outline: 3px solid var(--a11y-bar-focus);
    outline-offset: -3px;
}

.a11y-icon {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
}

/* The door to the tools is picked out, as it is the one a newcomer looks for. */
.a11y-menu--tools > .a11y-tool .a11y-icon {
    width: 20px;
    height: 20px;
    color: #ffd34d;
}

/* Language mark: a small अ over a small A. */
.a11y-icon-lang {
    position: relative;
    display: block;
    width: 20px;
    height: 18px;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
}

.a11y-icon-lang > span {
    position: absolute;
}

.a11y-icon-lang > span:first-child {
    top: -1px;
    left: 0;
}

.a11y-icon-lang > span:last-child {
    right: 0;
    bottom: -1px;
}

/* The skip link is an icon to the eye and a sentence to the keyboard: reached
   with Tab, it spells itself out. */
.a11y-tool__label,
.a11y-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.a11y-bar__skip:focus-visible .a11y-tool__label {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip: auto;
}

/* Where the skip link lands. Zero-sized. On the public layout the scroll
   margin keeps it clear of the fixed bar and header; the signed-in header
   scrolls away with the page and needs none. */
.a11y-main-anchor {
    display: block;
    width: 0;
    height: 0;
    outline: none;
}

.a11y-bar-slot ~ .a11y-main-anchor {
    scroll-margin-top: calc(var(--a11y-bar-h) + 16px + var(--header-height, 100px));
}


/* 2. The two menus
   ========================================================================== */

.a11y-pop {
    position: absolute;
    top: calc(100% + 6px);
    right: var(--a11y-pad);
    z-index: 5;
    background: #ffffff;
    color: #1f2937;
    border: 1px solid #e5e7eb;
    border-radius: 12px;
    box-shadow: 0 18px 40px rgba(15, 23, 42, .22);
    white-space: normal;
}

.a11y-pop :focus-visible {
    outline: 3px solid #1d4ed8;
    outline-offset: 2px;
}

/* Language ------------------------------------------------------------------ */

.a11y-pop--lang {
    right: calc(var(--a11y-pad) + 47px);   /* under its own icon */
    min-width: 168px;
    padding: 6px;
    border-radius: 10px;
}

.a11y-lang-link,
.a11y-lang-link:visited {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 9px 12px;
    border-radius: 6px;
    color: #1f2937;
    font-size: 13.5px;
    text-decoration: none;
}

.a11y-lang-link:hover {
    background: #f3f4f6;
    color: #111827;
    text-decoration: none;
}

.a11y-lang-link[aria-current="true"] {
    background: #f0fdf4;
    color: #14532d;
    font-weight: 700;
}

.a11y-lang-link .a11y-icon--check {
    width: 14px;
    height: 14px;
    stroke-width: 3;
    color: #16a34a;
}

/* Accessibility tools ------------------------------------------------------- */

.a11y-panel {
    width: 352px;
    /* --a11y-pop-zoom: 1, unless the public layout is zoomed ("Text size"),
       where the window measures that much less in the panel's own pixels. */
    max-width: calc(100vw / var(--a11y-pop-zoom, 1) - 16px);
    max-height: calc(100vh / var(--a11y-pop-zoom, 1) - var(--a11y-bar-h) - 16px);
    padding: 18px 16px 16px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.a11y-panel__title {
    margin: 0 0 14px;
    padding: 0;
    color: #111827;
    font-family: inherit;
    font-size: 16px;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: 0;
    text-align: center;
    text-transform: none;
}

.a11y-panel__heading {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin: 16px 0 8px;
    padding: 0;
    color: #374151;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: 0;
    text-transform: none;
}

.a11y-panel__title + .a11y-panel__heading {
    margin-top: 0;
}

.a11y-panel__readout {
    color: #6b7280;
    font-size: 11.5px;
    font-weight: 400;
}

.a11y-panel__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
}

.a11y-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 74px;
    margin: 0;
    padding: 8px 6px;
    background: #ffffff;
    border: 1px solid #e5e7eb;
    border-radius: 6px;
    color: #4b5563;
    font-family: inherit;
    font-size: 11.5px;
    font-weight: 400;
    line-height: 1.25;
    letter-spacing: 0;
    text-align: center;
    text-transform: none;
    white-space: normal;
    cursor: pointer;
}

.a11y-tile > .a11y-icon {
    width: 20px;
    height: 20px;
    color: #111827;
}

.a11y-tile__glyph {
    color: #111827;
    font-size: 18px;
    font-weight: 700;
    line-height: 20px;
}

.a11y-tile:hover {
    background: #f9fafb;
    border-color: #9ca3af;
}

.a11y-tile[aria-pressed="true"] {
    background: #f0fdf4;
    border-color: #16a34a;
    color: #14532d;
}

.a11y-tile:disabled {
    opacity: .45;
    cursor: not-allowed;
}

.a11y-tile__check {
    position: absolute;
    top: 5px;
    right: 5px;
    display: none;
    align-items: center;
    justify-content: center;
    width: 14px;
    height: 14px;
    border: 1.2px solid #16a34a;
    border-radius: 50%;
    color: #16a34a;
}

.a11y-tile__check .a11y-icon--check {
    width: 8px;
    height: 8px;
    stroke-width: 3.5;
}

.a11y-tile[aria-pressed="true"] > .a11y-tile__check {
    display: flex;
}

/* Select Colors */

.a11y-panel__swatches {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 6px;
}

.a11y-swatch {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 36px;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 8px;
    color: #ffffff;
    cursor: pointer;
}

.a11y-swatch--default { background: linear-gradient(135deg, #632765, #9b4d96); }
.a11y-swatch--green   { background: linear-gradient(135deg, #166534, #22a35a); }
.a11y-swatch--blue    { background: linear-gradient(135deg, #1d4ed8, #5b8df5); }
.a11y-swatch--orange  { background: linear-gradient(135deg, #b45309, #e8923a); }
.a11y-swatch--teal    { background: linear-gradient(135deg, #0f766e, #2bb5a8); }
.a11y-swatch--pink    { background: linear-gradient(135deg, #be123c, #ee5b86); }

.a11y-swatch .a11y-icon--check {
    display: none;
    width: 16px;
    height: 16px;
    stroke-width: 3;
}

.a11y-swatch[aria-pressed="true"] {
    box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #111827;
}

.a11y-swatch[aria-pressed="true"] .a11y-icon--check {
    display: block;
}

/* Reset All */

.a11y-panel__reset {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    margin: 16px 0 0;
    padding: 8px;
    background: #ffffff;
    border: 1px solid #e5e7eb;
    border-radius: 6px;
    color: #374151;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 400;
    line-height: 1.25;
    cursor: pointer;
}

.a11y-panel__reset:hover {
    background: #f9fafb;
    border-color: #9ca3af;
}

.a11y-panel__reset .a11y-icon {
    width: 14px;
    height: 14px;
}


/* 3. Narrow screens
   ==========================================================================
   The bar stays one row of the same height, because the public layout's fixed
   header is placed exactly that far down. The two names of the Government
   stack, and the panel takes the width of the screen. */

@media (max-width: 720px) {
    .a11y-bar,
    body[class*="role-"] .a11y-bar {
        --a11y-pad: 10px;
    }
}

@media (max-width: 520px) {
    .a11y-bar__gov {
        flex-direction: column;
        align-items: flex-start;
        justify-content: center;
        gap: 1px;
        font-size: 11px;
        line-height: 1.15;
    }

    .a11y-bar__gov-sep {
        display: none;
    }

    .a11y-panel {
        left: 8px;
        right: 8px;
        width: auto;
        max-width: none;
    }

    .a11y-pop--lang {
        right: 8px;
    }
}

@media print {
    .a11y-bar,
    .a11y-bar-slot {
        display: none !important;
    }
}


/* 4. The tools
   ==========================================================================
   All of it for the screen only: a printed page is always the standard one.
   ========================================================================== */

@media screen {

    /* 4.1 Select Colors
       ----------------------------------------------------------------------
       The signed-in theme takes its colour from --color-primary and a few
       gradients; the public pages carry the Samagam purple in a known handful
       of rules. Each colour below is dark enough for white text (5:1 or more),
       and the gradients run from it to a darker shade, never a lighter one. */

    html[data-a11y-accent="green"]  { --a11y-accent: #166534; --a11y-accent-dark: #0f3d22; --a11y-accent-deep: #071f11; --a11y-accent-tint: #e7f4ec; }
    html[data-a11y-accent="blue"]   { --a11y-accent: #1d4ed8; --a11y-accent-dark: #172f80; --a11y-accent-deep: #0b1740; --a11y-accent-tint: #e8eefd; }
    html[data-a11y-accent="orange"] { --a11y-accent: #b45309; --a11y-accent-dark: #7c3306; --a11y-accent-deep: #3a1803; --a11y-accent-tint: #fbeee2; }
    html[data-a11y-accent="teal"]   { --a11y-accent: #0f766e; --a11y-accent-dark: #0a4743; --a11y-accent-deep: #052422; --a11y-accent-tint: #e2f3f1; }
    html[data-a11y-accent="pink"]   { --a11y-accent: #be123c; --a11y-accent-dark: #7f0d29; --a11y-accent-deep: #3f0614; --a11y-accent-tint: #fce8ed; }

    /* -deep is for the near-black bands that carry white text (16:1 or more);
       -tint for the pale fills that carry text in -dark (7.9:1 or more). */

    html[data-a11y-accent] {
        --color-primary: var(--a11y-accent);
        --color-secondary: var(--a11y-accent-dark);
        --a11y-accent-gradient: linear-gradient(135deg, var(--a11y-accent-dark) 0%, var(--a11y-accent) 100%);
    }

    html[data-a11y-accent] .a11y-bar,
    html[data-a11y-accent] body[class*="role-"] .a11y-bar {
        --a11y-bar-bg: var(--a11y-accent-dark);
    }

    /* signed-in theme. nav.css paints the bar's three levels in three hues
       (purple bar, teal dropdown tiles, blue nested tiles, on a lilac panel);
       under a chosen colour all three take that colour, each level a shade
       deeper than the one above it, and the panel its pale tint. */
    html[data-a11y-accent] #main-nav {
        --samagam-nav-main: var(--a11y-accent-gradient);
        --samagam-nav-drop: linear-gradient(135deg, var(--a11y-accent) 0%, var(--a11y-accent-dark) 100%);
        --samagam-nav-sub: linear-gradient(135deg, var(--a11y-accent-dark) 0%, var(--a11y-accent-deep) 100%);
        --samagam-nav-drop-solid: var(--a11y-accent);
        background: linear-gradient(90deg, var(--a11y-accent-dark) 0%, var(--a11y-accent) 35%, var(--a11y-accent) 65%, var(--a11y-accent-dark) 100%);
    }

    html[data-a11y-accent] #main-nav .dropdown-menu,
    html[data-a11y-accent] #main-nav .samagam-dropdown-menu,
    html[data-a11y-accent] #main-nav .dropdown-submenu > .dropdown-menu,
    html[data-a11y-accent] #main-nav .samagam-dropdown-submenu {
        background: linear-gradient(180deg, #ffffff 0%, var(--a11y-accent-tint) 100%);
        box-shadow: 0 10px 28px rgba(0, 0, 0, 0.18);
    }

    html[data-a11y-accent] #main-nav .dropdown-header,
    html[data-a11y-accent] #main-nav .samagam-nav-section-header,
    html[data-a11y-accent] #main-nav .fln-mobile-nav-heading {
        color: var(--a11y-accent-dark);
    }

    /* --hq-g1 is the violet of the theme's primary parts (primary buttons,
       plain card headers, table footers) and --hq-g6 that of its purple ones;
       g2 to g5 are the other colours of its tile palette and stay. g1 runs the
       other way round, so two tiles side by side still differ. */
    html[data-a11y-accent] body[class*="role-"]:not(.role-guest) {
        --hq-brand: var(--a11y-accent-gradient);
        --hq-g6: var(--a11y-accent-gradient);
        --hq-g1: linear-gradient(135deg, var(--a11y-accent) 0%, var(--a11y-accent-dark) 100%);
    }

    html[data-a11y-accent] body[class*="role-"]:not(.role-guest) .form-select:focus,
    html[data-a11y-accent] body[class*="role-"]:not(.role-guest) .form-control:focus {
        border-color: var(--a11y-accent);
        box-shadow: 0 0 0 .18rem var(--a11y-accent-tint);
    }

    html[data-a11y-accent] .auth-welcome-tile--welcome {
        background: var(--a11y-accent-gradient);
    }

    /* public pages */
    html[data-a11y-accent] .login-text,
    html[data-a11y-accent] .lp-eyebrow,
    html[data-a11y-accent] .lp-title,
    html[data-a11y-accent] .lg-brand h1,
    html[data-a11y-accent] .lg-card-title,
    html[data-a11y-accent] .lg-forgot,
    html[data-a11y-accent] .lg-note svg {
        color: var(--a11y-accent);
    }

    html[data-a11y-accent] .lp-hero-btn,
    html[data-a11y-accent] .lg-submit,
    html[data-a11y-accent] .lp-initiatives {
        background: var(--a11y-accent-gradient);
    }

    html[data-a11y-accent] .lg-note {
        border-left-color: var(--a11y-accent);
    }

    html[data-a11y-accent] .lg-input:focus,
    html[data-a11y-accent] .login-link:hover,
    html[data-a11y-accent] .login-link:focus {
        border-color: var(--a11y-accent);
    }

    html[data-a11y-accent] .lp-hero-btn:hover,
    html[data-a11y-accent] .lg-submit:hover {
        background: var(--a11y-accent-dark);
    }

    /* The pale fills, and the words on them. */
    html[data-a11y-accent] .lp-eyebrow,
    html[data-a11y-accent] .lg-note {
        background: var(--a11y-accent-tint);
        color: var(--a11y-accent-dark);
    }

    html[data-a11y-accent] .lg-note {
        border-color: transparent;
        border-left-color: var(--a11y-accent);
    }

    /* Landing page: headings, line icons, and the rule under a heading. */
    html[data-a11y-accent] .lp-section-head h2,
    html[data-a11y-accent] .lp-plat-content h2 {
        color: var(--a11y-accent-dark);
    }

    html[data-a11y-accent] .lp-plat-icon,
    html[data-a11y-accent] .lp-stat-card:nth-child(1) .lp-stat-value {
        color: var(--a11y-accent);
    }

    html[data-a11y-accent] .lp-stat-icon.purple {
        background: var(--a11y-accent-tint);
        color: var(--a11y-accent);
    }

    html[data-a11y-accent] .lp-head-divider::before,
    html[data-a11y-accent] .lp-head-divider::after,
    html[data-a11y-accent] .lp-head-divider span {
        background: var(--a11y-accent);
    }

    /* The Login button's figure is a picture, tinted purple by a filter no
       variable can steer; its outline is cut from a fill instead: the chosen
       colour here, the link yellow under high contrast (4.2), where the purple
       one all but vanished. */
    html[data-a11y-accent] .login-link {
        border-color: #d1d5db;
    }

    html[data-a11y-accent] .avatar-circle,
    html[data-a11y-contrast="high"] .avatar-circle {
        -webkit-mask: url("../../../images/admin_img.svg") center / 19px 22px no-repeat;
        mask: url("../../../images/admin_img.svg") center / 19px 22px no-repeat;
    }

    html[data-a11y-accent] .avatar-circle {
        background: var(--a11y-accent);
    }

    html[data-a11y-accent] .avatar-circle img,
    html[data-a11y-contrast="high"] .avatar-circle img {
        visibility: hidden;
    }

    /* The sign-in dialog of the landing page, which is what /login shows. It
       is styled inside pages/home/index.php, in a violet of its own. Its veil
       and its fields go neutral: a veil in the old purple would tint the whole
       page behind it. */
    html[data-a11y-accent] .lp-login-brand span,
    html[data-a11y-accent] .lp-login-title,
    html[data-a11y-accent] .lp-login-forgot,
    html[data-a11y-accent] .lp-login-close:hover {
        color: var(--a11y-accent);
    }

    html[data-a11y-accent] .lp-login-submit {
        background: var(--a11y-accent-gradient);
    }

    html[data-a11y-accent] .lp-login-overlay {
        background: rgba(17, 24, 39, .55);
    }

    html[data-a11y-accent] .lp-login-input {
        background: #f9fafb;
        border-color: #d1d5db;
    }

    html[data-a11y-accent] .lp-login-input:focus {
        background: #ffffff;
        outline-color: var(--a11y-accent);
    }

    /* The dark bands. "Our Related Portals and Apps" runs near-black to the
       chosen colour and back; the fades at the two ends of its moving row must
       start from the same near-black, or the old purple shows at the edges.
       The cards inside keep their colours: each is that portal's own. */
    html[data-a11y-accent] .lp-portals {
        background: linear-gradient(135deg, var(--a11y-accent-deep) 0%, var(--a11y-accent-dark) 40%, var(--a11y-accent-deep) 100%);
    }

    html[data-a11y-accent] .lp-portals::before {
        background:
            radial-gradient(ellipse 60% 80% at 15% 50%, var(--a11y-accent) 0%, transparent 70%),
            radial-gradient(ellipse 50% 70% at 85% 50%, var(--a11y-accent) 0%, transparent 70%);
        opacity: .35;
    }

    html[data-a11y-accent] .lp-portals-marquee::before {
        background: linear-gradient(90deg, var(--a11y-accent-deep) 0%, transparent 100%);
    }

    html[data-a11y-accent] .lp-portals-marquee::after {
        background: linear-gradient(270deg, var(--a11y-accent-deep) 0%, transparent 100%);
    }

    /* On a band the words are white, and so is the rule under them: one in
       the chosen colour would sink into a band of that colour. */
    html[data-a11y-accent] .lp-portals .lp-section-head h2,
    html[data-a11y-accent] .lp-initiatives .lp-section-head h2 {
        color: #ffffff;
    }

    html[data-a11y-accent] .lp-portals .lp-head-divider::before,
    html[data-a11y-accent] .lp-portals .lp-head-divider::after,
    html[data-a11y-accent] .lp-initiatives .lp-head-divider::before,
    html[data-a11y-accent] .lp-initiatives .lp-head-divider::after {
        background: rgba(255, 255, 255, .5);
    }

    html[data-a11y-accent] .lp-portals .lp-head-divider span,
    html[data-a11y-accent] .lp-initiatives .lp-head-divider span {
        background: #ffffff;
        box-shadow: none;
    }

    html[data-a11y-accent] .lp-initiative p,
    html[data-a11y-accent] .lp-initiative-icon {
        color: rgba(255, 255, 255, .88);
    }


    /* 4.2 High contrast
       ----------------------------------------------------------------------
       The Portal's pages were written over years, by module, with colours set
       in stylesheets, in inline style="" attributes and by scripts. High
       contrast therefore cannot restyle them piece by piece; it lays one
       foreground and one line colour over everything, and gives every surface
       one of three backgrounds, by what it was:

           was white             grey      #2b2b2b   the page, cards, fields
           was a dark colour     black     #000000   headers, menus, filled buttons
           was a light colour    greyish   #454545   tinted boxes, disabled fields

       That is also what guarantees the contrast on a page nobody has checked by
       hand. Text is white (14:1, 21:1, 9.6:1 on the three) and links yellow
       (11:1, 16.6:1, 7.6:1): nothing under the 7:1 of WCAG AAA.

       What a surface was cannot be seen from a stylesheet, so the script marks
       it (data-a11y-tone, see accessibility-bar.js). The mark only sets
       --a11y-surface, which is inherited, and every element is painted with it.
       Everything inside a marked element so wears its colour until another mark
       says otherwise; every element stays opaque, so a floating menu never
       turns see-through; and what a script adds later wears the colour of the
       place it was added to, even before it is read. With no marks at all the
       page is simply grey throughout.

       How the selectors are built:

       - ":not(#_):not(#_)" names no element. It only lends the rules the weight
         of two ids, so they outrank the !important rules already in the theme
         (hq-revamp.css carries many) without a matching id in the markup.
       - ":where(...)" weighs nothing, so the long exclusion list of the base
         rule does not outweigh the exceptions that follow it. A browser too old
         for :where() drops the rule whole and simply shows the standard page. */

    html[data-a11y-contrast="high"] {
        --a11y-bg: #2b2b2b;         /* was white */
        --a11y-bg-dark: #000000;    /* was a dark colour */
        --a11y-bg-light: #454545;   /* was a light colour */
        --a11y-surface: var(--a11y-bg);
        --a11y-fg: #ffffff;
        --a11y-link: #ffe600;
        --a11y-line: #ffffff;
        color-scheme: dark;
    }

    /* The bar's own two surfaces, known without being read. */
    html[data-a11y-contrast="high"] .a11y-bar { --a11y-surface: var(--a11y-bg-dark); }
    html[data-a11y-contrast="high"] .a11y-pop { --a11y-surface: var(--a11y-bg); }

    html[data-a11y-contrast="high"] [data-a11y-tone="white"] { --a11y-surface: var(--a11y-bg); }
    html[data-a11y-contrast="high"] [data-a11y-tone="dark"]  { --a11y-surface: var(--a11y-bg-dark); }
    html[data-a11y-contrast="high"] [data-a11y-tone="light"] { --a11y-surface: var(--a11y-bg-light); }

    /* While the script reads the page's own colours (accessibility-bar.js). */
    html[data-a11y-measuring] *,
    html[data-a11y-measuring] *::before,
    html[data-a11y-measuring] *::after {
        transition-duration: 0s !important;
        transition-delay: 0s !important;
    }

    html[data-a11y-contrast="high"]:not(#_):not(#_),
    html[data-a11y-contrast="high"]:not(#_):not(#_) body {
        background: var(--a11y-surface) !important;
        color: var(--a11y-fg) !important;
    }

    /* Left alone: pictures and drawings, which carry their own colours; the
       charts, which are given a white plate below; the colour swatches. */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body :not(:where(
        img, picture, video, canvas, iframe, embed, object, svg, svg *,
        .apexcharts-canvas, .apexcharts-canvas *,
        .a11y-swatch, .a11y-swatch *
    )) {
        background-color: var(--a11y-surface) !important;
        background-image: none !important;
        color: var(--a11y-fg) !important;
        -webkit-text-fill-color: currentColor !important;
        border-color: var(--a11y-line) !important;
        box-shadow: none !important;
        text-shadow: none !important;
    }

    /* Decorative overlays and gradient fades are drawn with pseudo-elements;
       left in place they would sit over the text. */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body :not(:where(.a11y-swatch, .apexcharts-canvas *))::before,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body :not(:where(.a11y-swatch, .apexcharts-canvas *))::after {
        background-color: transparent !important;
        background-image: none !important;
        box-shadow: none !important;
        text-shadow: none !important;
    }

    html[data-a11y-contrast="high"]:not(#_):not(#_) body ::placeholder {
        color: var(--a11y-fg) !important;
        opacity: .8 !important;
    }

    html[data-a11y-contrast="high"]:not(#_):not(#_) body ::selection {
        background: var(--a11y-link) !important;
        color: var(--a11y-bg-dark) !important;
    }

    html[data-a11y-contrast="high"]:not(#_):not(#_) body .opacity-25,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .opacity-50,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .opacity-75 {
        opacity: 1 !important;
    }

    /* Links */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body a,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body a * {
        color: var(--a11y-link) !important;
    }

    html[data-a11y-contrast="high"]:not(#_):not(#_) body a:not(.btn):not(.nav-link):not(.dropdown-item):not(.page-link):not(.navbar-brand):not(.a11y-tool) {
        text-decoration: underline !important;
    }

    /* Keyboard focus */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body :focus-visible {
        outline: 3px solid var(--a11y-link) !important;
        outline-offset: 2px !important;
    }

    /* Controls: with every surface one colour, the line is what shows them. */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body button,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .btn,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body [role="button"],
    html[data-a11y-contrast="high"]:not(#_):not(#_) body input,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body select,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body textarea {
        outline: 1px solid var(--a11y-line);
        outline-offset: -1px;
    }

    /* Bootstrap draws these with background images, which the base rule has
       removed; hand them back to the browser, which follows color-scheme. */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body select,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body input[type="checkbox"],
    html[data-a11y-contrast="high"]:not(#_):not(#_) body input[type="radio"] {
        -webkit-appearance: auto !important;
        appearance: auto !important;
        accent-color: var(--a11y-link);
    }

    html[data-a11y-contrast="high"]:not(#_):not(#_) body input[type="checkbox"],
    html[data-a11y-contrast="high"]:not(#_):not(#_) body input[type="radio"] {
        outline: none;
    }

    html[data-a11y-contrast="high"]:not(#_):not(#_) body .btn-close {
        opacity: 1 !important;
    }

    html[data-a11y-contrast="high"]:not(#_):not(#_) body .btn-close::before {
        content: "\00d7";
        display: block;
        font-size: 1.5em;
        line-height: .7;
        color: var(--a11y-fg);
    }

    /* Where colour alone marked "this one": the current tab / page / menu item,
       the filled part of a progress bar and the chosen tiles of this panel are
       turned inside out, black on white. Two of the greys side by side are
       under 1.5:1 apart, enough to tell a card from a header but not to say
       which of five tabs is open. Filled buttons and badges need none of it:
       a dark one is black, a light one greyish, and both carry a line. */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .progress-bar,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .nav-link.active,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .dropdown-item.active,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .list-group-item.active,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .page-item.active > .page-link,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .a11y-tile[aria-pressed="true"],
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .a11y-lang-link[aria-current="true"] {
        background-color: var(--a11y-fg) !important;
        color: var(--a11y-bg-dark) !important;
    }

    html[data-a11y-contrast="high"]:not(#_):not(#_) body .progress-bar *,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .nav-link.active *,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .dropdown-item.active *,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .list-group-item.active *,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .page-item.active > .page-link *,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .a11y-tile[aria-pressed="true"] *,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .a11y-lang-link[aria-current="true"] * {
        background-color: transparent !important;
        border-color: currentColor !important;
        color: inherit !important;
    }

    /* Layers that must stay see-through, or the page behind them goes blank. */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .modal,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .form-floating > label {
        background-color: transparent !important;
    }

    html[data-a11y-contrast="high"]:not(#_):not(#_) body .swal2-container,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .modal-backdrop,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .offcanvas-backdrop {
        background-color: rgba(0, 0, 0, .7) !important;
    }

    /* Boxes that were told apart by their fill alone: a card from the page, an
       alert from the text around it, a badge from its row, the empty part of a
       progress bar. The greys still differ, but a line does not depend on it. */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .card,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .alert,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .badge,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .progress {
        outline: 1px solid var(--a11y-line);
        outline-offset: -1px;
    }

    /* ...and the panels floating over the page, which now share its colour and
       need a line to be told from it. */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .swal2-popup,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .modal-content,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .dropdown-menu,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .popover,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .toast,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .offcanvas,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .a11y-pop {
        outline: 2px solid var(--a11y-line) !important;
    }

    /* Charts keep their own colours, on a white plate. */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body canvas,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .apexcharts-canvas {
        background-color: #ffffff !important;
        color: #000000 !important;
    }

    /* The bar: a line under it, now that it is the header's colour, taken back
       from the row inside so the bar keeps the exact height the public layout's
       fixed header is placed below. */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .a11y-bar {
        border-bottom: 1px solid var(--a11y-line) !important;
    }

    html[data-a11y-contrast="high"]:not(#_):not(#_) body .a11y-bar__inner {
        min-height: calc(var(--a11y-bar-h) - 1px);
    }

    html[data-a11y-contrast="high"]:not(#_):not(#_) body .a11y-tool {
        height: calc(var(--a11y-bar-h) - 1px);
    }

    html[data-a11y-contrast="high"]:not(#_):not(#_) body .a11y-swatch[aria-pressed="true"] {
        box-shadow: 0 0 0 2px var(--a11y-bg), 0 0 0 4px var(--a11y-fg) !important;
    }

    /* The Login button's figure, cut from a fill (see 4.1): it sits in a link. */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .avatar-circle {
        background-color: var(--a11y-link) !important;
    }

    /* The panel's icons are drawings, which the base rule leaves alone; their
       own near-black would vanish here, so they take the colour of the tile
       they sit in (and turn with it when the tile is chosen). */
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .a11y-pop .a11y-icon,
    html[data-a11y-contrast="high"]:not(#_):not(#_) body .a11y-pop .a11y-tile__glyph {
        color: inherit !important;
    }


    /* 4.3 Invert, saturation
       ----------------------------------------------------------------------
       One filter on <html>, built from whichever of the two is on. On the root
       element a filter does not re-anchor position:fixed, so the fixed bar and
       header stay where they are. Pictures are turned back, so a photograph
       still looks like one. */

    html[data-a11y-invert] {
        --a11y-f-invert: invert(1) hue-rotate(180deg);
        background-color: #ffffff;
    }

    html[data-a11y-saturation] {
        --a11y-f-saturation: saturate(0);
    }

    html[data-a11y-invert],
    html[data-a11y-saturation] {
        filter: var(--a11y-f-invert, invert(0)) var(--a11y-f-saturation, saturate(1));
    }

    html[data-a11y-invert] :where(img, video, canvas, iframe, embed, object, [style*="background-image"]) {
        filter: invert(1) hue-rotate(180deg);
    }


    /* 4.4 Highlight links
       ---------------------------------------------------------------------- */

    html[data-a11y-links]:not(#_):not(#_) body a:not(:where(.a11y-bar a)) {
        background-color: #ffeb3b !important;
        background-image: none !important;
        color: #000000 !important;
        -webkit-text-fill-color: #000000 !important;
        text-decoration: underline !important;
        text-shadow: none !important;
        outline: 2px solid #000000 !important;
        outline-offset: 0 !important;
    }

    html[data-a11y-links]:not(#_):not(#_) body a:not(:where(.a11y-bar a)) * {
        background-color: transparent !important;
        color: #000000 !important;
        -webkit-text-fill-color: #000000 !important;
    }


    /* 4.5 Text size
       ----------------------------------------------------------------------
       Two layouts, two means.

       The signed-in pages are Bootstrap's, sized in rem throughout, so the root
       font size scales their text and nothing else: ordinary layout, which the
       scripted widgets (dropdowns, DataTables, Tom Select, charts) never notice.

       The public pages size their text in px, which no font-size rule reaches.
       They are scaled with zoom instead, which enlarges the text and gives the
       layout the room to hold it, as the browser's own zoom would. zoom is kept
       off the signed-in pages on purpose: it shifts the coordinates scripts
       measure with, and a Bootstrap dropdown opened at 130% flipped above its
       button with a screenful of room below. The public pages position nothing
       by script. */

    html[data-a11y-text-size] {
        font-size: calc(100% * var(--a11y-zoom, 1));
    }

    /* layout.css pins the signed-in <body> to 16px, which everything without a
       size of its own (table cells, labels, paragraphs) inherits. */
    html[data-a11y-text-size]:not([data-a11y-layout="public"]) body {
        font-size: 1rem;
    }

    html[data-a11y-layout="public"][data-a11y-text-size] {
        font-size: 100%;
        --a11y-pop-zoom: var(--a11y-zoom, 1);
    }

    html[data-a11y-layout="public"][data-a11y-text-size] body {
        zoom: var(--a11y-zoom, 1);
    }

    /* The landing page's hero sets its words beside a photograph that is part
       of its background image (background-size: cover). Zoom narrows the page
       without waking the tablet media queries, so the photograph grows and
       slides under the words. Enlarged (^="1" matches 110 to 150; 100 is never
       marked, 80 and 90 do not start with 1), the words are therefore given a
       plate of their own to stand on, kept to the left half, and the 96px title
       held to what that half can carry. Wide screens only: below that the
       landing page's own media queries have already stacked the hero. */
    @media (min-width: 900px) {
        html[data-a11y-layout="public"][data-a11y-text-size^="1"] .lp-hero-content {
            max-width: min(640px, calc(48vw / var(--a11y-zoom, 1)));
            margin-left: -20px;
            padding: 20px;
            background: rgba(255, 255, 255, .88);
            border-radius: 18px;
        }

        html[data-a11y-layout="public"][data-a11y-text-size^="1"] .lp-title {
            font-size: min(96px, calc(7.4vw / var(--a11y-zoom, 1)));
        }
    }


    /* 4.6 Text spacing, line height
       ----------------------------------------------------------------------
       The values WCAG 1.4.12 asks a page to bear. Icon fonts are left out (a
       spaced-out glyph is a misplaced icon), and so is the bar, whose panel is
       a grid of fixed tiles. */

    html[data-a11y-spacing] body :not(:where(.a11y-bar, .a11y-bar *, i, .fa, .fas, .far, .fab, [class^="fa-"], [class*=" fa-"])) {
        letter-spacing: .12em !important;
        word-spacing: .16em !important;
    }

    html[data-a11y-line-height] body :not(:where(.a11y-bar, .a11y-bar *, i, .fa, .fas, .far, .fab, [class^="fa-"], [class*=" fa-"])) {
        line-height: 1.8 !important;
    }


    /* 4.7 Hide images
       ----------------------------------------------------------------------
       Hidden, not removed, so nothing on the page moves. Pictures a reader
       needs in order to act stay: the captcha and its refresh button, QR codes
       and barcodes. Of the CSS backgrounds only the known photographs go; a
       blanket "background-image: none" would also strip the gradients that
       white text stands on. */

    html[data-a11y-hide-images] body :where(img, picture, video, svg image, [role="img"]):not(:where(
        [id*="captcha" i], [class*="captcha" i], [src*="captcha" i],
        [src*="/qr" i], [src*="barcode" i],
        .a11y-bar *
    )) {
        visibility: hidden !important;
    }

    html[data-a11y-hide-images] body :where(.lp-hero, .lg-page, .main-container, [style*="background-image"]) {
        background-image: none !important;
    }


    /* 4.8 Big cursor
       ---------------------------------------------------------------------- */

    html[data-a11y-big-cursor],
    html[data-a11y-big-cursor] * {
        cursor: url("../../img/a11y-cursor.svg") 5 3, auto !important;
    }

    html[data-a11y-big-cursor] :where(a, button, summary, select, label, [role="button"], [role="tab"], [role="link"],
        input[type="submit"], input[type="button"], input[type="reset"], input[type="checkbox"], input[type="radio"],
        .btn, .nav-link, .dropdown-item, .page-link),
    html[data-a11y-big-cursor] :where(a, button, summary, label, [role="button"], .btn) * {
        cursor: url("../../img/a11y-cursor-pointer.svg") 16 3, pointer !important;
    }
}
