/* ============================================================================
   SWORT interaction layer
   ---------------------------------------------------------------------------
   One place that owns how every clickable thing on the site RESPONDS. Colour per
   variant stays with the variant; this file owns timing, press feedback, focus,
   and touch behaviour, so interaction feels identical everywhere.

   Why this file exists
   --------------------
   The recurring "the button looks fine until you press it" defect had two
   separate causes, and only the first was a colour problem:

   1. COLOUR. An !important rule in contrast.css beat `:hover`, so a primary CTA
      kept black text while its background went transparent. Fixed at the source;
      a cascade-accurate audit now resolves 280 interactive elements across 1,120
      states with zero failures.

   2. NO PRESS FEEDBACK. A "magnetic CTA" script wrote an INLINE transform on
      every pointermove. An inline style outranks any stylesheet, so it silently
      defeated `:active { transform }`: the button gave no response to being
      pressed and slid out from under the cursor by up to 28% of the pointer
      offset. That script is deleted on all three pages that had it.

   The press response here is pure CSS and cannot be overridden by a stray
   inline write, because nothing writes inline transforms to buttons any more.

   Smoothness
   ----------
   - One duration and one easing for all interactive feedback, from the shared
     motion tokens. Hover, active, and focus all settle on the same curve, so
     moving across a row of buttons reads as one system rather than several.
   - transform and colour animate TOGETHER at the same duration. When they had
     different durations there was a window mid-transition where the label and
     the background were briefly close in tone.
   - touch-action: manipulation removes the ~300ms double-tap delay browsers
     otherwise add, which is the single biggest cause of a control feeling
     unresponsive on a phone.
   - The tap highlight is set explicitly. Left alone, mobile Safari and Chrome
     paint their own translucent overlay on tap, which on a dark button reads as
     the label washing out: exactly the symptom being fixed.
   ========================================================================= */

/* ── Selector sets ─────────────────────────────────────────────────────────
   Derived by enumerating every interactive class actually present in the
   rendered markup across all 14 routes, not hand-written. A hand-written list
   is how .btn-primary and .btn-secondary, the two most prominent CTAs on the
   homepage, were missed on the first attempt: buttons.css loaded, reported
   success, and left the hero buttons on the old behaviour.

   $universal  everything clickable, for touch behaviour only
   $pressable  things that should visibly depress, with the shared timing */

/* Touch behaviour: safe and correct on every interactive element, including
   plain text links. */
a, button, [role="button"], label, summary,
input[type="submit"], input[type="button"] {
  -webkit-tap-highlight-color: rgba(255, 255, 255, 0.08);
  touch-action: manipulation;
}
/* On light surfaces a white tap flash is invisible; use a dark one. */
.s-paper a, .s-paper button, .s-paper label,
.surface-paper a, .surface-paper button, .surface-paper label,
.form-surface a, .form-surface button, .form-surface label,
.p-form-surface a, .p-form-surface button, .p-form-surface label {
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0.08);
}

/* The full pressable set. */
.btn-primary, .btn-secondary, .btn-full,
.p-btn, .p-btn-primary, .p-btn-ghost, .p-btn-ink, .p-btn-ink-ghost, .p-btn-full,
.c-btn, .c-btn-primary, .c-btn-ghost,
.nav-cta, .nav-hamburger, .hw-btn,
.slot-btn, .bk-tz-btn, .bk-cal-arrow, .bk-submit, .bk-success-meet,
.bk-radio-label, .bk-budget-label,
.sim-reset-btn, .role-apply-link, .role-card, .route-cell,
.feat-panel-cta, .feat-panel-cta-strong,
.footer-legal-link, .footer-link, .t-link {
  /* One timing contract. Longhands, never `all`, so a transition can never
     animate a layout property and cause jitter. background-color and color run
     at the SAME duration: when they differed there was a window mid-transition
     where the label and its background were briefly close in tone, which is
     what "the text disappears when I press it" looks like even when both end
     states are fine. */
  transition:
    background-color var(--dur-ctrl) var(--ease-out),
    color            var(--dur-ctrl) var(--ease-out),
    border-color     var(--dur-ctrl) var(--ease-out),
    opacity          var(--dur-ctrl) var(--ease-out),
    transform        var(--dur-ctrl) var(--ease-out);
}

/* Press feedback: a small consistent shift. 1px translate, not a scale, because
   scaling a bordered button visibly thickens its border mid-animation. */
.btn-primary:active, .btn-secondary:active, .btn-full:active,
.p-btn:active, .p-btn-full:active,
.c-btn:active, .c-btn-primary:active, .c-btn-ghost:active,
.nav-cta:active, .hw-btn:active,
.slot-btn:active, .bk-tz-btn:active, .bk-cal-arrow:active, .bk-submit:active,
.sim-reset-btn:active, .role-apply-link:active,
.feat-panel-cta:active, .feat-panel-cta-strong:active {
  transform: translateY(1px);
}

