/* ─────────────────────────────────────────────────────────────────────────
   Interaction layer — press feedback, scales, accessibility fallbacks.

   Loaded LAST so it wins on source order at equal specificity, and kept in
   its own file so the whole thing can be removed with one <link> if it turns
   out to be wrong.

   WHY THIS EXISTS
   The audit found 127 :hover rules against 23 :active, and zero uses of
   `@media (hover: hover)`. On a phone — which is what this PWA mostly is —
   that means two things: tapping a card produced no feedback at all, and the
   hover style then stuck to it afterwards, because touch fires a synthetic
   hover that never leaves.
   ───────────────────────────────────────────────────────────────────────── */

/* ─── 1. Scales ───────────────────────────────────────────────────────────
   There was no spacing or type scale: 353 font-size declarations, 12 of them
   responsive, and geometry tokens limited to --radius/--radius-sm. These are
   the values new work should reach for. Existing rules are not rewritten
   wholesale — that would be a large, risky diff for no visual gain. */

:root {
  /* 4px base. Enough steps to be useful, few enough to force a choice. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;

  /* Type scale. Tracking and leading are paired to each size rather than set
     globally: letters read too far apart as they grow, so display sizes get
     negative tracking and tight leading, body sizes sit near zero and looser.
     A single letter-spacing for every size — 0.5px, used 20 times today — is
     wrong at one end of the scale by construction. */
  --text-xs: 0.75rem;      --text-xs-lh: 1.5;    --text-xs-ls: 0.02em;
  --text-sm: 0.875rem;     --text-sm-lh: 1.5;    --text-sm-ls: 0.01em;
  --text-base: 1rem;       --text-base-lh: 1.55; --text-base-ls: 0;
  --text-lg: 1.125rem;     --text-lg-lh: 1.45;   --text-lg-ls: -0.005em;
  --text-xl: 1.375rem;     --text-xl-lh: 1.3;    --text-xl-ls: -0.01em;
  --text-2xl: 1.75rem;     --text-2xl-lh: 1.2;   --text-2xl-ls: -0.015em;
  --text-3xl: clamp(2rem, 4vw, 2.75rem);
  --text-3xl-lh: 1.1;      --text-3xl-ls: -0.02em;
  --text-display: clamp(2.5rem, 6vw, 4rem);
  --text-display-lh: 1.05; --text-display-ls: -0.03em;

  /* Motion vocabulary. style.css defines four easing tokens that resolve to
     only two curves (--ease-out == --ease-crisp, --ease == --ease-snappy).
     These are the two that are actually missing. */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);

  --dur-press: 120ms;
  --dur-enter: 200ms;
  --dur-panel: 260ms;
}

/* ─── 2. Press feedback ───────────────────────────────────────────────────
   Response must be instant and must happen on press, not release. 120ms is
   inside the 100–160ms press budget; 0.97 is felt rather than seen, which is
   right for something tapped dozens of times a day. Only transform is
   animated, so this stays on the compositor. */

.tab-btn,
.score-card,
.panel,
.gw-card,
.chat-item,
.transfer-card,
.simple-card,
.ftab,
.faa-item,
.faa-lead,
.faa-mini-btn,
.faa-back,
.chatfpl-new-btn,
.chatfpl-sidebar-toggle {
  -webkit-tap-highlight-color: transparent;

  /* Properties are named rather than left as `all`.
     These elements previously carried `transition: var(--transition)` — a bare
     duration with no property, which resolves to `all` and animates whatever
     happens to change, including layout properties. Naming them fixes that,
     but the list has to stay complete: an earlier version of this rule
     declared only `transform` and silently killed the colour and shadow
     easing these elements already had.
     Transform is quick because it is press feedback; colour and shadow are
     slower because they are hover polish. */
  transition:
    transform var(--dur-press) var(--ease-out, cubic-bezier(0.23, 1, 0.32, 1)),
    background-color 180ms var(--ease-out, cubic-bezier(0.23, 1, 0.32, 1)),
    border-color 180ms var(--ease-out, cubic-bezier(0.23, 1, 0.32, 1)),
    box-shadow 180ms var(--ease-out, cubic-bezier(0.23, 1, 0.32, 1)),
    color 180ms var(--ease-out, cubic-bezier(0.23, 1, 0.32, 1));
}

