/* ============================================================================
   ACCESSIBILITY WIDGET — floating panel + the effects it switches on
   ----------------------------------------------------------------------------
   Loaded on every public page (see commonAssets/headerPlugins.blade.php, which
   links it LAST so its rules win over light-mode.css, dark-mode.css and the
   admin-managed theme.css that precede it).

   TWO SEPARATE JOBS IN ONE FILE
     1. .ct-a11y — the widget itself: launcher, panel, 12 tiles, reset,
        move/hide. Everything is namespaced with .ct-a11y and driven by its own
        tokens, so it can be restyled without touching the site's CSS.
     2. html[data-a11y-*] — the effects. Each effect is a single attribute on
        <html>, which is what the inline boot script in headerPlugins sets
        before the first paint (so a returning visitor never sees the page
        paint, then jump). The panel's script only ever writes those attributes.

   WHY THE EFFECTS ARE SCOPED TO `body > *:not(.ct-a11y)`
     Two reasons, both load-bearing:
       - the widget must stay legible and clickable while its own effects are
         on, so every typography effect exempts it;
       - `filter` creates a containing block for `position: fixed` children,
         so filtering a wrapper that holds the fixed navbar would pin the navbar
         to the page instead of the viewport. Filtering the page's own blocks
         and never the widget keeps both the navbar and this panel fixed.

   THE ONE THING TO KNOW BEFORE EDITING THE TYPE-SIZE EFFECTS
     This site declares ~340 `font-size: …px` values, so raising the root
     font-size moves nothing. "Bigger text" therefore uses `zoom`, which scales
     text and the layout around it exactly like the browser's own zoom — that
     is the honest equivalent of what the tile promises. Browsers that don't
     support `zoom` (Firefox before 126) simply show the page unscaled rather
     than a broken one.

   Add an effect: give it a data attribute here, add a tile in
   commonAssets/accessibility.blade.php, and list it in accessibility.js's
   STEPS map. Nothing else has to change.
   ========================================================================= */

/* ---------------------------------------------------------------- widget ---- */
.ct-a11y {
    /* Widget-only tokens. Light is the default; dark overrides below. They are
       intentionally separate from the site's own colour tokens (the
       --main-color-* family and the --dm-* family): the panel is chrome that
       must stay readable whatever an admin sets in Admin > Appearance.

       Keep "*" and "/" apart in this file's comments. An accidental "* /"
       written as one pair closes the comment early, and the parser then eats
       the declaration that follows it — which is how --ct-a11y-surface went
       missing and made the panel see-through. */
    --ct-a11y-surface: #ffffff;
    --ct-a11y-surface-2: #f3f6fc;
    --ct-a11y-text: #0a1128;
    --ct-a11y-muted: #5b6472;
    --ct-a11y-line: #e2e8f4;
    --ct-a11y-accent: #2f6fed;
    --ct-a11y-accent-ink: #ffffff;
    /* The keyboard ring. This was #0345b2 — dark enough to read as black
       against the panel and be mistaken for the browser's default outline. */
    --ct-a11y-ring: #2f6fed;
    --ct-a11y-shadow: 0 24px 60px -22px rgba(10, 17, 40, .38), 0 8px 22px rgba(10, 17, 40, .12);
    --ct-a11y-radius: 18px;
    /* Above the back-to-top button (9997), below the cookie banner / preloader
       (9999) and the cookie modal (10000) — the same order as before, with one
       step added. The open panel is 384px wide and rises from the corner, so it
       covers the back-to-top button's slot: at the old 9900 that arrow painted
       straight through the panel, because it was three above. */
    --ct-a11y-z: 9998;

    /* The bottom-right corner, as the first of the three launchers stacked
       there — the slots above it (cookie settings, back to top) and the lift
       they all share are declared together at the end of this file.
       `left: auto` matters: with both edges set the widget stretches. */
    position: fixed;
    left: auto;
    right: 22px;
    bottom: calc(var(--ct-corner-base) + var(--corner-slot, 0) * var(--ct-corner-step) + var(--ct-a11y-lift));
    transition: bottom .2s ease;
    z-index: var(--ct-a11y-z);
    font-family: "Open Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
    color: var(--ct-a11y-text);
    /* The panel has its own coordinate space, so nothing the page does to
       `body` (a filter, a zoom, a font swap) can move it. */
    isolation: isolate;
}

