/* ==========================================================================
   a11y-fixes.css — Bambo Booking, Phase 1 accessibility / contrast quick wins
   CSS ONLY. Loaded by includes/header.php (staff) and by a <link> in each of the 10 public/customer pages (hook H1).
   NOTE: public pages (index, book, login…) have their own <style> blocks that
   come AFTER any <link>, so to win the cascade this file (a) uses the exact legacy
   selector prefixed with "html body" (+0,0,2 specificity) and (b) uses !important
   only where the legacy rule is itself !important, is an inline style="" attribute,
   or where we must replace "outline:none" / ring shadows that legacy :hover rules touch.
   Rollback: delete the <link> line in includes/header.php and the 10 page links (file can then be removed).
   Theme: dark navy / gold is unchanged. Only focus, contrast, size floors, motion.
   Generated tables of every pair: PHASE1-CHANGES-design.md (and verify script).
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. TOKENS  (A-04 / A-09)
   html:root (0,1,1) beats the per-page ":root{…}" copies (0,1,0) that legacy pages
   declare inside their own <style>, so ONE override fixes every var(--muted) etc.
   -------------------------------------------------------------------------- */
html:root{
  /* text colours lifted just enough to reach >=4.5:1 on navy-deep/mid/light AND on
     their own 8-15% tints (badges, alerts). Hue/saturation kept. */
  --muted:   #A0B1C6;   /* was #7A8FA8 (3.76-4.13:1 on navy-mid/light) */
  --danger:  #FF8A7B;   /* was #E74C3C (3.27-3.59:1) — also used for borders (slightly lighter coral) */
  --success: #43D081;   /* was #27AE60 (4.35:1 on navy-light, 4.1 on tint) */
  --info:    #6DB8EA;   /* was #3498DB (3.97:1) */
  --gold-dark: #A8842B;  /* was #8B6A1F: gradient end stop under navy button text 3.59 -> 5.16:1 */
  /* focus ring: two-tone. light-gold ring + navy gap so it reads on dark surfaces AND on gold fills */
  --a11y-ring: #E8C96A;        /* 11.2:1 on navy-deep, 8.5:1 on navy-mid, 7.7:1 on navy-light */
  --a11y-ring-gap: #0D1628;    /* navy-deep gap: 7.9:1 vs gold fill, 11.2:1 vs ring */
  --a11y-ring-w: 3px;
  --a11y-ring-off: 2px;
  --a11y-border: #93803F;      /* control border: 4.65:1 navy-deep, 3.53:1 navy-mid, 3.21:1 navy-light */
  --a11y-placeholder: #93A5BB;
}
html{ scroll-padding-top: 7rem; }  /* sticky headers (A-09 / WCAG 2.4.11): focused items are not hidden under them */

/* --------------------------------------------------------------------------
   1. FOCUS RING  (A-09, 25 outline:none rules; B-02)
   Ring = 3px light-gold outline + 2px navy gap (box-shadow) => pair-wise >=3:1 on every
   surface used (verified in verify-a11y.js). !important: legacy rules such as
   ".form-group input:focus{outline:none}" and ".btn:hover{box-shadow:…}" must lose.
   -------------------------------------------------------------------------- */
html body :is(a[href], button, input, select, textarea, summary, [tabindex]:not([tabindex="-1"]),
              [role="button"], [role="tab"], [role="link"], [role="switch"], [contenteditable="true"],
              .btn, .option-card, .calendar-day, .type-btn, .gallery-item, .sidebar-nav a):focus-visible{
  outline: var(--a11y-ring-w) solid var(--a11y-ring) !important;
  outline-offset: var(--a11y-ring-off) !important;
  box-shadow: 0 0 0 var(--a11y-ring-off) var(--a11y-ring-gap) !important;
}
/* text fields: keep the legacy gold border on focus too, ring sits outside */
html body :is(input, select, textarea):focus-visible{ border-color: var(--gold) !important; }
/* elements that clip their own outline: draw the ring inside instead */
/* R3 (follow-up): the generic ring rule above has specificity (0,3,2) because :is() takes its most specific member
   ([tabindex]:not([tabindex="-1"])). This rule was (0,2,3) and never applied, so the ring was drawn outside and clipped by
   overflow containers. ":focus-visible:focus-visible" raises it to (0,3,3) so it wins. */
