/* ============================================================
   preferences.css — User-controllable display & accessibility
   ------------------------------------------------------------
   Every preference is expressed as a data-* attribute (or CSS
   custom property) on <html>, set before first paint by the
   inline script in _Layout and thereafter by preferences.js.
   This keeps the whole system declarative and easy to extend:
   add a new attribute here + a new entry in the JS registry.
   ============================================================ */

/* ---- Text scaling -------------------------------------------------
   Overrides the base html font-size (rem cascade scales the whole UI).
   Loaded after site.css so this wins. Range is clamped in JS. */
:root {
    --user-font-scale: 1;
}

html {
    font-size: calc(14px * var(--user-font-scale));
}

@media (min-width: 768px) {
    html {
        font-size: calc(16px * var(--user-font-scale));
    }
}

/* ---- Skip to content link (first focusable in <body>) ------------- */
.skip-link {
    position: absolute;
    left: 0.75rem;
    top: -3.5rem;
    z-index: 2000;
    background: var(--accent-on-fill);
    color: #fff;
    padding: 0.55rem 1rem;
    border-radius: 0 0 8px 8px;
    font-weight: 600;
    text-decoration: none;
    transition: top 0.15s ease;
}

.skip-link:focus {
    top: 0;
    color: #fff;
    outline: 3px solid #fff;
    outline-offset: 2px;
}

/* ---- Theme-switch transition suppression --------------------------
   A theme switch changes custom properties, not declarations. Chrome does
   not restart a running transition when only the var() behind a property
   changes, so anything transitioning color/background keeps the OLD palette
   until the next full render — body text and .btn-outline-accent both stuck
   at the light-mode green after switching to dark, dropping that button from
   6.46:1 to 2.29:1. Transitions are suppressed for the one frame the switch
   takes, which forces every consumer to resolve against the new values. */
html.theme-switching,
html.theme-switching *,
html.theme-switching *::before,
html.theme-switching *::after {
    transition: none !important;
}

/* ---- Keyboard focus visibility -----------------------------------
   Only for keyboard users (:focus-visible), so mouse clicks stay clean. */
:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 2px;
    border-radius: 2px;
}

