/* ============================================================================
 * Save action — the platform's save button and its anchored pill.
 *
 * Loaded on every page from //layouts/main (cache-busted on filemtime), so the
 * classes below are available everywhere without a per-view include.
 *
 * WHAT COUNTS AS A "SAVE": the action that commits the user's work on the page.
 * NOT every type="submit" — a row-adding button, a search, a navigation link or
 * a modal dismiss are not saves and keep the neutral/primary reference buttons
 * (.boat-rent-btn / .boat-rent-btn-primary). See docs/save-action/README.md.
 *
 * THE GREEN AND THE PILL'S NAVY ARE LITERAL, NOT var(--…), on purpose. The save
 * green is one colour platform-wide, not a per-area accent, so it does not belong
 * in the area-tokens.css token set; and tests/Unit/SaveActionStyleTest.php measures
 * these literals (the label, the button's edge on the navy). The focus ring reads
 * the per-area accent so keyboard focus matches the rest of the page, and the
 * texts on the navy read the kit's on-fill tokens (css/ref-tokens.css, printed
 * before every sheet by the four root layouts since 2026-10-14, so a stale copy of
 * this file can no longer leave them unresolved).
 *
 * Contrast (WCAG 2.1, guarded by tests/Unit/SaveActionStyleTest.php):
 *   #157347 + white label ............ 5.87:1  (AA text, needs 4.5)
 *   #157347 vs white card ............ 5.87:1  (UI boundary, needs 3)
 *   #157347 vs #e3e3e3 page .......... 4.58:1  (UI boundary, needs 3)
 *   #157347 vs #2c3e50 pill .......... 1.87:1  FAILS — hence the light border
 *   rgba(255,255,255,.7) vs #2c3e50 .. 6.32:1  the border carries the boundary
 *                                              (composited, that border is #c0c5cb)
 *
 * No green satisfies both "3:1 against the navy pill" and "4.5:1 under a white
 * label" — the two thresholds are mutually exclusive across the whole green
 * scale. That is why the pill lends the button a border instead of the button
 * changing colour on dark ground.
 * ========================================================================== */

/* ---- The atom: the save button itself ---------------------------------- */
/* Bootstrap in this build ships border-radius:0 on .btn AND on .btn-lg, so the
   8px radius has to be restated here — it is not inherited from anywhere. */
.bs-btn-save {
    background: #157347;
    border: 1px solid #157347;
    border-radius: 8px;
    color: var(--ref-on-fill);
    font-size: 16px;
    font-weight: 600;
    padding: 10px 24px;
    transition: background-color .15s ease, border-color .15s ease;
}

.bs-btn-save:hover,
.bs-btn-save:focus,
.bs-btn-save:active,
.bs-btn-save:active:focus {
    background: #0f5132;
    border-color: #0f5132;
    color: var(--ref-on-fill);
    outline: none;
    box-shadow: none;
}

.bs-btn-save i {
    margin-right: 6px;
}

/* Same focus ring as the rest of the reference style: Bootstrap's outline is
   cleared above, so keyboard users depend entirely on :focus-visible. */
.bs-btn-save:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--area-accent-ring-strong, rgba(26, 188, 156, .25));
}

.bs-btn-save[disabled],
.bs-btn-save.disabled {
    background: #7f9d8b;
    border-color: #7f9d8b;
    color: var(--ref-on-fill);
    cursor: not-allowed;
}

/* ---- The container: anchored pill, centred ------------------------------ */
/* Centred on purpose. The Intercom messenger parks its launcher in the
   bottom-RIGHT corner on a z-index in the billions, which no stacking context
   of ours can outrank; staying centred sidesteps it entirely and needs no
   vertical_padding correction on the Intercom side.
   Geometry taken from the pill this app already uses (#rb-linkbar in
   admin/views/orderDetail/resourceBoard.php), minus its 20000 z-index: the save
   pill must sit UNDER Bootstrap modals (1040) so a dialog is never blocked — and
   under the top bar's menus (D-60): the static navbar is 1000, and at 1030 a long
   voice's dropdown (the Shipyard's, ~25 rows) was painted under the pill. */
.bs-save-pill {
    position: fixed;
    bottom: 16px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 999;
    display: flex;
    align-items: center;
    gap: 14px;
    max-width: calc(100% - 24px);
    padding: 10px 16px;
    background: var(--ref-ink);
    border-radius: 8px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, .3);
    color: var(--ref-on-fill);
    font-size: 13px;
}

/* On the dark pill the green fill alone cannot mark the button's edge
   (1.87:1). The border does it (6.32:1 against the navy), so page authors never
   have to think about it — the container adapts the button. */
.bs-save-pill .bs-btn-save {
    border-color: rgba(255, 255, 255, .7);
}

/* The "there are unsaved changes" line, shown only while the form is dirty (see the
   gate below) — so it states a fact rather than labelling a button. 8.45:1 on the
   navy. Callers may replace it with their own text, or pass '' for none. */
