/**
 * ARTBID Button System
 *
 * Single button system using .btn classes for artbid/button block
 *
 * Usage:
 * - ARTBID Button Block: .btn with .btn-* modifier classes
 * - Variants: .btn-primary, .btn-secondary, .btn-ghost, .btn-text
 * - Inverted: .btn-primary-inverted, .btn-secondary-inverted
 * - Sizes: .btn-sm, .btn-md (default), .btn-lg
 *
 * IMPORTANT: This file requires design-tokens/dist/tokens.css to be loaded first
 * The tokens are loaded via frontend-assets.php
 *
 * @package ARTBID
 * @since 2.0.0
 */

/* ============================================
   CSS CUSTOM PROPERTIES
   ============================================ */

:root {
    /* Button typography */
    --btn-font-family: "helvetica-neue-lt-pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    /* THE DEFAULT BUTTON TYPE (Yael's ARTBID Button card; Chuck 2026-10-11 —
       REVERSES the earlier "no uppercase" requirement): the site's caps, the
       header nav's size and tracking, one weight up so it holds on a solid
       black button. ONE text size for all three button sizes — a size changes
       the box, not the type. */
    --btn-font-weight: var(--font-weight-normal);
    --btn-text-transform: uppercase;
    --btn-letter-spacing: var(--font-letterSpacing-wider);

    /* THE FRAME (ruled 2026-10-05, Chuck + the button frame lab): four bars
       3px thick meeting at true MITRES — each joint runs from the frame's
       outer corner to its inner corner (45°), with a gap of HALF the bar width
       between the two angled ends; one colour (no bottom bevel). Drawn by a
       mask on ::before (see .btn-secondary below), coloured by
       --btn-frame-color — so ONE rule serves the black and the white frame,
       the thickness is ONE token, and the frame button is the solid button's
       exact size (it keeps the 1px border + the normal padding tokens).
       Replaces the 1018×183 SVG border-image (4px border, black sliced at 12 /
       white at 10, 8 hand-tuned "-3px" paddings). The corner pieces are drawn
       for the gap = width/2 proportion, so they scale with the token. */
    --btn-frame-width: 3px;
    --btn-frame-corner: calc(var(--btn-frame-width) * 1.35355); /* width + (width/2)/√2 */
    --btn-frame-mask:
        url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20270.711%20270.711'%3E%3Cpath%20d='M70.711%200%20L270.711%200%20L270.711%20200Z'/%3E%3Cpath%20d='M0%2070.711%20L200%20270.711%20L0%20270.711Z'/%3E%3C/svg%3E") top left / var(--btn-frame-corner) var(--btn-frame-corner) no-repeat,
        url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20270.711%20270.711'%3E%3Cpath%20d='M200%200%20L0%200%20L0%20200Z'/%3E%3Cpath%20d='M270.711%2070.711%20L70.711%20270.711%20L270.711%20270.711Z'/%3E%3C/svg%3E") top right / var(--btn-frame-corner) var(--btn-frame-corner) no-repeat,
        url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20270.711%20270.711'%3E%3Cpath%20d='M200%20270.711%20L0%20270.711%20L0%2070.711Z'/%3E%3Cpath%20d='M270.711%20200%20L70.711%200%20L270.711%200Z'/%3E%3C/svg%3E") bottom right / var(--btn-frame-corner) var(--btn-frame-corner) no-repeat,
        url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20270.711%20270.711'%3E%3Cpath%20d='M70.711%20270.711%20L270.711%20270.711%20L270.711%2070.711Z'/%3E%3Cpath%20d='M0%20200%20L200%200%20L0%200Z'/%3E%3C/svg%3E") bottom left / var(--btn-frame-corner) var(--btn-frame-corner) no-repeat,
        linear-gradient(#000 0 0) top center / calc(100% - 2 * var(--btn-frame-corner)) var(--btn-frame-width) no-repeat,
        linear-gradient(#000 0 0) bottom center / calc(100% - 2 * var(--btn-frame-corner)) var(--btn-frame-width) no-repeat,
        linear-gradient(#000 0 0) left center / var(--btn-frame-width) calc(100% - 2 * var(--btn-frame-corner)) no-repeat,
        linear-gradient(#000 0 0) right center / var(--btn-frame-width) calc(100% - 2 * var(--btn-frame-corner)) no-repeat;

    /* Button sizing - using design tokens */
    --btn-padding-y-sm: var(--spacing-scale-1_5); /* 6px */
    --btn-padding-x-sm: var(--spacing-scale-6);
    --btn-font-size-sm: var(--font-size-xs);

    --btn-padding-y-md: var(--spacing-scale-2_5); /* 10px */
    --btn-padding-x-md: var(--spacing-scale-8); /* "a bit more narrow and a bit longer" (Yael): the smaller caps make it slimmer, this makes it longer */
    --btn-font-size-md: var(--font-size-xs);

    --btn-padding-y-lg: var(--spacing-scale-3_5);
    --btn-padding-x-lg: var(--spacing-scale-10);
    --btn-font-size-lg: var(--font-size-xs);

    /* Minimum width (2026-08-25): a short label ("Bid") should still read as a
       proper button, not a tiny nub — best practice. Per size; the .btn-text
       (link-style) variant is EXCLUDED below. */
    /* Minimum widths one scale step smaller (Yael's ARTBID Button card, 2026-10-01:
       "fit to text a bit more narrow") — short labels stop being forced wide; the
       padding does the hugging. Was 80 / 112 / 144 (the 08-25 ruling). */
    --btn-min-width-sm: var(--spacing-scale-12); /* 3rem / 48px */
    --btn-min-width-md: var(--spacing-scale-16); /* 4rem / 64px */
    --btn-min-width-lg: var(--spacing-scale-20); /* 5rem / 80px */

    /* Button appearance */
    --btn-border-radius: var(--border-radius-brand, 0); /* Sharp corners for ARTBID */
    --btn-border-width: var(--border-width-1, 1px);
    --btn-transition: all var(--transition-duration-200, 200ms) var(--transition-timing-ease, ease);
    --btn-gap: var(--spacing-scale-2, 0.5rem);

    /* Focus styles */
    --btn-focus-outline-width: 2px;
    --btn-focus-outline-offset: 2px;
}

/* ============================================
   BUTTON FOUNDATION
   ============================================ */

.btn {
    /* Layout */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--btn-gap, 0.5rem);
    box-sizing: border-box; /* Ensure padding is included in width */

    /* Typography */
    font-family: var(--btn-font-family, "helvetica-neue-lt-pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);
    font-weight: var(--btn-font-weight, 500);
    text-transform: var(--btn-text-transform, none);
    letter-spacing: var(--btn-letter-spacing, normal);
    text-decoration: none;
    line-height: 1.2;

    /* Appearance */
    border-radius: var(--btn-border-radius, 0);
    border-width: var(--btn-border-width, 1px);
    border-style: solid;
    cursor: pointer;

    /* Transitions */
    transition: var(--btn-transition, all 200ms ease);

    /* Reset */
    outline: none;

    /* Default size (medium) - with fallbacks */
    padding: var(--btn-padding-y-md, 10px) var(--btn-padding-x-md, 16px);
    font-size: var(--btn-font-size-md, 1rem);
}

/* Focus states */
.btn:focus-visible {
    outline: var(--btn-focus-outline-width) solid var(--color-base-black);
    outline-offset: var(--btn-focus-outline-offset);
}

/* ============================================
   BUTTON SIZES
   ============================================ */

/* Small */
.btn.btn-sm {
    padding: var(--btn-padding-y-sm, 6px) var(--btn-padding-x-sm, 12px);
    font-size: var(--btn-font-size-sm, 0.875rem);
}

/* Medium (default) */
.btn.btn-md {
    padding: var(--btn-padding-y-md, 10px) var(--btn-padding-x-md, 16px);
    font-size: var(--btn-font-size-md, 1rem);
}

/* Large */
.btn.btn-lg {
    padding: var(--btn-padding-y-lg, 10px) var(--btn-padding-x-lg, 32px);
    font-size: var(--btn-font-size-lg, 1.125rem);
}

/* Minimum width per size (2026-08-25) — so a short label still forms a real,
   tappable button. EXCLUDES .btn-text (the link-style variant, which has no
   padding/border and should hug its text). A button set to width:100% (stacked /
   mobile / equal-grid track) is unaffected — min-width is below those widths. */
.btn.btn-sm:not(.btn-text) { min-width: var(--btn-min-width-sm, 5rem); }
.btn.btn-md:not(.btn-text),
.btn:not(.btn-sm):not(.btn-lg):not(.btn-text) { min-width: var(--btn-min-width-md, 7rem); }
.btn.btn-lg:not(.btn-text) { min-width: var(--btn-min-width-lg, 9rem); }

/* Small never drops under the smallest stated button height. */
.btn.btn-sm:not(.btn-text) { min-height: var(--button-height-sm); }

/* Touch screens: at least the stated Medium height (44), whatever the size —
   a finger needs more than the slim desktop box (Chuck 2026-10-11). The
   underline style is a link, outside the box scale. Large keeps ONE padding
   at every width (the old per-breakpoint scaling is gone). */
@media (pointer: coarse) {
    .btn:not(.btn-text) { min-height: var(--button-height-md); }
}

/* ============================================
   BUTTON VARIANTS
   ============================================ */

/* Primary (filled black) */
.btn-primary {
    background-color: var(--color-base-black, #000000);
    color: var(--color-base-white, #ffffff);
    border-color: var(--color-base-black, #000000);
}

.btn-primary:hover {
    background-color: var(--color-gray-900);
    border-color: var(--color-gray-900);
}

.btn-primary:active {
    background-color: var(--color-gray-800);
    border-color: var(--color-gray-800);
}

/* Secondary (outlined with art frame) - ARTBID signature design */
.btn-secondary {
    background-color: transparent;
    color: var(--color-base-black);
    position: relative;
    border-color: transparent; /* the base 1px border — the frame is drawn by ::before */
    --btn-frame-color: var(--color-base-black);
}

/* THE FRAME, both variants (see --btn-frame-* in :root). The pseudo covers the
   border box (inset = minus the 1px border); its colour is a variable, NOT
   currentColor, so the hover fill (which flips the text colour) never recolours
   the frame. ::after stays free for the loading spinner. */
.btn-secondary::before,
.btn-secondary-inverted::before {
    content: "";
    position: absolute;
    inset: calc(-1 * var(--btn-border-width, 1px));
    pointer-events: none;
    background: var(--btn-frame-color);
    -webkit-mask: var(--btn-frame-mask);
            mask: var(--btn-frame-mask);
}

.btn-secondary:hover {
    background-color: var(--color-base-black);
    color: var(--color-base-white);
}

.btn-secondary:active {
    background-color: var(--color-gray-900);
}

/* Ghost (subtle) */
.btn-ghost {
    background-color: transparent;
    color: var(--color-base-black);
    border-color: transparent;
}

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

.btn-ghost:active {
    background-color: var(--color-gray-200);
}

/* Text (link-style) */
.btn-text {
    background-color: transparent;
    color: var(--color-base-black);
    border: 0;
    padding-left: 0;
    padding-right: 0;
    /* THE LINE IS DRAWN, not decorated (Yael: "give button with underline the
       same animation as the others", 2026-10-09): the header nav's pattern —
       a hairline inside the box that draws left→right on hover (nav · footer
       links · journal Read more all do this). Rest = a resting hairline at
       gray-300 so the button still reads as a link; hover draws black over it. */
    position: relative;
    text-decoration: none;
    padding-bottom: calc(var(--spacing-scale-0_5) + var(--border-width-1));
    box-shadow: inset 0 calc(-1 * var(--border-width-1)) 0 0 var(--color-gray-300);
}

.btn-text::after,
.btn-text-inverted::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: var(--border-width-1);
    background: currentColor;
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform var(--transition-duration-300) var(--transition-timing-ease-out);
}

.btn-text:hover::after,
.btn-text:focus-visible::after,
.btn-text-inverted:hover::after,
.btn-text-inverted:focus-visible::after {
    transform: scaleX(1);
}

@media (prefers-reduced-motion: reduce) {
    .btn-text::after,
    .btn-text-inverted::after {
        transition: none;
    }
}

.btn-text:hover {
    color: var(--color-base-black);
}

.btn-text:active {
    color: var(--color-gray-700);
}

/* ============================================
   INVERTED VARIANTS (for dark backgrounds)
   ============================================ */

/* Primary Inverted (white filled) */
.btn-primary-inverted {
    background-color: var(--color-base-white);
    color: var(--color-base-black);
    border-color: var(--color-base-white);
}

.btn-primary-inverted:hover {
    background-color: var(--color-gray-100);
    border-color: var(--color-gray-100);
}

.btn-primary-inverted:active {
    background-color: var(--color-gray-200);
    border-color: var(--color-gray-200);
}

.btn-primary-inverted:focus-visible {
    outline-color: var(--color-base-white);
}

/* Secondary Inverted (white outlined) */
.btn-secondary-inverted {
    background-color: transparent;
    color: var(--color-base-white);
    position: relative;
    border-color: transparent;
    --btn-frame-color: var(--color-base-white);
}

.btn-secondary-inverted:hover {
    background-color: var(--color-base-white);
    color: var(--color-base-black);
}

.btn-secondary-inverted:active {
    background-color: var(--color-gray-100);
}

.btn-secondary-inverted:focus-visible {
    outline-color: var(--color-base-white);
}

/* Ghost Inverted */
.btn-ghost-inverted {
    background-color: transparent;
    color: var(--color-base-white);
    border-color: transparent;
}

.btn-ghost-inverted:hover {
    background-color: rgba(255, 255, 255, 0.1);
    border-color: transparent;
}

.btn-ghost-inverted:active {
    background-color: rgba(255, 255, 255, 0.2);
}

.btn-ghost-inverted:focus-visible {
    outline-color: var(--color-base-white);
}

/* Text Inverted */
.btn-text-inverted {
    background-color: transparent;
    color: var(--color-base-white);
    border: 0;
    padding-left: 0;
    padding-right: 0;
    /* same drawn line as .btn-text (the ::after rules sit with it above) */
    position: relative;
    text-decoration: none;
    padding-bottom: calc(var(--spacing-scale-0_5) + var(--border-width-1));
    box-shadow: inset 0 calc(-1 * var(--border-width-1)) 0 0 rgba(255, 255, 255, 0.4);
}

/* The size rules (.btn.btn-lg …, two classes) outrank the one-class text
   rules above, so a sized text button kept the size's side and bottom
   padding: the line ran past the words and sat a full padding under them.
   Two classes here, so text buttons hug their words like the app's
   (the 404 twin, 2026-11-09). */
.btn.btn-text,
.btn.btn-text-inverted {
    padding-left: 0;
    padding-right: 0;
    padding-bottom: calc(var(--spacing-scale-0_5) + var(--border-width-1));
}

.btn-text-inverted:hover {
    color: var(--color-base-white);
}

.btn-text-inverted:active {
    color: rgba(255, 255, 255, 0.7);
}

/* (2026-10-05) The "SECONDARY BUTTON HEIGHT COMPENSATION" block — eight
   hand-tuned "token − 3px" paddings that absorbed the old 4px frame border —
   is gone: the frame button now keeps the 1px border and the normal padding
   tokens, so it is the solid button's exact size by construction. */

/* ============================================
   DISABLED STATES
   ============================================ */

.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

/* ============================================
   BUTTON GROUPS (core/buttons wrapper)
   Note: Keep .wp-block-buttons for button group layouts
   ============================================ */

.wp-block-buttons {
    gap: var(--spacing-fluid-hero-button-gap, 1rem);
}

/* Responsive button group behavior */
@media (max-width: 639px) {
    .wp-block-buttons {
        flex-direction: column;
        align-items: stretch;
    }

    .wp-block-buttons .wp-block-button {
        width: 100%;
    }

    .wp-block-buttons .btn {
        width: 100%;
        justify-content: center;
    }
}

/* ============================================
   UTILITY HELPERS
   ============================================ */

/* Full width button */
.btn-full-width {
    width: 100%;
}

/* Icon buttons */
.btn svg {
    width: 1.25em;
    height: 1.25em;
    flex-shrink: 0;
}

/* Loading state */
.btn.is-loading {
    color: transparent;
    position: relative;
    pointer-events: none;
}

.btn.is-loading::after {
    content: "";
    position: absolute;
    width: 1em;
    height: 1em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: button-spin 0.6s linear infinite;
}

@keyframes button-spin {
    to { transform: rotate(360deg); }
}
