/* ════════════════════════════════════════════════════════════════════
   Portal Button and Badge Standard (CPP-1160)

   One shape, one brand fill, content centred on both axes — for every
   button in the portal, on every page, at every size. Badges take the
   same corner and derive a scale of their own from the button tokens;
   see section 4.

   Loaded from layouts/styles.php (authenticated pages) and
   layouts/custom-styles.php (login, register, lock, 404/500/501), last
   of the shared stylesheets — after style.css, skin-modes.css,
   mobile-responsive.css and the FullCalendar block.

   Before this file the portal declared a button radius across 27 files
   in eight different values: 0.21rem, 4px, 5px, 6px, 8px, 10px, 12px and
   999px, so the same button was a near-square on a customer page, a
   rounded one on a partner page and a pill in a hero. The brand fill was
   spread over five reds (#cd1316, #c4161c and three hover shades) plus
   inline #8D0D40 on the ticket list. Both now live in --xt-btn-radius and
   --xt-btn-fill and nowhere else: every other stylesheet and page
   references the token, so changing the shape or the brand colour is a
   one-line edit here.

   Load order note: partner-xr-styles.css is linked by the page itself
   and therefore loads AFTER this file. It no longer declares a button
   radius or a brand-primary fill; it keeps --xr-red for the badges,
   progress bars, links and calendar accents that are not buttons.

   Out of scope, deliberately:
   - Semantic buttons (.btn-success / -danger / -warning / -info) keep
     their meaning and their colours.
   - Input-group and header-search buttons keep the flat inner corners
     that joining them to a field requires (style.css).
   - The partner burgundy repaint belongs to CPP-1159; it becomes a
     flip of --primary-bg-color once that ticket lands.
   ════════════════════════════════════════════════════════════════════ */

