/*
    SET Weight Label - application styles.

    Built on the Fluent design tokens the component library exposes, so light/dark themes
    and high-contrast mode work without a second set of colours. Toyota red is used as the
    accent, with a calm slate/blue surface palette so the yellow sticker and the red stop
    sign remain the most eye-catching things on the page - they are the safety-critical
    elements and must not compete with decoration.
*/

/*
    The app is light-only, declared explicitly.

    A dark palette was tried and removed: the Fluent web components keep their light theme
    regardless of the media query, so dark surfaces ended up with Fluent's dark button text
    on top - a contrast ratio of 1.04, i.e. completely invisible. color-scheme also stops the
    browser applying dark user-agent styling to the native <select> and scrollbars.

    A single predictable appearance is also the right call for a plant floor, where the
    screen is shared and operators should not see two different looking apps.
*/
:root {
    color-scheme: light;

    /* Softened from the original #d5202f / #a3121f. Same hue (355deg), but saturation
       pulled back 74%->59% and 80%->60%: the banner is a large solid field, and at full
       saturation it glares and tires the eye on a shift-long shared screen. Contrast
       actually improves (white-on-red 5.15 -> 5.76; the dark red as text on white
       7.88 -> 8.91), so both still clear WCAG AA for normal text. */
    --wl-red: #bd3038;
    --wl-red-dark: #8a232b;
    --wl-ink: #16202c;
    --wl-muted: #4a5a6b;
    --wl-line: #e3e8ef;
    --wl-surface: #ffffff;
    --wl-canvas: #f4f7fb;
    --wl-ok: #0f7b3f;
    --wl-warn: #8a5600;
    --wl-warn-bg: #fff4d6;
    --wl-ok-bg: #e6f5ec;
    --wl-radius: 12px;
    --wl-radius-sm: 8px;
    --wl-shadow: 0 1px 2px rgba(16, 32, 48, .06), 0 8px 24px rgba(16, 32, 48, .07);
    --wl-shadow-lg: 0 2px 4px rgba(16, 32, 48, .08), 0 16px 40px rgba(16, 32, 48, .12);
}

html, body {
    margin: 0;
    padding: 0;
    background: var(--wl-canvas);
    color: var(--wl-ink);
    font-family: "Segoe UI Variable", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
    font-size: 14px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

.mono {
    font-family: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;
    font-variant-numeric: tabular-nums;
    letter-spacing: .02em;
}

/* ---------------------------------------------------------------- page shell */

.wl-page {
    max-width: 1400px;
    margin: 0 auto;
    padding: 20px 24px 56px;
}

/*
    The banner uses the same solid brand red as the section headers, so the page opens
    with the same treatment it repeats below. No separate top rule here: the whole card
    is already red, so a red stripe on top of it would not read as anything.
*/
.wl-hero {
    display: flex;
    align-items: center;
    /* Centred as a unit: the logo and the heading read as one banner. */
    justify-content: center;
    gap: 18px;
    padding: 18px 22px;
    margin-bottom: 20px;
    background: var(--wl-red);
    border: 1px solid var(--wl-red-dark);
    border-radius: var(--wl-radius);
    box-shadow: var(--wl-shadow);
    text-align: center;
    color: #fff;
}

/* Catch-all, so anything added to the banner later is legible by default. */
.wl-hero,
.wl-hero * {
    color: #fff;
}

.wl-logo {
    /* SVG, so it scales cleanly at any size and needs no object-fit correction: the
       viewBox is cropped to the artwork. */
    height: 42px;
    width: auto;
    flex: none;
    /* The wordmark is near-black on transparency, so it would be lost against the red
       banner. A white chip keeps it legible and preserves the artwork as supplied. */
    background: #fff;
    padding: 6px 10px;
    border-radius: 8px;
}

.wl-hero-text h1 {
    margin: 0;
    /* Sized up towards the legacy header, which was noticeably larger than the 22px the
       rewrite started with, without going all the way to its size. */
    font-size: 26px;
    font-weight: 650;
    letter-spacing: -.01em;
}

.wl-hero-text p {
    margin: 2px 0 0;
    /* Slightly held back from pure white so it still reads as a subtitle on the red. */
    color: rgba(255, 255, 255, .88);
    /* Raised 13px -> 15px. Note this is already LARGER than the 12px form labels
       ("TMS Weight Sticker Amt (if any)"); those only look bigger because they are
       600-weight, uppercase and letter-spaced on dark ink, whereas this is regular
       weight in translucent white on red. Stepped back to 13px under 560px so the
       longer sentence does not wrap awkwardly on a phone. */
    font-size: 15px;
}

.wl-boot,
.wl-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 32px;
    color: var(--wl-muted);
}

