/* ============================================================
   components/mutton.css — Majestic V2 signature action button
   ------------------------------------------------------------
   The mutton keeps the two signature interactions of the brand:
     1. A left-to-right grapheme rolling-label wave.
     2. A marching technical dash border drawn on the button edge.
   Both are additive overlays: neither the rolling label nor the
   SVG border alters the button's intrinsic box, so hover/focus
   never reflows layout.

   Authoring contract (see shared/static/bootstrap/CLAUDE.md):
     <button class="mutton mutton--primary">
         <span class="mutton__icon"><svg class="majestic-icon" aria-hidden="true">
             <use href="…#save"></use></svg></span>
         <span class="mutton__label">Save changes</span>
     </button>

   Variants:  --primary --secondary --success --warning --danger
   Sizes:     --sm (32) · default (40) · --lg (48)
   Modifiers: --fill --icon-only --truncate --strong
   State is expressed through native/ARIA attributes:
     disabled | aria-busy="true" (loading) | aria-pressed="true" (toggle)

   Loads after majestic.css so the V2 base wins over any lower-level rules.
   Variants and sizes are authored with namespaced modifiers only
   (.mutton--primary, .mutton--sm, …); the legacy unnamespaced aliases were
   removed in the Phase 10 legacy-deletion pass.
   ============================================================ */

.mutton {
    /* Per-variant channel — the base is a neutral tonal (secondary) surface. */
    --mutton-bg: var(--surface-2);
    --mutton-fg: var(--text-color);
    --mutton-border: var(--border-color);
    --mutton-hover-bg: var(--surface-hover);
    --mutton-hover-fg: var(--text-color);
    --mutton-hover-border: var(--border-color-strong);
    --mutton-dash: var(--border-color-strong);
    --mutton-on-solid: var(--button-on-strong-color);

    --mutton-height: var(--control-height);
    --mutton-pad-x: 14px;
    --mutton-font-size: 0.8125rem;
    --mutton-radius: var(--radius-control);

    position: relative;
    isolation: isolate;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: var(--mutton-height);
    padding: 0 var(--mutton-pad-x);
    max-width: 100%;
    border: 1px solid var(--mutton-border);
    border-radius: var(--mutton-radius);
    background: var(--mutton-bg);
    color: var(--mutton-fg);
    font-family: var(--font-display);
    font-size: var(--mutton-font-size);
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    cursor: pointer;
    box-sizing: border-box;
    box-shadow: none;
    -webkit-user-select: none;
    user-select: none;
    transition:
        background-color var(--hover-transition-duration) var(--hover-transition-easing),
        color var(--hover-transition-duration) var(--hover-transition-easing),
        border-color var(--hover-transition-duration) var(--hover-transition-easing),
        transform var(--motion-fast) var(--ease-out) !important;
}

/* Links styled as muttons keep the flex box and drop prose underline. */
a.mutton { text-decoration: none; }

/* --- Structure slots ------------------------------------------------------ */

.mutton__icon {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    font-size: 1.125rem;
    line-height: 0;
}

.mutton__icon .majestic-icon,
.mutton__icon > svg { width: 1em; height: 1em; }

.mutton__icon > i { font-size: 0.95rem; line-height: 1; }

/* The label clips the rolling second line to exactly one text line. */
.mutton__label {
    position: relative;
    display: inline-block;
    height: 1em;
    line-height: 1em;
    overflow: hidden;
    vertical-align: middle;
    pointer-events: none;
}

.mutton__roll { display: inline-flex; }

.mutton__char {
    display: inline-block;
    position: relative;
    transition: transform var(--motion-expressive) var(--ease-out);
    transition-delay: calc(var(--char-index, 0) * 12ms);
}

.mutton__char::after {
    content: attr(data-char);
    position: absolute;
    left: 0;
    top: 100%;
    transition: inherit;
    transition-delay: inherit;
}

.mutton:hover .mutton__char,
.mutton:focus-visible .mutton__char { transform: translateY(-100%); }

