/* ===========================
   Accessibility Utilities (WCAG 2.1 AA)
   =========================== */

/* ===========================
   Skip Navigation
   =========================== */
.skip-nav {
    position: absolute;
    top: -100px;
    left: 0;
    background: var(--g-accent-hover);
    color: white;
    padding: 0.75rem 1.5rem;
    text-decoration: none;
    font-weight: 600;
    z-index: 10000;
    border-radius: 0 0 0.375rem 0;
}

.skip-nav:focus {
    top: 0;
    outline: 3px solid var(--g-hold);
    outline-offset: 2px;
}

/* ===========================
   Focus Indicators
   ===========================

   The ring itself is primitives.css's bare `:focus-visible`. One owner, one
   appearance — it is deliberately not restated here.

   What was here before was three overlapping blocks: a ring on `:focus`, the
   same ring again on `:focus-visible`, and a `:focus:not(:focus-visible)`
   reset to undo the first for mouse users. The reset listed button/a/input/
   select/textarea — but not `[tabindex]`. <FocusOnNavigate Selector="h1"> in
   Routes.razor makes Blazor stamp `tabindex="-1"` onto the page heading and
   focus it after every navigation, so the heading matched the `:focus` ring,
   matched nothing in the reset, and every page rendered with a box drawn
   around its title.

   Dropping to `:focus-visible` alone removes that whole class of bug: with a
   single rule there is no second list to fall out of step with the first, and
   the browser decides what counts as keyboard focus instead of us
   approximating it by hand. Supported everywhere since Safari 15.4.

   Note the old element-specific ring never reached classed form fields anyway:
   `input:focus-visible` is (0,1,1) and `.form-control:focus { outline: none }`
   is (0,2,0), so the fields were always indicated by their border-colour and
   focus-ring shadow instead. That treatment is unchanged. */

/* A programmatic focus target is not a control. <FocusOnNavigate Selector="h1">
   parks focus on the page heading after every navigation so a screen reader
   announces the new page — the announcement is the point, and a ring around a
   heading only suggests it can be operated. Nothing a keyboard user can reach
   by tabbing carries tabindex="-1" (that value is what removes it from the tab
   order), so this cannot swallow a ring anyone needs. */
[tabindex="-1"]:focus,
[tabindex="-1"]:focus-visible {
    outline: none;
}

/* Error states keep their own colour, on the same keyboard-only gate. */
input:invalid:focus-visible,
select:invalid:focus-visible,
textarea:invalid:focus-visible {
    outline: 3px solid var(--g-alert);
    outline-offset: 2px;
}

/* ===========================
   Screen Reader Only
   =========================== */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border-width: 0;
}

/* Make visible when focused (for skip links) */
.sr-only-focusable:focus {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip: auto;
    white-space: normal;
}

/* ===========================
   High Contrast Mode Support
   =========================== */
@media (prefers-contrast: high) {
    /* Increase border thickness */
    button,
    input,
    select,
    textarea,
    .card,
    .modal {
        border-width: 2px;
    }

    /* Stronger focus indicators */
    *:focus-visible {
        outline-width: 4px;
    }

    /* Remove subtle backgrounds */
    .bg-subtle,
    .bg-light {
        background: white !important;
        border: 2px solid black;
    }
}

/* ===========================
   Reduced Motion
   =========================== */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ===========================
   Touch Target Sizing
   ===========================

   Opt-in, and sizing only.

   This block used to list `button, a, .btn` alongside `.touch-target`, and set
   display/align/justify on all of them. Two kinds of damage came out of that.

   Every inline link in prose became a 44px-tall inline-flex box with a 44px
   floor on its width, so it could no longer wrap mid-sentence. WCAG 2.2 SC
   2.5.8 asks for 24x24 and explicitly exempts links inside a sentence; the
   44x44 figure is SC 2.5.5, which is AAA and aimed at standalone controls.

   And `display: inline-flex` silently beat `.public-nav-burger { display: none }`
   — same specificity, and this file loads later — so the mobile menu burger
   rendered on desktop, where `align-items: center` then collapsed its three
   bars to zero width. It read as an empty box next to the logo.

   Setting no display or alignment here means this rule can never rewrite a
   component's layout again. The button classes (.g-btn, .public-btn, .btn)
   each set their own, and their padding already clears the minimum. */
.touch-target {
    min-height: 44px;
    min-width: 44px;
}

/* Buttons still centre their content, so an icon and its label sit on one
   optical line — several one-off buttons (.icon-btn, .toast-close) never set
   this themselves and were relying on the block above for it.

   As a bare element selector this is specificity (0,0,1), the weakest thing
   in the sheet, so any class rule overrides it. That is the whole difference
   from what was here before: `.touch-target` is (0,1,0), strong enough to beat
   a component's own `display` on load order alone. Anchors are deliberately
   left out — an <a> in a sentence must stay inline and wrap with the text. */