/* Keyboard focus must be visible on every one of them, on both surfaces. */
.btn-primary:focus-visible, .btn-secondary:focus-visible, .btn-full:focus-visible,
.p-btn:focus-visible, .p-btn-full:focus-visible, .c-btn:focus-visible,
.nav-cta:focus-visible, .nav-hamburger:focus-visible, .hw-btn:focus-visible,
.slot-btn:focus-visible, .bk-tz-btn:focus-visible, .bk-cal-arrow:focus-visible,
.bk-submit:focus-visible, .sim-reset-btn:focus-visible,
.role-apply-link:focus-visible, .footer-legal-link:focus-visible,
.footer-link:focus-visible, .feat-panel-cta:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}
.s-paper .p-btn:focus-visible, .surface-paper .btn-full:focus-visible,
.p-form-surface .btn-full:focus-visible, .form-surface .btn-full:focus-visible,
.surface-paper .bk-submit:focus-visible, .t-link:focus-visible {
  outline-color: var(--focus-ring-paper);
}

/* Disabled: recolour, never fade. Reducing opacity on a button reduces the
   contrast of its label at the same time, which is how a disabled control ends
   up unreadable rather than merely inactive. */
/* NAMED variants only. A bare `button:disabled` was included here and it was
   too broad: the booking calendar's day cells are <button> elements, so disabled
   and past days got a filled gray-dark background from this rule while the
   contrast floor in contrast.css forced their text to the LIGHT dim value.
   Two of my own rules fighting produced 1.37:1 on real cells. A calendar cell is
   not a filled button and must not be styled as one. */
.btn-primary:disabled, .btn-secondary:disabled, .btn-full:disabled,
.p-btn:disabled, .p-btn-full:disabled, .c-btn:disabled,
.bk-submit:disabled {
  background-color: var(--button-disabled-bg);
  color: var(--button-disabled-text);
  border-color: var(--button-disabled-border);
  cursor: not-allowed;
  transform: none;
  opacity: 1;
}

/* Reduced motion: keep every colour change, drop the travel. The state is still
   communicated, just without movement. */
@media (prefers-reduced-motion: reduce) {
  .btn-primary, .btn-secondary, .btn-full,
  .p-btn, .p-btn-full, .c-btn, .nav-cta, .hw-btn,
  .slot-btn, .bk-tz-btn, .bk-submit, .sim-reset-btn, .role-apply-link,
  .role-card, .route-cell, .feat-panel-cta, .footer-legal-link, .footer-link, .t-link {
    transition:
      background-color var(--dur-micro) linear,
      color            var(--dur-micro) linear,
      border-color     var(--dur-micro) linear;
  }
  .btn-primary:active, .btn-secondary:active, .btn-full:active,
  .p-btn:active, .c-btn:active, .nav-cta:active, .hw-btn:active,
  .slot-btn:active, .bk-submit:active, .sim-reset-btn:active,
  .role-apply-link:active, .feat-panel-cta:active { transform: none; }
}

/* Forced colors: hand it entirely to the OS. */
@media (forced-colors: active) {
  .btn-primary, .btn-secondary, .btn-full, .p-btn, .c-btn, .nav-cta, .hw-btn {
    forced-color-adjust: auto;
  }
}


/* ── CTAs that were removed from the contrast floor ───────────────────────────
   These live HERE, not in page.css. page.css is loaded by only 4 of the 15
   pages, so the same rules placed there silently did nothing on the homepage and
   the booking page: .feat-panel-cta measured 3.51:1 and .role-card-cta 2.53:1
   because their only surviving rule was a page-level inline #555.

   Placement is part of correctness. A rule in a stylesheet the page does not
   load is indistinguishable from no rule at all.

   Rest colour is the measured dim-on-dark floor so nothing regressed; full white
   on interaction. Nothing here is !important: an !important colour on an
   interactive element is what broke hover states earlier in this project. */
.role-card-cta, .route-cell-cta, .feat-panel-cta, .feat-panel-cta-strong,
.sim-panel-cta {
  color: var(--dim-on-dark);
}
.role-card-cta:hover, .role-card-cta:focus-visible,
.route-cell-cta:hover, .route-cell-cta:focus-visible,
.feat-panel-cta:hover, .feat-panel-cta:focus-visible,
.feat-panel-cta-strong:hover, .feat-panel-cta-strong:focus-visible,
.sim-panel-cta:hover, .sim-panel-cta:focus-visible { color: var(--swort-white); }
.role-card:hover .role-card-cta,
.route-cell:hover .route-cell-cta { color: var(--swort-white); }
.role-card-cta:active, .route-cell-cta:active,
.feat-panel-cta:active, .sim-panel-cta:active { color: var(--swort-silver); }
