/**
 * Accessibility toolbar — effects and panel styling.
 *
 * Effect rules key off data-a11y-* attributes on <html>, set by a11y.js /
 * a11y-boot.php. They use !important because they exist specifically to win
 * over utility classes and inline theme colours — that is their whole job.
 */

/* ── Text size ────────────────────────────────────────────────────────────
   Scaling the ROOT font-size, not body, so every rem-based Bootstrap
   spacing/sizing utility (padding, gaps, icon sizes) grows with it — the
   same effect as a user pressing browser zoom, but persisted per account. */
:root { --a11y-scale: 1; }
/* Multiplies app.css's fluid root rather than replacing it. Written as
   `100% * scale`, this rule silently discarded the responsive size and pinned
   every display to the browser's 16px default. */
html { font-size: calc(var(--pc-root-size, 100%) * var(--a11y-scale)); }

/* ── High contrast ─────────────────────────────────────────────────────── */
html[data-a11y-contrast="on"] {
  --bs-body-bg: #000 !important;
  --bs-body-color: #fff !important;
  --ink: #fff !important;
  --ink-2: #f5f5f5 !important;
  --surface: #000 !important;
  /* --surface-2 is the plate colour behind chips and pills. It was the one
     surface token this block did not override, and it stayed a near-white
     #f7fbf8 — so every chip rendered light-grey text on light-grey while the
     card behind it went black. The programme's Pacific Pillar chip, on 107 of
     126 tiles, measured 1.21:1. */
  --surface-2: #000 !important;
  --line: #fff !important;
  --muted: #e5e5e5 !important;
}
html[data-a11y-contrast="on"] body {
  background: #000 !important;
  color: #fff !important;
}
html[data-a11y-contrast="on"] a {
  color: #ffe600 !important;
  text-decoration: underline !important;
}
html[data-a11y-contrast="on"] .card,
html[data-a11y-contrast="on"] .pc-portal-bar,
html[data-a11y-contrast="on"] .pc-tabbar,
html[data-a11y-contrast="on"] .btn,
html[data-a11y-contrast="on"] .form-control,
html[data-a11y-contrast="on"] .form-select,
html[data-a11y-contrast="on"] .alert {
  background: #000 !important;
  color: #fff !important;
  border: 1px solid #fff !important;
}
html[data-a11y-contrast="on"] .btn-brand,
html[data-a11y-contrast="on"] .lp-btn-solid {
  background: #ffe600 !important;
  color: #000 !important;
  border-color: #ffe600 !important;
}
html[data-a11y-contrast="on"] img { filter: grayscale(1) contrast(1.2); }
/* Marketing pages layer decorative photos, glows and gradients (the public
   homepage hero, section dividers) behind their own text using a private
   background — not `body` — so the rules above never reach them. Every one
   of those layers is already marked aria-hidden="true" (screen readers skip
   them today), which makes them safe to remove outright rather than guess
   at overriding each one's own background property by name. */
html[data-a11y-contrast="on"] [aria-hidden="true"]:not(.bi, [class*="bi-"]) {
  display: none !important;
}
/* Except the Exhibitors page's booth rings (2026-09-25). They are aria-hidden
   because the list says everything they do, not because they are decoration:
   removed, a shared #booth-N link showed nothing on the plan. More specific
   than the rule above, which it has to beat. */
html[data-a11y-contrast="on"] .pc-exhibitors-plan .pc-booth-pin[aria-hidden="true"] { display: block !important; }
html[data-a11y-contrast="on"] .pc-exhibitors-plan .pc-booth-pin.is-on {
  border-color: #ffe600 !important;
  box-shadow: 0 0 0 3px #000, 0 0 0 6px #ffe600 !important;
}
/* The booth numbers are links, and the mode's link yellow on green was 3.1:1. */
html[data-a11y-contrast="on"] .pc-exhibitor-no {
  background: #000 !important; color: #fff !important; text-decoration: none !important;
  box-shadow: inset 0 0 0 2px #fff;
}
/* A plan card's head (venue page too) kept its pale background, and the yellow
   "Enlarge" / "Tap to enlarge" link on it was about 1.2:1. */
html[data-a11y-contrast="on"] .pc-venue-plan-head {
  background: #000 !important; color: #fff !important; border-bottom: 1px solid #fff;
}
html[data-a11y-contrast="on"] .pc-venue-plan-open { opacity: 1 !important; }
html[data-a11y-contrast="on"] .hp-hero,
html[data-a11y-contrast="on"] .hp-section,
html[data-a11y-contrast="on"] .pc-footer {
  background: #000 !important;
  color: #fff !important;
}

