/*
    Buttons — the ONE button stylesheet for the whole portal (auth family + dashboard).

    Loaded by BOTH the auth family (Login, Register, Agreement, ForgotPassword, AcceptInvite, all on
    the shared _AuthLayout) and the authenticated dashboard (_AccountLayout). Both layouts load the
    Metronic theme CSS first, so this file sits on top of the theme's own `.btn`. `!important` is
    kept on the rules that must beat the theme bundle's button colours and radius.

    Before this file, the portal had three independent "universal button" recipes: partner.css's
    `.btn`/`.btn-primary` (dashboard), auth-shell.css's `.auth-submit` (auth family), and several
    page-local reimplementations of the same 48px primary pill (`.otp-continue`, `.apply-modal__continue`)
    plus a quieter tinted-pill one-off (`.agreement-jump`) and a from-scratch
    button system (`contacts.css`'s `.wp-cf-btn` family). This file is now the single source of truth
    for shape/size/colour/state; the class names those older selectors used are kept as additional
    selectors on the shared rules below (so no markup elsewhere had to change), except for the four
    auth-submit call sites and .otp-continue/.apply-modal__continue, which now carry `.btn` classes
    directly (see the pages themselves).

    The public marketing site's `.btn` (custom.css) is a deliberately different, disjoint system —
    never co-loaded with this file — and is NOT part of this consolidation.
*/

/* ═══════════════════════════════════════════════════════════
   1. STRUCTURE — shape, alignment, states. Framework-independent.
   ═══════════════════════════════════════════════════════════ */

/*
    `.btn:not(.dropdown-toggle)`, the same carve-out the size rule and the radius rule below both
    make, and for the reason their comments already give: a dropdown toggle reads as a form field,
    not an action button. It was missing HERE, and this rule is the one that actually broke it.

    Two declarations below are the problem. `line-height: 1` against the theme's own 1.5 takes
    about 8px off the toggle, so a picker sat visibly shorter than the input beside it. And
    `display: inline-flex` replaces the theme's inline-block, which makes the dropdown plugin's
    label (laid out with `float: left; height: 100%`) stop behaving, since a flex container
    ignores floats; `justify-content: center` then centres the label where the theme left-aligns
    it. Excluded here, a toggle takes the theme's own box and matches .form-control exactly, since
    Metronic computes both as calc(1.5em + 1.3rem + 2px).
*/
/* Theme image-input buttons ([data-action]) are left to the theme so its Cancel/Remove visibility works;
   :where() keeps this selector's specificity unchanged for every other button. */
.btn:not(.dropdown-toggle):not(:where([data-action])),
.wp-cf-btn,
.wp-companies__add,
.agreement-jump {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    /* 1px transparent, not `none` — the outline variants (.btn-outline-primary etc.) only
       override border-color, so the width has to already be there for the ring to render. */
    border: 1px solid transparent;
    margin: 0;
    font-family: inherit; /* each surface owns its own body font (Poppins on the dashboard,
                              Poppins or Josefin per auth route) — a button always matches it */
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
    transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}

.btn:not(.dropdown-toggle) > svg {
    flex-shrink: 0;
    margin: 0 !important;
}

/*
    DEFAULT size for a labelled button with no .btn-sm/-md/-lg tier — there are plenty
    (Bootstrap's own base .btn never required one). Without this, such a button silently falls
    back to Bootstrap's own `.btn` rule (padding:.65rem 1rem; font-size:1rem; line-height:1.5 —
    16px text, no relation to this design system), which is exactly the "modal button looks
    different" class of bug. A size-tier class overrides height/font-size on top of this as
    normal. `.btn-icon` is excluded: Metronic sizes icon buttons off calc(1.5em + ...), directly
    driven by the button's own font-size, so forcing 14px here would quietly shrink them.

    `.dropdown-toggle` is ALSO excluded, for the same reason the radius rule below excludes it: a
    dropdown toggle reads as a form field, not an action button. The theme sizes every toggle (the
    currency composite's .wp-ccy__toggle and each selectpicker) to match the .form-control beside
    it, and a fixed 38px here broke that match (measured 6px short of the amount input).
*/
.btn:not(.btn-icon):not(.dropdown-toggle),
.wp-cf-btn,
.wp-companies__add,
.agreement-jump {
    height: 38px;
    padding: 0 20px;
    font-size: 14px !important;
}

