/*
 * Buttons — the one primitive used everywhere.
 *
 * Variants compose on the base `.btn`:
 *   .btn.btn--primary   — the single affirmative action on a screen
 *   .btn.btn--secondary — neutral, alongside a primary
 *   .btn.btn--ghost     — no background, subtle hover
 *   .btn.btn--block     — full-width
 *   .btn.btn--sm        — small variant (default size is the standard)
 *   .btn.btn--responsive — icon + label that collapses to icon-only on
 *                          small screens (wrap the text in `.btn__label`)
 *
 * Heroicons drop straight in (the helper renders inline SVG); `.btn`
 * sizes any child SVG and the flex gap spaces it from the label.
 *
 * States: default, :hover, :focus-visible, :active, :disabled.
 */

@layer components {
  .btn {
    /* Default (secondary) — white surface, never changes on hover;
       only the border darkens. Text is desaturated slate so the
       button reads as neutral chrome, never competing with primary.
       Three palette pulls (700 / 200 / 400) so a future palette
       tune-up propagates through the secondary button family in
       lockstep — see the discrepancy report §3b. */
    --btn-bg: var(--color-white);
    --btn-bg-hover: var(--color-white);
    --btn-fg: var(--color-slate-700);
    --btn-border: var(--color-slate-200);
    --btn-border-hover: var(--color-slate-400);
    --btn-ring: var(--color-primary);

    /* Focus-ring composition is button-specific (white halo + primary
       halo); the inner / outer widths don't map onto the single
       `--focus-ring-size` system token. */
    --btn-focus-inset:  2px;
    --btn-focus-outset: 4px;

    /* Active-press translate — the button is the only surface that
       presses; no system motion token covers this. */
    --btn-active-shift: 0.5px;

    /* Hairline border — 1px is the universal border width across the
       codebase; the token scale does not yet include a border-width
       ramp, so each component declares its own. */
    --btn-border-size: 1px;

    /* Icon size — Heroicon SVGs sit a touch larger than body type so
       they read clearly next to the label. */
    --btn-icon-size: 1.125rem;

    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: var(--space-10);
    padding: 0 var(--space-4);
    border: var(--btn-border-size) solid var(--btn-border);
    border-radius: var(--radius-md);
    background: var(--btn-bg);
    color: var(--btn-fg);
    font: inherit;
    font-weight: 500;
    font-size: var(--text-sm);
    line-height: var(--leading-none);
    text-decoration: none;
    cursor: pointer;
    user-select: none;
    transition: background-color var(--duration-base) var(--ease-out),
                border-color var(--duration-base) var(--ease-out),
                box-shadow var(--duration-base) var(--ease-out),
                transform var(--duration-fast) var(--ease-out);
  }

  .btn:hover {
    background: var(--btn-bg-hover);
    border-color: var(--btn-border-hover);
  }

  .btn:focus-visible {
    outline: none;
    /* Layered focus ring — inner white halo (separates the ring from
       the button surface) then outer primary halo. Two literals kept
       as component-local tokens since the inner halo width is shared
       with the outer-halo step, not with the system `--focus-ring-
       size` (2px) on its own. */
    box-shadow:
      0 0 0 var(--btn-focus-inset) var(--color-white),
      0 0 0 var(--btn-focus-outset) var(--btn-ring);
  }

  .btn:active {
    transform: translateY(var(--btn-active-shift));
  }

  .btn:disabled,
  .btn[aria-disabled="true"] {
    opacity: 0.55;
    cursor: not-allowed;
  }

  /* Variants --------------------------------------------------------- */

  .btn--primary {
    --btn-bg: var(--color-primary);
    --btn-bg-hover: var(--color-primary-hover);
    --btn-fg: var(--color-on-primary);
    --btn-border: var(--color-primary);
    --btn-border-hover: var(--color-primary-hover);
    --btn-ring: var(--color-primary);
  }

  .btn--secondary {
    /* Same as base .btn — listed for semantic intent. */
  }

  .btn--ghost {
    --btn-bg: transparent;
    --btn-bg-hover: var(--color-slate-100);
    --btn-border: transparent;
    --btn-border-hover: transparent;
  }

  /* Sizes ------------------------------------------------------------ */

  .btn--sm {
    min-height: var(--space-8);
    padding: 0 var(--space-3);
    font-size: var(--text-13);
  }

  /* Icon — any SVG inside a button (Heroicon) sized for the row and
     held at its intrinsic width so the label gets the remaining space. */
  .btn svg {
    flex: 0 0 auto;
    width: var(--btn-icon-size);
    height: var(--btn-icon-size);
  }

  /* Layout ----------------------------------------------------------- */

  .btn--block {
    display: flex;
    width: 100%;
  }

  /* Responsive — icon + label by default; below the mobile breakpoint
     the label collapses (kept in the DOM so screen readers still read
     it) and the button shrinks to a square icon button. Lets a dense
     toolbar stay usable on small screens.

       <button class="btn btn--primary btn--responsive">
         <%= heroicon "plus" %><span class="btn__label">New entry</span>
       </button> */
  @media (max-width: 600px) {
    .btn--responsive {
      gap: 0;
      padding-inline: 0;
      width: var(--space-10);
    }

    .btn--responsive.btn--sm {
      width: var(--space-8);
    }

    .btn--responsive .btn__label {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip: rect(0, 0, 0, 0);
      white-space: nowrap;
      border: 0;
    }
  }
}