:root {
    /* ── Shape ───────────────────────────────────────────────────────
       A single radius for every button whatever its size. btn-sm and
       btn-lg deliberately do NOT get their own value: the ticket asks
       for one shape, not a family of them. */
    --xt-btn-radius: 10px;

    /* ── Brand fill ──────────────────────────────────────────────────
       --primary-bg-color is the portal-wide brand colour (style.css
       :root, Xiting red). Routing the button fill through it keeps one
       flip point for the partner repaint in CPP-1159.

       The hover shade and the low-alpha tints are DERIVED from that one
       value rather than written out, so the flip cannot leave a burgundy
       button that hovers red or a calendar still tinted red. Everything
       downstream mixes off --xt-btn-fill the same way:
           color-mix(in srgb, var(--xt-btn-fill) <n>%, transparent)
       color-mix is already used elsewhere in the portal (roadmap.php). */
    --xt-btn-fill: var(--primary-bg-color, #cd1316);
    --xt-btn-fill-hover: color-mix(in srgb, var(--xt-btn-fill) 80%, #000);

    /* --primary-bg-hover was still the purchased template's GREEN (#82c035)
       in style.css :root, and it drives .fc .fc-button-primary:hover — so a
       calendar button not covered by the xr-cal theme turned green under the
       pointer. themeColors.js only overwrites this one when someone has
       picked a colour in the template's theme switcher, so redefining it here
       is enough. (--primary09, the other "darker primary" token, cannot be
       fixed this way: themeColors.js sets it as an inline style on <html> on
       every page load, which outranks any stylesheet. See the .btn-primary
       hover rule further down.) */
    --primary-bg-hover: var(--xt-btn-fill-hover);

    /* ── Badges ──────────────────────────────────────────────────────
       Same corner as a button, so a tag sitting next to one reads as the
       same kit, but a scale of their own: a badge is a marker, not a
       control, and must stay subordinate. Before this the portal had two
       badge radii (3px, and 8px wherever partner-xr-styles.css loaded),
       five heights (19, 23, 24, 28 and 36px) and five font sizes — a
       badge on the dashboard stood 36px tall beside a 35px button.

       Two sizes only: the default, and a compact one for badges that sit
       inside a button or in a dense list. */
    --xt-badge-radius: var(--xt-btn-radius);
    --xt-badge-padding: 4px 10px;
    --xt-badge-font-size: .75rem;
    --xt-badge-padding-compact: 2px 7px;
    --xt-badge-font-size-compact: .6875rem;

    /* Badge fills, all of them on the CI sheet. What they replace were
       purchased-template colours with no place in it: #e984b1 pink on
       secondary, #13bfa6 on success, #e7c354 on warning and #59adec on info.

       The sheet names no success or warning colour, so these follow the role
       table in assets/css/ci-semantics.css (CPP-1159): warning is the
       attention red, info the main-palette steel, and anything finished or
       neutral is grey. Success and secondary are therefore both grey and
       differ only in weight, the darker step for a state that was reached and
       the lighter one for a plain marker, with the label carrying the rest.
       Success and warning stood on Bootstrap's green and amber because they
       were taken from --xr-success and --xr-warning, which are themselves CI
       values now. */
    --xt-badge-neutral: #58595B;
    --xt-badge-success: #414042;
    --xt-badge-warning: #CD1316;
    --xt-badge-info: #344C76;
}

/* ════════════════════════════════════════════════════════════════════
   1. SHAPE — one radius, every button
   ════════════════════════════════════════════════════════════════════ */

.btn,
.btn-sm,
.btn-lg,
.btn-group-sm > .btn,
.btn-group-lg > .btn,
.login100-form-btn,
.fc .fc-button {
    border-radius: var(--xt-btn-radius);
}

/* Bootstrap and FullCalendar both flatten the inner corners of a button
   group themselves, at a higher specificity than the rule above, so groups
   keep their joined look and take the standard radius on the outer corners.
   That is also why the rule above is not !important: it would win the
   shorthand and un-flatten every group in the portal. */

/* ════════════════════════════════════════════════════════════════════
   2. ALIGNMENT — icon and label centred on both axes
   ════════════════════════════════════════════════════════════════════ */

/* style.css already gives .btn `text-align: center`, so a label is centred
   horizontally. What was off was the graphic: an icon sat on the text
   baseline, a couple of pixels low, which is why buttons across the portal
   had grown their own ad-hoc `d-flex align-items-center` patches.

   Deliberately NOT done by making .btn a flex container. That centres just
   as well — measured at 0.1px against flex's 0.0px — but a flex container
   establishes no line box, so a button whose only content is an icon loses
   the height its text-sized line box used to give it. On the dashboard the
   release-overview arrows came out 31px next to 35px text buttons. Keeping
   .btn inline-block also means the whitespace between an icon and its label
   still renders, so the markup needs no margin utilities added to it. */
.btn > i,
.btn > svg,
.btn > .fe,
.btn > .fa {
    vertical-align: middle;
}

/* Buttons that ARE flex containers, because the markup put d-flex on them,
   keep their own alignment; this only makes sure the icon does not squash. */
.btn.d-flex > i,
.btn.d-flex > svg {
    flex-shrink: 0;
}

/* The CTA pair is normally written as `btn btn-xiting` and picks up the
   template's inline-block that way, but it renders on its own here and
   there. Give a bare one the same box so it is not a full-width block link
   among inline buttons. */
.btn-xiting,
.btn-xiting-outline {
    display: inline-block;
    text-align: center;
}

/* ════════════════════════════════════════════════════════════════════
   3. FILL — the brand-primary buttons
   ════════════════════════════════════════════════════════════════════ */

/* .btn-xiting / .btn-xiting-outline are the portal's own CTA pair, used
   on eleven pages. They were defined three times over (layouts/styles.php
   as a 999px pill that inverted and scaled on hover, partner-xr-styles.css
   as a 12px button that darkened, education_videos.php in a second red)
   so the same class looked different depending on the page. One
   definition, and it behaves like .btn-primary: darken on hover, no
   scale — a button that changes size on hover moves the layout under
   the pointer. */
.btn-xiting {
    background-color: var(--xt-btn-fill);
    border: 1px solid var(--xt-btn-fill);
    color: #fff;
}

/* Resting fill, restated for :focus. Bootstrap 5.3 draws .btn:focus-visible
   from --bs-btn-hover-bg, and this pair never defines the --bs-btn-* set, so
   the unset var() left a focused CTA transparent with default-dark text.
   See the shared focus note below for why :focus is the resting fill. */
.btn-xiting:focus {
    background-color: var(--xt-btn-fill);
    border-color: var(--xt-btn-fill);
    color: #fff;
}

.btn-xiting:hover,
.btn-xiting:active,
.btn-xiting:focus-visible {
    background-color: var(--xt-btn-fill-hover);
    border-color: var(--xt-btn-fill-hover);
    color: #fff;
}

.btn-xiting-outline {
    background-color: transparent;
    border: 1px solid var(--xt-btn-fill);
    color: var(--xt-btn-fill);
}

.btn-xiting-outline:focus {
    background-color: transparent;
    border-color: var(--xt-btn-fill);
    color: var(--xt-btn-fill);
}

.btn-xiting-outline:hover,
.btn-xiting-outline:active,
.btn-xiting-outline:focus-visible {
    background-color: var(--xt-btn-fill);
    border-color: var(--xt-btn-fill);
    color: #fff;
}

/* Bootstrap's .btn-primary and .btn-outline-primary take their resting fill
   from var(--primary-bg-color) in style.css, so they need no rule for that
   here. Their hover does need one.

   style.css writes `.btn-primary:hover { background-color: var(--primary09)
   !important }`, and --primary09 is the brand colour at 0.9 alpha, written
   onto <html> as an inline style by assets/js/themeColors.js on every page
   load. So a hovered primary button went LIGHTER and semi-transparent —
   whatever sits behind it showing through — while every other button in the
   portal darkens. An inline style on <html> outranks any :root declaration,
   so the token cannot be redefined; the rule has to be overridden, and
   !important is needed to beat style.css's own !important.

   This also retires the workaround that sat in layouts/styles.php, which
   painted the hovered button's text and border #dc3545 — Bootstrap's red, not
   the brand's — to keep a label readable on a fill that had gone see-through.

   ── Focus, handled the same way for both brand classes ──────────────
   :focus holds the RESTING fill. A mouse click leaves :focus behind, so
   darkening there would leave the last button clicked sitting dark long
   after the pointer had gone, with nothing to explain it.
   :focus-visible darkens. It fires for keyboard navigation and not for
   clicks, and since style.css suppresses the focus ring portal-wide (see
   the note at the end of this file) it is the only cue a keyboard user
   gets. Ordered :focus, then :focus-visible, then :hover/:active, so the
   more specific state wins when several apply at once. */
.btn-primary:focus {
    background-color: var(--xt-btn-fill) !important;
    border-color: var(--xt-btn-fill) !important;
    color: #fff !important;
}

.btn-primary:hover,
.btn-primary:active,
.btn-primary:focus-visible {
    background-color: var(--xt-btn-fill-hover) !important;
    border-color: var(--xt-btn-fill-hover) !important;
    color: #fff !important;
}

/* ════════════════════════════════════════════════════════════════════
   4. BADGES — one shape, one scale, palette fills
   ════════════════════════════════════════════════════════════════════ */

/* style.css:2073 sets `font-size: 90% !important` on .badge — a
   percentage, so the size depended on whatever the badge happened to sit
   in, which is where the five font sizes came from. Overriding it needs
   !important; the rest of the rule does not. It also sets
   `line-height: 0` and `vertical-align: baseline`, both restored here. */
.badge {
    border-radius: var(--xt-badge-radius);
    padding: var(--xt-badge-padding);
    font-size: var(--xt-badge-font-size) !important;
    font-weight: 600;
    line-height: 1.35;
    vertical-align: middle;
}

/* Compact: inside a button, and in the dense marker rows under a file
   name. A badge in a button must stay clearly smaller than the button,
   so this goes by position rather than by an extra class in the markup. */
.btn .badge,
.badge--compact {
    padding: var(--xt-badge-padding-compact);
    font-size: var(--xt-badge-font-size-compact) !important;
}

/* An icon glyph sets a taller line box than digits do, which pushed a
   badge carrying one 4px above the scale. */
.badge > i,
.badge > svg {
    line-height: 1;
    vertical-align: middle;
}

/* Fills. Scoped to .badge.bg-* so a .bg-* utility used on something that
   is not a badge keeps the template's colour; !important because the
   utilities themselves carry it (style.css:79007 and neighbours), and a
   plain declaration cannot outrank that however specific it is. */
.badge.bg-primary,
.badge.bg-danger {
    background-color: var(--xt-btn-fill) !important;
    color: #fff !important;
}

.badge.bg-secondary {
    background-color: var(--xt-badge-neutral) !important;
    color: #fff !important;
}

.badge.bg-success {
    background-color: var(--xt-badge-success) !important;
    color: #fff !important;
}

.badge.bg-info {
    background-color: var(--xt-badge-info) !important;
    color: #fff !important;
}

/* The amber this replaced needed dark text, and carrying white on it was a
   real contrast failure rather than merely an off-palette colour. The CI
   attention red is dark, so the text goes back to white (CPP-1159). */
.badge.bg-warning {
    background-color: var(--xt-badge-warning) !important;
    color: #fff !important;
}

/* ── Focus ring: deliberately not set here ───────────────────────────
   No button in the portal shows one on desktop. style.css:6200 carries
   `.btn.focus, .btn:focus { box-shadow: none !important }`, which beats
   anything this file could declare without another !important, and
   mobile-responsive.css adds an outline ring under 768px instead — so
   the suppression reads as a decision, not an oversight. Restoring a
   desktop focus ring is an accessibility change worth making on its own
   ticket, with someone choosing how it should look; it is not one of the
   three things CPP-1160 asks for, so it is left alone rather than
   smuggled in behind an !important. */
