/*
 * FSI theme tokens and base typography.
 * Canonical design tokens live in fsi-tokens.css (single source of truth for
 * the whole FSI ecosystem); it is imported first so the aliases below resolve.
 * The Fleet UI Kit uses the system font stack, so no web-font import is needed;
 * templates stay lean by including this single stylesheet via the fsi_theme()
 * helper.
 */
@import url("fsi-tokens.css");

:root {
    /* Legacy QUOTES token names mapped onto the canonical --fsi-* schema.
       Values now converge on fsi-tokens.css; app-specific extensions with no
       canonical counterpart keep their literal values. Typography, spacing,
       radius and shadow tokens (--fsi-font-*, --fsi-space-*, --fsi-radius-*,
       --fsi-shadow-*) are supplied directly by fsi-tokens.css. */
    --fsi-color-primary: var(--fsi-primary);
    --fsi-color-primary-strong: var(--fsi-primary-strong);
    --fsi-color-primary-soft: color-mix(in srgb, var(--fsi-primary) 12%, transparent);
    --fsi-color-secondary: var(--fsi-neutral-700);
    --fsi-color-secondary-soft: color-mix(in srgb, var(--fsi-neutral-700) 12%, transparent);
    --fsi-color-text: var(--fsi-text);
    --fsi-color-text-strong: var(--fsi-text-strong);
    --fsi-color-surface: var(--fsi-surface);
    --fsi-color-surface-alt: var(--fsi-surface-alt);
    --fsi-color-white: var(--fsi-white);
    --fsi-color-border: var(--fsi-border);
    --fsi-color-success: var(--fsi-success);
    --fsi-color-success-soft: var(--fsi-success-soft);
    --fsi-color-info: var(--fsi-info);
    --fsi-color-info-soft: var(--fsi-info-soft);
    --fsi-color-warning: var(--fsi-warning);
    --fsi-color-warning-soft: var(--fsi-warning-soft);
    --fsi-color-warning-text: var(--fsi-text-strong);
    --fsi-color-muted-earth: var(--fsi-neutral-500);
    --fsi-color-sage-light: var(--fsi-neutral-300);

    /* Bootstrap variable overrides — form border visibility in light mode */
    --bs-border-color: color-mix(in srgb, var(--fsi-neutral-700) 32%, transparent);
}

[data-bs-theme="dark"] {
    /* Core token dark values (text, surface, border, primary, shadows, …) come
       from fsi-tokens.css. Only app-specific extensions are overridden here. */
    --fsi-color-primary-soft: rgb(45 120 228 / 24%);
    --fsi-color-secondary: #aeb8c2;
    --fsi-color-secondary-soft: rgb(174 184 194 / 20%);
    --fsi-color-warning-text: #ffe6bf;
    --bs-border-color: rgb(231 237 248 / 30%);

    .fsi-summary__label {
        color: rgb(226 229 234 / 82%);
    }

    .fsi-summary__total {
        border-top-color: rgb(231 237 248 / 24%);
    }

    .fsi-nav-link--cta {
        border-color: rgb(106 167 255 / 48%);
        background-color: rgb(45 120 228 / 24%);
    }

    .fsi-nav-link--cta:hover,
    .fsi-nav-link--cta:focus {
        background-color: rgb(45 120 228 / 34%);
        color: #dbeaff;
    }

    .fsi-notice--info {
        color: #dbeaff;
        border-color: rgb(45 120 228 / 48%);
        background-color: rgb(45 120 228 / 24%);
    }

    .btn.fsi-button-secondary:hover,
    .btn.fsi-button-secondary:focus-visible {
        color: #d4dce5;
    }

    .fsi-email-request__return-panel {
        border-color: rgb(255 194 122 / 52%);
        background-color: rgb(166 92 0 / 34%);
    }

    .fsi-email-request__return-label {
        color: #d4dce5;
    }
}

.fsi-card {
    background-color: var(--fsi-color-white);
    border: 1px solid var(--fsi-color-border);
    border-radius: var(--fsi-radius-md);
    box-shadow: var(--fsi-shadow-sm);
    padding: var(--fsi-space-4);
}

.fsi-summary {
    margin-block: var(--fsi-space-4);
    padding: var(--fsi-space-4);
    border-radius: var(--fsi-radius-md);
    border: 1px solid color-mix(in srgb, var(--fsi-warning) 42%, transparent);
    background-color: var(--fsi-color-warning-soft);
    color: var(--fsi-color-text);
}

.fsi-summary__label {
    color: var(--fsi-color-secondary);
}

.fsi-summary__total {
    border-top: 1px solid var(--fsi-color-border);
    margin-top: var(--fsi-space-2);
    padding-top: var(--fsi-space-2);
}

.fsi-summary__amount {
    font-size: clamp(1.75rem, 4vw, 2.25rem);
    font-weight: 700;
    line-height: 1;
    margin-bottom: 0;
}

.fsi-notice {
    border: 1px solid transparent;
    border-radius: var(--fsi-radius-md);
    padding: var(--fsi-space-3) var(--fsi-space-4);
}

