/* HabHub personal accessibility settings (plan 2026-09-30, task 2).

   base.html writes the person's saved choices onto <html> server-side, so
   nothing flashes; a11y.js flips the same attributes live from the panel:
     data-text="standard|large|largest"   text size
     data-contrast="on"                    high contrast
     data-motion="reduced"                 reduce motion
     data-font="readable"                  readable font
   The panel itself (opened from the floating feedback button) is styled at
   the bottom of this file. */

/* ---------------------------------------------------------- Text size */
/* Everything in the portal is sized in rem/em, so scaling the root scales
   the page. (Fixed-size glyphs — the round feedback button, badges — stay px
   on purpose: they sit inside fixed boxes.) */
html[data-text="large"] { font-size: 115%; }
html[data-text="largest"] { font-size: 130%; }

/* Long words must wrap rather than push the page sideways at bigger sizes.
   (break-word, not anywhere: it only breaks a word that cannot fit a line,
   so ordinary words are never split mid-way.) */
html[data-text="large"] .hh-main,
html[data-text="largest"] .hh-main { overflow-wrap: break-word; }

/* The header: at bigger sizes the name beside the avatar is what collides
   with the nav first, so it goes (the avatar and menu stay). The menu
   itself still shows the full name. */
html:is([data-text="large"], [data-text="largest"]) .hh-profile-name { display: none; }
html:is([data-text="large"], [data-text="largest"]) .hh-topnav { gap: 0.8rem; }

/* The phone tab bar is a fixed 68px strip of four short labels: it grows a
   little with the text size but is capped so every label stays on one line
   inside its quarter of a 390px screen (the page content above it scales in
   full). */
@media (max-width: 767px) {
  html:is([data-text="large"], [data-text="largest"]) .hh-tabbar .hh-navitem {
    font-size: min(0.75rem, 13px); white-space: nowrap; letter-spacing: 0; word-spacing: 0;
  }
  html:is([data-text="large"], [data-text="largest"]) .hh-tabbar .hh-navitem .fas {
    font-size: min(1.375rem, 24px);
  }
  /* Verdana is too wide for "Who I Support" in a quarter of a phone at any
     legible size, so the tab bar alone keeps the system sans. */
  html[data-font="readable"] .hh-tabbar .hh-navitem {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    letter-spacing: 0; word-spacing: 0; padding-left: 0.1rem; padding-right: 0.1rem;
  }
}

/* Roster rows: at bigger sizes a phone cannot fit the name beside the type
   picker, so every part of a row stacks full width (names stay whole). */
@media (max-width: 767px) {
  html:is([data-text="large"], [data-text="largest"]) :is(.hh-roster-row,
    .hh-roster-list--modules .hh-roster-row) { grid-template-columns: minmax(0, 1fr); gap: 0.4rem; }
  html:is([data-text="large"], [data-text="largest"]) .hh-roster-name { overflow-wrap: break-word; }
  html:is([data-text="large"], [data-text="largest"]) .hh-roster-actions { justify-content: flex-start; }
}

/* Tile grids get fewer, wider columns so a title like "GoEasyCare" is not
   split mid-word. */
