/* Adaptive access: scan highlight, dwell ring, switch bar, large targets,
   focus visibility, high contrast, reduced motion.
   Loaded last so access overrides always win. */

/* ============ Scan highlight (switch) & dwell (eye-gaze) ============ */
.scan-current {
    outline: 5px solid var(--scan-ring) !important;
    outline-offset: 4px;
    box-shadow: 0 0 0 10px var(--scan-glow) !important;
    border-radius: 18px;
    position: relative; z-index: 5;
    animation: scanPulse 1.1s ease-in-out infinite;
}
@keyframes scanPulse {
    0%,100% { box-shadow: 0 0 0 10px var(--scan-glow); }
    50% { box-shadow: 0 0 0 16px var(--scan-glow); }
}

/* Switch control bar (bottom). Not sticky: nothing scrolls, so as a flex child
   of the fixed .stage column it simply stays put. */
.switch-bar {
    z-index: 45; flex-shrink: 0;
    display: none; gap: 12px;
}
body.mode-switch .switch-bar { display: flex; }
.switch-key {
    appearance: none; font-family: 'Fredoka', sans-serif;
    flex: 1; padding: clamp(12px, calc(2 * var(--vh)), 22px); border: none; border-radius: 18px;
    font-size: clamp(19px, 3vw, 26px); font-weight: 600; cursor: pointer;
    color: #fff; box-shadow: var(--shadow-md);
    display: inline-flex; align-items: center; justify-content: center; gap: 12px;
    transition: transform .12s ease, filter .12s ease;
}
.switch-key .ico { width: 1.05em; height: 1.05em; }
.switch-key:active { transform: scale(0.985); filter: brightness(1.06); }
.switch-key.next { background: linear-gradient(135deg, var(--accent), #f7c667); color: #4a3200; }
.switch-key.select { background: linear-gradient(135deg, var(--primary), var(--primary-strong)); }
.switch-key small { display: block; font-family: 'Nunito', sans-serif; font-weight: 700; font-size: 13.5px; opacity: 0.84; }
/* The sub-label is a first-run explanation; the bar itself is the control. On a
   short screen the row it costs belongs to the game. */
body.is-tight .switch-key { padding: 10px; font-size: clamp(18px, 2.4vw, 22px); }
body.is-tight .switch-key small { display: none; }
body:not(.scan-manual) .switch-key.next { display: none; }

/* Dwell ring overlay */
#dwell-overlay {
    position: fixed; z-index: 60; pointer-events: none;
    display: none; place-items: center;
}
#dwell-overlay.show { display: grid; }
#dwell-overlay svg { width: 74px; height: 74px; transform: rotate(-90deg); filter: drop-shadow(0 4px 12px rgba(0,0,0,.5)); }
#dwell-overlay circle.track { stroke: rgba(255,255,255,.4); }
#dwell-overlay circle.fill { stroke: var(--accent); stroke-linecap: round; transition: stroke-dashoffset linear; }

/* Access-hint banner */
.access-hint {
    display: none;
    flex-shrink: 0;
    align-items: center; gap: 12px;
    background: color-mix(in srgb, var(--primary) 12%, var(--surface));
    border: 1px solid var(--line-strong);
    border-radius: 14px;
    padding: 10px 16px; font-weight: 700; color: var(--ink-dim); font-size: 14px;
}
.access-hint .ico { width: 20px; height: 20px; flex-shrink: 0; }
.access-hint.for-switch .ico { color: var(--switch); }
.access-hint.for-dwell .ico { color: var(--gaze); }
/* Only on the hub. The hint explains the mode you just turned on, which is
   worth a row of the screen once — but inside a game that row is taken from
   the game itself, and by then the player has already been told. */
body.on-hub.mode-switch .access-hint.for-switch,
body.on-hub.mode-dwell .access-hint.for-dwell { display: flex; }
.access-hint .k { color: var(--primary-ink); font-weight: 800; }
body.is-tighter .access-hint { display: none !important; }

/* Group scanning: the temporary "Go back" step inside a group */
.scan-goback { min-width: 140px; padding: 14px 20px; font-size: 18px; align-self: center; }

/* Extra-large targets.
   Each of these is capped by the box the element was actually given (100cqh /
   the tight steps), so asking for bigger buttons can never make an item taller
   than the region holding it — that would clip instead of paging. */
body.big-targets .chip, body.big-targets .rail-btn, body.big-targets .tool-btn, body.big-targets .back-btn,
body.big-targets .btn-soft, body.big-targets .btn-solid, body.big-targets .hint-exit { min-height: 64px; }
body.big-targets .count-btn { width: 80px; height: 80px; font-size: 32px; }
body.big-targets .btn-big { min-width: 280px; padding: 30px 52px; }
body.big-targets .btn-ghost { padding: 26px 42px; }
body.big-targets .game-card { min-height: min(230px, 100cqh); }
body.big-targets .featured-cta { min-height: 64px; }
body.big-targets .switch-key { padding: 30px; }

body.big-targets.is-tight .chip, body.big-targets.is-tight .rail-btn, body.big-targets.is-tight .tool-btn,
body.big-targets.is-tight .back-btn, body.big-targets.is-tight .hint-exit { min-height: 52px; }
body.big-targets.is-tight .count-btn { width: 56px; height: 56px; font-size: 24px; }
body.big-targets.is-tight .btn-big { min-width: 200px; padding: 14px 32px; }
body.big-targets.is-tight .btn-ghost { padding: 14px 26px; }
body.big-targets.is-tight .switch-key { padding: 14px; }
/* At the last density step the extra-large sizing gives way to the ordinary
   44-48px targets. It is still a comfortable target — and a button that fits is
   worth more than a bigger one that is cut off the screen. */
body.big-targets.is-tighter .chip, body.big-targets.is-tighter .rail-btn, body.big-targets.is-tighter .tool-btn,
body.big-targets.is-tighter .back-btn, body.big-targets.is-tighter .hint-exit,
body.big-targets.is-tighter .btn-soft, body.big-targets.is-tighter .btn-solid { min-height: 44px; }
body.big-targets.is-tighter .count-btn { width: 44px; height: 44px; font-size: 19px; }
body.big-targets.is-tighter .btn-big { min-width: 170px; padding: 10px 24px; }
body.big-targets.is-tighter .btn-ghost { padding: 10px 20px; }
body.big-targets.is-tighter .switch-key { padding: 10px; }

/* Focus visibility */
button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible, [tabindex]:focus-visible {
    outline: 4px solid var(--scan-ring); outline-offset: 3px;
}

/* High contrast theme boosts */
body[data-contrast="high"] .panel,
body[data-contrast="high"] .game-card,
body[data-contrast="high"] .aside-card,
body[data-contrast="high"] .access-group,
body[data-contrast="high"] .die,
body[data-contrast="high"] .field { border-width: 3px; border-color: var(--line-strong); }
body[data-contrast="high"] .card-desc,
body[data-contrast="high"] .featured-desc,
body[data-contrast="high"] .aside-lede,
body[data-contrast="high"] .aside-item span,
body[data-contrast="high"] .status-text,
body[data-contrast="high"] .rail-btn,
body[data-contrast="high"] .brand-sub { color: var(--ink); }
/* The art panels are the one place colour is decoration; at high contrast they
   compete with the text that matters. */
body[data-contrast="high"] .card-art { display: none; }

/* Reduced motion */
body.reduced-motion *,
body.reduced-motion *::before,
body.reduced-motion *::after { animation: none !important; transition: none !important; }
/* The dwell ring is essential feedback for eye-gaze users, not decoration — keep it. */
body.reduced-motion #dwell-overlay circle.fill { transition: stroke-dashoffset linear !important; }
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

@media (max-width: 720px) {
    .choice-grid { gap: 14px; }
}

/* ============ ?debug=scan overlay ============
   Numbers every scan stop on the active screen and outlines any button the
   scanner cannot reach. Dev-only: inert unless the query flag is present. */
.dbg-badge {
    position: absolute; z-index: 200; pointer-events: none;
    transform: translate(-40%, -40%);
    min-width: 24px; height: 24px; padding: 0 6px;
    border-radius: 999px; background: #0b7285; color: #fff;
    font: 700 13px/24px 'Nunito', sans-serif; text-align: center;
    box-shadow: 0 2px 8px rgba(0,0,0,.4);
}
.dbg-miss { outline: 4px dashed #e03131 !important; outline-offset: 3px; }
.dbg-overflow { outline: 4px solid #f76707 !important; outline-offset: -4px; }
#dbg-bar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 210;
    background: #0b7285; color: #fff; padding: 8px 14px;
    font: 700 13px 'Nunito', sans-serif; text-align: center;
}
#dbg-bar.bad { background: #c92a2a; }