.tab-btn:active,
.score-card:active,
.gw-card:active,
.chat-item:active,
.transfer-card:active,
.ftab:active,
.faa-item:active,
.faa-mini-btn:active,
.faa-back:active,
.chatfpl-new-btn:active,
.chatfpl-sidebar-toggle:active {
  transform: scale(0.97);
}

/* Large surfaces need less scale to read as pressed — 0.97 on a full-width
   card is a bigger absolute movement than on a chip, and reads as a lurch. */
.panel:active,
.simple-card:active,
.faa-lead:active {
  transform: scale(0.99);
}

/* ─── 3. Hover is a pointer capability, not a default ─────────────────────
   Touch fires a synthetic hover on tap that never clears, so a lifted card
   stays lifted until you tap elsewhere. Neutralising the transform-based
   hover on non-hover pointers costs nothing on desktop, where the media
   query simply does not match. */

@media (hover: none), (pointer: coarse) {
  .tab-btn:hover,
  .score-card:hover,
  .panel:hover,
  .gw-card:hover,
  .chat-item:hover,
  .transfer-card:hover,
  .simple-card:hover,
  .ftab:hover,
  .faa-item:hover,
  .player-card:hover,
  .player-slot:hover,
  .upload-zone:hover {
    transform: none;
  }
}

/* ─── 3b. Touch targets ───────────────────────────────────────────────────
   7 of 21 visible controls measured under 44px tall on a 375px viewport.
   The hit area is expanded with a pseudo-element rather than by growing the
   control, so nothing reflows and the visual design is untouched — the
   button simply becomes catchable by a thumb.

   ::after is used because .tab-btn already owns ::before for its active
   indicator. The overlay is inert and sits beneath the label. */

.tab-btn,
.ftab,
.faa-mini-btn,
.pc-remove,
.chat-icon-btn {
  position: relative;
}

.tab-btn::after,
.ftab::after,
.faa-mini-btn::after,
.pc-remove::after,
.chat-icon-btn::after {
  content: "";
  position: absolute;
  inset: -8px;
  z-index: 0;
  pointer-events: auto;
}

/* Keep the real content above the invisible hit pad. */
.tab-btn > *,
.ftab > *,
.faa-mini-btn > *,
.pc-remove > *,
.chat-icon-btn > * {
  position: relative;
  z-index: 1;
}

/* ─── 3c. Typography — tracking follows size ──────────────────────────────
   Tracking is size-specific: letters read too far apart as type grows, so
   display sizes need to tighten. The codebase had 91 letter-spacing
   declarations and only 7 negative, with `0.5px` applied at 20 different
   sizes. These are the places where the fixed value was most visibly wrong. */

.hero-title {
  letter-spacing: var(--text-display-ls);
  line-height: var(--text-display-lh);
}

.logo-text {
  letter-spacing: var(--text-xl-ls);
}

h1, .faa-reader h1 {
  letter-spacing: var(--text-3xl-ls);
  line-height: var(--text-3xl-lh);
}

h2 {
  letter-spacing: var(--text-2xl-ls);
  line-height: var(--text-2xl-lh);
}

/* Small uppercase labels are the one case that wants *more* tracking, not
   less — at this size letterforms crowd each other. */
.hero-eyebrow,
.faa-tag,
.vm-state {
  letter-spacing: 0.14em;
}

/* ─── 3d. Light mode ──────────────────────────────────────────────────────
   Light mode was built by overriding dark mode rather than designed for, and
   it inherits assumptions that only hold on a dark surface. */