.fsi-notice--info {
    background-color: var(--fsi-color-info-soft);
    border-color: color-mix(in srgb, var(--fsi-info) 32%, transparent);
    color: var(--fsi-color-primary);
}

.fsi-email-request__return-label {
    color: var(--fsi-color-secondary);
}

.fsi-notice--warning {
    background-color: var(--fsi-color-warning-soft);
    border-color: color-mix(in srgb, var(--fsi-warning) 42%, transparent);
    color: var(--fsi-color-warning-text);
}

.btn.fsi-button-primary,
.btn.fsi-button-secondary {
    border-radius: var(--fsi-radius-pill);
    border-width: 1px;
    border-style: solid;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    letter-spacing: 0.02em;
    padding: var(--fsi-space-2) var(--fsi-space-4);
    text-decoration: none;
}

.btn.fsi-button-primary {
    background-color: var(--fsi-color-primary);
    border-color: var(--fsi-color-primary);
    color: var(--fsi-color-white);
}

.btn.fsi-button-primary:hover,
.btn.fsi-button-primary:focus-visible {
    background-color: var(--fsi-color-primary-strong);
    border-color: var(--fsi-color-primary-strong);
    color: var(--fsi-color-white);
}

.btn.fsi-button-secondary {
    background-color: var(--fsi-color-secondary-soft);
    border-color: color-mix(in srgb, var(--fsi-neutral-700) 30%, transparent);
    color: var(--fsi-color-secondary);
}

.btn.fsi-button-secondary:hover,
.btn.fsi-button-secondary:focus-visible {
    background-color: color-mix(in srgb, var(--fsi-neutral-700) 18%, transparent);
    border-color: color-mix(in srgb, var(--fsi-neutral-700) 44%, transparent);
    color: var(--fsi-color-primary);
}

.fsi-form-section {
    margin-top: var(--fsi-space-4);
}

.fsi-form-section--boxed {
    background-color: var(--fsi-color-white);
    border: 1px solid var(--fsi-color-border);
    border-radius: var(--fsi-radius-md);
    padding: var(--fsi-space-4);
}

.form-control,
.form-select,
.form-check-input {
    --bs-body-bg: var(--fsi-color-surface-alt);
}

.form-control:focus,
.form-select:focus,
.form-check-input:focus {
    --bs-body-bg: var(--fsi-color-white);
    border-color: var(--fsi-color-primary);
    box-shadow: 0 0 0 0.25rem var(--fsi-color-primary-soft);
}

html,
body {
    font-family: var(--fsi-font-body);
    color: var(--fsi-color-text);
    background-color: var(--fsi-color-surface);
}

/* Semantic type system: apply classes intentionally instead of styling every heading tag. */
.fsi-display,
.display,
.display-heading {
    font-family: var(--fsi-font-heading);
    color: var(--fsi-color-text-strong);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    line-height: 1;
}

.fsi-section-title {
    font-family: var(--fsi-font-heading);
    color: var(--fsi-color-text-strong);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    line-height: 1.1;
}

.fsi-body {
    font-family: var(--fsi-font-body);
    color: var(--fsi-color-text);
    letter-spacing: normal;
    text-transform: none;
}

.fsi-body-muted {
    font-family: var(--fsi-font-body);
    color: var(--fsi-muted);
    text-transform: none;
}

.fsi-navbar {
    background-color: var(--fsi-color-white);
    border-bottom: 1px solid var(--fsi-color-border);
    box-shadow: var(--fsi-shadow-sm);
    padding-block: var(--fsi-space-2);
}

.fsi-navbar__container {
    gap: var(--fsi-space-3);
}

.fsi-brand {
    display: inline-flex;
    align-items: center;
    gap: var(--fsi-space-3);
    text-decoration: none;
}

.fsi-brand__lockup {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--fsi-radius-sm);
    background: linear-gradient(135deg, var(--fsi-color-primary-strong),
            var(--fsi-color-primary));
    color: var(--fsi-color-white);
    font-weight: 700;
    font-size: 0.9rem;
    letter-spacing: 0.08em;
}


.fsi-brand__logo {
    height: 2.25rem;
    width: auto;
    display: inline-block;
}

.fsi-brand__text {
    display: flex;
    flex-direction: column;
    line-height: 1.05;
}

.fsi-brand__site,
.fsi-brand__app {
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--fsi-color-text-strong);
    font-size: 0.7rem;
    font-weight: 700;
}

.fsi-brand__app {
    color: var(--fsi-color-primary);
}

.fsi-navbar__toggler {
    border-color: var(--fsi-color-border);
}

.fsi-navbar__menu {
    align-items: center;
    gap: var(--fsi-space-2);
}

.fsi-nav-link {
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.74rem;
    font-weight: 600;
    color: var(--fsi-color-text-strong);
    padding: var(--fsi-space-2) var(--fsi-space-3);
}