/*
    ── RADIUS: one radius for every size, matched to the public website ──
    Every button carries 97px (a full pill), matching custom.css's public-site `.btn` base
    radius, so every surface reads as the same brand shape regardless of size. Circle and pill
    buttons are carved out — their radius is their shape, not a size decision. `.btn-icon` isn't
    included: the dashboard's Metronic icon buttons (`.wp-topbar__back`/`.wp-topbar__btn`) keep
    their own radius rules in partner.css, since nothing in the auth family needs an icon-only
    button — there's no duplication to remove there.

    `.dropdown-toggle` is also carved out: bootstrap-select's generated toggle button structurally
    carries `.btn` (Bootstrap needs it for the dropdown JS/positioning to work), but it is meant
    to read as a FORM FIELD, not an action button, so it keeps the theme's field radius. Without
    this exclusion the `!important` below turned every portal dropdown (the Lead/Duration pickers
    in Book Meeting among them) into a 97px pill beside square-cornered inputs.

    Buttons inside a `.btn-group-toggle` (the lead temperature choice) are carved out too: the
    theme squares their inner corners so the group reads as one control, and a pill per button
    would split it back into three.
*/
.btn:not(.btn-circle):not(.btn-pill):not(.wp-topbar__back):not(.dropdown-toggle):not(.btn-group-toggle > .btn),
.wp-cf-btn,
.wp-companies__add,
.agreement-jump {
    /* !important: this is the one universal shape rule for every button variant grouped onto
       this file — nothing legitimately needs a different radius, so nothing should ever be
       able to accidentally win over it by loading later at the same specificity. */
    border-radius: 97px !important;
}

/* cursor:progress is a small universal addition — previously only otp-continue signalled this
   locally; every busy button now does, portal-wide. */
.btn[aria-busy="true"] { pointer-events: none; cursor: progress; }

.btn:disabled,
.btn.disabled {
    background-color: var(--dark-border) !important;
    border-color: var(--dark-border) !important;
    color: var(--text-5) !important;
    cursor: not-allowed;
}

/*
    Focus is replaced, never merely removed. Inputs are excluded deliberately elsewhere (their
    focus is shown by the border turning --primary); buttons and links have no border change, so
    they keep the ring.
*/
.btn:focus-visible,
.wp-cf-btn:focus-visible,
.wp-companies__add:focus-visible,
.agreement-jump:focus-visible,
a:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(98, 0, 238, 0.12) !important; /* --primary at 12% */
}

/* ═══════════════════════════════════════════════════════════
   2. SIZE TIERS — height + font-size, the one thing every page used to restate by hand.
      Padding stays a per-caller concern: it already varies intentionally with icon presence
      and label width at the same height, so unifying it would be a visual regression, not a
      dedupe.
   ═══════════════════════════════════════════════════════════ */

/* "Compact-action" convention: row/header/card actions. */
.btn-sm,
.wp-cf-btn--sm,
.wp-companies__add {
    height: 38px !important;
    font-size: 14px !important;
}

/* "Form-footer" convention: modal footers, panel actions, standalone CTAs. */
.btn-md,
.wp-cf-btn {
    height: 44px !important;
    font-size: 14px !important;
}

/* The primary full-flow CTA: the big pill at the bottom of an auth screen or a full-page modal. */
.btn-lg {
    height: 48px !important;
    font-size: 14px !important;
    padding: 0 32px;
}

/* ═══════════════════════════════════════════════════════════
   3. COLOUR VARIANTS
   ═══════════════════════════════════════════════════════════ */