/* Mirrors the site's own theme switch: dark-mode.css sets this attribute on
   <html> (see ct-navbar.js's initThemeSwitcher). */
html[data-theme="dark"] .ct-a11y {
    --ct-a11y-surface: #151b30;
    --ct-a11y-surface-2: #1c2340;
    --ct-a11y-text: #f3f5fc;
    --ct-a11y-muted: #a7afc9;
    --ct-a11y-line: #2a3357;
    --ct-a11y-accent: #6c9bff;
    --ct-a11y-accent-ink: #0b1020;
    --ct-a11y-ring: #9dbaff;
    --ct-a11y-shadow: 0 24px 60px -18px rgba(0, 0, 0, .65), 0 8px 22px rgba(0, 0, 0, .45);
}

/* Left-hand placement (Move / hide → Left), for readers who would rather have
   it on that side. Right is the default now that the corner is a managed
   stack. Keyed off <html> so the widget already sits on the correct side on
   the first paint, before the deferred script runs. */
html[data-a11y-pos="left"] .ct-a11y {
    left: 22px;
    right: auto;
}

/* The panel is capped in JS to the room between the launcher and the top of
   the viewport, so it never opens past the top edge — necessary once the
   launcher has been lifted clear of a tall cookie bar. */
.ct-a11y__grid {
    flex: 1 1 auto;
    min-height: 0; /* lets a flex child actually shrink and scroll */
    overflow-y: auto;
    overscroll-behavior: contain;
    /* The focus ring of an edge tile would otherwise be clipped by the
       scroll container. */
    margin: -4px;
    padding: 4px;
    /* The site paints a decorative brand-gradient scrollbar globally
       (`::-webkit-scrollbar-thumb { background-image: var(--main-gradient) }`
       in light-mode.css). Inside the widget that reads as a stray coloured
       stripe down the panel, so the grid takes a neutral one. A class beats
       that bare pseudo-element on specificity, and the rule carries no
       !important, so this wins without touching the site's own scrollbars. */
    scrollbar-width: thin;
    scrollbar-color: var(--ct-a11y-line) transparent;
}

/* Same 5px as every other scrollbar on the site (the bare
   `::-webkit-scrollbar` rule in light-mode.css) — only the colour is the
   widget's own. Both axes for the same reason as there. */
.ct-a11y__grid::-webkit-scrollbar {
    width: 5px;
    height: 5px;
}

.ct-a11y__grid::-webkit-scrollbar-track {
    background: transparent;
}

.ct-a11y__grid::-webkit-scrollbar-thumb {
    background-image: none;
    background-color: var(--ct-a11y-line);
    border-radius: 99px;
}

.ct-a11y__grid::-webkit-scrollbar-thumb:hover {
    background-color: var(--ct-a11y-muted);
}

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

.ct-a11y [hidden] {
    display: none !important;
}

/* --------------------------------------------------------------- launcher --- */
.ct-a11y__launch {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    padding: 0;
    border: 1px solid var(--ct-a11y-line);
    border-radius: 50%;
    background: var(--ct-a11y-surface);
    color: var(--ct-a11y-text);
    box-shadow: var(--ct-a11y-shadow);
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition: transform .18s ease, box-shadow .18s ease, background-color .18s ease;
}

.ct-a11y__launch:hover {
    transform: translateY(-2px);
    background: var(--ct-a11y-surface-2);
}

.ct-a11y__launch svg {
    width: 26px;
    height: 26px;
    flex: 0 0 auto;
    color: var(--ct-a11y-accent);
}

/* The round icon button above is the default. "Move / hide → Label" swaps in
   the pill with the word — the only difference is the box and whether the
   label is painted. */
html[data-a11y-min="0"] .ct-a11y__launch {
    width: auto;
    max-width: 260px;
    height: auto;
    min-height: 56px;
    padding: 0 18px;
    gap: 10px;
    border-radius: 999px;
}

html[data-a11y-min="0"] .ct-a11y__launch-text {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip: auto;
    white-space: nowrap;
}

/* Hidden by default, never removed: the word stays in the button's accessible
   name while the button is round, so it is never an unlabelled control. */