.wl-access-denied {
    margin-top: 8px;
}

/* ---------------------------------------------------------------- cards */

.wl-card {
    background: var(--wl-surface);
    border: 1px solid var(--wl-line);
    border-radius: var(--wl-radius);
    box-shadow: var(--wl-shadow);
    padding: 0;
    /* No overflow:hidden - the header rounds its own top corners instead, so nested
       content is never clipped unexpectedly. */
}

/*
    Red framing, matching the rule the banner used to carry.

    The VIN search card is framed on all four sides. The three result sections are framed
    on left, right and bottom only: their red section header already supplies the top
    edge, so a rule above it would just thicken that band.

    Selected by :has() rather than by adding a class to each component: a card qualifies
    either because it owns a red section header, or because it is the VIN search card.
    That deliberately leaves the "not found" card plain, since it is an error surface
    rather than part of the inquiry flow.

    A descendant selector is used rather than ":has(> .wl-card-header)": fluent-card is a
    web component and slots its content, so the header is not guaranteed to be a direct
    DOM child.
*/
.wl-inquiry-card {
    border: 3px solid var(--wl-red);
}

.wl-card:has(.wl-card-header) {
    border: 3px solid var(--wl-red);
    border-top: 0;
}

/*
    With a 3px frame the header's corners have to nest inside it, so its top radius is
    reduced by the border width (12 - 3). Without this the header's curve sits proud of
    the card's outer curve.
*/
.wl-card:has(.wl-card-header) .wl-card-header {
    border-radius: 9px 9px 0 0;
}

/*
    Section headers use the solid brand red, matching the solid blue bars in the legacy
    app. Everything sitting on that bar has to be light, so the header sets white on
    itself and on every descendant. Individual rules below then only need to handle the
    cases that do not inherit colour - the icon fill and the two pill backgrounds.
*/
.wl-card-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--wl-red-dark);
    background: var(--wl-red);
    color: #fff;
    /* The card no longer clips its children, so the header rounds its own top corners. */
    border-radius: var(--wl-radius) var(--wl-radius) 0 0;
}

/* Catch-all, so anything added to the header later is legible by default. */
.wl-card-header,
.wl-card-header * {
    color: #fff;
}

.wl-card-header h2 {
    margin: 0;
    /* Matches the proportional step applied to the page title, so the section bars read
       as headings rather than labels - closer to the legacy layout. */
    font-size: 17px;
    font-weight: 650;
    letter-spacing: .01em;
}

/* FluentIcon with Color.Fill emits an inline fill, so this needs to win. */
.wl-card-header svg {
    fill: #fff !important;
}

.wl-count {
    margin-left: auto;
    min-width: 24px;
    padding: 1px 9px;
    border-radius: 999px;
    /* Translucent white reads as part of the red bar at any red shade. */
    background: rgba(255, 255, 255, .22);
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    text-align: center;
}

.wl-card-body {
    padding: 18px;
}

.wl-grid-body {
    padding: 6px 6px 10px;
}

.wl-divider {
    border: 0;
    border-top: 1px solid var(--wl-line);
    margin: 16px 0;
}

.wl-empty {
    margin: 0;
    padding: 18px;
    color: var(--wl-muted);
    text-align: center;
    font-style: italic;
}

/* ---------------------------------------------------------------- inquiry form */

.wl-inquiry-card {
    margin-bottom: 20px;
}

.inquiry-grid {
    display: grid;
    grid-template-columns: minmax(220px, 1.3fr) minmax(170px, 1fr) minmax(180px, 1fr) auto;
    gap: 18px;
    align-items: start;
}

.field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

.field-vin::part(control) {
    font-family: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;
    letter-spacing: .12em;
    text-transform: uppercase;
}

.field-inquiry {
    padding-top: 22px;
}

/*
    The checkbox label is rendered as child content (see VehicleInquiry.razor) because the
    Label parameter uses a low-contrast Fluent token that was unreadable on this card.
*/
.inquiry-label {
    color: var(--wl-ink);
    font-weight: 600;
    font-size: 14px;
}