html body :is(.sidebar-nav a, .nav-link, .tab, .fc-button, .fc-event, td a, th a):focus-visible:focus-visible{
  outline-offset: -3px !important;
  box-shadow: inset 0 0 0 2px var(--a11y-ring-gap) !important;
}
/* 1b. hidden-input controls: ring the visible control that wraps / follows the real input */
/* toggle switches (admin/schedule.php:212, barber/schedule.php:240): <input> is opacity:0 */
html body .toggle-switch input:focus-visible + .toggle-slider{
  outline: var(--a11y-ring-w) solid var(--a11y-ring) !important;
  outline-offset: var(--a11y-ring-off) !important;
  box-shadow: 0 0 0 var(--a11y-ring-off) var(--a11y-ring-gap) !important;
}
html body .toggle-switch input:focus-visible{ outline: none !important; box-shadow: none !important; } /* the slider carries the ring; input is 0x0 */
/* file drop-zone (admin/gallery.php:208): input is an invisible full-size overlay */
html body .upload-zone:has(input:focus-visible){
  outline: var(--a11y-ring-w) solid var(--a11y-ring) !important; outline-offset: var(--a11y-ring-off) !important;
  box-shadow: 0 0 0 var(--a11y-ring-off) var(--a11y-ring-gap) !important;
}
html body .upload-zone input:focus-visible{ outline: none !important; box-shadow: none !important; }
/* time-slot radios (public/book.php): TJ's visually-hidden radio + label. Replace the #0b3d91 ring
   (1.8:1 on navy) with ours. Selected slots are gold fills: the navy gap keeps the ring separated. */
html body .slot-option:has(input:focus-visible){
  outline: var(--a11y-ring-w) solid var(--a11y-ring) !important;
  outline-offset: var(--a11y-ring-off) !important;
  box-shadow: 0 0 0 var(--a11y-ring-off) var(--a11y-ring-gap) !important;
}
html body .slot-option.selected:has(input:focus-visible),
html body .slot-option:has(input:checked:focus-visible){
  box-shadow: inset 0 0 0 2px var(--a11y-ring-gap), 0 0 0 var(--a11y-ring-off) var(--a11y-ring-gap) !important;
}
/* R1 (follow-up): .slots-grid has no gap and every .slot-option is position:relative, so later siblings painted over the
   ring (bottom/right sides invisible). Lift the focused slot above its neighbours. */
html body .slot-option:has(input:focus-visible){ z-index: 1; }
@supports not selector(:has(*)){
  html body .slot-option:focus-within{ z-index: 1; }
  html body .slot-option:focus-within{ outline: var(--a11y-ring-w) solid var(--a11y-ring) !important; outline-offset: var(--a11y-ring-off) !important; box-shadow: 0 0 0 var(--a11y-ring-off) var(--a11y-ring-gap) !important; }
}
/* TJ's ring on book.php controls used #0b3d91 + white halo: same selectors, ours wins by !important + later load */
html body .form-group input:focus-visible, html body .form-group textarea:focus-visible,
html body .btn-nav:focus-visible, html body .option-card:focus-visible,
html body .calendar-day:focus-visible, html body .back-link:focus-visible{
  outline: var(--a11y-ring-w) solid var(--a11y-ring) !important;
  outline-offset: var(--a11y-ring-off) !important;
  box-shadow: 0 0 0 var(--a11y-ring-off) var(--a11y-ring-gap) !important;
}
/* N1 (Phase 2, Designer finding): .calendar-grid has no gap, so later day cells painted over the right/bottom sides of the focus
   ring. Same fix as .slot-option: lift the focused day above its neighbours. No ancestor clips it (.calendar-grid has no overflow). */
