/* ========================================================
   BUTTONS  (redesigned v2.3.0 for Clay & Butter)
   ========================================================
   Five kinds, and a button is always exactly one of them:

     PRIMARY    the one thing this screen is for. Solid clay, white label.
                One per screen. Two primaries is a screen with no primary.
     SECONDARY  everything else that is safe. Outlined, transparent fill.
     DANGER     destructive. Tinted at rest so it is not mistaken for a
                secondary, solid red once the pointer is on it.
     GHOST      a button that has to sit inside dense furniture — a table
                toolbar, a card header. No fill, no border, until hovered.
     EDIT/SMALL the compact variants of the above for table rows.

   MOVEMENT LIVES IN components/motion.css, NOT HERE. The press bounce, the
   hover lift and the reduced-motion opt-out are declared once there for
   every tappable thing in the app; this file declares what a button LOOKS
   like at rest, on hover and on focus. Splitting it that way is what stops a
   sixth button variant being added next year with its own slightly
   different 0.25s ease-in-out.

   THE HOVER IS FOUR CHANGES AT ONCE, and each is doing a job:
     colour     the fill deepens one step — the state change you can see
                from across the room
     lift       translateY(-1px), from motion.css — the affordance
     shadow     --elev-1 to --elev-hover, softer and WIDER, not darker, so
                the button reads as rising rather than as the shadow being
                turned up
     label      on the outlined variants the text takes the brand ink, which
                is what makes a bordered button feel like it woke up

   All four are on --dur-fast (120ms). A hover slower than about 150ms feels
   like the interface is thinking about it.
   ======================================================== */

/* Base Button Class */
.btn, .btn-primary, .btn-secondary, .btn-submit, .btn-danger, .btn-action,
.btn-edit, .btn-import, .btn-export, .btn-delete, .btn-ghost {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;                       /* standardised icon spacing */
    /* --radius-md, which is --radius-lg minus --space-2: a button sitting
       8px inside a card is concentric with it by construction. See the
       RADIUS block in base/variables.css. */
    border-radius: var(--radius-md);
    font-weight: 600;
    font-family: inherit;
    border: 1px solid transparent;  /* declared even when invisible, so the
                                       outlined variants do not change size
                                       when a border appears on hover */
    cursor: pointer;
    padding: 10px 16px;
    min-height: 44px;               /* the WCAG 2.5.8 / iOS touch minimum */
    font-size: 14px;
    line-height: 1.2;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;  /* the grey flash Android
                                       paints over the bounce, which makes
                                       the bounce look like a rendering
                                       glitch on exactly the devices the
                                       bounce is for */
    /* The transition list is in components/motion.css so every tappable
       element in the app shares one. Do not add a `transition:` here — a
       second declaration later in the cascade silently replaces it. */
}

/* Focus. A 2px ring at 2px offset, on --brand in light and on --brand-ink in
   dark, which is the lighter of the two on that theme. :focus-visible, not
   :focus, so a mouse click does not leave a ring behind — but note the ring
   must never be removed outright: it is the only affordance a keyboard user
   has, and this app is used with a keyboard at the weighbridge desk. */
.btn:focus-visible, .btn-primary:focus-visible, .btn-secondary:focus-visible,
.btn-submit:focus-visible, .btn-danger:focus-visible, .btn-edit:focus-visible,
.btn-import:focus-visible, .btn-export:focus-visible, .btn-delete:focus-visible,
.btn-action:focus-visible, .btn-ghost:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
}
html.dark-theme .btn:focus-visible,
html.dark-theme .btn-primary:focus-visible,
html.dark-theme .btn-secondary:focus-visible,
html.dark-theme .btn-submit:focus-visible,
html.dark-theme .btn-danger:focus-visible,
html.dark-theme .btn-ghost:focus-visible {
    outline-color: var(--brand-ink);
}

/* ---- PRIMARY / SUBMIT --------------------------------------------------
   `color` is --on-brand, NOT #ffffff. In dark mode --brand is the lighter
   clay (#D6947B) and white text on it is 2.2:1; --on-brand flips to the
   near-black page ink and keeps it at 7.1:1. See the token block in
   layout/main.css. */
.btn-primary, .btn-submit, .btn--primary {
    background: var(--brand);
    color: var(--on-brand);
    border-color: var(--brand);
    box-shadow: var(--elev-1);
}
@media (hover: hover) and (pointer: fine) {
    .btn-primary:hover, .btn-submit:hover, .btn--primary:hover {
        background: var(--brand-hover);
        border-color: var(--brand-hover);
        box-shadow: var(--elev-hover);
    }
}
/* Touch devices get the colour change on :active instead, since there is no
   hover to give it to them. */