.ct-a11y__launch-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* ------------------------------------------------------------------ panel --- */
.ct-a11y__panel {
    position: absolute;
    /* Opens above the launcher and stays inside the viewport on the right-hand
       side by default — the same side as the launcher. */
    left: auto;
    right: 0;
    bottom: calc(100% + 14px);
    width: 384px;
    max-width: calc(100vw - 44px);
    max-height: min(78vh, 720px);
    /* A column whose MIDDLE scrolls: the tile grid is the only part that can
       grow past the viewport, so Reset and Move / hide stay pinned and always
       reachable. Scrolling the whole panel instead (the first cut) put the
       reset button below the fold on a short screen — the one control someone
       needs precisely when the settings are making the page hard to read. */
    display: flex;
    flex-direction: column;
    overflow: hidden;
    overscroll-behavior: contain;
    padding: 18px;
    border: 1px solid var(--ct-a11y-line);
    border-radius: var(--ct-a11y-radius);
    background: var(--ct-a11y-surface);
    box-shadow: var(--ct-a11y-shadow);
}

html[data-a11y-pos="left"] .ct-a11y__panel {
    left: 0;
    right: auto;
}

/* The panel is what takes focus when it opens (see accessibility.js) — the
   dialog pattern — so nothing inside is highlighted before the reader has
   moved there. It is a container, not a control: no ring, ever. */
.ct-a11y__panel:focus,
.ct-a11y__panel:focus-visible {
    outline: 0;
}

.ct-a11y__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}

.ct-a11y__title {
    margin: 0;
    font-family: "Barlow Semi Condensed", "Open Sans", sans-serif;
    font-size: 20px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: .2px;
    color: var(--ct-a11y-text);
}

.ct-a11y__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 1px solid var(--ct-a11y-line);
    border-radius: 50%;
    background: var(--ct-a11y-surface-2);
    color: var(--ct-a11y-muted);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease;
}

.ct-a11y__close:hover {
    color: var(--ct-a11y-text);
    border-color: var(--ct-a11y-accent);
}

/* ------------------------------------------------------------------ tiles --- */
.ct-a11y__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
}

.ct-a11y__tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
    min-height: 98px;
    padding: 13px 10px 11px;
    border: 1px solid var(--ct-a11y-line);
    border-radius: 14px;
    background: var(--ct-a11y-surface);
    color: var(--ct-a11y-text);
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.25;
    text-align: center;
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease, transform .15s ease;
}

.ct-a11y__tile:hover {
    background: var(--ct-a11y-surface-2);
    border-color: var(--ct-a11y-accent);
}

.ct-a11y__tile svg {
    width: 28px;
    height: 28px;
    color: var(--ct-a11y-text);
}

/* An "on" tile reads as a pressed switch: tinted surface, accent border, and
   the icon in the accent colour. Status is also exposed to assistive tech via
   aria-pressed, set by accessibility.js. */
.ct-a11y__tile[aria-pressed="true"] {
    border-color: var(--ct-a11y-accent);
    background: color-mix(in srgb, var(--ct-a11y-accent) 12%, var(--ct-a11y-surface));
    box-shadow: inset 0 0 0 1px var(--ct-a11y-accent);
}

.ct-a11y__tile[aria-pressed="true"] svg {
    color: var(--ct-a11y-accent);
}

/* Step dots for the four controls with more than one level. Read out as part
   of the tile's accessible name instead (see accessibility.js), so this is
   decoration. */
.ct-a11y__level {
    display: inline-flex;
    gap: 4px;
    margin-top: auto;
    min-height: 6px;
}

.ct-a11y__level i {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--ct-a11y-line);
}

.ct-a11y__level i.is-on {
    background: var(--ct-a11y-accent);
}

/* -------------------------------------------------------- reset + move/hide -- */
.ct-a11y__reset {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    min-height: 48px;
    margin-top: 14px;
    padding: 0 16px;
    border: 0;
    border-radius: 12px;
    background: var(--ct-a11y-accent);
    color: var(--ct-a11y-accent-ink);
    font: inherit;
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
    transition: transform .16s ease, filter .16s ease;
}

.ct-a11y__reset:hover {
    transform: translateY(-1px);
    filter: brightness(1.06);
}

.ct-a11y__reset svg {
    width: 20px;
    height: 20px;
}

.ct-a11y__move {
    flex: 0 0 auto;
    margin-top: 12px;
    border-top: 1px solid var(--ct-a11y-line);
    padding-top: 12px;
}

.ct-a11y__move-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 4px;
    border: 0;
    background: none;
    color: var(--ct-a11y-text);
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

.ct-a11y__move-toggle svg {
    width: 20px;
    height: 20px;
    flex: 0 0 auto;
    color: var(--ct-a11y-accent);
}