/* Solid primary */
.btn.btn-primary,
.wp-cf-btn--primary,
.wp-companies__add {
    background-color: var(--primary) !important;
    border-color: var(--primary) !important;
    color: var(--white) !important;
}

.btn.btn-primary:hover,
.btn.btn-primary:focus,
.btn.btn-primary:active,
.btn.btn-primary.active,
.show > .btn.btn-primary.dropdown-toggle,
.wp-cf-btn--primary:hover,
.wp-companies__add:hover {
    background-color: var(--button-hover) !important;
    border-color: var(--button-hover) !important;
}

.btn.btn-primary:active,
.btn.btn-primary.active,
.wp-cf-btn--primary:active,
.wp-companies__add:active {
    background-color: var(--button-pressed) !important;
    border-color: var(--button-pressed) !important;
}

/* Tinted — strong reveal on hover (fills solid on hover, unlike .btn-tint below). --wp-spin
   feeds the loading spinner (below): on this light fill, a white ring would wash out, so it
   takes the same primary colour as the label instead. */
.btn.btn-light-primary,
.btn.btn-soft {
    background-color: var(--primary-10) !important;
    color: var(--primary) !important;
    border-color: transparent !important;
    --wp-spin: var(--primary);
}

.btn.btn-light-primary:hover,
.btn.btn-soft:hover,
.btn.btn-soft:focus,
.btn.btn-light-primary:focus,
.btn.btn-light-primary:active {
    background-color: var(--primary) !important;
    color: var(--white) !important;
}

/*
    Tinted, quiet: stays tinted on hover. The recipe `.agreement-jump` used to hand-roll
    (primary-5 rest, primary-10 hover) for a lower-emphasis pill
    action that should never read as "as loud as the primary CTA" — genuinely different from
    .btn-soft's full-fill hover above, so kept as its own variant rather than collapsed into it.
*/
.btn.btn-tint,
.agreement-jump {
    background-color: var(--primary-5) !important;
    color: var(--primary) !important;
    border-color: transparent !important;
    --wp-spin: var(--primary);
}

.btn.btn-tint:hover,
.btn.btn-tint:focus,
.agreement-jump:hover {
    background-color: var(--primary-10) !important;
}

/*
    Secondary — ONE recipe for every quiet / cancel / neutral action in the portal, whatever
    Metronic or page-level class it carries (Metronic ships btn-secondary, btn-light, btn-light-dark,
    btn-clean and outline-secondary each with a different grey).

    `.btn-light:not(.dropdown-toggle)` everywhere `.btn-light` appears below: bootstrap-select's
    plugin defaults every picker's toggle button to that exact class (it has nothing to do with
    this being a Cancel-style button), so without the exclusion this `!important` rule hijacked
    every portal dropdown's background/border into the same grey as a secondary button: invisible
    border, grey fill, one more thing that didn't match the plain inputs beside it. The theme
    already draws .dropdown-toggle as a field; this rule should never have reached it.
*/
.btn.btn-secondary,
.btn.btn-light:not(.dropdown-toggle),
.btn.btn-light-secondary,
.btn.btn-light-dark,
.btn.btn-outline-secondary,
.btn.btn-clean,
.btn.btn-quiet,
.wp-cf-btn--quiet {
    background-color: var(--dark-bg) !important;
    border-color: var(--dark-bg) !important;
    color: var(--text-2) !important;
    --wp-spin: var(--text-2);
}

.btn.btn-secondary:hover,
.btn.btn-secondary:focus,
.btn.btn-light:not(.dropdown-toggle):hover,
.btn.btn-light:not(.dropdown-toggle):focus,
.btn.btn-light-secondary:hover,
.btn.btn-light-secondary:focus,
.btn.btn-light-dark:hover,
.btn.btn-light-dark:focus,
.btn.btn-outline-secondary:hover,
.btn.btn-outline-secondary:focus,
.btn.btn-clean:hover,
.btn.btn-clean:focus,
.btn.btn-quiet:hover,
.btn.btn-quiet:focus,
.wp-cf-btn--quiet:hover,
.wp-cf-btn--quiet:focus {
    background-color: var(--dark-border) !important;
    border-color: var(--dark-border) !important;
    color: var(--text-1) !important;
}