html:is([data-text="large"], [data-text="largest"]) .hh-tile-title { overflow-wrap: break-word; }
@media (min-width: 768px) {
  html[data-text="largest"] .hh-tile-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1200px) {
  html[data-text="large"] .hh-tile-grid,
  html[data-text="largest"] .hh-tile-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ------------------------------------------------------ High contrast */
/* Black text on white everywhere. Brand colours survive only where they
   were already borders or icons (tiles, shelf dots, section bars). */
html[data-contrast="on"] {
  --hh-muted: #000000;
  --hh-faint: #000000;
  --hh-border: #000000;
  --hh-text: #000000;
  --hh-link: #0039A6;
}
html[data-contrast="on"] body.hh-body :where(*:not(i, svg, svg *, img, video, canvas, iframe)) {
  color: #000000 !important;
}
/* Tile and card icons keep their brand colour (icons, not text). */
html[data-contrast="on"] body.hh-body .hh-tile-icon { color: var(--tile) !important; }
html[data-contrast="on"] body.hh-body :is(.hh-site-card-icon, .hh-sec-card-icon) {
  color: var(--hh-accent, var(--hh-blue)) !important;
}
html[data-contrast="on"] body.hh-body ::placeholder { color: #000000 !important; opacity: 1 !important; }

/* Links are underlined so they are not signalled by colour alone. Tiles,
   nav items and buttons are already boxed, labelled controls. */
html[data-contrast="on"] body.hh-body a:not(.hh-tile):not(.hh-navitem):not(.hh-btn):not(.hh-skip) {
  text-decoration: underline !important;
  text-underline-offset: 0.15em;
}

/* Cards and inputs: at least a 2px black border. */
html[data-contrast="on"] body.hh-body :is(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select, textarea) {
  border: 2px solid #000000 !important;
  background-color: #FFFFFF !important;
}
html[data-contrast="on"] body.hh-body :is(.hh-card, .hh-home-card, .hh-ann-card, .hh-news-card,
  .hh-site-card, .hh-sec-card, .hh-lb-card, .hh-el-card, .hh-modal-card, .hh-pcard, .hh-section,
  .hh-notif-dd, .hh-flash, .dffb-panel, .hh-a11y-pop, .hh-btn) {
  border: 2px solid #000000 !important;
  box-shadow: none !important;
}
html[data-contrast="on"] body.hh-body .hh-tile { border-width: 3px; box-shadow: none; }
html[data-contrast="on"] body.hh-body .hh-thanks { background: #FFFFFF; border-top: 2px solid #000000; }
html[data-contrast="on"] body.hh-body .hh-tabbar { border-top: 2px solid #000000; }

/* Filled components that used white text on a brand fill become white with
   a black border, so the forced black text stays readable. Icons inside them
   go black too (they were white). */
html[data-contrast="on"] body.hh-body :is(.hh-btn-primary, .hh-manage-btn, .ms-button,
  .hh-viewer-btn:hover, .hh-tree-row.selected, .hh-avatar-initials, .hh-pcard-head,
  .hh-badge-rejected, .hh-badge-danger, .hh-tab.is-active .hh-tab-count, .hh-bell-badge,
  .hh-notif-banner, .hh-notif-banner-x, .lms-scribe-no, .hh-impersonation-banner,
  .hh-impersonation-exit, .hh-exit-actas, .hh-skip, .hh-cb-toast, .hh-elw-toast, .hh-lb-toast,
  .hh-lb-toast button, .hh-cm-table th, .hh-el-table th, .hh-gp-chip,
  .hh-lb-filter .hh-chip.is-active, .hh-lb-level:has(input:checked), .hh-news-chip.is-active,
  .pl-badge-current, .pl-badge-overdue, .pl-ask-user, .pl-ask-stop, .hh-sec-btn-primary,
  .hh-owner-chip-x:hover, .spw-pill.active, .spw-seg-btn.active, .spw-chip-new,
  .hh-plate-chip-overdue, .hh-seg button.active, .dffb-head, .dffb-btn-primary) {
  background: #FFFFFF !important;
  border: 2px solid #000000 !important;
}
html[data-contrast="on"] body.hh-body :is(.hh-btn-primary, .hh-manage-btn, .ms-button,
  .hh-avatar-initials, .hh-pcard-head, .hh-bell-badge, .hh-notif-banner, .hh-notif-banner-x,
  .hh-impersonation-banner, .hh-impersonation-exit, .hh-exit-actas, .hh-lb-toast, .hh-sec-btn-primary,
  .dffb-head, .dffb-close) i {
  color: #000000 !important;
}
/* Selected/active states that were shown by fill alone get a bold label and
   a thick underline bar, so the state is not carried by colour. */
html[data-contrast="on"] body.hh-body :is(.hh-tree-row.selected, .hh-lb-filter .hh-chip.is-active,
  .hh-lb-level:has(input:checked), .hh-news-chip.is-active, .spw-pill.active, .spw-seg-btn.active,
  .hh-seg button.active, .hh-tab.is-active) {
  font-weight: 700 !important;
  box-shadow: inset 0 -4px 0 #000000 !important;
}

/* Focus is always a thick dark-blue ring. */
html[data-contrast="on"] body.hh-body :focus-visible {
  outline: 3px solid #0039A6 !important;
  outline-offset: 2px !important;
}

/* ------------------------------------------------------ Reduce motion */
html[data-motion="reduced"] { scroll-behavior: auto !important; }
html[data-motion="reduced"] *,
html[data-motion="reduced"] *::before,
html[data-motion="reduced"] *::after {
  animation: none !important;
  transition: none !important;
  scroll-behavior: auto !important;
}
/* No lift-on-hover either. */
html[data-motion="reduced"] body.hh-body :is(.hh-tile, .dffb-launcher):hover { transform: none !important; }

/* ------------------------------------------------------ Readable font */
/* Atkinson Hyperlegible is not vendored and the CSP forbids font CDNs, so
   this uses the wide, open system faces instead. The tokens cover headings
   (display face) and body; form controls don't inherit fonts by default. */
html[data-font="readable"] {
  --hh-sans: Verdana, Tahoma, "Segoe UI", sans-serif;
  --hh-display: Verdana, Tahoma, "Segoe UI", sans-serif;
}
html[data-font="readable"] body.hh-body {
  font-family: Verdana, Tahoma, "Segoe UI", sans-serif;
  letter-spacing: 0.02em;
  word-spacing: 0.08em;
  line-height: 1.6;
}
html[data-font="readable"] body.hh-body :is(button, input, select, textarea, .dffb-panel) {
  font-family: inherit;
  letter-spacing: inherit;
  word-spacing: inherit;
}

/* ================================================================== */
/* The floating widget: launcher menu + accessibility panel.           */
/* Built by a11y.js; positioned from the launcher's live rectangle.     */
/* ================================================================== */
.hh-a11y-pop {
  position: fixed; z-index: 1085;
  background: #FFFFFF; color: #000000;
  border: 1px solid var(--hh-gray-3); border-radius: 0.9rem;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.22);
  font-family: var(--hh-sans);
}
.hh-a11y-pop[hidden] { display: none; }

/* Launcher menu: two big rows. */
.hh-a11y-menu { min-width: 15rem; padding: 0.4rem; }
.hh-a11y-menu [role="menuitem"] {
  display: flex; align-items: center; gap: 0.75rem; width: 100%;
  min-height: 48px; padding: 0.6rem 0.8rem; border: 0; border-radius: 0.6rem;
  background: #FFFFFF; color: #000000; font: inherit; font-size: 1rem;
  text-align: left; cursor: pointer;
}
.hh-a11y-menu [role="menuitem"] i { width: 1.25rem; text-align: center; color: var(--hh-dark-blue); }
.hh-a11y-menu [role="menuitem"]:hover { background: var(--hh-gray-1); }
.hh-a11y-menu [role="menuitem"]:focus-visible,
.hh-a11y-panel :focus-visible { outline: 3px solid var(--hh-dark-blue); outline-offset: 2px; }

/* Accessibility panel. */
.hh-a11y-panel { width: 22rem; max-width: calc(100vw - 24px); max-height: calc(100vh - 7rem); overflow: auto; }
.hh-a11y-head {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.9rem 1rem 0.6rem; border-bottom: 1px solid var(--hh-border);
}
.hh-a11y-head h2 { margin: 0; font-family: var(--hh-display); font-size: 1.15rem; color: #000000; }
.hh-a11y-close {
  width: 2.5rem; height: 2.5rem; border: 0; border-radius: 50%; background: #FFFFFF;
  color: #000000; font-size: 1.25rem; cursor: pointer;
}
.hh-a11y-close:hover { background: var(--hh-gray-1); }
.hh-a11y-body { padding: 0.9rem 1rem 1rem; }
.hh-a11y-note { margin: 0 0 0.8rem; font-size: 0.875rem; color: var(--hh-muted); }

.hh-a11y-group { margin: 0 0 1rem; padding: 0; border: 0; }
.hh-a11y-group legend { padding: 0; margin-bottom: 0.45rem; font-weight: 700; font-size: 0.95rem; }

/* Segmented control: three radio buttons that look like one bar. */
.hh-a11y-seg { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.35rem; }
.hh-a11y-seg label { position: relative; display: block; }
.hh-a11y-seg input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.hh-a11y-seg span {
  display: flex; align-items: center; justify-content: center; min-height: 44px;
  padding: 0.35rem 0.25rem; border: 2px solid var(--hh-gray-3); border-radius: 0.6rem;
  background: #FFFFFF; color: #000000; font-size: 0.9rem; text-align: center; line-height: 1.2;
  position: relative; pointer-events: none;
}
.hh-a11y-seg input:checked + span {
  border-color: var(--hh-dark-blue); box-shadow: inset 0 -4px 0 var(--hh-dark-blue); font-weight: 700;
}
.hh-a11y-seg input:focus-visible + span { outline: 3px solid var(--hh-dark-blue); outline-offset: 2px; }

/* Toggle rows: label + one-line description on the left, a switch on the right. */
.hh-a11y-toggle {
  display: flex; align-items: center; justify-content: space-between; gap: 0.9rem;
  padding: 0.7rem 0; border-top: 1px solid var(--hh-border); cursor: pointer;
}
.hh-a11y-toggle-text { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.hh-a11y-toggle-text strong { font-size: 0.95rem; }
.hh-a11y-toggle-text small { font-size: 0.8125rem; color: var(--hh-muted); }
.hh-a11y-switch { position: relative; flex: 0 0 auto; width: 3rem; height: 1.75rem; }
.hh-a11y-switch input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.hh-a11y-switch span {
  position: absolute; inset: 0; border-radius: 999px; background: #FFFFFF;
  border: 2px solid var(--hh-gray-10); pointer-events: none;
}
.hh-a11y-switch span::after {
  content: ""; position: absolute; top: 50%; left: 0.2rem; width: 1.1rem; height: 1.1rem;
  transform: translateY(-50%); border-radius: 50%; background: var(--hh-gray-10);
  transition: left 0.15s;
}
.hh-a11y-switch input:checked + span { border-color: var(--hh-dark-blue); background: var(--hh-dark-blue); }
.hh-a11y-switch input:checked + span::after { left: calc(100% - 1.3rem); background: #FFFFFF; }
.hh-a11y-switch input:focus-visible + span { outline: 3px solid var(--hh-dark-blue); outline-offset: 2px; }

.hh-a11y-error {
  margin: 0.6rem 0 0; padding: 0.5rem 0.7rem; border: 2px solid var(--hh-magenta);
  border-radius: 0.5rem; color: #000000; font-size: 0.875rem;
}
.hh-a11y-error[hidden] { display: none; }
.hh-a11y-status { margin: 0.5rem 0 0; min-height: 1.2em; font-size: 0.8125rem; color: var(--hh-muted); }

/* High contrast inside the panel: the "on" switch keeps a white knob on
   dark blue (not text), and the off track gets a black border. */
html[data-contrast="on"] .hh-a11y-switch span { border-color: #000000; }
html[data-contrast="on"] .hh-a11y-switch input:checked + span { background: #0039A6 !important; }
html[data-contrast="on"] .hh-a11y-seg span { border-color: #000000; }

/* Phones: the panel is a bottom sheet sitting on top of the tab bar. */
@media (max-width: 767px) {
  .hh-a11y-panel {
    left: 0 !important; right: 0 !important; top: auto !important;
    bottom: calc(68px + env(safe-area-inset-bottom)) !important;
    width: auto; max-width: none; max-height: calc(100vh - 68px - 4rem - env(safe-area-inset-bottom));
    border-radius: 1rem 1rem 0 0; border-bottom: 0;
    box-shadow: 0 -8px 28px rgba(0, 0, 0, 0.22);
  }
}