html body .calendar-day:focus-visible{ position: relative; z-index: 1; }
/* chat widget (chat.css:264/268 outline:none) */
html body #bl-chat-input:focus-visible, html body #bl-chat-send:focus-visible, html body #bl-chat-close:focus-visible,
html body #bl-chat-bubble:focus-visible, html body .bl-quick:focus-visible{
  outline: var(--a11y-ring-w) solid var(--a11y-ring) !important; outline-offset: var(--a11y-ring-off) !important;
  box-shadow: 0 0 0 var(--a11y-ring-off) var(--a11y-ring-gap) !important; border-color: var(--a11y-ring) !important;
}
/* mouse users: no ring on plain click for buttons/links (focus-visible heuristic) — nothing to add */

/* --------------------------------------------------------------------------
   2. FONT-SIZE FLOOR 12px (0.75rem)   (D-04 / A-04)
   Only selectors the audit (extract.js / fs-report.txt) found below 12px. No "*" rule.
   Where a selector name is reused at >=12px on other pages (.btn-submit, .btn-ghost,
   .back-link) it is scoped with body:has(<page-only element>) so larger sizes are NOT shrunk.
   Heavily tracked (>=0.2em) uppercase labels raised from <10px also get letter-spacing:.14em to
   offset the wider glyphs (overflow guard).
   -------------------------------------------------------------------------- */