.field-go {
    padding-top: 20px;
}

/*
    The Go button keeps the visual weight of the original 100x100 square button - operators
    hit it constantly, often with gloves on - but with a modern shape and a clear press
    affordance.
*/
.go-button {
    min-width: 96px;
    height: 46px;
    font-size: 15px;
    font-weight: 650;
    letter-spacing: .02em;
}

/*
    Inline validation replaces the absolutely-positioned red tooltips of the old UI, which
    overlapped neighbouring fields and were cut off on smaller screens.
*/
.field-error {
    color: var(--wl-red-dark);
    font-size: 12px;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 4px;
    min-height: 16px;
}

.field-hint {
    color: var(--wl-muted);
    font-size: 12px;
    min-height: 16px;
}

/* ---------------------------------------------------------------- printer row */

.printer-section {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px dashed var(--wl-line);
}

.printer-row {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}

.printer-label {
    font-weight: 650;
    color: var(--wl-ink);
    white-space: nowrap;
}

.printer-controls {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.printer-spinner {
    width: 18px;
    height: 18px;
}

.printer-loading-text,
.printer-saved {
    color: var(--wl-muted);
    font-size: 13px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.printer-saved {
    color: var(--wl-ok);
    font-weight: 600;
    animation: wl-fade-in .18s ease-out;
}

/* ---------------------------------------------------------------- print status */

.print-status {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-top: 16px;
    padding: 11px 14px;
    border-radius: var(--wl-radius-sm);
    font-weight: 600;
    animation: wl-fade-in .2s ease-out;
}

.print-ok {
    background: var(--wl-ok-bg);
    color: var(--wl-ok);
    border: 1px solid rgba(15, 123, 63, .22);
}

.print-fail {
    background: #fdeaec;
    color: var(--wl-red-dark);
    border: 1px solid rgba(189, 48, 56, .22);
}

/* ---------------------------------------------------------------- detail area */

.detail-grid {
    display: grid;
    grid-template-columns: minmax(360px, 0.85fr) minmax(420px, 1.15fr);
    gap: 20px;
    margin-bottom: 20px;
    align-items: start;
}

.vehicle-facts {
    display: grid;
    grid-template-columns: minmax(120px, auto) 1fr;
    gap: 8px 18px;
    margin: 0;
}

.vehicle-facts dt {
    color: var(--wl-muted);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    align-self: center;
}

.vehicle-facts dd {
    margin: 0;
    font-weight: 600;
    word-break: break-all;
}

.sticker-area {
    display: flex;
    justify-content: center;
    padding: 4px 0;
}

/* ---------------------------------------------------------------- the sticker */

/*
    Fixed 150x163 dimensions and the rotated VIN are carried over verbatim from the legacy
    stylesheet. This artwork is legally mandated, so it is deliberately NOT made responsive
    or restyled.
*/
.sticker-frame {
    padding: 12px;
    background: #fffdf2;
    border: 1px solid #ece2b8;
    border-radius: var(--wl-radius-sm);
    box-shadow: inset 0 0 0 1px #fff, 0 1px 3px rgba(16, 32, 48, .08);
}

.sticker-canvas {
    position: relative;
    width: 150px;
    height: 163px;
}

.sticker-image {
    display: block;
    width: 150px;
    height: 163px;
}

.sticker-vin {
    position: absolute;
    left: calc(50% - 10px);
    top: calc(50% - 10px);
}

.sticker-vin-rotated {
    transform: rotate(90deg);
    font-family: "Arial Narrow", Arial, sans-serif;
    font-size: 12pt;
    font-weight: 700;
    white-space: nowrap;
}

.sticker-weight {
    position: absolute;
    bottom: 14px;
    left: 0;
}

/* ---------------------------------------------------------------- stop sign */

.stop-panel {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 16px 18px;
    background: #fff8c4;
    border: 2px solid #e3c800;
    border-radius: var(--wl-radius-sm);
    text-align: center;
}

.stop-icon {
    width: 84px;
    height: auto;
}

.stop-text {
    margin: 0;
    font-weight: 700;
    color: #6b1a12;
    max-width: 340px;
}

/* ---------------------------------------------------------------- weight summary */

.weight-summary {
    margin: 0 0 6px;
    text-align: center;
    font-size: 16px;
    font-weight: 700;
    color: var(--wl-red);
}

.tms-note {
    margin: 0;
    text-align: center;
    color: var(--wl-muted);
    font-size: 13px;
}

.tms-value {
    color: var(--wl-red);
    font-weight: 700;
}

/* ---------------------------------------------------------------- grids */

/*
    Fluent's data grid inherits low-contrast neutral tokens for its header and cell text,
    which on this light card left the column titles and values hard to read. Everything here
    restores full contrast and adds the zebra striping and row hover the old grid had.
*/
.wl-grid {
    width: 100%;
    font-size: 13px;
    color: var(--wl-ink);
}

/* Column headers: dark, bold and clearly separated from the rows. */
.wl-grid .column-header,
.wl-grid [role="columnheader"],
.wl-grid fluent-data-grid-cell[cell-type="columnheader"] {
    color: var(--wl-ink) !important;
    font-weight: 700 !important;
    font-size: 12px !important;
    letter-spacing: .02em;
    text-transform: uppercase;
    background: #eef2f8 !important;
    border-bottom: 2px solid var(--wl-line) !important;
}

/* Sort buttons inside a header must not fade the title. */
.wl-grid .column-header button,
.wl-grid [role="columnheader"] button {
    color: inherit !important;
    font-weight: inherit !important;
    opacity: 1 !important;
}

/* Body cells at full contrast. */
.wl-grid fluent-data-grid-cell,
.wl-grid [role="gridcell"] {
    color: var(--wl-ink) !important;
    padding-top: 7px !important;
    padding-bottom: 7px !important;
    border-bottom: 1px solid #f0f3f7;
}

/* Zebra striping and hover, so long part lists stay readable across a row. */
.wl-grid fluent-data-grid-row[row-type="default"]:nth-of-type(even),
.wl-grid [role="row"]:nth-of-type(even) {
    background: #fafbfd;
}

.wl-grid fluent-data-grid-row[row-type="default"]:hover,
.wl-grid [role="row"]:hover {
    background: #eaf1fb;
}

.wl-status-text {
    color: var(--wl-warn);
    font-weight: 600;
    font-style: italic;
}

.wl-pill {
    display: inline-block;
    padding: 1px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .04em;
}

.wl-pill-ok {
    background: var(--wl-ok-bg);
    color: var(--wl-ok);
}

.wl-pill-warn {
    background: var(--wl-warn-bg);
    color: var(--wl-warn);
}

.wl-badge {
    margin-left: 8px;
    padding: 1px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
}

/*
    The only badge in the app sits inside the red section header, so the amber-on-cream
    warning palette would clash and read poorly. A translucent white pill with a solid
    white border keeps the "this needs attention" emphasis while staying legible on red.
*/
.wl-badge-warn {
    background: rgba(255, 255, 255, .18);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, .65);
}

/* ---------------------------------------------------------------- dialogs */

.popup-header,
.confirm-header {
    display: flex;
    align-items: center;
    gap: 11px;
    margin-bottom: 6px;
}

/*
    Close button, shown only when the dialog was opened from Change. margin-left:auto
    pushes it to the far edge; the negative margins pull it back over the dialog padding
    so it sits in the corner rather than indenting the header text.
*/
.confirm-close {
    margin-left: auto;
    margin-top: -6px;
    margin-right: -8px;
    flex: none;
}

.popup-header h3,
.confirm-header h3 {
    margin: 0;
    font-size: 17px;
    font-weight: 650;
}

.popup-header-error h3 {
    color: var(--wl-red-dark);
}

.popup-header-ok h3 {
    color: var(--wl-ok);
}

.popup-message {
    margin: 10px 0 20px;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.55;
}

.popup-message-error {
    color: var(--wl-red-dark);
}

.popup-footer,
.confirm-footer {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    flex-wrap: wrap;
}

.confirm-subline {
    margin: 1px 0 0;
    color: var(--wl-muted);
    font-size: 13px;
}

.confirm-body {
    margin: 18px 0 22px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.confirm-error {
    margin-top: 4px;
}

/* ---------------------------------------------------------------- motion */

@keyframes wl-fade-in {
    from { opacity: 0; transform: translateY(-3px); }
    to   { opacity: 1; transform: none; }
}

/* Respect users who have asked the OS to reduce motion. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        transition-duration: .001ms !important;
    }
}

/* ---------------------------------------------------------------- responsive */

@media (max-width: 1100px) {
    .detail-grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 820px) {
    .wl-page {
        padding: 14px 14px 40px;
    }

    .inquiry-grid {
        grid-template-columns: 1fr 1fr;
    }

    .field-go,
    .field-inquiry {
        padding-top: 6px;
    }

    .go-button {
        width: 100%;
    }
}

@media (max-width: 560px) {
    .wl-hero {
        flex-direction: column;
        align-items: flex-start;
        text-align: left;
    }

    /* Step the enlarged headings back down so they do not wrap awkwardly on a phone. */
    .wl-hero-text h1 {
        font-size: 22px;
    }

    .wl-hero-text p {
        font-size: 13px;
    }

    .wl-card-header h2 {
        font-size: 16px;
    }

    .inquiry-grid {
        grid-template-columns: 1fr;
    }

    .vehicle-facts {
        grid-template-columns: 1fr;
        gap: 2px 0;
    }

    .vehicle-facts dd {
        margin-bottom: 10px;
    }
}

/* ---------------------------------------------------------------- dark mode */



/* ---------------------------------------------------------------- splash + error */

/*
    Shown by index.html while the WebAssembly runtime downloads, and removed automatically
    once Blazor renders into #app. Styled here rather than inline so it inherits the same
    palette as the app it precedes.
*/
.wl-splash {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--wl-canvas);
}

.wl-splash-card {
    text-align: center;
    padding: 34px 44px;
    background: var(--wl-surface);
    border: 1px solid var(--wl-line);
    border-radius: var(--wl-radius);
    box-shadow: var(--wl-shadow-lg);
}

.wl-splash-logo {
    height: 46px;
    width: auto;
    margin-bottom: 14px;
}

.wl-splash-card h1 {
    margin: 0 0 18px;
    font-size: 19px;
    font-weight: 650;
}

.wl-splash-card p {
    margin: 14px 0 0;
    color: var(--wl-muted);
    font-size: 13px;
}

.wl-splash-bar {
    width: 230px;
    height: 4px;
    margin: 0 auto;
    border-radius: 999px;
    background: var(--wl-line);
    overflow: hidden;
}

.wl-splash-bar span {
    display: block;
    width: 40%;
    height: 100%;
    border-radius: 999px;
    background: var(--wl-red);
    animation: wl-indeterminate 1.15s ease-in-out infinite;
}

@keyframes wl-indeterminate {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(350%); }
}

