/* =====================================================================
   Vatar · components/button.css · v1.1.0 (19 Oct 2026; comments v1.3.0)
   Direction B · Angular / chamfered (user pick). Spec: design-system.md §8.1.
   Load after tokens.css. Every value is a token from tokens.css; the only
   other custom properties are this file's private --_* knobs, set from tokens.

   Markup (links use the same classes on <a>):
   <button class="btn btn--primary btn--md" type="button">
     <span class="btn__face">
       <span class="btn__label">Play now</span>
       <svg class="arrow" …aria-hidden="true">…</svg>
       <span class="btn__spin" aria-hidden="true"></span>
     </span>
   </button>

   Variants: btn--primary · btn--secondary · btn--ghost · btn--icon (add to a
   variant; needs aria-label) · btn--hero (primary only, one per page).
   Sizes:    btn--sm 44 · btn--md 52 (default) · btn--lg 60 · btn--hero 64px face.
   States:   :hover :active :focus-visible :disabled, plus .is-loading
             (with aria-busy="true") and .is-disabled (for <a>, with
             aria-disabled="true" and no href). .is-hover / .is-active /
             .is-focus force a state for static specimens only.

   The outer element never moves: it is the hit area, the focus-ring box and
   the slab (::before). Only .btn__face moves, so the target never slides
   away from the pointer and the ring never jumps.
   ===================================================================== */

.btn {
  /* size knobs (md default) */
  --_h: var(--button-height-md);
  --_px: var(--button-padding-x-md);
  --_ch: var(--button-chamfer-md);
  --_off: var(--button-offset-md);
  --_ico: var(--button-icon-size-md);
  --_fs: var(--type-button-font-size);
  --_fw: var(--type-button-font-weight);
  --_ls: var(--type-button-letter-spacing);
  /* press travel = the slab offset; loading holds the plate half-way */
  --_travel: var(--_off);
  --_hold: calc(var(--_off) / 2);
  /* two clipped corners: top-left and bottom-right */
  --_clip: polygon(var(--_ch) 0, 100% 0, 100% calc(100% - var(--_ch)), calc(100% - var(--_ch)) 100%, 0 100%, 0 var(--_ch));

  position: relative;
  display: inline-flex;
  flex: none;
  vertical-align: top;
  isolation: isolate;
  margin: 0;
  padding: 0 var(--_off) var(--_off) 0; /* room for the slab, right and down */
  border: 0;
  border-radius: var(--button-radius);
  background: none;
  color: var(--_label);
  font-family: var(--type-button-font-family);
  font-size: var(--_fs);
  font-weight: var(--_fw);
  line-height: var(--type-button-line-height);
  letter-spacing: var(--_ls);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.btn--sm {
  --_h: var(--button-height-sm); --_px: var(--button-padding-x-sm);
  --_ch: var(--button-chamfer-sm); --_off: var(--button-offset-sm); --_ico: var(--button-icon-size-sm);
  --_fs: var(--type-button-sm-font-size); --_ls: var(--type-button-sm-letter-spacing);
}
.btn--lg {
  --_h: var(--button-height-lg); --_px: var(--button-padding-x-lg);
  --_ch: var(--button-chamfer-lg); --_off: var(--button-offset-lg); --_ico: var(--button-icon-size-lg);
}
.btn--hero {
  --_h: var(--button-height-hero); --_px: var(--button-padding-x-hero);
  --_ch: var(--button-chamfer-hero); --_off: var(--button-offset-hero); --_ico: var(--button-icon-size-hero);
  --_fs: var(--button-hero-font-size); --_fw: var(--button-hero-font-weight);
}

/* ---------- the plate (face) ---------- */
.btn__face {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--button-gap);
  height: var(--_h);
  padding-inline: var(--_px);
  border-radius: var(--button-radius);
  clip-path: var(--_clip);
  background-color: var(--_face);
  color: var(--_label);
  transform: translate(0, 0);
  transition:
    transform var(--button-duration-hover) var(--motion-easing-standard),
    background-color var(--button-duration-hover) var(--motion-easing-standard),
    box-shadow var(--button-duration-hover) var(--motion-easing-standard),
    color var(--button-duration-hover) var(--motion-easing-standard);
}
.btn__label, .btn svg { position: relative; z-index: 2; }
.btn svg { width: var(--_ico); height: var(--_ico); flex: none; }
.btn .arrow { transition: transform var(--button-duration-hover) var(--motion-easing-standard); }
.btn--icon .btn__face { width: var(--_h); padding-inline: 0; }