.btn.btn-secondary:active,
.btn.btn-secondary.active,
.btn.btn-light:not(.dropdown-toggle):active,
.btn.btn-light:not(.dropdown-toggle).active,
.btn.btn-light-secondary:active,
.btn.btn-light-dark:active,
.btn.btn-outline-secondary:active,
.btn.btn-clean:active,
.btn.btn-quiet:active,
.wp-cf-btn--quiet:active {
    background-color: var(--text-5) !important;
    border-color: var(--text-5) !important;
    color: var(--text-1) !important;
}

/* Destructive — Logout, "mark as lost", confirm-modal destructive actions. Mapped onto our error
   token so Metronic's own red never surfaces and every destructive button reads as the one red. */
.btn.btn-danger {
    background-color: var(--error-active) !important;
    color: var(--white) !important;
    border-color: transparent !important;
}

.btn.btn-danger:hover,
.btn.btn-danger:focus,
.btn.btn-danger:active {
    background-color: var(--error-100) !important;
    color: var(--white) !important;
}

.btn.btn-hover-primary:hover {
    background-color: var(--primary) !important;
    color: var(--white) !important;
}

.btn.btn-outline-primary {
    border-color: var(--primary) !important;
    color: var(--primary) !important;
    --wp-spin: var(--primary);
}

.btn.btn-outline-primary:hover {
    background-color: var(--primary) !important;
    color: var(--white) !important;
}

/* The checked option of a theme toggle group (lead temperature). The outline rule above forces the
   label purple with !important, which would leave purple text on the theme's purple fill. Keyboard
   focus lands on the clipped radio, so the plugin's .focus class on the label carries the ring. */
.btn-group-toggle > .btn.btn-outline-primary.active {
    background-color: var(--primary) !important;
    color: var(--white) !important;
}

.btn-group-toggle > .btn.focus {
    box-shadow: 0 0 0 3px rgba(98, 0, 238, 0.12) !important; /* --primary at 12% */
}

/* Once a light / outline / hover-primary button has filled to --primary, its pressed state is
   the same --button-pressed as a solid primary button, so every purple fill presses alike. */
.btn.btn-light-primary:active,
.btn.btn-soft:active,
.btn.btn-outline-primary:active,
.btn.btn-hover-primary:active {
    background-color: var(--button-pressed) !important;
    border-color: var(--button-pressed) !important;
    color: var(--white) !important;
}

/* ═══════════════════════════════════════════════════════════
   4. LOADING STATES
   ═══════════════════════════════════════════════════════════ */

/*
    Block loading — label hides, pointer off, a spinner rides the button centre. The button keeps
    its width so nothing reflows. Toggle by adding/removing `.wp-loading` on the `.btn`.
*/
.btn.wp-loading,
.wp-cf-btn.wp-loading {
    position: relative;
    color: transparent !important;
    pointer-events: none;
}
.btn.wp-loading::after,
.wp-cf-btn.wp-loading::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 16px;
    height: 16px;
    margin: -8px 0 0 -8px;
    box-sizing: border-box; /* keep the 16x16 square exact so border-radius:50% is a true circle */
    /* The common "loader" ring: three sides fully transparent (a real gap, not a dimmed
       continuation), one solid arc that rotates — the open-circle look, not a filled/hazy
       disc. --wp-spin: set per colour variant above on light/tinted buttons, where a plain
       white arc would wash out; defaults to white for every dark/solid variant (primary,
       danger, filled hover states) that doesn't set it. */
    border: 2px solid transparent;
    border-top-color: var(--wp-spin, var(--white));
    border-radius: 50%;
    animation: wp-spin 0.7s linear infinite;
}
@keyframes wp-spin { to { transform: rotate(360deg); } }