.ct-a11y__move-toggle .ct-a11y__chevron {
    width: 16px;
    height: 16px;
    margin-left: auto;
    color: var(--ct-a11y-muted);
    transition: transform .18s ease;
}

.ct-a11y__move-toggle[aria-expanded="true"] .ct-a11y__chevron {
    transform: rotate(180deg);
}

.ct-a11y__move-menu {
    display: grid;
    gap: 8px;
    margin-top: 8px;
}

.ct-a11y__move-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.ct-a11y__move-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--ct-a11y-muted);
}

.ct-a11y__seg {
    display: inline-flex;
    padding: 3px;
    border: 1px solid var(--ct-a11y-line);
    border-radius: 999px;
    background: var(--ct-a11y-surface-2);
}

.ct-a11y__seg button {
    min-width: 62px;
    padding: 6px 12px;
    border: 0;
    border-radius: 999px;
    background: none;
    color: var(--ct-a11y-muted);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.ct-a11y__seg button[aria-pressed="true"] {
    background: var(--ct-a11y-accent);
    color: var(--ct-a11y-accent-ink);
}

/* ------------------------------------------------------------------ notice -- */
/* Shown when a feature cannot work in this browser (e.g. zoom is unavailable),
   so the tile never silently does nothing. */
.ct-a11y__notice {
    margin: 12px 0 0;
    padding: 10px 12px;
    border-left: 3px solid var(--ct-a11y-accent);
    border-radius: 8px;
    background: var(--ct-a11y-surface-2);
    color: var(--ct-a11y-muted);
    font-size: 13px;
    line-height: 1.5;
}

.ct-a11y__sr {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ----------------------------------------------------------------- tooltip -- */
/* The "Tooltips" tile's bubble. Kept outside the page's filtered blocks (it is
   a child of .ct-a11y) so it stays sharp and readable with every effect on. */
.ct-a11y__tip {
    position: fixed;
    z-index: calc(var(--ct-a11y-z) + 10);
    max-width: 320px;
    padding: 8px 12px;
    border: 1px solid var(--ct-a11y-line);
    border-radius: 10px;
    background: var(--ct-a11y-text);
    color: var(--ct-a11y-surface);
    box-shadow: var(--ct-a11y-shadow);
    font-family: "Open Sans", system-ui, sans-serif;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.45;
    pointer-events: none;
}

/* Focus visibility for the panel's controls, declared here because the site's
   own rules are scoped to its components. Keyboard only — a mouse click gets
   nothing, both from the site's :focus:not(:focus-visible) reset and from the
   fact that these selectors are :focus-visible and nothing else. */
.ct-a11y :focus-visible,
.ct-a11y button:focus-visible {
    outline: 2px solid var(--ct-a11y-ring);
    outline-offset: 2px;
}

/* ============================================================================
   EFFECTS — every selector below is switched on by one attribute on <html>
   ========================================================================= */

/* 1. Contrast + -------------------------------------------------------------
   Driven through the site's own colour tokens (not a filter), because the whole
   frontend reads those: raising them here lifts every heading, paragraph,
   subtitle and muted label at once, and this file loads after dark-mode.css and
   theme.css so the override wins in both themes. */
html[data-a11y-contrast="1"] {
    --heading-color: #000000;
    --paragraph-color: #10131f;
    --main-subtitle-color: #10131f;
}

html[data-theme="dark"][data-a11y-contrast="1"] {
    --heading-color: #ffffff;
    --paragraph-color: #e8ecfa;
    --main-subtitle-color: #e8ecfa;
}

/* Muted greys that don't come from a token get the same treatment. */
html[data-a11y-contrast="1"] body > *:not(.ct-a11y) :is(p, li, td, th, span, small) {
    color: var(--paragraph-color) !important;
}

/* Interactive edges become visible rather than discovered by hover. */
html[data-a11y-contrast="1"] body > *:not(.ct-a11y) :is(a, button, input, select, textarea) {
    outline: 1px solid currentColor;
    outline-offset: 2px;
}

/* 2. Highlight links -------------------------------------------------------- */
html[data-a11y-links="1"] body > *:not(.ct-a11y) a {
    text-decoration: underline !important;
    text-decoration-thickness: 2px;
    text-underline-offset: 3px;
    background-color: #fff3a3;
    color: #10131f !important;
    box-shadow: 0 0 0 2px #fff3a3;
}

html[data-theme="dark"][data-a11y-links="1"] body > *:not(.ct-a11y) a {
    background-color: #443c00;
    color: #ffe98a !important;
    box-shadow: 0 0 0 2px #443c00;
}

/* 3. Bigger text (3 steps) --------------------------------------------------
   See the file header: `zoom` because the site's type is in px. */
html[data-a11y-text="1"] {
    zoom: 1.1;
}

html[data-a11y-text="2"] {
    zoom: 1.22;
}

html[data-a11y-text="3"] {
    zoom: 1.35;
}

/* 4. Text spacing (3 steps) — WCAG 1.4.12's letter/word spacing. */
html[data-a11y-spacing="1"] body > *:not(.ct-a11y) :is(p, li, a, span, td, th, blockquote, figcaption, dd, dt) {
    letter-spacing: .05em !important;
    word-spacing: .1em !important;
}

html[data-a11y-spacing="2"] body > *:not(.ct-a11y) :is(p, li, a, span, td, th, blockquote, figcaption, dd, dt) {
    letter-spacing: .1em !important;
    word-spacing: .18em !important;
}

html[data-a11y-spacing="3"] body > *:not(.ct-a11y) :is(p, li, a, span, td, th, blockquote, figcaption, dd, dt) {
    letter-spacing: .16em !important;
    word-spacing: .26em !important;
}

/* 5. Pause animations -------------------------------------------------------
   `animation: none` rather than `animation-play-state: paused`. Pausing looks
   like the literal promise, but this site reveals plenty of content with
   entrance animations (wow-lite's .wow elements start at opacity 0 and are
   animated in), and a paused reveal leaves those blocks invisible — the
   opposite of an accessibility win. Cancelling the animation lands each element
   on its final, visible state; scroll-behavior and transitions go too, so
   nothing moves. */
html[data-a11y-motion="1"] body > *:not(.ct-a11y) *,
html[data-a11y-motion="1"] body > *:not(.ct-a11y) *::before,
html[data-a11y-motion="1"] body > *:not(.ct-a11y) *::after {
    animation: none !important;
    transition: none !important;
}

html[data-a11y-motion="1"] {
    scroll-behavior: auto !important;
}

/* 6. Hide images ------------------------------------------------------------
   Images, videos and embeds only — never icons, which on this site are either
   font glyphs or inline <svg> (hiding those would strip the navbar and every
   button). Inline background-image declarations are neutralised too. */
html[data-a11y-images="1"] body > *:not(.ct-a11y) :is(img, picture, video, iframe, lite-youtube) {
    display: none !important;
}

html[data-a11y-images="1"] body > *:not(.ct-a11y) [style*="background-image"] {
    background-image: none !important;
}

/* 7. Dyslexia friendly ------------------------------------------------------
   A wider, rounder face at a larger size with generous spacing and left-aligned
   text, which is what the setting is for. Verdana is the widely available
   stand-in for a dyslexia-specific font — the site can drop a self-hosted face
   in here without touching anything else. */
html[data-a11y-dyslexia="1"] body > *:not(.ct-a11y) :is(p, li, a, span, td, th, blockquote, figcaption, label, input, textarea, select, button, h1, h2, h3, h4, h5, h6) {
    font-family: Verdana, "Trebuchet MS", "Open Sans", sans-serif !important;
    letter-spacing: .045em !important;
    word-spacing: .16em !important;
    line-height: 1.8 !important;
}

html[data-a11y-dyslexia="1"] body > *:not(.ct-a11y) :is(p, li, blockquote, figcaption, h1, h2, h3, h4, h5, h6) {
    text-align: left !important;
}

/* 8. Cursor (3 sizes) -------------------------------------------------------
   Inline SVG so there is no extra request. The arrow is white-outlined black so
   it stays visible on any background; `#` inside the data URI is %23. */
html[data-a11y-cursor="1"] body {
    cursor: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M6 2l18 14-8 1 4 9-3 1.5-4-9-5 6z' fill='%23000' stroke='%23fff' stroke-width='1.8'/%3E%3C/svg%3E") 3 2, auto;
}

html[data-a11y-cursor="1"] body > *:not(.ct-a11y) a,
html[data-a11y-cursor="1"] body > *:not(.ct-a11y) button {
    cursor: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M12 3v18M12 21c0 4 2 6 6 6s6-2 6-6V9' fill='none' stroke='%23fff' stroke-width='6'/%3E%3Cpath d='M12 3v18M12 21c0 4 2 6 6 6s6-2 6-6V9' fill='none' stroke='%23000' stroke-width='3'/%3E%3C/svg%3E") 12 3, pointer;
}

html[data-a11y-cursor="2"] body {
    cursor: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'%3E%3Cpath d='M8 3l28 21-12 1.5 6 14-4.5 2-6-14-7.5 9z' fill='%23000' stroke='%23fff' stroke-width='2.2'/%3E%3C/svg%3E") 4 3, auto;
}

html[data-a11y-cursor="2"] body > *:not(.ct-a11y) a,
html[data-a11y-cursor="2"] body > *:not(.ct-a11y) button {
    cursor: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'%3E%3Cpath d='M18 4v27M18 31c0 6 3 9 9 9s9-3 9-9V13' fill='none' stroke='%23fff' stroke-width='9'/%3E%3Cpath d='M18 4v27M18 31c0 6 3 9 9 9s9-3 9-9V13' fill='none' stroke='%23000' stroke-width='4.5'/%3E%3C/svg%3E") 18 4, pointer;
}

html[data-a11y-cursor="3"] body {
    cursor: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3E%3Cpath d='M10 4l38 29-16 2 8 19-6 2.5-8-19-10 12z' fill='%23000' stroke='%23fff' stroke-width='3'/%3E%3C/svg%3E") 5 4, auto;
}

html[data-a11y-cursor="3"] body > *:not(.ct-a11y) a,
html[data-a11y-cursor="3"] body > *:not(.ct-a11y) button {
    cursor: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3E%3Cpath d='M24 5v36M24 41c0 8 4 12 12 12s12-4 12-12V17' fill='none' stroke='%23fff' stroke-width='12'/%3E%3Cpath d='M24 5v36M24 41c0 8 4 12 12 12s12-4 12-12V17' fill='none' stroke='%23000' stroke-width='6'/%3E%3C/svg%3E") 24 5, pointer;
}

/* 9. Tooltips ---------------------------------------------------------------
   The bubble is positioned by accessibility.js; this only reserves the room the
   highlighted target needs so the page doesn't jump when a title is added. */
html[data-a11y-tooltips="1"] body > *:not(.ct-a11y) a {
    position: relative;
}

/* 10. Line height (3 steps) ------------------------------------------------ */
html[data-a11y-line="1"] body > *:not(.ct-a11y) :is(p, li, td, th, a, span, blockquote, figcaption, dd, dt) {
    line-height: 1.7 !important;
}

html[data-a11y-line="2"] body > *:not(.ct-a11y) :is(p, li, td, th, a, span, blockquote, figcaption, dd, dt) {
    line-height: 2 !important;
}

html[data-a11y-line="3"] body > *:not(.ct-a11y) :is(p, li, td, th, a, span, blockquote, figcaption, dd, dt) {
    line-height: 2.4 !important;
}

/* 11. Text align (4 states, 0 = off) --------------------------------------- */
html[data-a11y-align="1"] body > *:not(.ct-a11y) :is(p, li, h1, h2, h3, h4, h5, h6, blockquote, td, th) {
    text-align: left !important;
}

html[data-a11y-align="2"] body > *:not(.ct-a11y) :is(p, li, h1, h2, h3, h4, h5, h6, blockquote, td, th) {
    text-align: center !important;
}

html[data-a11y-align="3"] body > *:not(.ct-a11y) :is(p, li, h1, h2, h3, h4, h5, h6, blockquote, td, th) {
    text-align: right !important;
}

html[data-a11y-align="4"] body > *:not(.ct-a11y) :is(p, li, h1, h2, h3, h4, h5, h6, blockquote, td, th) {
    text-align: justify !important;
}

/* 12. Saturation (3 steps: muted / no colour / boosted) ---------------------
   Per-block filters, not one filter on body — see the file header on containing
   blocks. Because each top-level block is its own filter, the fixed navbar
   inside the header block keeps working. */
html[data-a11y-saturation="1"] body > *:not(.ct-a11y) {
    filter: saturate(.5);
}

html[data-a11y-saturation="2"] body > *:not(.ct-a11y) {
    filter: grayscale(1);
}

html[data-a11y-saturation="3"] body > *:not(.ct-a11y) {
    filter: saturate(1.7) contrast(1.05);
}

/* ------------------------------------------------------------------ mobile --- */
@media (max-width: 560px) {
    /* `bottom` deliberately not set here: the column's base and step are shared
       by all three launchers, and the widget's slot is written by
       accessibility.js. Only the horizontal edge and the size are per-breakpoint. */
    .ct-a11y {
        left: auto;
        right: 14px;
    }

    html[data-a11y-pos="left"] .ct-a11y {
        left: 14px;
        right: auto;
    }

    .ct-a11y__panel {
        width: min(360px, calc(100vw - 28px));
        max-width: calc(100vw - 28px);
        max-height: 72vh;
        padding: 15px;
    }

    .ct-a11y__tile {
        min-height: 96px;
        padding: 12px 8px 10px;
        font-size: 13px;
    }

    /* A labelled launcher would cover a third of the screen at this width, so
       on a phone it is round whatever the reader chose. Both selectors are
       listed because the Label choice would otherwise win on specificity and
       put the pill back. */
    .ct-a11y__launch,
    html[data-a11y-min="0"] .ct-a11y__launch {
        width: 54px;
        height: 54px;
        min-height: 54px;
        padding: 0;
        justify-content: center;
        border-radius: 50%;
    }

    .ct-a11y__launch-text,
    html[data-a11y-min="0"] .ct-a11y__launch-text {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }
}

/* --------------------------------------------- the bottom-right launcher stack ---
   Three fixed launchers share the bottom-right corner and all three have to
   stay clickable, so they share one column — and the column is packed. From the
   corner upwards the order is:

       slot 0   accessibility    (this widget, 56px)   <- the corner
       slot 1   cookie settings  (.cb-float, 54px)
       slot 2   back to top      (.cf-to-top, ~50px)   <- first in the column

   A launcher's slot is `--corner-slot`, written by accessibility.js: it walks
   that order and hands each launcher that is *on screen* the next number. Two
   of the three are hidden most of the time — back to top until the page is
   scrolled, cookie settings until the banner has been answered — and a fixed
   offset for an invisible launcher reserves a hole, which is the gap that used
   to open in the column for no visible reason. Launchers that are hidden are
   parked *above* the stack instead, where their invisible boxes cannot open a
   hole between the ones you can see.

   Without JavaScript the declared defaults hold: the old arrangement, minus the
   holes. `right` is restated because the site sets it per breakpoint.

   The numbers live here rather than in light-mode.css for two reasons: this
   file loads last, so they win without !important; and they only mean anything
   next to each other — resizing a launcher means moving the slots above it. */
:root {
    /* The upward shift applied while the cookie bar is on screen. The bar is
       `position: fixed; bottom: 0; z-index: 9999` and spans the full width, so
       at the corner the launcher sits inside it — behind it, and unclickable,
       which is exactly what the first live test found. Lifting beats raising the
       z-index: the bar's own Accept / Decline buttons stay clickable either
       way. Declared on <html> rather than on the widget because all three
       launchers in the column have to travel together; accessibility.js writes
       it. */
    --ct-a11y-lift: 0px;

    /* Where the column starts and how far apart its slots are. One pair of
       numbers, so the three offsets cannot drift out of step. */
    --ct-corner-base: 24px;
    --ct-corner-step: 78px;
}

.cf-to-top {
    bottom: calc(var(--ct-corner-base) + var(--corner-slot, 2) * var(--ct-corner-step) + var(--ct-a11y-lift));
    right: 24px;
}

.cb-float {
    bottom: calc(var(--ct-corner-base) + var(--corner-slot, 1) * var(--ct-corner-step) + var(--ct-a11y-lift));
    right: 24px;
}

/* Matches the site's own 576px breakpoint (light-mode.css moves .cf-to-top and
   .cb-float to 16px there) so all three slots keep their spacing on a phone. */
@media (max-width: 576px) {
    :root {
        --ct-corner-base: 14px;
    }

    .cf-to-top {
        right: 16px;
    }

    .cb-float {
        right: 16px;
    }
}

/* Someone who has asked their system to reduce motion should not get this
   panel's transitions either. */
@media (prefers-reduced-motion: reduce) {
    .ct-a11y *,
    .ct-a11y *::before,
    .ct-a11y *::after {
        transition: none !important;
        animation: none !important;
    }
}

/* Printing a page should never include the widget. */
@media print {
    .ct-a11y {
        display: none !important;
    }
}