/* The footer needs its CHILDREN named, not just itself — both halves of it.
   The rule above sets .pc-footer, but nothing was ever painted from that
   element: .pc-footer-body is a child with its own `background:
   var(--pc-foot-bg)`, so the mint went straight back over the black, and
   .pc-footer-body::before draws the green contour band on top of that. The
   footer therefore stayed full colour in high-contrast mode however dark the
   parent was told to be. Text has the mirror-image problem: `color: #fff
   !important` is INHERITED by the children, and a child's own ordinary
   declaration beats an inherited important one — and the links, eyebrows,
   lede, venue line, contact rows and the #PreCOP31 tag each take a
   --pc-foot-* token. Both ends have to be stated. */
html[data-a11y-contrast="on"] .pc-footer-body { background: #000 !important; }
html[data-a11y-contrast="on"] .pc-footer-body::before { display: none !important; }
html[data-a11y-contrast="on"] .pc-footer * { color: #fff !important; }

/* ── Programme tiles: the venue colour is a SHAPE here, never text ─────────
   The board tints a session by its venue — Crowne Plaza red, Sofitel blue —
   and uses that colour in three places: a 4px spine down the left edge, the
   start time, and the hotel name. The spine is fine on black. The other two
   are text, and measured against #000 the venue colours fail badly:

     Sofitel      #134FA0 on #000 = 2.65:1   FAIL
     Crowne Plaza #B3122A on #000 = 3.04:1   large text only

   .pc-board-card's background resolves to #000 in this mode because it reads
   var(--surface), which is overridden above — but --tint is an inline style on
   the element and survives untouched, so without this the time and the hotel
   would be dark red or dark blue text on pure black.

   So in high contrast the colour keeps doing its job where it costs nothing —
   the spine, which is decorative and always paired with the hotel's NAME — and
   the text goes to the same white everything else uses. Nothing is lost: the
   card still says which hotel in words. */
html[data-a11y-contrast="on"] .pc-board-time,
html[data-a11y-contrast="on"] .pc-board-venue,
html[data-a11y-contrast="on"] .pc-cal-time,
html[data-a11y-contrast="on"] .pc-cal-venue,
/* The day heading above each column, which was white on the near-white plate
   at 1.04:1 — invisible rather than merely low. */
html[data-a11y-contrast="on"] .pc-board-colday,
html[data-a11y-contrast="on"] .pc-board-colmon,
/* "Show all 28 sessions": brand blue on black at 2.65:1, and it is a 15px
   control, so large-text AA does not rescue it. */
html[data-a11y-contrast="on"] .pc-board-showall { color: #fff !important; }

/* The chips and status pills. Each one colour-mixes its own background against
   var(--surface), which is now #000, so every one of them resolved to a dark
   tint of itself on black. An outline carries the same distinction without
   relying on a fill, which is the pattern this file already uses for the
   footer's icon plates. */
html[data-a11y-contrast="on"] .pc-board-state,
html[data-a11y-contrast="on"] .pc-cal-state {
  background: #000 !important;
  color: #fff !important;
  box-shadow: inset 0 0 0 1px #fff;
}
/* The hover border is a colour-mix against --line, which this mode forces to
   #fff; the mix would come out a muddy near-white. A plain white border says
   "focused" more clearly on black anyway. */
html[data-a11y-contrast="on"] .pc-board-card:hover { border-color: #fff !important; }
/* The round icon slot is a tinted plate rather than text, so it needs its own
   rule; an outline instead of a fill keeps the glyph on it readable. */
html[data-a11y-contrast="on"] .pc-footer .bi {
  background: transparent !important;
  box-shadow: inset 0 0 0 1px #fff;
}

/* ── Dyslexia-friendly text ───────────────────────────────────────────────
   The evidence behind dyslexia-friendly display is mostly about SPACING and
   a plain, uniform-width-feeling sans typeface, not a novelty font — so this
   widens letter/word spacing and switches to a widely-available legible
   stack rather than shipping a custom webfont. */
html[data-a11y-dyslexia="on"] body,
html[data-a11y-dyslexia="on"] p,
html[data-a11y-dyslexia="on"] li,
html[data-a11y-dyslexia="on"] label,
html[data-a11y-dyslexia="on"] h1,
html[data-a11y-dyslexia="on"] h2,
html[data-a11y-dyslexia="on"] h3,
html[data-a11y-dyslexia="on"] h4,
html[data-a11y-dyslexia="on"] h5,
html[data-a11y-dyslexia="on"] h6,
html[data-a11y-dyslexia="on"] .btn,
html[data-a11y-dyslexia="on"] .form-control {
  font-family: Verdana, Tahoma, "Segoe UI", Arial, sans-serif !important;
  letter-spacing: .035em !important;
  word-spacing: .12em !important;
  line-height: 1.7 !important;
}
html[data-a11y-dyslexia="on"] p,
html[data-a11y-dyslexia="on"] li {
  text-align: left !important;
}

/* ── Underline links ──────────────────────────────────────────────────── */
html[data-a11y-underline="on"] a { text-decoration: underline !important; }

/* ── Reduce motion ────────────────────────────────────────────────────── */
html[data-a11y-motion="on"] *,
html[data-a11y-motion="on"] *::before,
html[data-a11y-motion="on"] *::after {
  animation-duration: .001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: .001ms !important;
  scroll-behavior: auto !important;
}

/* ── Large cursor ─────────────────────────────────────────────────────────
   A self-contained inline SVG data URI — no extra file request, nothing
   for the Content-Security-Policy's img/script origins to allow. */
html[data-a11y-cursor="on"],
html[data-a11y-cursor="on"] a,
html[data-a11y-cursor="on"] button {
  cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24"><path d="M4 2l14 12-6 1.5 3 6-3 1.5-3-6-4 4V2z" fill="black" stroke="white" stroke-width="1.2"/></svg>') 2 2, auto !important;
}

/* ── Toggle button ────────────────────────────────────────────────────── */
[data-a11y-open] { line-height: 1; }

/* ── Floating trigger (public pages) ──────────────────────────────────────
   Same fixed-circle language as .pc-totop (the back-to-top button), on the
   OPPOSITE corner and permanently visible rather than scroll-triggered —
   this is the one control every visitor must be able to find immediately,
   signed in or not, without first scrolling to discover it exists. */
.pc-a11y-fab {
  position: fixed; left: clamp(.9rem, 2.5vw, 1.75rem); bottom: clamp(.9rem, 2.5vw, 1.75rem);
  width: 3.1rem; height: 3.1rem; padding: 0; border: 0; border-radius: 50%;
  z-index: 1040; cursor: pointer; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(140deg, var(--brand-2, #4f46e5) 0%, var(--brand, #0059b3) 55%, var(--brand-deep, #003090) 100%);
  box-shadow: 0 10px 26px -8px rgba(0,48,144,.62);
  color: #fff; font-size: 1.55rem; transition: box-shadow .3s ease, transform .3s ease;
}
.pc-a11y-fab:hover, .pc-a11y-fab:focus-visible {
  transform: translateY(-3px);
  box-shadow: 0 16px 34px -10px rgba(0,48,144,.7), 0 0 0 6px rgba(0,160,80,.22);
}
.pc-a11y-fab:focus-visible { outline: 3px solid var(--reef-2, #00a050); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  .pc-a11y-fab { transition: none; }
}

/* ── Panel ────────────────────────────────────────────────────────────── */
.pc-a11y-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 1090;
}
.pc-a11y-sheet {
  position: fixed; z-index: 1091; background: var(--surface, #fff);
  color: var(--ink, #0f172a); border-radius: 14px 14px 0 0;
  left: 0; right: 0; bottom: 0; max-height: 82vh; overflow-y: auto;
  padding: 1rem 1.1rem calc(1.25rem + env(safe-area-inset-bottom));
  box-shadow: 0 -8px 30px rgba(0,0,0,.25);
}
@media (min-width: 576px) {
  .pc-a11y-sheet {
    left: auto; bottom: auto; top: 4.2rem; right: 1rem;
    width: 21rem; border-radius: 14px; max-height: calc(100vh - 6rem);
  }
}
.pc-a11y-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: .75rem;
}
.pc-a11y-head h2 { font-size: 1.05rem; font-weight: 800; margin: 0; }
.pc-a11y-close {
  border: 0; background: transparent; font-size: 1.4rem; line-height: 1;
  color: inherit; padding: .2rem .4rem; border-radius: 8px;
}
.pc-a11y-close:hover { background: rgba(127,127,127,.15); }
.pc-a11y-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: .6rem 0; border-bottom: 1px solid var(--line, #e5e7eb);
}
.pc-a11y-row:last-of-type { border-bottom: 0; }
.pc-a11y-stepper { display: flex; align-items: center; gap: .5rem; }
.pc-a11y-stepper button {
  width: 2.1rem; height: 2.1rem; border-radius: 8px; border: 1px solid var(--line, #cbd5e1);
  background: transparent; color: inherit; font-weight: 700;
}
.pc-a11y-stepper button:disabled { opacity: .4; }
.pc-a11y-stepper span { min-width: 3.2rem; text-align: center; font-variant-numeric: tabular-nums; }
.pc-a11y-toggle {
  display: flex; align-items: center; justify-content: space-between;
  padding: .6rem 0; border-bottom: 1px solid var(--line, #e5e7eb);
  cursor: pointer; gap: 1rem;
}
.pc-a11y-toggle:last-of-type { border-bottom: 0; }
.pc-a11y-toggle input { width: 2.6rem; height: 1.5rem; accent-color: var(--brand, #0059b3); }
.pc-a11y-reset {
  margin-top: .85rem; width: 100%; padding: .6rem; border-radius: 10px;
  border: 1px solid var(--line, #cbd5e1); background: transparent; color: inherit; font-weight: 700;
}
.pc-a11y-reset:hover { background: rgba(127,127,127,.12); }