/* Materials: a light translucent surface stacked on another light translucent
   surface destroys legibility — the blur has nothing to separate. Light mode
   has 45 backdrop-filtered surfaces, so the chrome is made materially more
   opaque and the blur reduced, which is what keeps a light material readable. */
:root.light-mode .header,
:root.light-mode .main-tabs,
:root.light-mode .chat-composer,
:root.light-mode .faa-panel,
:root.light-mode .acct-panel {
  backdrop-filter: blur(12px) saturate(150%);
  -webkit-backdrop-filter: blur(12px) saturate(150%);
}

/* Vibrancy: over a light translucent surface, flat mid-grey text loses its
   footing as the backdrop shifts. Slightly darker and slightly heavier holds
   contrast without changing the layout. */
:root.light-mode .faa-credit,
:root.light-mode .faa-byline,
:root.light-mode .acct-hint,
:root.light-mode .hero-sub {
  color: rgba(26, 8, 32, 0.62);
  font-weight: 500;
}

/* Press feedback should feel the same in both themes. Light mode defined its
   own scales — 0.92 on tabs, 0.88 on step buttons — which read as a lurch at
   these sizes. Brought in line with the 0.97 used everywhere else. */
:root.light-mode .tab-btn:active { transform: scale(0.97); }
:root.light-mode .rsnav-btn:active { transform: scale(0.97); }
:root.light-mode .wi-step-btn:active { transform: scale(0.95); }

/* Depth: shadows on a light background need to be softer and warmer than the
   near-black ones inherited from dark mode, or cards look cut out rather than
   resting on the surface. */
:root.light-mode .panel,
:root.light-mode .faa-panel,
:root.light-mode .acct-panel {
  box-shadow:
    0 0.5px 0 rgba(26, 8, 32, 0.04),
    0 1px 3px rgba(26, 8, 32, 0.05),
    0 8px 24px -10px rgba(26, 8, 32, 0.12);
}

/* Focus rings are tuned for a dark backdrop; cyan on white is far too faint
   to serve as a visible focus indicator. */
:root.light-mode *:focus-visible {
  outline: 2px solid rgba(0, 140, 72, 0.9);
  outline-offset: 2px;
}

/* ─── 4. Trigger-anchored panels ──────────────────────────────────────────
   transform-origin appeared three times in the whole codebase, so popovers
   grew from their own centre with no spatial link to the control that opened
   them. Modals are deliberately excluded: they are not anchored to a
   trigger, so centre is correct for them. */

.xpts-popover,
.autocomplete-list {
  transform-origin: top center;
}

/* ─── 5. Accessibility fallbacks ──────────────────────────────────────────
   55 translucent surfaces existed with no fallback for either preference. */

@media (prefers-reduced-transparency: reduce) {
  .header,
  .main-tabs,
  .chat-composer,
  .faa-panel,
  .acct-panel,
  .chatfpl-sidebar {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    background-color: var(--pl-purple2, #1a0f2e) !important;
  }
}

@media (prefers-contrast: more) {
  .panel,
  .score-card,
  .faa-panel,
  .acct-panel,
  .chat-composer {
    border-color: rgba(255, 255, 255, 0.55) !important;
    backdrop-filter: none !important;
  }
}

/* Reduced motion in style.css collapses every animation and transition to
   0.01ms with !important. That is safe but blunt: the guidance is a gentler
   equivalent, not nothing. Opacity carries no vestibular risk, so fades are
   restored while every transform-based movement stays suppressed. */
@media (prefers-reduced-motion: reduce) {
  .faa-lead,
  .faa-item,
  .vm-overlay,
  .chatfpl-sidebar-backdrop {
    transition-property: opacity !important;
    transition-duration: 160ms !important;
  }

  .tab-btn:active,
  .score-card:active,
  .panel:active,
  .gw-card:active,
  .chat-item:active,
  .transfer-card:active,
  .simple-card:active,
  .ftab:active,
  .faa-item:active,
  .faa-lead:active {
    transform: none !important;
  }
}