.bs-save-pill-status {
    color: var(--ref-on-fill-2);
    white-space: nowrap;
}

/* The summary (SavePill `summary`, D-60): a running figure the pill keeps in view, clean or dirty — the boat
   configurator's total — before the status line, set apart by a hairline. It is what lets a page whose save must sit
   beside a figure use the kit's save instead of a bar of its own. */
.bs-save-pill-summary {
    display: flex;
    align-items: baseline;
    gap: var(--ref-gap-sm);
    padding-right: 14px;
    border-right: 1px solid var(--ref-on-fill-line);
    white-space: nowrap;
}

.bs-save-pill-summary-label {
    color: var(--ref-on-fill-2);
}

.bs-save-pill-summary-value {
    color: var(--ref-on-fill);
    font-size: var(--ref-fs-display);
    font-weight: var(--ref-fw-title);
}

/* Secondary action inside the pill is a text link, never a second box: one
   primary per action group (docs/reference-style.md §4). */
.bs-save-pill-cancel {
    background: none;
    border: 0;
    padding: 6px 4px;
    color: var(--ref-on-fill-2);
    font-size: 14px;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}

.bs-save-pill-cancel:hover,
.bs-save-pill-cancel:focus {
    color: var(--ref-on-fill);
    text-decoration: underline;
}

.bs-save-pill-cancel:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(255, 255, 255, .4);
    border-radius: 4px;
}

/* The pill is out of flow, so it would sit over the last rows of the form and
   over the layout's global #footer. The spacer reserves its height in flow —
   rendered by the SavePill widget right before the pill, so no page has to
   remember a magic margin (which is what tenant/config.php does by hand). */
.bs-save-pill-spacer {
    height: 76px;
}

/* ---- Only while there is something to save ------------------------------ */
/* js/save-pill.js marks the form clean; nothing here hides the pill on its own. The pill is rendered
   VISIBLE and only ever hidden by that class, so a JS failure leaves a usable save button rather than a
   form the user cannot submit. The spacer collapses with it, or a clean page would keep an empty
   76px gap above its footer.
   The `data-hide-when-clean` gate is what the widget's opt-out switches off — but the STATUS line is
   hidden on any clean form regardless, because a pill that deliberately stays visible must never claim
   there are unsaved changes when there are none. */
form.bs-save-clean .bs-save-pill[data-hide-when-clean="1"] {
    display: none;
}

form.bs-save-clean .bs-save-pill-spacer[data-hide-when-clean="1"] {
    height: 0;
}

form.bs-save-clean .bs-save-pill-status {
    display: none;
}

/* …but on a pill that STAYS visible (`hideWhenClean => false`) the line keeps its room, hidden rather than removed
   (D-60): the pill is centred, so a line appearing on the first edit re-centred it and the save jumped 91 px under
   the pointer (the receipt of goods, the delivery note review). Hidden, it stays out of the accessibility tree. */
form.bs-save-clean .bs-save-pill:not([data-hide-when-clean]) .bs-save-pill-status {
    display: inline;
    visibility: hidden;
}

/* A field that takes the focus scrolls clear of the fixed pill (WCAG 2.2 2.4.11, D-60) — what the guided form does
   for its own bar. Only while the pill is fixed: below 992 px it is back in the flow. */
@media (min-width: 992px) {
    html:has(.bs-save-pill) {
        scroll-padding-bottom: 96px;
    }
}

/* ---- Narrow screens ---------------------------------------------------- */
/* Below Bootstrap's `md` the pill returns to the flow. Two reasons, and the
   second is measured: anchoring buys little once the form is a single stacked
   column, and a FIXED pill collides with the layout footer's language picker in
   the 768-991px band — 134px of the select covered at 768px, 68px at 900px, and
   nothing from 992px up (where 23px of clearance remains, growing with width).
   992px is also where the page's own col-md-* grid stacks, so an in-flow save is
   what the rest of the layout is already doing there. */
@media (max-width: 991px) {
    .bs-save-pill {
        position: static;
        left: auto;
        bottom: auto;
        transform: none;
        max-width: none;
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
        margin-top: 20px;
    }

    .bs-save-pill .bs-btn-save,
    .bs-save-pill-cancel {
        width: 100%;
    }

    /* The cancel is an <a> at full width, which would keep its text on the left while the status line
       above it is centred — the stack has to read as one column. */
    .bs-save-pill-cancel {
        text-align: center;
    }

    .bs-save-pill-status {
        text-align: center;
        white-space: normal;
    }

    .bs-save-pill-summary {
        flex-wrap: wrap;
        justify-content: center;
        padding-right: 0;
        border-right: 0;
        white-space: normal;
    }

    .bs-save-pill-spacer {
        height: 0;
    }
}

/* ---- Reduced motion ---------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .bs-btn-save {
        transition: none;
    }
}