/* ---------- the slab: same chamfered plate, offset down-right (a painted sign's drop shadow) ---------- */
.btn::before {
  content: "";
  position: absolute;
  z-index: 0;
  inset: var(--_off) 0 0 var(--_off);
  clip-path: var(--_clip);
  background: var(--_slab);
}

/* secondary stroke: the face is the stroke colour, face::before is the fill inset by the stroke.
   Inner chamfer = chamfer − stroke × (2 − √2) so the stroke is even along the cut. */
.btn__face::before {
  content: "";
  position: absolute;
  z-index: 0;
  inset: var(--_stroke, 0px);
  --_chi: calc(var(--_ch) - var(--_stroke, 0px) * 0.586);
  clip-path: polygon(var(--_chi) 0, 100% 0, 100% calc(100% - var(--_chi)), calc(100% - var(--_chi)) 100%, 0 100%, 0 var(--_chi));
  background: var(--_fill, transparent);
  transition: background-color var(--button-duration-hover) var(--motion-easing-standard);
}

/* ---------- variants ---------- */
.btn--primary {
  --_face: var(--button-primary-bg);
  --_face-hover: var(--button-primary-bg-hover);
  --_face-pressed: var(--button-primary-bg-pressed);
  --_label: var(--button-primary-text);
  --_slab: repeating-linear-gradient(var(--button-stripe-angle), var(--button-primary-slab) 0 var(--space-0-5), var(--button-primary-hatch) var(--space-0-5) var(--space-1));
}
.btn--secondary {
  --_stroke: var(--button-border-width);
  --_face: var(--button-secondary-border);
  --_face-hover: var(--button-secondary-border);
  --_face-pressed: var(--button-secondary-border);
  --_fill: var(--button-secondary-bg);
  --_label: var(--button-secondary-text);
  --_slab: var(--button-secondary-slab);
}
.btn--ghost {
  --_off: 0px;
  --_face: transparent;
  --_face-hover: var(--button-ghost-bg-hover);
  --_face-pressed: var(--button-ghost-bg-pressed);
  --_label: var(--button-ghost-text);
  padding: 0;
}
.btn--ghost::before { display: none; }
.btn--ghost .btn__face { clip-path: none; }

/* ghost: four HUD corner brackets that lock on when hovered */
.btn--ghost::after {
  content: "";
  position: absolute;
  z-index: 2;
  pointer-events: none;
  inset: calc(var(--button-ghost-bracket-inset) * -1);
  background:
    linear-gradient(var(--button-ghost-bracket), var(--button-ghost-bracket)) top left / var(--button-ghost-bracket-size) var(--button-ghost-bracket-width) no-repeat,
    linear-gradient(var(--button-ghost-bracket), var(--button-ghost-bracket)) top left / var(--button-ghost-bracket-width) var(--button-ghost-bracket-size) no-repeat,
    linear-gradient(var(--button-ghost-bracket), var(--button-ghost-bracket)) top right / var(--button-ghost-bracket-size) var(--button-ghost-bracket-width) no-repeat,
    linear-gradient(var(--button-ghost-bracket), var(--button-ghost-bracket)) top right / var(--button-ghost-bracket-width) var(--button-ghost-bracket-size) no-repeat,
    linear-gradient(var(--button-ghost-bracket), var(--button-ghost-bracket)) bottom left / var(--button-ghost-bracket-size) var(--button-ghost-bracket-width) no-repeat,
    linear-gradient(var(--button-ghost-bracket), var(--button-ghost-bracket)) bottom left / var(--button-ghost-bracket-width) var(--button-ghost-bracket-size) no-repeat,
    linear-gradient(var(--button-ghost-bracket), var(--button-ghost-bracket)) bottom right / var(--button-ghost-bracket-size) var(--button-ghost-bracket-width) no-repeat,
    linear-gradient(var(--button-ghost-bracket), var(--button-ghost-bracket)) bottom right / var(--button-ghost-bracket-width) var(--button-ghost-bracket-size) no-repeat;
  opacity: 0;
  transform: scale(var(--button-ghost-bracket-scale-from));
  transition:
    opacity var(--button-duration-hover) var(--motion-easing-standard),
    transform var(--button-duration-release) var(--button-easing-release);
}

