/* Clutch5 pressable CTAs -- one shared layer for every page that has actions.
 *
 * Loaded before each page's own <style>/<link>, so a page keeps the last word
 * on colour, size and layout. Nothing here sets a dimension: the only things
 * declared are how a control responds to being pressed and the properties that
 * make the whole painted surface the target rather than just the glyphs.
 *
 * Two rules govern what may appear in the selector lists below:
 *
 *   1. Only things that actually do something. A card, a score, a section
 *      heading or a status line must never look pressable, because a surface
 *      that moves under a thumb is a promise that something will happen.
 *   2. Never a container that holds another control. Pressing the outer one
 *      would animate the inner one with it, and a nested pair of interactive
 *      elements is a bug in its own right.
 *
 * The effect is deliberately small: about a pixel down, a couple of percent in,
 * and a slight dim. It should read as a physical key travelling, not a bounce.
 */

:root {
  /* Down, in, and darker. Tuned together -- raising one without lowering the
     others starts to look like a bounce. */
  --press-shift: 1px;
  --press-scale: 0.978;
  --press-dim: 0.94;
  /* Fast in so the control feels connected to the finger, slower out so the
     release is not a snap. Both short enough to finish inside a tap. */
  --press-in: 90ms;
  --press-out: 170ms;
  --press-ease: cubic-bezier(0.2, 0.7, 0.35, 1);
  /* One focus ring for every page, so keyboard users see the same thing
     everywhere. Pages may override the colour; none may remove the ring. */
  --focus-ring: #ff8a80;
}

/* Every actionable surface in the app, named one by one.
 *
 * `button` and `[role="switch"]` cover the shell, Settings, onboarding, the
 * bottom navigation and the Home control without listing each. The named
 * classes are the links and labels that are styled as buttons: an <a> or a
 * <label> gets no default affordance, so each one is opted in explicitly. */
button,
[role="switch"],
[role="button"],
.watch-link,
.watch-app-link,
.market-row-link,
.redeem-entry-link,
.admin-entry-link,
.dashboard-choice,
.ob-choice,
.legal-notice-check,
.subscription-consent,
.subscription-signin,
a.brand,
.back-link,
.legal-nav a,
.subscribe-redeem,
.redeem-signin,
.redeem-continue,
.consent-check,
.button,
.link-button {
  /* The whole box is the target, and a tap acts immediately instead of waiting
     out the double-tap-to-zoom delay. */
  touch-action: manipulation;
  /* The grey flash Safari paints over the element fights the pressed state and
     ignores border-radius. The transform below replaces it. */
  -webkit-tap-highlight-color: transparent;
  transition:
    transform var(--press-out) var(--press-ease),
    filter var(--press-out) var(--press-ease);
}

/* Pressed.
 *
 * :active covers mouse, touch and the keyboard's Space/Enter hold, so there is
 * one state rather than a set of pointer listeners. Disabled and aria-disabled
 * controls are excluded: a control that will not act must not pretend to. */
button:active:not(:disabled):not([aria-disabled="true"]),
[role="switch"]:active:not(:disabled):not([aria-disabled="true"]),
[role="button"]:active:not([aria-disabled="true"]),
.watch-link:active,
.watch-app-link:active,
.market-row-link:active,
.redeem-entry-link:active,
.admin-entry-link:active,
.dashboard-choice:active,
.ob-choice:active,
.legal-notice-check:active,
.subscription-consent:active,
.subscription-signin:active,
a.brand:active,
.back-link:active,
.legal-nav a:active,
.subscribe-redeem:active,
.redeem-signin:active,
.redeem-continue:active,
.consent-check:active,
.button:active:not(:disabled),
.link-button:active:not(:disabled) {
  transform: translateY(var(--press-shift)) scale(var(--press-scale));
  filter: brightness(var(--press-dim));
  transition-duration: var(--press-in), var(--press-in);
}

/* Keyboard focus stays obvious. Pages that already draw their own ring keep it
   -- this is the floor, not a replacement. */
button:focus-visible,
[role="switch"]:focus-visible,
[role="button"]:focus-visible,
.watch-link:focus-visible,
.watch-app-link:focus-visible,
.market-row-link:focus-visible,
.redeem-entry-link:focus-visible,
.admin-entry-link:focus-visible,
.dashboard-choice:focus-within,
.ob-choice:focus-within,
.legal-notice-check:focus-within,
.subscription-consent:focus-within,
.subscription-signin:focus-visible,
a.brand:focus-visible,
.back-link:focus-visible,
.legal-nav a:focus-visible,
.subscribe-redeem:focus-visible,
.redeem-signin:focus-visible,
.redeem-continue:focus-visible,
.consent-check:focus-within,
.button:focus-visible,
.link-button:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* A control that cannot act says so with the cursor as well as the styling. */
button:disabled,
.button:disabled,
.link-button:disabled,
[aria-disabled="true"] {
  cursor: default;
}

/* Reduced motion: the feedback stays, the movement goes.
 *
 * Someone who has asked for less motion still needs to know their tap landed,
 * so the dim is kept and only the travel and the scale are dropped. */
@media (prefers-reduced-motion: reduce) {
  button,
  [role="switch"],
  [role="button"],
  .watch-link,
  .watch-app-link,
  .market-row-link,
  .redeem-entry-link,
  .admin-entry-link,
  .dashboard-choice,
  .ob-choice,
  .legal-notice-check,
  .subscription-consent,
  .subscription-signin,
  a.brand,
  .back-link,
  .legal-nav a,
  .subscribe-redeem,
  .redeem-signin,
  .redeem-continue,
  .consent-check,
  .button,
  .link-button {
    transition: filter 1ms linear;
  }

  button:active:not(:disabled):not([aria-disabled="true"]),
  [role="switch"]:active:not(:disabled):not([aria-disabled="true"]),
  [role="button"]:active:not([aria-disabled="true"]),
  .watch-link:active,
  .watch-app-link:active,
  .market-row-link:active,
  .redeem-entry-link:active,
  .admin-entry-link:active,
  .dashboard-choice:active,
  .ob-choice:active,
  .legal-notice-check:active,
  .subscription-consent:active,
  .subscription-signin:active,
  a.brand:active,
  .back-link:active,
  .legal-nav a:active,
  .subscribe-redeem:active,
  .redeem-signin:active,
  .redeem-continue:active,
  .consent-check:active,
  .button:active:not(:disabled),
  .link-button:active:not(:disabled) {
    transform: none;
    filter: brightness(var(--press-dim));
    transition-duration: 1ms;
  }
}
