/**
 * Button mechanics, for Dr Badhri's PWAs.
 *
 *   <link rel="stylesheet" href="https://badhrilabs.app/shared/button.css">
 *
 * This file deliberately carries no colour, no radius and no font. Each app
 * should look like itself — SET playful, Health Guardian sober — and the audit
 * that produced this file found roughly half of every app's button CSS was
 * exactly that kind of personality. None of it belongs here.
 *
 * What it does carry is the half that is not taste: the answers that are the
 * same in every app and were simply forgotten in different ones.
 *
 *   app            target  focus  disabled  press  tap-hl  reduced-motion
 *   SET              yes     NO      NO      yes    yes         yes
 *   Number Knots     yes     NO      yes     yes    yes         yes
 *   Recall           NO      NO      NO      yes    yes          NO
 *   Brain Trainer    yes     NO      NO      yes    yes          NO
 *   Reversi          yes    yes      yes     yes    yes         yes
 *
 * Four of the five had no visible keyboard focus ring at all. Reversi is the
 * one that got everything right, so what follows is largely Reversi's own
 * mechanics with the colour taken out.
 *
 * ── Two layers, on purpose ──────────────────────────────────────────────────
 * The first layer changes nothing about size or position, so it is safe on
 * every button in an app that has never seen this file — including icon
 * buttons, segmented controls and grid cells, which a blanket `min-height`
 * would wreck.
 *
 * The sizing lives in an opt-in `.btn` class instead, so an app adopts it one
 * button at a time and can leave its dense controls alone.
 *
 * ── Overriding ──────────────────────────────────────────────────────────────
 *   --btn-focus     ring colour   (defaults to the Badhri Labs accent)
 *   --btn-target    tap size      (defaults to 44px, the documented minimum)
 *   --btn-disabled  dimming       (defaults to .45, Reversi's figure)
 */

:root {
  --_btn-focus-default: #7c3aed;
}
@media (prefers-color-scheme: dark) {
  :root { --_btn-focus-default: #a78bfa; }
}
:root[data-theme="dark"] {
  --_btn-focus-default: #a78bfa;
}
:root[data-theme="light"] {
  --_btn-focus-default: #7c3aed;
}

/* ── Layer one: no effect on layout, so it is safe everywhere ─────────────── */

button,
[role="button"],
.btn {
  /* iOS paints a grey flash on tap that fires even when the press is a scroll.
     Every app had already turned this off; it is here so a new one need not
     remember. */
  -webkit-tap-highlight-color: transparent;
  cursor: pointer;
}

/* The gap this file exists to close. `:focus-visible` rather than `:focus`, so
   the ring appears for keyboard and switch users and stays out of the way of a
   mouse or a thumb — which is why apps that styled `:focus` ended up removing
   it again. `outline` rather than a border or shadow: it is drawn outside the
   box, so it cannot shift the layout, and it follows a rounded button because
   modern engines curve the outline to the border radius. */
button:focus-visible,
[role="button"]:focus-visible,
.btn:focus-visible {
  outline: 2px solid var(--btn-focus, var(--_btn-focus-default));
  outline-offset: 2px;
}

/* A dead button that looks live is the same bug in three of the five apps. */
button:disabled,
[role="button"][aria-disabled="true"],
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: var(--btn-disabled, .45);
  cursor: not-allowed;
  /* A disabled control should not report a press, and `aria-disabled` alone
     does not stop one — unlike the real `disabled` attribute. */
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  button,
  [role="button"],
  .btn {
    transition: none;
    animation: none;
  }
}

/* ── Layer two: opt-in, because it does change size ───────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  /* 44px is the smallest reliable tap area on a phone; Recall's buttons sit
     under it today. `min-height` rather than `height` so a wrapped label
     grows the button instead of spilling out of it. */
  min-height: var(--btn-target, 44px);
  padding: 10px 16px;
  /* Buttons do not inherit type by default, which is how a button ends up in
     the browser's font in the middle of an app that set its own. */
  font: inherit;
  line-height: 1.2;
  text-align: center;
  /* Safari rounds and tints a bare button on its own. */
  -webkit-appearance: none;
  appearance: none;
  box-sizing: border-box;
  transition: transform .05s ease, opacity .15s ease;
}

/* Something has to happen on press, on a touch screen where there is no hover
   to confirm the target was hit. All five apps agreed on this already. */
.btn:active:not(:disabled):not([aria-disabled="true"]) {
  transform: translateY(1px);
}