.btn-primary:active, .btn-submit:active, .btn--primary:active {
    background: var(--brand-hover);
    border-color: var(--brand-hover);
    box-shadow: var(--elev-1);
}

/* ---- SECONDARY ---------------------------------------------------------
   Transparent, not --surface. On the butter page a white-filled secondary
   button looks like a small card; transparent lets the page show through and
   the outline do the work, which is what makes it read as secondary at all.
   Inside a white card it is invisible-filled either way. */
.btn-secondary, .btn--secondary {
    background: transparent;
    border-color: var(--border-strong);
    color: var(--text-muted);
}
@media (hover: hover) and (pointer: fine) {
    .btn-secondary:hover, .btn--secondary:hover {
        background: var(--brand-wash);
        border-color: var(--brand);
        color: var(--brand-ink);
        box-shadow: var(--elev-1);
    }
}
.btn-secondary:active, .btn--secondary:active {
    background: var(--brand-wash-strong);
    border-color: var(--brand);
    color: var(--brand-ink);
}
html.dark-theme .btn-secondary, html.dark-theme .btn--secondary {
    background: var(--surface-raised);
}
html.dark-theme .btn-secondary:hover, html.dark-theme .btn--secondary:hover {
    background: var(--brand-wash-strong);
}

/* ---- DANGER ------------------------------------------------------------
   Tinted at rest, solid on hover. The tint is what stops "Delete" reading as
   just another secondary in a row of table actions; the solid fill on hover
   is the last chance to notice what is about to be pressed.

   Deleting is SOFT in this app (30-day recycle bin, see CLAUDE.md), which is
   why this is a warning and not an interrogation. */
.btn-danger {
    background: rgba(var(--accent-red-rgb), 0.12);
    color: var(--negative-ink);
    border-color: rgba(var(--accent-red-rgb), 0.30);
}
@media (hover: hover) and (pointer: fine) {
    .btn-danger:hover {
        background: var(--negative);
        color: var(--on-negative);
        border-color: var(--negative);
        box-shadow: var(--elev-hover);
    }
}
.btn-danger:active {
    background: var(--negative);
    color: var(--on-negative);
    border-color: var(--negative);
}

/* ---- GHOST -------------------------------------------------------------
   For dense furniture: table toolbars, card headers, the places where a
   bordered button per action turns the header into a fence. */
.btn-ghost {
    background: transparent;
    color: var(--text-muted);
    border-color: transparent;
    box-shadow: none;
}
@media (hover: hover) and (pointer: fine) {
    .btn-ghost:hover {
        background: var(--brand-wash);
        color: var(--brand-ink);
    }
}
.btn-ghost:active { background: var(--brand-wash-strong); color: var(--brand-ink); }

/* ---- THE TOOLBAR TRIO: EXPORT / IMPORT / DELETE ------------------------
   Moved here from templates/records.html's <style> block in v2.8.0. They had
   never been anywhere else — the base selector list at the top of this file
   named .btn-import and .btn-export, so those two got the shape, the radius
   and the touch target from here and their COLOUR from a page-level block
   that also overrode `border-radius` back to --radius-sm and replaced the
   motion layer's easing with `transition: all 0.2s`. `.btn-delete` was not
   in this file at all.

   All three are tinted at rest and solid on hover, the same grammar
   .btn-danger uses: a row of toolbar buttons where one is filled reads as
   one real action and two decorations, which is not what a CSV export is.

   .btn-action is NOT a variant. It is the SIZE these three are used at —
   see below — and carries no colour of its own, which is why every call site
   pairs it with one of the three. */
.btn-export {
    background: var(--brand-wash-strong);
    color: var(--brand-ink);
    border-color: var(--brand);
}
@media (hover: hover) and (pointer: fine) {
    .btn-export:hover {
        background: var(--brand);
        color: var(--on-brand);
        box-shadow: var(--elev-hover);
    }
}
.btn-export:active { background: var(--brand); color: var(--on-brand); }

.btn-import {
    background: rgba(var(--accent-green-rgb), 0.12);
    color: var(--positive-ink);
    border-color: rgba(var(--accent-green-rgb), 0.30);
}
@media (hover: hover) and (pointer: fine) {
    .btn-import:hover {
        background: var(--positive);
        color: var(--on-positive);
        border-color: var(--positive);
        box-shadow: var(--elev-hover);
    }
}
.btn-import:active {
    background: var(--positive); color: var(--on-positive);
    border-color: var(--positive);
}