#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    padding: 12px 18px;
    background: #fff2c4;
    border-top: 2px solid #e3c800;
    box-shadow: 0 -4px 16px rgba(16, 32, 48, .12);
    color: #4a3800;
    font-weight: 600;
}

#blazor-error-ui .reload,
#blazor-error-ui .dismiss {
    margin-left: 14px;
    cursor: pointer;
    text-decoration: underline;
}

/* ---------------------------------------------------------------- dialog sizing */

/*
    Sizes the confirm dialog so its content fits without scrolling the dialog itself.

    The printer picker inside it is a native <select>, so the browser renders the option list
    as an OS-level popup outside the dialog - the dialog does not need to make room for it,
    and nothing here has to defeat clipping.

    ⚠️ `height` has to be set explicitly. Fluent's own rule is
        height: calc(var(--dialog-height) - 2 * var(--dialog-padding))
    and --dialog-height defaults to 100dvh, so the dialog is laid out at full viewport
    height regardless of how little content it holds. A `max-height` alone does not
    override it - max-height only caps a height that is already being computed, so the
    dialog kept its tall fixed box and the body scrolled inside it. Setting height:auto
    lets it size to its content, with max-height as the cap on very small viewports.

    ⚠️ Sizing ::part(control) alone is still not enough. The control sits inside the web
    component's own shadow-DOM `positioning-region`, which is a full-viewport flex box.
    That region has to centre the control and allow scrolling, otherwise a dialog taller
    than the region is clipped at the bottom edge - which is what cut the footer off even
    after the height:auto fix. Both parts are styled below, and the region gets vertical
    padding so the dialog never sits flush against the viewport edge.
*/
fluent-dialog::part(positioning-region) {
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;

    /* Breathing room top and bottom, and a scroll if the viewport is very short. */
    padding: 24px 16px !important;
    overflow-y: auto !important;
}