/* Inline loading — the label STAYS visible and a spinner rides to the LEFT of the text,
   matching every other loading button portal-wide. ::before (not ::after) so it lands ahead
   of the label with no flex `order` needed. */
.btn.wp-loading-inline { pointer-events: none; }
.btn.wp-loading-inline::before {
    content: "";
    flex: 0 0 auto; /* .btn is inline-flex — never let the spinner shrink into an oval */
    display: inline-block;
    width: 16px;
    height: 16px;
    margin-right: 8px;
    vertical-align: -3px;
    box-sizing: border-box;
    /* Same open-ring technique as the block spinner above. */
    border: 2px solid transparent;
    border-top-color: var(--wp-spin, var(--white));
    border-radius: 50%;
    animation: wp-spin 0.7s linear infinite;
}

/*
    Shared loading-button SPINNER SHAPE — consolidated from what were five independent copies of
    the same 16-18px rotating ring (auth-shell's old `.auth-submit__spinner` + its own `auth-spin`
    keyframe, otp-verify's `.otp-continue__spinner` + `otp-spin`, wp-modal's `.wp-md__spinner`,
    support-page's `.wp-support__send-spinner`). One keyframe (`wp-spin`, defined once above) for
    all of them now; each selector below keeps only its own size/duration/position — the
    markup and the aria-busy/visibility trigger for each stay exactly as each page already wired
    them, since that's genuine per-page interaction behaviour, not a duplicate to remove.

    `border-top-color` is deliberately NOT set here: every one of these five pages loads its own
    stylesheet AFTER this file, and that stylesheet's own `border: 2px solid transparent` rule on
    the same selector (equal specificity, later in the cascade) would silently win and clobber a
    `border-top-color` declared only here — the arc would vanish along with the rest of the
    border. Each page's own file sets `border-top-color` itself, right beside its `border` line,
    so both live in the one rule that actually wins.
*/
.auth-submit__spinner,
.otp-continue__spinner,
.wp-md__spinner,
.wp-support__send-spinner,
.apply-modal__continue-spinner {
    display: none;
    border-radius: 50%;
    animation-name: wp-spin;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}

@media (prefers-reduced-motion: reduce) {
    .btn.wp-loading::after,
    .btn.wp-loading-inline::before,
    .wp-cf-btn.wp-loading::after {
        animation-duration: 1800ms;
    }
}

/* ═══════════════════════════════════════════════════════════
   5. TEXT-STYLE ACTIONS
      A family of page-local "plain text" buttons (a quiet secondary action styled as a link,
      not a filled pill) that each independently reset the same native-button chrome. Colour,
      size and hover TREATMENT stay local — a colour-shift hover, an underline hover, and a
      background-tint hover are three real, different affordances here, not three copies of one
      duplicate to force together. Only the identical reset + (where a caller draws one) the
      identical focus ring are shared.
   ═══════════════════════════════════════════════════════════ */
.wp-summary__link,
.ld-sec__link,
.ld-ba-toggle,
.otp-resend,
.wp-cf-panel__back,
.wp-picker-jump,
.wp-reveal {
    border: 0;
    background: transparent;
    padding: 0;
    cursor: pointer;
    font-family: inherit;
}

/* The password reveal fills the theme's .input-icon slot, so the whole icon cell is the target. The
   icon's colour is the theme's own (.input-icon span i). */
.input-icon .wp-reveal {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

/* Callers that draw a ring on focus (ld-ba-toggle/otp-resend use an underline instead, matching
   their own hover, so they're not part of this group). */
.wp-summary__link:focus-visible,
.ld-sec__link:focus-visible,
.wp-cf-panel__back:focus-visible,
.wp-reveal:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(98, 0, 238, 0.12); /* --primary at 12% */
}