/* The same treatment .btn-danger gets, and deliberately the same: deleting
   is deleting whether the button says "Revoke" or "Delete Selected".
   Deleting is SOFT in this app (30-day recycle bin), which is why this is a
   warning and not an interrogation. */
.btn-delete {
    background: rgba(var(--accent-red-rgb), 0.12);
    color: var(--negative-ink);
    border-color: rgba(var(--accent-red-rgb), 0.30);
}
@media (hover: hover) and (pointer: fine) {
    .btn-delete:hover {
        background: var(--negative);
        color: var(--on-negative);
        border-color: var(--negative);
        box-shadow: var(--elev-hover);
    }
}
.btn-delete:active {
    background: var(--negative); color: var(--on-negative);
    border-color: var(--negative);
}

/* ---- TOOLBAR SIZE ------------------------------------------------------
   Between .btn and .btn-sm: 40px, so a row of five toolbar controls above a
   DataTable does not out-weigh the table, while still clearing the 40px most
   thumbs need. Below the 44px WCAG 2.5.8 minimum, and permitted for the same
   reason .btn-sm is: layout/mobile.css raises every one of these to 44px
   under `(hover: none)`, i.e. on exactly the devices where it matters. */
.btn-action {
    min-height: 40px;
    padding: 8px 16px;
    font-size: 13px;
}

/* ---- SMALL / EDIT ------------------------------------------------------
   36px rather than 44px. Below the touch minimum on purpose and only ever
   inside a table row, where the ROW is the tap target and these are the
   pointer-and-keyboard affordances on top of it. Do not use .btn-sm as the
   only way to perform an action on a touch screen. */
.btn-sm, .btn-edit {
    min-height: 36px;
    min-width: 36px;
    padding: 6px 12px;
    /* --radius-sm, one step down, because a 36px control with a 12px radius
       is 2/3 of the way to a pill and stops reading as a rectangle. */
    border-radius: var(--radius-sm);
}
.btn-edit {
    background: var(--brand-wash-strong);
    color: var(--brand-ink);
    border-color: transparent;
}
@media (hover: hover) and (pointer: fine) {
    .btn-edit:hover {
        background: var(--brand);
        color: var(--on-brand);
        box-shadow: var(--elev-1);
    }
}
.btn-edit:active { background: var(--brand); color: var(--on-brand); }

/* ---- DISABLED ----------------------------------------------------------
   No hover, no lift, no bounce. A disabled button that still animates is a
   disabled button people keep pressing.

   Opacity rather than a grey fill, so the variant is still recognisable —
   someone needs to be able to see WHICH button is unavailable, not just that
   one is. 0.5 keeps a white label on clay at 4.8:1, which is above the 3:1
   that WCAG 1.4.3 requires of an inactive control and comfortably readable.
   `pointer-events: none` is NOT used: it would stop the disabled state
   having a tooltip and stop a keyboard user reaching it. */
.btn:disabled, .btn[aria-disabled="true"],
.btn-primary:disabled, .btn-submit:disabled, .btn-secondary:disabled,
.btn-danger:disabled, .btn-edit:disabled, .btn-ghost:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    box-shadow: none;
}
.btn:disabled:hover, .btn-primary:disabled:hover, .btn-submit:disabled:hover,
.btn-secondary:disabled:hover, .btn-danger:disabled:hover,
.btn-edit:disabled:hover, .btn-ghost:disabled:hover,
.btn:disabled:active, .btn-primary:disabled:active, .btn-submit:disabled:active {
    transform: none;
    box-shadow: none;
    filter: none;
}

/* ---- PENDING -----------------------------------------------------------
   Added by main.core.js to a submit button while its form is in flight, so
   a slow save on the mill's connection cannot be double-submitted by someone
   who assumed the first tap missed. The spinner is a border, not an image:
   no extra request, and it inherits the label colour so it is correct on
   both themes and on every variant without a rule per variant. */
.btn.is-pending, .btn-primary.is-pending, .btn-submit.is-pending {
    pointer-events: none;
    opacity: 0.75;
}
.btn.is-pending::after, .btn-primary.is-pending::after, .btn-submit.is-pending::after {
    content: "";
    width: 14px;
    height: 14px;
    border-radius: var(--radius-full);
    border: 2px solid currentColor;
    border-top-color: transparent;
    animation: btn-spin 700ms linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }

/* Login specific */
.btn-login { width: 100%; padding: 12px 20px; }