.fsi-nav-link:hover,
.fsi-nav-link:focus {
    color: var(--fsi-color-primary);
}

.fsi-nav-link--icon {
    min-width: 2rem;
}

.fsi-nav-link--cta {
    border: 1px solid color-mix(in srgb, var(--fsi-color-primary) 38%, transparent);
    border-radius: var(--fsi-radius-pill);
    color: var(--fsi-color-primary);
    background-color: color-mix(in srgb, var(--fsi-color-primary) 10%, transparent);
}

.fsi-nav-link--cta:hover,
.fsi-nav-link--cta:focus {
    background-color: color-mix(in srgb, var(--fsi-color-primary) 18%, transparent);
    color: var(--fsi-color-primary-strong);
}

@media (max-width: 991.98px) {
    .fsi-navbar__collapse {
        margin-top: var(--fsi-space-2);
    }

    .fsi-navbar__menu {
        align-items: stretch;
        gap: 0;
    }

    .fsi-nav-link {
        padding-inline: 0;
        padding-block: var(--fsi-space-2);
    }

    .fsi-nav-link--cta {
        text-align: center;
        margin-block: var(--fsi-space-2);
        padding-inline: var(--fsi-space-3);
    }
}


.fsi-pre-wrap {
    white-space: pre-wrap;
}

.fsi-email-request__return-panel {
    margin-top: var(--fsi-space-4);
    padding: var(--fsi-space-4);
    border: 3px solid color-mix(in srgb, var(--fsi-warning) 48%, transparent);
    border-radius: var(--fsi-radius-md);
    background-color: color-mix(in srgb, var(--fsi-warning) 20%, transparent);
}

.fsi-admin-quotes__metadata {
    max-width: 420px;
    white-space: pre-wrap;
}

.fsi-admin-zip-zones__notes {
    white-space: pre-wrap;
}

/*
 * App-wide container width.
 *
 * Bootstrap's default `.container` caps at 1140px (xl) / 1320px (xxl). On
 * modern monitors that leaves a lot of whitespace and forces multi-column
 * forms like the Science Care multi-leg quote into a narrower grid than
 * the screen can comfortably show. We introduce two larger custom
 * breakpoints (1600px / 1920px) so widescreen monitors get ~33% more
 * horizontal real estate while still keeping outer margins (each
 * `max-width` stays below its breakpoint's `min-width`). Sub-1600px
 * viewports (laptops, tablets, mobile) continue to use Bootstrap's
 * stock xl / xxl widths.
 */
@media (min-width: 1600px) {
    .container {
        max-width: 1520px;
    }
}

@media (min-width: 1920px) {
    .container {
        max-width: 1760px;
    }
}

/* ══════════════════════════════════════════════════════════════════════
   Fleet UI Kit alignment  (canonical: ~/Repos/fleet-ui-kit/tokens.css)
   v1.1.0 "FSI Brand Standard" reinstates the uppercase display treatment
   in Bebas Neue — it is the measured freightservices.net display type.
   (v1.0.0 was system-font-only and had retired it; reverted here.)
   Small uppercase labels (nav links, captions) are unaffected.
   ══════════════════════════════════════════════════════════════════════ */