button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* ===========================
   Form Accessibility
   =========================== */

/* Required field indicator */
.form-label.required::after {
    content: " *";
    color: var(--g-alert);
    font-weight: 700;
}

/* Error state */
input:invalid,
select:invalid,
textarea:invalid {
    border-color: var(--g-alert) !important;
    border-width: 2px;
}

.field-error {
    color: var(--g-alert);
    font-size: 0.875rem;
    margin-top: 0.25rem;
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.field-error::before {
    content: "⚠";
    font-weight: 700;
}

/* High contrast warning color */
@media (prefers-contrast: high) {
    .field-error {
        background: var(--g-alert-wash);
        border: 2px solid var(--g-alert);
        padding: 0.5rem;
        border-radius: 0.25rem;
    }
}

/* ===========================
   ARIA Live Regions
   =========================== */
.live-region {
    position: absolute;
    left: -10000px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

[aria-live="polite"],
[aria-live="assertive"] {
    /* Ensure live regions are announced */
    position: relative;
}

/* ===========================
   Table Accessibility
   =========================== */
table caption {
    padding: 0.75rem;
    text-align: left;
    font-weight: 600;
    background: var(--g-surface-2);
    border-bottom: 2px solid var(--g-border);
}

/* Zebra striping for better readability */
tbody tr:nth-child(even) {
    background: var(--g-surface-2);
}

/* Mark the row a keyboard user is working inside. `:focus-within` alone would
   also fire on a mouse click of any button in the row, outlining the whole row
   on top of whatever the button already shows. */
tr:has(:focus-visible) {
    outline: 2px solid var(--g-accent);
    outline-offset: -2px;
}

/* ===========================
   Color Contrast Utilities
   =========================== */

/* WCAG AA Compliant Color Pairings */
.text-high-contrast {
    color: var(--g-text); /* 4.5:1 on white */
}

.text-aa-large {
    color: var(--g-text-muted); /* 3:1 on white (for large text) */
}

.bg-high-contrast {
    background: var(--g-text);
    color: white;
}

/* ===========================
   Tooltips & Hints
   =========================== */
.tooltip-trigger {
    position: relative;
    display: inline-block;
}

.tooltip-content {
    position: absolute;
    background: var(--g-text);
    color: white;
    padding: 0.5rem 0.75rem;
    border-radius: 0.375rem;
    font-size: 0.875rem;
    white-space: nowrap;
    z-index: 1000;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s;
}

.tooltip-trigger:hover .tooltip-content,
.tooltip-trigger:focus .tooltip-content {
    opacity: 1;
}

/* High contrast tooltips */
@media (prefers-contrast: high) {
    .tooltip-content {
        border: 2px solid white;
    }
}

/* ===========================
   Loading States
   =========================== */
.loading-spinner {
    display: inline-block;
    width: 1.5rem;
    height: 1.5rem;
    border: 3px solid var(--g-border);
    border-top-color: var(--g-accent);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

/* Disable animation for reduced motion */
@media (prefers-reduced-motion: reduce) {
    .loading-spinner {
        animation: none;
        border-top-color: var(--g-accent);
    }
}

/* Loading text for screen readers */
.loading-text {
    position: absolute;
    left: -10000px;
}

[aria-busy="true"] {
    position: relative;
}

/* ===========================
   Status Messages
   =========================== */
.status-message {
    padding: 1rem;
    border-radius: 0.5rem;
    border: 2px solid transparent;
    margin-bottom: 1rem;
}

.status-success {
    background: var(--g-live-wash);
    color: var(--g-live);
    border-color: var(--g-live);
}

.status-error {
    background: var(--g-alert-wash);
    color: var(--g-alert);
    border-color: var(--g-alert);
}

.status-warning {
    background: var(--g-hold-wash);
    color: var(--g-hold);
    border-color: var(--g-hold);
}

.status-info {
    background: var(--g-accent-wash);
    color: var(--g-accent);
    border-color: var(--g-accent);
}

/* Icon indicators */
.status-message::before {
    font-weight: 700;
    margin-right: 0.5rem;
}

.status-success::before {
    content: "✓";
}

.status-error::before {
    content: "✕";
}

.status-warning::before {
    content: "⚠";
}

.status-info::before {
    content: "ℹ";
}

/* ===========================
   Keyboard Navigation Helpers
   =========================== */

/* Highlight focusable elements in development */
[data-keyboard-nav-debug="true"] *:focus {
    outline: 3px dashed var(--g-hold) !important;
    outline-offset: 4px !important;
}

/* Tab order indicator */
[data-show-tab-order="true"] [tabindex]::after {
    content: attr(tabindex);
    position: absolute;
    top: -8px;
    right: -8px;
    background: var(--g-hold);
    color: white;
    font-size: 10px;
    padding: 2px 4px;
    border-radius: 50%;
    font-weight: 700;
}