/* --- Marching dash border ------------------------------------------------- */

.mutton__border {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    pointer-events: none;
    z-index: 2;
}

.mutton__border rect {
    fill: none;
    stroke: var(--mutton-dash);
    stroke-width: 1;
    stroke-linecap: butt;
    stroke-dasharray: 14 6;
    stroke-dashoffset: 0;
    opacity: 0;
    transition: opacity var(--motion-default) var(--ease-out);
}

@keyframes mutton-dash-march {
    to { stroke-dashoffset: -20; }
}

.mutton:hover .mutton__border rect,
.mutton:focus-visible .mutton__border rect,
.mutton[aria-pressed="true"] .mutton__border rect {
    opacity: 1;
    animation: mutton-dash-march 900ms linear infinite;
}

/* --- Focus / press / hover ------------------------------------------------ */

/* The dash path is the focus affordance — no extra glow ring. */
.mutton:focus-visible { outline: none; }
.mutton:hover { transform: translateY(-1px); }
.mutton:active { transform: scale(0.97); }

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

.mutton--primary {
    --mutton-bg: var(--primary-color);
    --mutton-fg: var(--button-on-primary-color);
    --mutton-border: transparent;
    --mutton-hover-bg: color-mix(in srgb, var(--primary-color) 82%, var(--background-solid));
    --mutton-hover-fg: var(--button-on-primary-color);
    --mutton-hover-border: transparent;
    --mutton-dash: var(--button-on-primary-color);
}

.mutton--secondary {
    --mutton-bg: var(--surface-2);
    --mutton-fg: var(--text-color);
    --mutton-border: var(--border-color);
    --mutton-hover-bg: var(--surface-hover);
    --mutton-hover-fg: var(--text-color);
    --mutton-hover-border: var(--border-color-strong);
    --mutton-dash: var(--border-color-strong);
}

.mutton--success {
    --mutton-bg: var(--success-background);
    --mutton-fg: var(--success-color);
    --mutton-border: var(--success-border-color);
    --mutton-hover-bg: color-mix(in srgb, var(--success-color) 22%, var(--surface-1));
    --mutton-hover-fg: var(--success-color);
    --mutton-hover-border: var(--success-color);
    --mutton-dash: var(--success-color);
}

.mutton--warning {
    --mutton-bg: var(--warning-background);
    --mutton-fg: var(--warning-color);
    --mutton-border: var(--warning-border-color);
    --mutton-hover-bg: color-mix(in srgb, var(--warning-color) 20%, var(--surface-1));
    --mutton-hover-fg: var(--warning-color);
    --mutton-hover-border: var(--warning-color);
    --mutton-dash: var(--warning-color);
}

.mutton--danger {
    --mutton-bg: var(--danger-background);
    --mutton-fg: var(--danger-color);
    --mutton-border: var(--danger-border-color);
    --mutton-hover-bg: color-mix(in srgb, var(--danger-color) 22%, var(--surface-1));
    --mutton-hover-fg: var(--danger-color);
    --mutton-hover-border: var(--danger-color);
    --mutton-dash: var(--danger-color);
}

/* Solid semantic fill — reserved for the final confirmation in an
   irreversible dialog (danger) or a confirmed primary success action. */
.mutton--danger.mutton--strong {
    --mutton-bg: var(--danger-color);
    --mutton-fg: var(--mutton-on-solid);
    --mutton-border: transparent;
    --mutton-hover-bg: color-mix(in srgb, var(--danger-color) 82%, var(--background-solid));
    --mutton-hover-fg: var(--mutton-on-solid);
    --mutton-hover-border: transparent;
    --mutton-dash: var(--mutton-on-solid);
}

.mutton--success.mutton--strong {
    --mutton-bg: var(--success-color);
    --mutton-fg: var(--mutton-on-solid);
    --mutton-border: transparent;
    --mutton-hover-bg: color-mix(in srgb, var(--success-color) 82%, var(--background-solid));
    --mutton-hover-fg: var(--mutton-on-solid);
    --mutton-hover-border: transparent;
    --mutton-dash: var(--mutton-on-solid);
}

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