.fsi-display,
.display,
.display-heading,
.fsi-section-title {
    font-family: var(--fsi-font-display);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* ══════════════════════════════════════════════════════════════════════
   Status-tint pattern (Fleet UI Kit v1.1.0)

   QUOTES renders status chips with Bootstrap's contextual badge classes
   (`badge bg-success`, `badge bg-danger`, …), which are solid opaque
   fills. Restyling them here converts every chip in the app to the kit's
   translucent-tint pattern without touching markup in 86 templates:
   the fill is a translucent status color so it tracks the page surface,
   and only the label swaps between themes (the --*-label tokens flip in
   fsi-tokens.css). Never opaque pastels — they float on a dark surface.

   bg-primary is brand, not status, so it takes the accent tint.
   `text-dark` / `text-light` utilities that templates pair with badges
   are overridden here too, or they would fight the label color.
   ══════════════════════════════════════════════════════════════════════ */
.badge.bg-success,
.badge.text-bg-success {
    background-color: var(--success-tint) !important;
    color: var(--success-label) !important;
}

.badge.bg-warning,
.badge.text-bg-warning {
    background-color: var(--warning-tint) !important;
    color: var(--warning-label) !important;
}

.badge.bg-danger,
.badge.text-bg-danger {
    background-color: var(--danger-tint) !important;
    color: var(--danger-label) !important;
}

.badge.bg-info,
.badge.text-bg-info {
    background-color: var(--info-tint) !important;
    color: var(--info-label) !important;
}

.badge.bg-secondary,
.badge.text-bg-secondary,
.badge.bg-dark,
.badge.text-bg-dark {
    background-color: var(--neutral-tint) !important;
    color: var(--neutral-label) !important;
}

.badge.bg-primary,
.badge.text-bg-primary {
    background-color: color-mix(in srgb, var(--accent) 12%, transparent) !important;
    color: var(--accent) !important;
}

/* Templates pair some badges with .text-dark/.text-light; the tint pattern
   sets legibility via the label token, so neutralise those utilities here. */
.badge.bg-success.text-dark,
.badge.bg-warning.text-dark,
.badge.bg-info.text-dark,
.badge.bg-secondary.text-dark,
.badge.bg-success.text-light,
.badge.bg-warning.text-light,
.badge.bg-danger.text-light,
.badge.bg-dark.text-light {
    color: inherit;
}

.badge.bg-warning.text-dark {
    color: var(--warning-label) !important;
}

/* ---- Help Center screenshots -------------------------------------------- */
/* Screenshots render at ~35% width on wide screens (full width on small),    */
/* and swap between the light and dark capture to match the viewer's theme.    */
.help-figure {
    max-width: 35%;
}

@media (max-width: 991.98px) {
    .help-figure {
        max-width: 100%;
    }
}

.help-figure .help-shot {
    width: 100%;
    height: auto;
    cursor: zoom-in;
}

.help-figure .help-shot--dark {
    display: none;
}

[data-bs-theme="dark"] .help-figure .help-shot--light {
    display: none;
}

[data-bs-theme="dark"] .help-figure .help-shot--dark {
    display: block;
}

/* Click a help screenshot to view it full screen. */
.help-lightbox {
    position: fixed;
    inset: 0;
    z-index: 1080;
    display: flex;
    padding: 2rem;
    background: rgba(0, 0, 0, 0.85);
    cursor: zoom-out;
    /* Genuinely tall captures (long rate tables, full forms) get the
       ``is-tall`` class from base.html and are shown at full width, so this
       container scrolls them vertically rather than shrinking them to an
       unreadable sliver. Normal- and small-aspect captures are handled by the
       default ``img`` rule below and never trigger a scrollbar. */
    overflow: auto;
}

.help-lightbox[hidden] {
    display: none;
}

.help-lightbox img {
    /* Default: fit the whole screenshot inside the padded overlay, scaling up
       or down while preserving aspect ratio. ``object-fit: contain`` on an
       element sized to the overlay enlarges small captures (a bare
       ``max-width``/``max-height`` can only shrink, never grow — so a capture
       whose intrinsic width is under the inline figure, which upsizes to 35%
       of a wide content column via ``.help-shot { width: 100% }``, would show
       *smaller* full screen than on the page) and shrinks large ones, and a
       normal 16:10 capture stays fully visible with no scrolling. */
    width: 100%;
    height: 100%;
    object-fit: contain;
    margin: auto;
}

.help-lightbox.is-tall img {
    /* Genuinely tall captures would collapse to a narrow, unreadable sliver
       under ``contain``. Instead fill the width and let natural height push
       past the viewport so the container (above) scrolls. ``margin: auto``
       centers horizontally and collapses vertically when the image overflows,
       so the top is never clipped (the flexbox + overflow trap that
       ``justify-content: center`` would hit). */
    height: auto;
    object-fit: fill;
}


/* ============================================================
   Error badge — shared error-state illustration ("Mongo")

   Source of truth: Fleet UI Kit, components/17-error-badge.html.
   Rendered by the Jinja macro in templates/partials/error_badge.html.

   Deliberately NOT `.badge` — that is Bootstrap's / the kit's status pill and a
   different component.

   No colour is declared here, on purpose. The artwork's ink is `currentColor`,
   so it inherits whatever --text resolved to for the active theme and one asset
   serves both light and dark. Declaring a colour here would break that.

   The SVG must be INLINED (the macro does this). Through <img src> or
   background-image an external SVG cannot see this page's CSS, `currentColor`
   falls back to black, and it stops adapting. Use the --mask variant if an
   external image is ever unavoidable.
   ============================================================ */
.fsi-error-badge {
    display: block;
    width: 100%;
    max-width: var(--fsi-error-badge-w, 22rem);
    margin: 0 auto var(--space-4);
}

.fsi-error-badge svg {
    display: block;
    width: 100%;
    height: auto;
}

/* Same adaptivity without inlining: paints a currentColor block through the
   artwork's alpha channel. Requires mongo-error-mask.png in theme static. */
.fsi-error-badge--mask {
    aspect-ratio: 1037 / 684;
    background-color: currentColor;
    -webkit-mask: var(--fsi-error-badge-mask) center / contain no-repeat;
            mask: var(--fsi-error-badge-mask) center / contain no-repeat;
}

/* ==============================================================
   Fleet UI Kit v1.1.0 redesign — component additions/overrides.
   APPEND this file to the END of app/theme/static/fsi.css (or
   @import it after fsi.css). Cascade order matters: this relies on
   appearing AFTER the existing .fsi-summary rules to win at equal
   specificity — do not move it before them.
   ============================================================== */

:root {
  /* fsi-tokens.css defines *-tint and *-label but not *-border;
     these compute the missing halves of the tint/border/label triad. */
  --success-border: color-mix(in srgb, var(--success) 35%, transparent);
  --warning-border: color-mix(in srgb, var(--warning) 38%, transparent);
  --info-border: color-mix(in srgb, var(--info) 32%, transparent);
  --danger-border: color-mix(in srgb, var(--danger) 35%, transparent);
}

/* ---- 1. Nav group (replaces .fsi-brand__lockup used as nav) ---- */
.fsi-navgroup {
  display: flex;
  gap: 2px;
  align-items: center;
  background: var(--neutral-tint);
  border: 1px solid var(--fsi-color-border);
  border-radius: var(--fsi-radius-pill);
  padding: 3px;
}
.fsi-navgroup__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--fsi-color-secondary);
  padding: 7px 16px;
  border-radius: var(--fsi-radius-pill);
  text-decoration: none;
  white-space: nowrap;
}
.fsi-navgroup__item:hover,
.fsi-navgroup__item:focus-visible {
  color: var(--fsi-color-primary);
}
.fsi-navgroup__item[aria-current="page"] {
  background: var(--fsi-color-primary);
  color: #ffffff;
}
@media (max-width: 991.98px) {
  .fsi-navgroup {
    flex-direction: column;
    align-items: stretch;
    background: none;
    border: none;
    padding: 0;
    gap: 4px;
  }
  .fsi-navgroup__item {
    justify-content: flex-start;
    padding: 10px 12px;
  }
  .fsi-navgroup__item[aria-current="page"] {
    background: var(--accent-subtle);
    color: var(--fsi-color-primary);
  }
}