html body #bl-chat-badge,
html body #bl-chat-powered,
html body .action-btn,
html body .admin-lock,
html body .admin-lock i,
html body .alert-success .btn-secondary,
html body .amb-attr,
html body .back-btn,
html body .badge,
html body .badge-admin,
html body .badge-barber,
html body .badge-recurring,
html body .badge-single,
html body .barber-badge .back,
html body .barber-btn,
html body .barber-filter span,
html body .barber-info small,
html body .barber-quote,
html body .bl-chat-status,
html body .bl-quick,
html body .blocked-table th,
html body .booking-date-badge .month,
html body .brand-sub,
html body .btn,
html body .btn-book,
html body .btn-cancel,
html body .btn-gold,
html body .btn-nav,
html body .btn-nav-account,
html body .btn-nav-disabled,
html body .btn-sm,
html body .calendar-day .day-dow,
html body .calendar-header,
html body .customer-info small,
html body .data-table th,
html body .divider,
html body .f-book-cta,
html body .f-col-h,
html body .f-copy,
html body .f-est,
html body .f-legal a,
html body .f-links a,
html body .f-soc,
html body .f-tag,
html body .fc .fc-button,
html body .fc .fc-col-header-cell-cushion,
html body .fc .fc-timegrid-axis-cushion,
html body .fc .fc-timegrid-slot-label,
html body .fc .fc-timegrid-slot-label-cushion,
html body .fc th,
html body .fc-event,
html body .fc-event-time,
html body .fc-event-title,
html body .field-hint,
html body .filter-group label,
html body .filter-toggle,
html body .form-group label,
html body .form-label,
html body .gold-divider i,
html body .hero-loc,
html body .hero-scroll span,
html body .hero-vert-l,
html body .hero-vert-r,
html body .hint,
html body .history-date,
html body .history-table th,
html body .info-lbl,
html body .label-gold,
html body .legend-item,
html body .lightbox-caption,
html body .lightbox-counter,
html body .link-gold,
html body .loyalty-meta,
html body .marquee-track span,
html body .mini-footer p,
html body .mini-footer-links a,
html body .modal-actions .btn,
html body .modal-label,
html body .modal-tag,
html body .nav-link,
html body .nav-links a,
html body .nav-sub,
html body .option-card.selected::after,
html body .page-hero .badge,
html body .photo-order,
html body .photo-status,
html body .privacy,
html body .privacy-note,
html body .progress-text,
html body .public-header p,
html body .result-count,
html body .reward-badge,
html body .right-card h4,
html body .schedule-table th,
html body .section-num,
html body .sidebar-section,
html body .slot-status-text,
html body .slots-title,
html body .stat-card .stat-label,
html body .stat-label,
html body .status-badge,
html body .step-label,
html body .step-subtitle,
html body .strength-text,
html body .subtitle,
html body .summary h4,
html body .svc-meta,
html body .svc-num,
html body .tc-idx,
html body .tc-role,
html body .toc h3,
html body .type-btn-title,
html body .user-name,
html body .user-role,
html body label,
html body th{ font-size: 0.75rem; }
/* legacy rule is !important */
html body .staff-link{ font-size: 0.75rem !important; }
/* name reused at >=12px elsewhere => page-scoped */
html body:has(#hero) .btn-ghost,
html body:has(.brand-sub) .back-link,
html body:has(.brand-sub) .btn-submit,
html body:has(.form-control) .btn-submit,
html body:has(.login-box) .back-link,
html body:has(.login-box) .btn-submit{ font-size: 0.75rem; }
/* inline style="font-size:<0.75rem" (index.php, barber/dashboard.php, footer.php, …): attribute match, !important needed to beat inline */
[style*="font-size:0.45rem"],
[style*="font-size:0.5rem"],
[style*="font-size:0.52rem"],
[style*="font-size:0.55rem"],
[style*="font-size: 0.55rem"],
[style*="font-size:0.58rem"],
[style*="font-size:0.6rem"],
[style*="font-size:0.65rem"],
[style*="font-size: 0.65rem"],
[style*="font-size:0.68rem"],
[style*="font-size:0.7rem"],
[style*="font-size:0.72rem"],
[style*="font-size:0.74rem"]{ font-size: 0.75rem !important; }
/* inline "0.8em" hints (e.g. "(optionnel)" inside a label): em of a 12px label is 9.6px, so floor it */
html body [style*="font-size:0.8em"]{ font-size: max(12px, 0.8em) !important; }
/* restore sizes that our generic '.form-group label' floor would otherwise shrink (admin/blocked-slots.php:326 weekday chips are 0.8rem) */
html body .weekday-checkbox label{ font-size: 0.8rem; }
/* overflow guards */
html body .form-group label,
html body th,
html body .alert-success .btn-secondary,
html body .filter-group label,
html body .modal-label,
html body .barber-filter span,
html body .fc .fc-button,
html body .fc th,
html body .modal-tag,
html body .stat-label,
html body .photo-order,
html body .schedule-table th,
html body .blocked-table th,
html body .label-gold,
html body .badge,
html body .btn-gold,
html body:has(#hero) .btn-ghost,
html body .btn,
html body .nav-sub,
html body .nav-links a,
html body .btn-nav,
html body .hero-vert-l,
html body .hero-vert-r,
html body .hero-loc,
html body .hero-scroll span,
html body .marquee-track span,
html body .amb-attr,
html body .svc-num,
html body .svc-meta,
html body .tc-idx,
html body .tc-role,
html body .info-lbl,
html body .f-est,
html body .f-col-h,
html body .f-copy,
html body .f-book-cta,
html body .btn-nav-account,
html body .subtitle,
html body label,
html body:has(.login-box) .btn-submit,
html body .public-header p,
html body .step-label,
html body .step-subtitle,
html body .calendar-header,
html body .btn-nav-disabled,
html body:has(.brand-sub) .back-link,
html body .brand-sub,
html body .link-gold,
html body .back-btn,
html body .page-hero .badge,
html body .section-num,
html body .data-table th,
html body .mini-footer p{ letter-spacing: 0.14em; }
@media (min-width: 769px) and (max-width: 1100px){ html body .nav-links{ gap: 18px; } }  /* index.php nav: 12px links + 34px gaps would wrap */
@media (max-width: 640px){ html body .nav-link{ letter-spacing: .08em; padding: 10px 8px; } } /* staff nav wraps (flex-wrap) — keep it compact */

/* --------------------------------------------------------------------------
   3. CONTRAST  (A-04, A-03, D-07)
   Variables (--muted/--danger/--success/--info/--gold-dark) are fixed in section 0.
   Below: hard-coded hex / rgba pairs that do not use those variables.
   -------------------------------------------------------------------------- */
html body .badge-single,
html body .info-box i{ color: #6DB8EA; }
html body .badge-recurring,
html body .status-no-show,
html body .action-btn-noshow{ color: #C8A2D8; }
html body .status-confirmed,
html body .alert-success,
html body .success-box{ color: #43D081; }
html body .status-completed,
html body #bl-chat-close,
html body #bl-chat-powered,
html body .privacy,
html body .back-link,
html body .logo-wrap p,
html body .btn-ghost,
html body .links,
html body .divider,
html body .privacy-note,
html body .privacy-note a,
html body .hint{ color: #A0B1C6; }
html body .status-cancelled,
html body .error-message,
html body .btn-cancel,
html body .alert-error,
html body .error-box,
html body .invalid-icon{ color: #FF8A7B; }
html body .staff-link{ color: #A0B1C6 !important; }
html body .hero-vert-l,
html body .hero-vert-r,
html body .hero-scroll span{ color: #AF9447; }
html body .avatar-circle.inactive{ color: #F7F0E0; } /* text on rgba(122,143,168,.3) over navy-mid: 2.7 -> 10:1 */
/* navy text on gold gradients that hard-code #8B6A1F as end stop (login/register/dashboard/chat) */
html body .btn-submit, html body .btn-book, html body .btn-save, html body #bl-chat-send, html body .bl-msg.user, html body .btn-gold, html body .f-book-cta{
  background-image: linear-gradient(135deg, #E8C96A, #C9A84C, #A8842B);
}
html body .btn-gold, html body .f-book-cta, html body .marquee-band{ --gold-dark: #A8842B; }
html body .marquee-band{ background: linear-gradient(90deg, #A8842B, #C9A84C, #A8842B); }
/* placeholders: >=4.5:1 on every field fill (navy-deep, chat #1A2740, login staff input, mid) */
html body ::placeholder{ color: var(--a11y-placeholder) !important; opacity: 1 !important; }
/* footnote-ish inline opacity on text */
html body footer > p[style*="opacity"]{ opacity: 1 !important; }
html body [style*="font-size:0.8em"][style*="opacity:0.6"]{ opacity: .86 !important; } /* gold hint text: 4.65:1 worst case */
/* control boundaries (WCAG 1.4.11): legacy rgba(201,168,76,.18-.3) borders are 1.0-1.5:1 */
html body :is(input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="file"]):not([type="submit"]):not([type="button"]), select, textarea):not(:focus):not(:disabled):not([aria-invalid="true"]){
  border-color: var(--a11y-border) !important;
}
/* R5 (follow-up): :not(:hover) keeps the legacy gold hover border (this rule outranked the legacy :hover rules) */
html body :is(.slot-option:not(.selected):not(:hover), .calendar-day:not(.selected):not(.disabled):not(:hover), .option-card:not(.selected):not(:hover), .type-btn:not(.active):not(:hover), .toggle-slider, .btn-icon, .btn-delete, .btn-nav-secondary, .btn-ghost){
  border-color: var(--a11y-border);
}
html body .toggle-switch input:checked + .toggle-slider{ border-color: var(--gold) !important; }
html body .code-input:not(:focus){ border-color: var(--a11y-border) !important; }

/* --------------------------------------------------------------------------
   4. REDUCED MOTION  (A-05)   — also stops the bounce/pulse/blink loops
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto !important; }
  *, *::before, *::after{
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
  .hero-scroll, .btn-gold, .bl-chat-status::before, .bl-cursor, .bl-typing span{ animation: none !important; }
  .reveal{ opacity: 1 !important; transform: none !important; }   /* no scroll-triggered movement */
}
/* 4b. no-JS: .reveal starts at opacity:0 and only JS adds .in (index.php:259). CSS-only, noscript-free: */
@media (scripting: none){ .reveal{ opacity: 1 !important; transform: none !important; } }

/* --------------------------------------------------------------------------
   5. MARQUEE (index.php:146-156)  WCAG 2.2.2 (pause button in index.php; reduced-motion handled here)
   -------------------------------------------------------------------------- */
/* R4 (follow-up): the old hover/focus-within auto-pause is REMOVED. index.php now has a real pause/resume button
   (.marquee-toggle, .is-paused at index.php:155) which satisfies WCAG 2.2.2. The auto-pause kept the ticker paused while the
   pointer/focus was still on the band, so "Reprendre" could not resume it. Pausing is now solely controlled by the button. */
@media (prefers-reduced-motion: reduce){
  html body .marquee-track{ animation: none !important; transform: none !important; }
  html body .marquee-band{ overflow-x: auto; }   /* items no longer move; all remain reachable by scrolling */
}

/* --------------------------------------------------------------------------
   6. CUSTOMER DASHBOARD NAV <768px  (U-11)  public/dashboard.php:293 hides .sidebar entirely.
   Restore the same <nav class="sidebar-nav"> as a horizontally scrollable tab bar, 44px targets.
   -------------------------------------------------------------------------- */
@media (max-width: 768px){
  html body .dash-layout .sidebar{
    display: block !important; position: static; width: 100%; height: auto; overflow: visible;
    padding: 0; border-right: 0; border-bottom: 1px solid rgba(201,168,76,0.25);
  }
  html body .dash-layout .sidebar-nav{
    display: flex; flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity; scrollbar-width: thin; padding: 0 8px;
    position: relative;   /* R2 (follow-up): containing block for the absolutely positioned .sr-only prefixes, otherwise they escape overflow-x:auto and widen the page (scrollWidth 710 at 390px) */
  }
  html body .dash-layout .sidebar-nav a{
    flex: 0 0 auto; white-space: nowrap; min-height: 44px; padding: 0 16px; scroll-snap-align: start;
    border-left: 0; border-bottom: 3px solid transparent;
  }
  html body .dash-layout .sidebar-nav a:hover, html body .dash-layout .sidebar-nav a.active{ border-left-color: transparent; border-bottom-color: var(--gold); }
  html body .dash-layout .sidebar-section{ display: none; }  /* group captions would break the single row; see doc */
}

/* --------------------------------------------------------------------------
   7. BONUS: 44px tap targets <768px, forced-colors
   -------------------------------------------------------------------------- */
@media (max-width: 768px){
  html body :is(.btn, .btn-nav, .btn-gold, .btn-ghost, .btn-submit, .btn-book, .btn-save, .btn-cancel, .btn-primary,
                .btn-nav-account, .btn-modal-cancel, .btn-modal-confirm, .nav-link, .logout-btn, .btn-logout,
                .btn-icon, .btn-delete, .btn-sm, .action-btn, .f-soc, .hamburger, .mob-x, .lightbox-close){
    min-height: 44px; min-width: 44px;
  }
  html body :is(.btn-cancel, .btn-book, .btn-nav-account, .btn-logout, .btn-modal-cancel, .btn-modal-confirm){
    display: inline-flex; align-items: center; justify-content: center;
  }
  html body .hamburger{ align-items: center; justify-content: center; }
  html body .slot-option{ min-height: 44px; }
}
@media (forced-colors: active){
  html body *:focus-visible{ outline: 3px solid Highlight !important; outline-offset: 2px !important; box-shadow: none !important; }
  html body .toggle-slider, html body .slot-option, html body .calendar-day, html body .option-card{ border-color: ButtonText; }
  html body .toggle-switch input:checked + .toggle-slider{ border-color: Highlight !important; }
}