/* hero: the Vatar signal stripe before the arrow (monochrome, label colour; never amber) */
.btn--hero .btn__face { padding-right: calc(var(--button-padding-x-hero) + var(--space-12)); }
.btn--hero .btn__face::after {
  content: "";
  position: absolute;
  z-index: 1;
  top: 0;
  bottom: 0;
  right: calc(var(--space-12) + var(--space-1));
  width: var(--space-4);
  background: linear-gradient(90deg,
    var(--button-hero-stripe) 0 var(--space-1),
    transparent var(--space-1) calc(var(--space-1) * 2),
    var(--button-hero-stripe) calc(var(--space-1) * 2) calc(var(--space-1) * 3),
    transparent 0);
  transform: skewX(var(--button-hero-stripe-skew));
}
.btn--hero .arrow { position: absolute; right: var(--space-5); }

/* ---------- hover: the plate rises up-left (spring), the offset grows ---------- */
.btn.is-hover .btn__face {
  transform: translate(calc(var(--button-lift) * -1), calc(var(--button-lift) * -1));
  background-color: var(--_face-hover);
  transition-duration: var(--button-duration-release);
  transition-timing-function: var(--button-easing-release);
}
@media (hover: hover) {
  .btn:not(:disabled):not(.is-disabled):not(.is-loading):hover .btn__face {
    transform: translate(calc(var(--button-lift) * -1), calc(var(--button-lift) * -1));
    background-color: var(--_face-hover);
    transition-duration: var(--button-duration-release);
    transition-timing-function: var(--button-easing-release);
  }
}
.btn--secondary.is-hover .btn__face::before { background-color: var(--button-secondary-bg-hover); }
@media (hover: hover) {
  .btn--secondary:not(:disabled):not(.is-disabled):not(.is-loading):hover .btn__face::before { background-color: var(--button-secondary-bg-hover); }
}
.btn--ghost.is-hover .btn__face { transform: none; }
@media (hover: hover) {
  .btn--ghost:not(:disabled):not(.is-disabled):not(.is-loading):hover .btn__face { transform: none; }
}
.btn--ghost.is-hover::after { opacity: 1; transform: scale(1); }
@media (hover: hover) {
  .btn--ghost:not(:disabled):not(.is-disabled):not(.is-loading):hover::after { opacity: 1; transform: scale(1); }
}
.btn.is-hover .arrow { transform: translateX(var(--motion-distance-nudge)); }
@media (hover: hover) {
  .btn:not(:disabled):not(.is-disabled):not(.is-loading):hover .arrow { transform: translateX(var(--motion-distance-nudge)); }
}

/* ---------- pressed: the plate slides flush onto its slab (60ms, exit easing) ---------- */
.btn:not(:disabled):not(.is-disabled):not(.is-loading):active .btn__face,
.btn.is-active .btn__face {
  transform: translate(var(--_travel), var(--_travel));
  background-color: var(--_face-pressed);
  transition-duration: var(--button-duration-press);
  transition-timing-function: var(--button-easing-press);
}
.btn--secondary:not(:disabled):not(.is-disabled):not(.is-loading):active .btn__face::before,
.btn--secondary.is-active .btn__face::before { background-color: var(--button-secondary-bg-pressed); }
.btn--ghost:not(:disabled):not(.is-disabled):not(.is-loading):active .btn__face,
.btn--ghost.is-active .btn__face { transform: none; }
.btn--ghost:not(:disabled):not(.is-disabled):not(.is-loading):active::after,
.btn--ghost.is-active::after { opacity: 1; transform: scale(var(--button-ghost-bracket-scale-press)); transition-duration: var(--button-duration-press); }

/* ---------- focus-visible: a 2px lilac rectangle around plate + slab (HUD selection box) ---------- */
.btn:focus-visible, .btn.is-focus { outline: var(--focus-ring-width) solid var(--focus-ring-color); outline-offset: var(--focus-ring-offset); }
.btn:focus:not(:focus-visible) { outline: none; }