/* ---- 2. Page header ---- */
.fsi-page-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--fsi-space-4);
  flex-wrap: wrap;
  margin-bottom: var(--fsi-space-5);
}
.fsi-page-header__eyebrow {
  font-size: var(--text-xs);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fsi-color-secondary);
  font-weight: 700;
}
.fsi-page-header__title {
  margin: 0;
}
.fsi-page-header__subtitle {
  margin: 3px 0 0;
  font-size: var(--text-sm);
  color: var(--fsi-color-secondary);
}
.fsi-page-header__actions {
  display: flex;
  gap: var(--fsi-space-2);
  flex-wrap: wrap;
}

/* ---- 4. Quote summary / total panel — success tint (overrides the
   warning-tinted rules earlier in fsi.css at equal specificity) ---- */
.fsi-summary {
  border-color: var(--success-border);
  background-color: var(--success-tint);
}
.fsi-summary__label {
  color: var(--success-label);
  font-family: var(--fsi-font-display);
  letter-spacing: .06em;
  text-transform: uppercase;
}
.fsi-summary__amount {
  font-family: var(--fsi-font-display);
  font-weight: 400;
  letter-spacing: .02em;
}
[data-bs-theme="dark"] .fsi-summary__label {
  color: var(--success-label);
}

/* ---- 5. Cost-breakdown table ---- */
.fsi-cost-breakdown {
  border: 1px solid var(--fsi-color-border);
  border-radius: var(--fsi-radius-md);
  overflow: hidden;
}
.fsi-cost-breakdown table {
  margin-bottom: 0;
}
.fsi-cost-breakdown tfoot td {
  background-color: var(--neutral-tint);
  font-weight: 700;
  border-top: 2px solid var(--fsi-color-border);
}

/* ---- 6. Accordion (multi-leg quote) ---- */
.accordion-button {
  font-family: var(--fsi-font-display);
  letter-spacing: .04em;
}
.accordion-button:not(.collapsed) {
  background-color: var(--accent-subtle);
  color: var(--fsi-color-text);
  box-shadow: none;
}
.accordion-button:focus {
  box-shadow: 0 0 0 .2rem var(--fsi-color-primary-soft);
}
.fsi-leg-chip {
  margin-left: auto;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--success-label);
  background: var(--success-tint);
  border: 1px solid var(--success-border);
  border-radius: var(--fsi-radius-pill);
  padding: 2px 9px;
}

/* ---- 7. Pagination ---- */
.pagination {
  gap: 6px;
}
.page-link {
  border-radius: var(--fsi-radius-pill) !important;
  border-color: var(--fsi-color-border);
  color: var(--fsi-color-secondary);
  font-weight: 700;
  font-size: 12px;
}
.page-item.active .page-link {
  background-color: var(--fsi-color-primary);
  border-color: var(--fsi-color-primary);
  color: #ffffff;
}
.page-item.disabled .page-link {
  color: var(--fsi-color-secondary);
  opacity: .5;
}