fluent-dialog::part(control) {
    /* Wide enough for a printer name, capped so it never fills a large monitor. */
    width: min(92vw, 520px) !important;
    max-width: min(92vw, 520px) !important;

    /* Size to content, so the header, picker and Confirm button are all visible at once. */
    height: auto !important;

    /* Leave room for the positioning-region padding above and below. */
    max-height: calc(100dvh - 48px) !important;

    /* The region centres this; do not let flex stretch it back to full height. */
    flex: 0 0 auto !important;
    margin: auto !important;
}

/* The body is a grid area; let it grow with its content instead of scrolling. */
fluent-dialog .fluent-dialog-body {
    overflow-y: visible;
}

fluent-dialog::part(overlay) {
    /* Slightly stronger dim so the dialog reads as the only active surface. */
    background: rgba(16, 32, 48, .45) !important;
}

/* Keep the Confirm button reachable without scrolling. */
.confirm-footer {
    padding-top: 4px;
}


/* ---------------------------------------------------------------- native select */

/*
    Styles the native <select> used for printer selection so it matches the Fluent controls
    beside it.

    A native element is used deliberately: the browser renders its option list as an
    OS-level popup that is always positioned inside the viewport, flipping upward when there
    is no room below. FluentSelect draws its own list downward only, which ran off the bottom
    of the window on this page and made the later printers unreachable.
*/
.wl-select {
    height: 32px;
    min-width: 260px;
    padding: 0 30px 0 10px;
    border: 1px solid #8a8a8a;
    border-radius: 4px;
    background-color: var(--wl-surface);
    color: var(--wl-ink);
    font-family: inherit;
    font-size: 14px;
    line-height: 30px;
    cursor: pointer;

    /* Custom chevron, since removing the native one also removes the OS styling. */
    appearance: none;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23444' d='M3.2 5.7a1 1 0 0 1 1.4 0L8 9.1l3.4-3.4a1 1 0 1 1 1.4 1.4l-4.1 4.1a1 1 0 0 1-1.4 0L3.2 7.1a1 1 0 0 1 0-1.4z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 8px center;
    background-size: 14px;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.wl-select:hover:not(:disabled) {
    border-color: #4a4a4a;
}

.wl-select:focus-visible {
    outline: none;
    border-color: var(--wl-red);
    box-shadow: 0 0 0 2px rgba(189, 48, 56, .22);
}

.wl-select:disabled {
    opacity: .55;
    cursor: not-allowed;
}

/* Full width inside the confirm dialog. */
.wl-select-block {
    width: 100%;
    min-width: 0;
}

.confirm-select-label {
    display: block;
    margin-bottom: 4px;
    font-size: 12px;
    font-weight: 600;
    color: var(--wl-muted);
}



/* ---------------------------------------------------------------- contrast pass */

/*
    Fluent applies neutral foreground tokens to text inside its dialog, message bar and
    button components. On these light surfaces several of them fell below readable contrast,
    so anything carrying real information is pinned to the app's own ink colour.
*/
fluent-dialog p,
fluent-dialog h3,
fluent-dialog label,
fluent-dialog span:not([class*="pill"]) {
    color: var(--wl-ink);
}

/* The result message is the whole point of the dialog - make it unmissable. */
.popup-message {
    color: var(--wl-ink);
    font-size: 15px;
}

.popup-message-error {
    color: var(--wl-red-dark);
}

/* Hints sit under inputs and must still be legible, just quieter than the label. */
.field-hint {
    color: var(--wl-muted);
}

.field-hint strong {
    color: var(--wl-ink);
    font-weight: 700;
}

/* "Saved" confirmation next to the Persist button. */
.printer-saved {
    color: var(--wl-ok);
}

/* Message bars: Fluent's own text colour is too light on its tinted background. */
fluent-message-bar {
    color: var(--wl-ink) !important;
}

/*
    Empty-state text. Italic grey on white was the least readable thing on the page, and it
    appears whenever a vehicle genuinely has no accessories - which is information, not
    decoration.
*/
.wl-empty {
    color: var(--wl-muted);
    font-style: normal;
    font-weight: 500;
}

/* The count bubble in each card header, which now sits on the solid red bar. */
.wl-count {
    color: #fff;
    background: rgba(255, 255, 255, .22);
}

/* ---------------------------------------------------------------- fluent overrides */

/*
    Pins the Fluent components to this app's palette.

    Fluent derives its colours from design tokens that are independent of our CSS variables,
    so a component can end up with text that does not contrast with the surface we placed it
    on. Rather than fight token by token, the handful of components actually used here are
    given explicit colours.
*/

/* Accent buttons: Toyota red with white text, which is the app's primary action colour. */
fluent-button[appearance="accent"]::part(control) {
    background: var(--wl-red) !important;
    color: #ffffff !important;
    border-color: var(--wl-red) !important;
    font-weight: 600;
}

fluent-button[appearance="accent"]:hover::part(control) {
    background: var(--wl-red-dark) !important;
    border-color: var(--wl-red-dark) !important;
}

/* Neutral and stealth buttons: dark text on a light surface. */
fluent-button[appearance="neutral"]::part(control),
fluent-button[appearance="stealth"]::part(control),
fluent-button:not([appearance])::part(control) {
    color: var(--wl-ink) !important;
    background: #f2f5f9 !important;
    border-color: #d4dce7 !important;
    font-weight: 600;
}

fluent-button[appearance="stealth"]::part(control) {
    background: transparent !important;
    border-color: transparent !important;
    color: var(--wl-red) !important;
    text-decoration: underline;
}

fluent-button[appearance="neutral"]:hover::part(control),
fluent-button:not([appearance]):hover::part(control) {
    background: #e6ecf4 !important;
}

fluent-button[appearance="stealth"]:hover::part(control) {
    background: rgba(189, 48, 56, .08) !important;
}

fluent-button[disabled]::part(control) {
    opacity: .5 !important;
}

/* Input fields: dark text, clear border, red focus ring to match the accent. */
fluent-text-field::part(root),
fluent-number-field::part(root) {
    background: #ffffff !important;
    border-color: #8a97a6 !important;
}

fluent-text-field::part(control),
fluent-number-field::part(control) {
    color: var(--wl-ink) !important;
}

fluent-text-field::part(label),
fluent-number-field::part(label) {
    color: var(--wl-ink) !important;
    font-weight: 600 !important;
    font-size: 12px !important;
    text-transform: uppercase;
    letter-spacing: .03em;
}

fluent-text-field:focus-within::part(root),
fluent-number-field:focus-within::part(root) {
    border-color: var(--wl-red) !important;
    box-shadow: 0 0 0 2px rgba(189, 48, 56, .2) !important;
}

/*
    Checkbox.

    Fluent tracks the checked state with a "checked" CLASS on the host - not aria-checked -
    and fills the box from its --accent-fill-rest token. Setting that token is what actually
    colours the checked box.

    Earlier attempts failed for two reasons worth recording: they keyed off aria-checked,
    which Fluent does not style from, and they set an unconditional white background whose
    !important beat the checked rule. The result was a white tick on a white box, i.e. the
    checkbox appeared to do nothing.
*/
fluent-checkbox {
    --accent-fill-rest: var(--wl-red);
    --accent-fill-hover: var(--wl-red-dark);
    --accent-fill-active: var(--wl-red-dark);
    --neutral-fill-input-alt-rest: #ffffff;
    --neutral-fill-input-alt-hover: #f4f7fb;
}

/* Borders only. The background is left to the tokens above so the checked fill survives. */
fluent-checkbox:not(.checked)::part(control) {
    border-color: #8a97a6 !important;
}

fluent-checkbox.checked::part(control) {
    border-color: var(--wl-red) !important;
}

fluent-checkbox:not(.checked):hover::part(control) {
    border-color: var(--wl-ink) !important;
}

fluent-checkbox:focus-visible::part(control) {
    outline: 2px solid var(--wl-red);
    outline-offset: 2px;
}


/* Dialog surface. */
fluent-dialog::part(control) {
    background: var(--wl-surface) !important;
    color: var(--wl-ink) !important;
    border-radius: var(--wl-radius) !important;
    box-shadow: var(--wl-shadow-lg) !important;
}

/* Progress rings pick up the accent rather than a default blue. */
fluent-progress-ring::part(indeterminate-indicator-1),
fluent-progress-ring::part(determinate-indicator) {
    stroke: var(--wl-red) !important;
}

/* ---------------------------------------------------------------- footer */

.wl-footer {
    margin-top: 28px;
    padding-top: 16px;
    border-top: 1px solid var(--wl-line);
    text-align: center;
}

.wl-footer p {
    margin: 0;
    color: var(--wl-muted);
    font-size: 12px;
}
