/* What every control shares, whatever page it is on: the keyboard focus ring,
   and on a touch screen a size a thumb can hit. Loaded last (layouts/application),
   so it lands on top of each page's own rules at equal specificity.

   Sizes are in px, not rem: the root is 16px at 768px and under and 20px above,
   and a landscape tablet is both a coarse pointer and wider than 768px. */

/* ── Focus ring ──
   One ring, coloured by --focus-ring, which each surface sets: ink on parchment
   (the layout's :root), the theme's accent in a game (games/_theme_style), which
   the high-contrast palettes replace on the same element. Where a page used to
   say outline: none, the browser drew nothing a keyboard could follow. */
:focus-visible { outline: 2px solid var(--focus-ring, currentColor); outline-offset: 2px; }

/* A field's ring sits on its own edge, like a heavier border. */
:is(input:not([type="checkbox"], [type="radio"], [type="submit"], [type="button"]), textarea, select):focus-visible { outline-offset: 0; }

/* Full-width controls inside the sidebar, the dialogs and the travel grid,
   whose scroll box would clip a ring drawn outside them, so it goes inside; and
   the scrollers themselves, which Chrome now makes focusable. */
:is(.panel-action-btn, .rest-choice, .slot-btn, .world-map-region,
    .turn-log, .right-panel, .journal-entries):focus-visible { outline-offset: -3px; }
/* The story cards' strip scrolls sideways on a phone (pages/story_cards.css),
   so its scroll box clips a ring drawn outside a card's name, top and bottom.
   So do random setup's tray row and its jumps (pages/random_cards.css), and a
   chip menu's rows fill the menu from edge to edge. */
.story-strip-link:focus-visible { outline-offset: -3px; }
:is(.tray-tag, .tray-jump):focus-visible,
.tag-chip-menu button:focus-visible { outline-offset: -3px; }

/* The one field a player types in all game keeps its underline, doubled in the
   ring's colour: a ring around it would frame every word they write. */
.action-input:focus-visible { outline: none; border-bottom-color: var(--focus-ring); box-shadow: 0 1px 0 var(--focus-ring); }
@media (forced-colors: active) { .action-input:focus-visible { outline: 2px solid Highlight; outline-offset: 0; } }

/* The viewer's close button sits on a picture of any colour: a light ring with
   a dark halo. */
.lightbox { --focus-ring: #f0ece4; }
.lightbox .app-dialog-close:focus-visible { box-shadow: 0 0 0 6px rgba(0, 0, 0, 0.6); }
/* The redraw under the picture has its ring inside it, so it is backed instead. */
.lightbox .lightbox-action:focus-visible { background: rgba(0, 0, 0, 0.6); }

/* Where state is carried by colour alone, a forced-colours palette removes it. */
@media (forced-colors: active) {
  :is(.contrast-btn, .game-switch-btn)[aria-pressed="true"] { text-decoration: underline; text-underline-offset: 3px; }
}

/* ── Touch targets ──
   A phone's thumb, and the Android app's WebView, which matches (pointer: coarse)
   as game_controller#touchScreen does. The hamburger was 32×22, a "?" 16×16,
   the dialogs' × 21×22, a picture switch 21px tall. */
@media (pointer: coarse) {
  /* Glyph controls keep their drawn size; an invisible square centred on each
     takes the tap. The hamburger's dot is its ::after (game/layout.css). */
  :is(.game-topbar-home, .game-topbar-menu, .app-nav-home, .sidebar-help-btn, .setup-help-btn,
      .app-dialog-close:not(.lightbox-close), .turn-hint-close) { position: relative; }
  :is(.game-topbar-home, .game-topbar-menu, .app-nav-home, .sidebar-help-btn, .setup-help-btn,
      .app-dialog-close, .turn-hint-close)::before {
    content: ""; position: absolute; left: 50%; top: 50%;
    width: max(100%, 44px); height: max(100%, 44px); transform: translate(-50%, -50%);
  }
  /* The momentum pips under the sidebar's "?" are faint, and opacity makes
     each its own layer, drawn over the hit area; nothing there takes a tap. */
  .sidebar-help-btn { z-index: 1; }
  /* A hit area is painted over any neighbour inside it, so these rows leave
     it room: 14px is half of 44 less 16. */
  .scene-panel-header, .setup-toggle { gap: 14px; }
  .save-panel-header { margin-bottom: 14px; }

  /* Everything with a word on it grows to 44px tall. The story cards' own
     controls (the strip, the ×, the way back, the fields) are 44px on every
     screen already (pages/story_cards.css). */
  :is(.btn, .panel-action-btn, .rest-choice, .scene-toggle-btn, .contrast-btn, .game-switch-btn,
      .mobile-panel-close-btn, .turn-continue, .load-earlier, .turn-error-reload, .turn-log-jump,
      .turn-hint-dismiss, .btn-decline, .hero-card-attr-raise, .app-nav-signout, .app-nav-locale,
      .google-btn, .terms-reaccept-btn,
      .action-input, .details-input, .setup-card select) { min-height: 44px; }
  .stat-btn { min-width: 44px; min-height: 44px; }
  /* A word as short as "Off" is narrower than a thumb. */
  :is(.contrast-btn, .scene-toggle-btn) { min-width: 44px; }

  /* Links, summaries and labels need their words centred by hand. */
  :is(a.btn, .app-nav-user, .sidebar-details-link, .details-edit-link, .landing-link,
      .oot-card-primary, .theme-swatch, .setup-toggle-label, .demo-terms-label) {
    display: inline-flex; align-items: center; min-height: 44px;
  }
  a.btn { justify-content: center; }
  /* The demo bar's Sign in to save, drawn as Sign out on parchment, takes a
     thumb as Sign out does. Not in the list above, whose weight it would
     raise; in a game's top bar it keeps the bar's size. */
  .app-nav .app-nav-demo-cta { display: inline-flex; align-items: center; min-height: 44px; }
  /* Links whose own display outranks the list above, or is not in it. */
  .oot-card-line a.oot-card-primary, a.terms-reaccept-btn { display: inline-flex; align-items: center; justify-content: center; }
  .lightbox-action:not([hidden]) { display: flex; align-items: center; justify-content: center; }
  .rest-menu > summary.panel-action-btn,
  .sidebar-exit a.panel-action-btn { display: flex; align-items: center; justify-content: center; }
  /* The gap stands in for the space after the arrow, which flex drops. */
  .exit-label { display: flex; align-items: center; gap: 0.3em; width: 100%; min-height: 44px; }
  .survey-scale label { min-width: 44px; min-height: 44px; justify-content: center; }

  /* Legal links in the footer and the sidebar: WCAG's 24px, not 44.
     Premium's fine print reaches it with less (pages/premium.css). */
  :is(.site-footer a, .panel-legal a) { display: inline-block; padding-block: 0.4rem; }
}

/* ── Pressed ──
   Hover styles wait for a pointer that can hover (@media (hover: hover) in each
   page's rules): on a touch screen they stuck after a tap, the button left in
   its hover colour until the next tap somewhere else. What answers a finger is
   this instead: whatever is pressed dims while it is held. The Android app turns
   the tap highlight off (base.css), so nothing else would. A filter rather than
   opacity, so a link that is already faint (the sidebar's legal links) dims too
   instead of brightening. */
@media (hover: none) {
  :is(a[href], button:not(:disabled), summary, [role="button"], label:is([for], :has(input:not(:disabled))),
      input:is([type="submit"], [type="button"]):not(:disabled)):not([aria-disabled="true"]):active { filter: opacity(0.6); }
}