/* ---- 9. Empty state ---- */
.fsi-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--fsi-space-2);
  padding: var(--fsi-space-6) var(--fsi-space-4);
  color: var(--fsi-color-text);
}
.fsi-empty__icon {
  width: 40px;
  height: 40px;
  border-radius: 9999px;
  background: var(--accent-subtle);
  color: var(--fsi-color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
}
.fsi-empty__title {
  font-family: var(--fsi-font-display);
  font-size: 20px;
  letter-spacing: .04em;
  margin: 0;
}
.fsi-empty__body {
  font-size: 13px;
  color: var(--fsi-color-secondary);
  max-width: 320px;
  margin: 0;
}

/* ---- 10. Dashboard tile grid ---- */
.fsi-tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--fsi-space-3);
}
.fsi-tile {
  display: flex;
  flex-direction: column;
  gap: 2px;
  border: 1px solid var(--fsi-color-border);
  border-radius: var(--fsi-radius-md);
  padding: var(--fsi-space-3);
  text-decoration: none;
  color: inherit;
  transition: border-color .15s, background-color .15s;
}
.fsi-tile:hover,
.fsi-tile:focus-visible {
  border-color: var(--fsi-color-primary);
  background: var(--accent-subtle);
}
.fsi-tile__group {
  font-size: 9px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--fsi-color-secondary);
  font-weight: 700;
}
.fsi-tile__title {
  font-size: 13px;
  font-weight: 700;
  color: var(--fsi-color-text-strong);
}
.fsi-tile__meta {
  font-size: 11px;
  color: var(--fsi-color-secondary);
}