/* ---------- loading: plate held half-down, hazard stripes scroll across the face ---------- */
.btn.is-loading { cursor: progress; }
.btn.is-loading .btn__label, .btn.is-loading .arrow, .btn.is-loading .btn__face > svg { visibility: hidden; }
.btn__spin {
  display: none;
  position: absolute;
  z-index: 3;
  left: 50%;
  top: 50%;
  width: var(--space-5);
  height: var(--space-5);
  margin: calc(var(--space-5) / -2) 0 0 calc(var(--space-5) / -2);
  border-radius: var(--radius-pill); /* the spinner is a ring, not a button shape */
  border: var(--border-width-thick) solid currentColor;
  border-right-color: transparent;
  animation: btn-spin var(--motion-duration-entrance) var(--motion-easing-linear) infinite;
}
.btn.is-loading .btn__spin { display: block; }
.btn.is-loading .btn__face { transform: translate(var(--_hold), var(--_hold)); }
.btn.is-loading .btn__face::before {
  background-image: repeating-linear-gradient(var(--button-stripe-angle), var(--button-loading-stripe) 0 var(--space-2), transparent var(--space-2) var(--space-4));
  background-size: calc(var(--space-4) * 1.4142) 100%;
  animation: btn-stripe var(--motion-duration-entrance) var(--motion-easing-linear) infinite;
}
.btn--primary.is-loading .btn__face::before { inset: 0; clip-path: none; }
.btn--hero.is-loading .btn__face::after { visibility: hidden; }
.btn--ghost.is-loading .btn__face { transform: none; }
.btn--ghost.is-loading::after { opacity: 1; transform: scale(1); }
@keyframes btn-spin { to { transform: rotate(360deg); } }
@keyframes btn-stripe { to { background-position: calc(var(--space-4) * 1.4142) 0; } }

/* ---------- disabled: plate pushed flush onto its slab, flat colours ---------- */
.btn:disabled, .btn.is-disabled {
  cursor: not-allowed;
  --_face: var(--button-primary-bg-disabled);
  --_label: var(--button-primary-text-disabled);
  --_slab: var(--button-primary-bg-disabled);
  --_fill: var(--button-primary-bg-disabled);
}
.btn--secondary:disabled, .btn--secondary.is-disabled {
  --_face: var(--button-secondary-border-disabled);
  --_fill: var(--button-secondary-bg);
  --_label: var(--button-secondary-text-disabled);
}
.btn--ghost:disabled, .btn--ghost.is-disabled { --_face: transparent; --_fill: transparent; --_label: var(--button-ghost-text-disabled); }
.btn:disabled .btn__face, .btn.is-disabled .btn__face { transform: translate(var(--_off), var(--_off)); }
.btn:disabled::after, .btn.is-disabled::after { visibility: hidden; }
.btn--hero:disabled .btn__face::after, .btn--hero.is-disabled .btn__face::after { opacity: var(--opacity-disabled); }

/* ---------- reduced motion: no lift, spring, bracket zoom or animated stripes.
   The press still shows as an instant (unanimated) shift plus the pressed colour (WCAG 2.3.3).
   button.lift, the bracket scales and motion.easing.spring are already neutralised in tokens.css. ---------- */
@media (prefers-reduced-motion: reduce) {
  .btn__face, .btn::before, .btn::after, .btn__face::before, .btn .arrow {
    transition-property: background-color, color, box-shadow, opacity !important;
    transition-duration: var(--motion-duration-fast) !important;
    transition-timing-function: var(--motion-easing-standard) !important;
  }
  .btn--ghost::after { transform: none !important; }
  .btn__spin { animation: none; border-right-color: currentColor; border-top-color: transparent; opacity: var(--opacity-muted); }
  .btn.is-loading .btn__face::before { animation: none; }
}

/* ---------- forced colours (Windows High Contrast): real border, decorative layers drop out ---------- */
@media (forced-colors: active) {
  .btn__face { border: var(--border-width-thick) solid ButtonText; }
  .btn::before, .btn::after, .btn__face::before, .btn__face::after { forced-color-adjust: auto; background: none !important; }
}
