/** * IconButton — the shared icon-only button primitive (arch 09 §4 + §5). * * A square button holding a single `` (the controlled-vocabulary glyph * primitive) and nothing else. Because there is no visible text, an accessible * name is required: `label` becomes `aria-label` (APG button pattern) and, unless * overridden via `title`, the hover tooltip. * * Always ghost — borderless toolbar utility; the transparent border holds the * box size. Sizes are the control scale: `md` = `--control-height` (32px * square, the default), `lg` = `--control-height-lg` (40px — beside a lg * Button), `sm` = 24px (only nested inside another 32px control, e.g. a search * field's clear button). * * Hover follows the same one-elevation-step rule as Button, via the same * `--control-hover-fill` custom property; an open disclosure trigger * (`aria-expanded="true"`) holds the `--layer-02` fill. */ import type { ComponentPropsWithRef } from 'react'; import styles from './IconButton.module.css'; export interface IconButtonProps extends ComponentPropsWithRef<'button'> { /** Accessible name (required — there is no visible text). */ label: string; size?: 'sm' | 'md' | 'lg'; } export function IconButton({ label, size = 'md', className, type = 'button', title, ...rest }: IconButtonProps) { return (