/* ---- 11. Dropdown menu ---- */
.dropdown-menu {
  border-color: var(--fsi-color-border);
  border-radius: var(--fsi-radius-md);
  box-shadow: var(--fsi-shadow-md);
}
.dropdown-item {
  color: var(--fsi-color-text);
  font-size: 13px;
}
.dropdown-item:hover,
.dropdown-item:focus {
  background-color: var(--neutral-tint);
  color: var(--fsi-color-primary);
}
.dropdown-header {
  background-color: var(--neutral-tint);
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.dropdown-divider {
  border-color: var(--fsi-color-border);
}

/* ---- 12. Help-tip icon ---- */
.form-label i.bi-question-circle,
a i.bi-question-circle {
  font-size: 10px;
  width: 16px;
  height: 16px;
  border: 1px solid var(--fsi-color-border);
  border-radius: 9999px;
  color: var(--fsi-color-secondary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ==============================================================
   New Quote wizard shell — the one component that needs new markup
   (see templates/new_quote.html). Desktop: all four steps show on
   one scrolling page with a sticky live-estimate aside; the step rail
   stays hidden because nothing gates or navigates by step at that
   width. Mobile (<768px): true one-step-at-a-time flow, progress bar,
   and the aside collapses into a fixed bottom bar.
   ============================================================== */
.fsi-wizard {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.fsi-wizard__rail {
  /* Wayfinding only - aria-hidden, not focusable, no click handler - and on
     desktop every step is visible at once, so a highlighted "1 Route" chip
     reads as broken navigation. The mobile progress bar below is the real
     step indicator; this rail is never shown. */
  display: none;
  border: 1px solid var(--fsi-color-border);
  border-radius: var(--fsi-radius-md);
  background: var(--fsi-color-white);
  overflow: hidden;
}
.fsi-wizard__rail-step {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-left: 1px solid var(--fsi-color-border);
  background: none;
  border-top: none;
  border-bottom: none;
  border-right: none;
  font: inherit;
  text-align: left;
  cursor: default;
  color: var(--fsi-color-secondary);
}
.fsi-wizard__rail-step:first-child {
  border-left: none;
}
.fsi-wizard__rail-num {
  width: 22px;
  height: 22px;
  border-radius: 9999px;
  border: 1px solid var(--fsi-color-border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  flex: none;
}
.fsi-wizard__rail-step.is-active {
  background: var(--accent-subtle);
}
.fsi-wizard__rail-step.is-active .fsi-wizard__rail-num {
  background: var(--accent);
  border-color: var(--accent);
  color: #ffffff;
}
.fsi-wizard__rail-step.is-active .fsi-wizard__rail-label {
  color: var(--accent-hover);
}
.fsi-wizard__rail-label {
  font-size: 13px;
  font-weight: 700;
}
.fsi-wizard__progress,
.fsi-wizard__step-caption {
  display: none;
}
.fsi-wizard__body {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 20px;
  align-items: start;
}
.fsi-wizard__main {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.fsi-wizard__step-title {
  font-size: var(--fsi-fs-body-sm);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fsi-color-secondary);
  font-weight: 700;
  margin: 0 0 4px;
}
.fsi-wizard__aside {
  position: sticky;
  top: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.fsi-estimate {
  background: var(--fsi-color-white);
  border: 1px solid var(--fsi-color-border);
  border-radius: var(--fsi-radius-md);
  overflow: hidden;
}
.fsi-estimate__header {
  padding: 14px 16px;
  border-bottom: 1px solid var(--fsi-color-border);
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fsi-color-secondary);
  font-weight: 700;
}
.fsi-estimate__body {
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.fsi-estimate__total-label {
  font-family: var(--fsi-font-display);
  font-size: 16px;
  letter-spacing: .06em;
  color: var(--fsi-color-secondary);
}
.fsi-estimate__total {
  font-family: var(--fsi-font-display);
  font-size: 40px;
  line-height: 1;
  color: var(--fsi-color-text-strong);
}
.fsi-estimate__hint {
  margin: 0;
  font-size: 12px;
  color: var(--fsi-color-secondary);
}
.fsi-estimate__lines {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  border-top: 1px solid var(--fsi-color-border);
  padding-top: 10px;
}
.fsi-estimate__line {
  display: flex;
  justify-content: space-between;
}
/* Why the sidebar has no number yet - an incomplete form or a pricing
   outage. Wraps, unlike the two-column priced rows. */
.fsi-estimate__line--hint {
  display: block;
  color: var(--fsi-color-secondary);
}
.fsi-estimate__actions {
  padding: 14px 16px;
  border-top: 1px solid var(--fsi-color-border);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.fsi-estimate__actions .btn {
  width: 100%;
}
.fsi-quote-type-cards {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.fsi-quote-type-card {
  flex: 1;
  min-width: 220px;
  border: 1px solid var(--fsi-color-border);
  border-radius: var(--fsi-radius-md);
  padding: 12px 14px;
  cursor: pointer;
  display: block;
  position: relative;
}
.fsi-quote-type-card input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.fsi-quote-type-card:has(input:checked) {
  border: 2px solid var(--accent);
  background: var(--accent-subtle);
}
.fsi-quote-type-card:has(input:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.fsi-quote-type-card__title {
  font-size: 14px;
  font-weight: 700;
  color: var(--fsi-color-text-strong);
  display: block;
}
.fsi-quote-type-card__meta {
  font-size: 12px;
  color: var(--fsi-color-secondary);
  margin-top: 2px;
  display: block;
}
.fsi-chip-check {
  display: inline-flex;
  position: relative;
}
.fsi-chip-check input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.fsi-chip-check__label {
  border: 1px solid var(--fsi-color-border);
  color: var(--fsi-color-secondary);
  border-radius: 9999px;
  padding: 7px 14px;
  font-size: 13px;
  cursor: pointer;
}
.fsi-chip-check input:checked + .fsi-chip-check__label {
  border: 2px solid var(--accent);
  background: var(--accent-subtle);
  color: var(--fsi-color-text-strong);
  font-weight: 700;
}
.fsi-chip-check input:focus-visible + .fsi-chip-check__label {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (max-width: 767.98px) {
  .fsi-wizard__progress {
    display: flex;
    gap: 6px;
  }
  .fsi-wizard__progress-seg {
    flex: 1;
    height: 4px;
    border-radius: 9999px;
    background: var(--fsi-color-border);
  }
  .fsi-wizard__progress-seg.is-active,
  .fsi-wizard__progress-seg.is-done {
    background: var(--accent);
  }
  .fsi-wizard__step-caption {
    display: block;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--fsi-color-secondary);
  }
  .fsi-wizard__body {
    grid-template-columns: 1fr;
    padding-bottom: 96px;
  }
  .fsi-wizard__step:not(.is-active) {
    display: none;
  }
  .fsi-wizard__aside {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    top: auto;
    margin: 0;
    z-index: 20;
  }
  .fsi-estimate {
    border-radius: 0;
    border-width: 1px 0 0;
  }
  .fsi-estimate__header,
  .fsi-estimate__lines,
  .fsi-estimate__hint {
    display: none;
  }
  .fsi-estimate__body {
    flex-direction: row;
    align-items: center;
    padding: 10px 14px;
  }
  .fsi-estimate__total-label {
    font-size: 10px;
  }
  .fsi-estimate__total {
    font-size: 24px;
  }
  .fsi-estimate__actions {
    flex: none;
    margin-left: auto;
    padding: 0;
    border-top: none;
    width: auto;
    flex-direction: row;
    gap: 8px;
  }
  .fsi-estimate__actions .btn {
    width: auto;
    height: 48px;
    padding-inline: 20px;
  }
  .fsi-wizard input,
  .fsi-wizard select,
  .fsi-wizard .form-control,
  .fsi-wizard .btn {
    min-height: 44px;
  }
}

/* ---- 6 (completion). Accordion "SHIPMENT N" contrast fix — the .accordion-button
   block above was appended without the color override or the .fsi-leg-title class;
   this supplies both, per the redesign handoff's Science Care multi-lab pass.
   Bootstrap's own --bs-accordion-btn-color is a low-contrast muted blue/violet in
   both themes — that's why "SHIPMENT 1" reads faint regardless of the tint behind
   it. Appended (not merged into the earlier rule) so cascade order is preserved. ---- */
.accordion-button {
  color: var(--fsi-color-text);
}
.fsi-leg-title {
  font-family: var(--fsi-font-display);
  font-size: 17px;
  letter-spacing: .04em;
  color: var(--fsi-color-text-strong);
}

/* ---- 13. Sitewide button unification ("two button systems" from the
   audit) — restyle Bootstrap's contextual buttons to the same pill shape
   and weight as .fsi-button-primary/-secondary, with no markup changes.
   Applies everywhere: admin rate-table CRUD pages, settings, SC reference
   pages, error/help/auth pages. ---- */
.btn {
  border-radius: var(--fsi-radius-pill);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.btn-primary,
.btn-success {
  background-color: var(--fsi-color-primary);
  border-color: var(--fsi-color-primary);
  color: var(--fsi-color-white);
}
.btn-primary:hover,
.btn-primary:focus-visible,
.btn-success:hover,
.btn-success:focus-visible {
  background-color: var(--fsi-color-primary-strong);
  border-color: var(--fsi-color-primary-strong);
  color: var(--fsi-color-white);
}
.btn-outline-secondary,
.btn-secondary {
  background-color: var(--fsi-color-secondary-soft);
  border-color: color-mix(in srgb, var(--fsi-neutral-700) 30%, transparent);
  color: var(--fsi-color-secondary);
}
.btn-outline-secondary:hover,
.btn-outline-secondary:focus-visible,
.btn-secondary:hover,
.btn-secondary:focus-visible {
  background-color: color-mix(in srgb, var(--fsi-neutral-700) 18%, transparent);
  border-color: color-mix(in srgb, var(--fsi-neutral-700) 44%, transparent);
  color: var(--fsi-color-primary);
}
.btn-danger {
  background-color: var(--danger);
  border-color: var(--danger);
  color: var(--fsi-color-white);
}
.btn-warning {
  background-color: var(--warning);
  border-color: var(--warning);
  color: var(--fsi-color-white);
}
.btn-info {
  background-color: var(--info);
  border-color: var(--info);
  color: var(--fsi-color-white);
}
.btn-sm {
  padding: 4px 12px;
}

/* ---- 14. Sitewide card unification ("two card systems") — bring plain
   Bootstrap .card visually in line with .fsi-card everywhere it's used
   (admin dashboard rate tiles already moved to .fsi-card; this covers
   every remaining .card in admin CRUD, settings, SC reference pages). ---- */
.card {
  background-color: var(--fsi-color-white);
  border: 1px solid var(--fsi-color-border);
  border-radius: var(--fsi-radius-md);
  box-shadow: var(--fsi-shadow-sm);
}
.card-header {
  background-color: transparent;
  border-bottom: 1px solid var(--fsi-color-border);
  font-family: var(--fsi-font-display);
  letter-spacing: 0.03em;
}

/* ---- 15. Static notice consistency for bare .alert usage — the ~90
   count from the audit are mostly alert-warning/-info as body copy, not
   flash messages. Templates should migrate those to .fsi-notice--warning/
   --info (mechanical, see NOTES.md); until they do, this at least aligns
   the shape/radius/border weight with the rest of the kit so both read as
   one family in the meantime. Flash messages keep Bootstrap's dismissible
   behavior and icon-free plain look, just with matching geometry. ---- */
.alert {
  border-radius: var(--fsi-radius-md);
  border-width: 1px;
}
.alert-warning {
  background-color: var(--warning-tint);
  border-color: var(--warning-border);
  color: var(--warning-label);
}
.alert-info {
  background-color: var(--info-tint);
  border-color: var(--info-border);
  color: var(--info-label);
}
.alert-danger {
  background-color: var(--danger-tint);
  border-color: var(--danger-border);
  color: var(--danger-label);
}
.alert-success {
  background-color: var(--success-tint);
  border-color: var(--success-border);
  color: var(--success-label);
}

/* ---- 16. Notice variant completion — .fsi-notice--danger/--success.
   The static-notice sweep (§5a of the redesign handoff) converted several
   body-copy alert-danger/-success blocks to .fsi-notice, but only the
   --info and --warning variants existed, so those blocks rendered as
   unstyled transparent-bordered boxes. These complete the family using
   the same tint/border/label triad as the .alert-* rules in §15, so the
   two systems stay visually identical and both flip correctly in dark
   mode (the *-label tokens are redefined under [data-bs-theme="dark"]
   in fsi-tokens.css, so no dark override is needed here). ---- */
.fsi-notice--danger {
  background-color: var(--danger-tint);
  border-color: var(--danger-border);
  color: var(--danger-label);
}
.fsi-notice--success {
  background-color: var(--success-tint);
  border-color: var(--success-border);
  color: var(--success-label);
}

/* Release-tier banner (RELEASE_POLICY.md §3) — shown only when FSI_TIER=test.
   Warning tint so it reads as "attention", in both themes, without shouting. */
.fsi-tier-banner {
    background-color: var(--fsi-color-warning-soft);
    color: var(--fsi-color-warning-text);
    border-bottom: 1px solid var(--fsi-color-warning);
    padding: 0.4rem 1rem;
    text-align: center;
    font-size: 0.9rem;
    line-height: 1.3;
}

.fsi-tier-banner strong {
    font-family: var(--fsi-font-display);
    font-weight: 400;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-size: 1.05rem;
}

.fsi-tier-banner__build {
    margin-left: 0.75rem;
    font-family: var(--fsi-font-mono, ui-monospace, monospace);
    opacity: 0.8;
}