/* --- Toggle (pressed) state ---------------------------------------------- */

.mutton[aria-pressed="true"] {
    --mutton-bg: color-mix(in srgb, var(--primary-color) 16%, var(--surface-2));
    --mutton-fg: var(--text-color);
    --mutton-border: color-mix(in srgb, var(--primary-color) 45%, var(--border-color));
    --mutton-hover-bg: color-mix(in srgb, var(--primary-color) 22%, var(--surface-2));
    --mutton-hover-fg: var(--text-color);
}

/* Inset selection marker on the leading edge. */
.mutton[aria-pressed="true"]::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 3px;
    height: 55%;
    transform: translateY(-50%);
    border-radius: 0 2px 2px 0;
    background: var(--primary-color);
    z-index: 2;
}

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

.mutton--sm {
    --mutton-height: var(--control-height-sm);
    --mutton-pad-x: 10px;
    --mutton-font-size: 0.75rem;
    gap: 6px;
}

.mutton--lg {
    --mutton-height: var(--control-height-lg);
    --mutton-pad-x: 20px;
    --mutton-font-size: 0.875rem;
    gap: 10px;
}

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

.mutton--fill { display: flex; width: 100%; }

.mutton--icon-only {
    width: var(--mutton-height);
    padding: 0;
    gap: 0;
}
.mutton--icon-only .mutton__label { display: none; }

/* Constrained regions: ellipsis + shared tooltip carry the full label. */
.mutton--truncate { min-width: 0; }
.mutton--truncate .mutton__label {
    display: block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    height: auto;
    line-height: 1.2;
}

/* --- Loading -------------------------------------------------------------- */

/* The label stays in the box (visually hidden) so the measured width is
   preserved while a spinner takes its place. */
.mutton[aria-busy="true"] {
    pointer-events: none;
    color: color-mix(in srgb, var(--mutton-fg) 55%, transparent);
}
.mutton[aria-busy="true"] .mutton__label,
.mutton[aria-busy="true"] .mutton__icon { opacity: 0; }
.mutton[aria-busy="true"]::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 1em;
    height: 1em;
    margin: -0.5em 0 0 -0.5em;
    border: 2px solid color-mix(in srgb, currentColor 35%, transparent);
    border-top-color: currentColor;
    border-radius: 50%;
    animation: mutton-spin 700ms linear infinite;
    z-index: 3;
}
@keyframes mutton-spin { to { transform: rotate(360deg); } }

/* --- Disabled ------------------------------------------------------------- */

.mutton:disabled,
.mutton[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
    transform: none;
    box-shadow: none;
}
.mutton:disabled .mutton__border rect,
.mutton[aria-disabled="true"] .mutton__border rect { opacity: 0 !important; animation: none !important; }

/* --- Reduced motion ------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .mutton:hover,
    .mutton:active { transform: none; }
    .mutton__char { transition: none; }
    .mutton:hover .mutton__char,
    .mutton:focus-visible .mutton__char { transform: none; }
    /* Dashes appear statically on hover / focus, but do not march. */
    .mutton__border rect { transition: opacity var(--motion-default) linear; }
    .mutton:hover .mutton__border rect,
    .mutton:focus-visible .mutton__border rect,
    .mutton[aria-pressed="true"] .mutton__border rect { animation: none; opacity: 1; }
    .mutton[aria-busy="true"]::after { animation: none; }
}

/* --- Forced colors -------------------------------------------------------- */

@media (forced-colors: active) {
    .mutton { border: 1px solid ButtonText; }
    .mutton:focus-visible { outline: 2px solid Highlight; outline-offset: 2px; }
    .mutton__border rect { stroke: ButtonText; }
    .mutton[aria-pressed="true"]::before { background: Highlight; }
}
