/**
 * Button — the shared action-button primitive (arch 09 §4).
 *
 * Every textual action button in the app is one of these. The component owns the
 * base look (Button.module.css) so instances can't drift; call sites compose
 * `className` for layout-specific additions only (flex, margins), never to
 * restyle the control.
 *
 * Variants are the arch 09 §4 taxonomy:
 * - **primary** — filled `--accent`; at most one per region (emphasis hierarchy).
 * - **secondary** — bordered, `--bg` fill (the field-on-layer treatment).
 * - **ghost** — borderless; utilities in toolbars/headers that should recede.
 *   (A transparent border still holds the box size so hover doesn't shift
 *   neighbours.)
 * - **soft-accent** — ghost on an `--accent-soft` wash; low-emphasis solicitation.
 * - **danger** — filled `--support-error`; destructive confirm actions.
 * - **danger-outline** — secondary geometry with a red label, filling solid red
 *   on hover/focus (arch 10 — a destructive control signals danger before it
 *   acts). For destructive actions that sit among peers (a detail view's
 *   Delete); the filled `danger` stays reserved for the confirm step.
 *
 * Sizes are the control scale (tokens.css): `md` = `--control-height` (32px, the
 * default — toolbars, forms, dialog action rows), `lg` = `--control-height-lg`
 * (40px — standalone primary CTAs).
 *
 * Hover on secondary/ghost fills one elevation step above the surface (arch 09
 * §4). The step is resolved by the `--control-hover-fill` custom property:
 * defaults to `--layer-01` (controls on the `--bg` canvas); elevated surfaces
 * (the header, modal cards) set `--control-hover-fill: var(--layer-02)` once and
 * every Button/IconButton on them steps up automatically.
 */

import type { ComponentPropsWithRef } from 'react';
import styles from './Button.module.css';

type ButtonVariant =
  | 'primary'
  | 'secondary'
  | 'ghost'
  | 'soft-accent'
  | 'danger'
  | 'danger-outline';

export interface ButtonProps extends ComponentPropsWithRef<'button'> {
  variant?: ButtonVariant;
  size?: 'md' | 'lg';
}

const VARIANT_CLASS: Record<ButtonVariant, string> = {
  primary: styles.primary,
  secondary: styles.secondary,
  ghost: styles.ghost,
  'soft-accent': styles.softAccent,
  danger: styles.danger,
  'danger-outline': styles.dangerOutline,
};

export function Button({
  variant = 'secondary',
  size = 'md',
  className,
  type = 'button',
  ...rest
}: ButtonProps) {
  return (
    <button
      type={type}
      className={[styles.button, VARIANT_CLASS[variant], size === 'lg' && styles.lg, className]
        .filter(Boolean)
        .join(' ')}
      {...rest}
    />
  );
}