/* ---- Underline links preference ----------------------------------- */
html[data-underline="on"] a:not(.btn):not(.navbar-brand):not(.nav-link):not(.dropdown-item) {
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

/* ---- Readable font & spacing preference --------------------------- */
html[data-readable="on"] body,
html[data-readable="on"] .btn,
html[data-readable="on"] .form-control,
html[data-readable="on"] input,
html[data-readable="on"] textarea,
html[data-readable="on"] select {
    font-family: 'Atkinson Hyperlegible', 'Verdana', 'Tahoma', 'Segoe UI', sans-serif;
}

html[data-readable="on"] body {
    letter-spacing: 0.02em;
    word-spacing: 0.08em;
    line-height: 1.8;
}

/* ---- High-contrast preference ------------------------------------
   Re-points the palette variables on the themed element so every
   var(--text)/var(--surface)/... consumer picks it up automatically. */
html[data-contrast="high"] body:not(.dark-mode) {
    --text: #000000;
    --text-muted: #161616;
    --border: #000000;
    --background: #ffffff;
    --surface: #ffffff;
    --shadow: rgba(0, 0, 0, 0.4);
}

html[data-contrast="high"] body.dark-mode {
    --text: #ffffff;
    --text-muted: #f2f2f2;
    --border: #ffffff;
    --background: #000000;
    --surface: #0b0b0b;
    --shadow: rgba(0, 0, 0, 0.9);
}

html[data-contrast="high"] a:not(.btn) {
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

html[data-contrast="high"] .btn {
    border-width: 2px;
}

html[data-contrast="high"] .text-muted {
    color: var(--text-muted) !important;
}

html[data-contrast="high"] *:focus-visible {
    outline-width: 4px;
}

/* ---- Reduced-motion preference -----------------------------------
   Honour the OS setting by default, and let the user force it on. */
@media (prefers-reduced-motion: reduce) {
    html:not([data-motion="no-pref"]) *,
    html:not([data-motion="no-pref"]) *::before,
    html:not([data-motion="no-pref"]) *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}

html[data-motion="reduce"] *,
html[data-motion="reduce"] *::before,
html[data-motion="reduce"] *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
}

/* Neutralize the scroll fade-in so content is never stuck hidden. */
html[data-motion="reduce"] .fade-in {
    opacity: 1 !important;
    transform: none !important;
}

/* ============================================================
   Preferences controls
   ------------------------------------------------------------
   One shared partial, rendered on the public /Accessibility page
   and inside the signed-in profile card. Sizing is in rem so the
   panel scales with the very text-size setting it contains.
   ============================================================ */
.prefs-controls {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.pref-block {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.pref-block__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.pref-block__title {
    display: block;
    margin: 0;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.pref-block__hint {
    margin: 0;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.pref-block--footer {
    padding-top: 1.25rem;
    border-top: 1px solid var(--border);
}

/* ---- Segmented control (theme) ------------------------------------ */
.pref-seg {
    display: flex;
    gap: 0.35rem;
    padding: 0.3rem;
    background: var(--background);
    border: 1px solid var(--border);
    border-radius: 10px;
}

.pref-seg__btn {
    flex: 1 1 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.55rem 0.75rem;
    border: 1px solid transparent;
    border-radius: 7px;
    background: transparent;
    color: var(--text);
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color var(--transition), color var(--transition), border-color var(--transition);
}

.pref-seg__btn:hover:not([aria-pressed="true"]) {
    background: var(--accent-soft);
    color: var(--accent-text);
}

.pref-seg__btn[aria-pressed="true"] {
    background: var(--accent-on-fill);
    border-color: var(--accent-on-fill);
    color: #fff;
    box-shadow: 0 1px 4px var(--shadow);
}

.pref-seg__btn:active {
    transform: translateY(1px);
}

/* ---- Text size ---------------------------------------------------- */
.pref-badge {
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent-text);
    font-size: 0.85rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.pref-range-row {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

.pref-range-row input[type="range"] {
    flex: 1 1 auto;
    min-width: 0;
    height: 1.75rem;
    accent-color: var(--accent-on-fill);
    cursor: pointer;
}

.pref-range-cap {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-weight: 700;
    line-height: 1;
}

.pref-range-cap--sm { font-size: 0.85rem; }
.pref-range-cap--lg { font-size: 1.4rem; }

/* ---- Switch rows -------------------------------------------------- */
.pref-switches {
    list-style: none;
    margin: 0;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
}

.pref-switch {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.25rem;
    padding: 0.9rem 1rem;
    background: var(--surface);
    transition: background-color var(--transition);
}

.pref-switch + .pref-switch {
    border-top: 1px solid var(--border);
}

.pref-switch:hover,
.pref-switch:focus-within {
    background: var(--background);
}

.pref-switch__text {
    min-width: 0;
}

.pref-switch__label {
    display: block;
    margin: 0;
    font-weight: 600;
    color: var(--text);
    cursor: pointer;
}

.pref-switch__hint {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.82rem;
    line-height: 1.45;
    color: var(--text-muted);
}

/* Bootstrap's .form-switch reserves left padding for a check it no longer
   needs here — the switch is the only thing in this column. */
.pref-switch__control {
    flex: 0 0 auto;
    min-height: 0;
    margin: 0;
    padding-left: 0;
}

.pref-switch__control .form-check-input {
    width: 2.6rem;
    height: 1.45rem;
    margin: 0.1rem 0 0;
    background-color: var(--border);
    border-color: var(--border);
    cursor: pointer;
    transition: background-color var(--transition), border-color var(--transition);
}

.pref-switch__control .form-check-input:checked {
    background-color: var(--accent-on-fill);
    border-color: var(--accent-on-fill);
}

/* ---- Reset -------------------------------------------------------- */
.prefs-reset-btn {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 1.15rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: transparent;
    color: var(--text);
    font-weight: 600;
    transition: border-color var(--transition), color var(--transition), background-color var(--transition);
}

.prefs-reset-btn:hover,
.prefs-reset-btn:focus-visible {
    border-color: var(--accent-text);
    color: var(--accent-text);
    background: var(--accent-soft);
}

/* ---- Standalone /Accessibility page ------------------------------- */
.a11y-page .prefs-panel {
    padding: 1.75rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 4px 18px var(--shadow);
}

.a11y-statement h2 {
    font-size: 1.15rem;
    font-weight: 700;
    margin-top: 1.75rem;
    margin-bottom: 0.5rem;
    color: var(--text);
}

.a11y-statement p,
.a11y-statement li {
    color: var(--text-muted);
    line-height: 1.7;
}

/* High contrast needs a visible edge on the switch track, which otherwise
   reads as a plain rectangle once the palette flattens to black/white. */
html[data-contrast="high"] .pref-switch__control .form-check-input {
    border-width: 2px;
    border-color: var(--text);
}

/* ============================================================
   Motion & entrance animations
   ------------------------------------------------------------
   All use `animation`/`transition`, so the reduced-motion rules
   above neutralize them automatically (near-zero duration →
   elements settle instantly at their final, visible state).
   ============================================================ */
@keyframes prefRise {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Preference blocks rise in, gently staggered, on the standalone page */
.a11y-page .pref-block {
    animation: prefRise 0.35s ease both;
}
.a11y-page .pref-block:nth-of-type(1) { animation-delay: 0.03s; }
.a11y-page .pref-block:nth-of-type(2) { animation-delay: 0.09s; }
.a11y-page .pref-block:nth-of-type(3) { animation-delay: 0.15s; }
.a11y-page .pref-block:nth-of-type(4) { animation-delay: 0.21s; }

/* Profile cards rise in on load, gently staggered */
.profile-page .profile-card {
    animation: prefRise 0.45s ease both;
}
.profile-page .profile-card:nth-of-type(1) { animation-delay: 0.04s; }
.profile-page .profile-card:nth-of-type(2) { animation-delay: 0.10s; }
.profile-page .profile-card:nth-of-type(3) { animation-delay: 0.16s; }
.profile-page .profile-card:nth-of-type(4) { animation-delay: 0.22s; }
.profile-page .profile-card:nth-of-type(5) { animation-delay: 0.28s; }

/* Animated accent underline for main nav links */
.navbar-nav .nav-link:not(.dropdown-toggle) {
    position: relative;
}
.navbar-nav .nav-link:not(.dropdown-toggle)::after {
    content: '';
    position: absolute;
    left: 0.5rem;
    right: 0.5rem;
    bottom: 0.3rem;
    height: 2px;
    background: var(--accent);
    border-radius: 2px;
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.25s ease;
}
.navbar-nav .nav-link:not(.dropdown-toggle):hover::after,
.navbar-nav .nav-link:not(.dropdown-toggle):focus-visible::after {
    transform: scaleX(1);
}

/* Segmented + switch controls: gentle press feedback */
.pref-seg .btn:active {
    transform: translateY(1px);
}
