@charset "UTF-8";

    html[data-theme="dark"] { color-scheme: dark; }
    html.calm-pending body { opacity: 0; animation: cbpCalmShow 0s linear 1.5s forwards; }
    @keyframes cbpCalmShow { to { opacity: 1; } }

    /* ================================================================
       BRAND CHROME — one surface colour, one texture, one light, defined once
       for the admin, dealer/public and guest layouts. This file is the only one
       all three include, so it is the only place these can be said once.

       Consumers paint --cbp-chrome FIRST and the texture LAST, so a missing
       image leaves every surface a flat solid colour rather than a white hole.

       --cbp-navy is deliberately NOT reused. It is overloaded — it is also a
       TEXT colour (brand-foundation, cars/index) — and it means two different
       things in the two dark themes. This token means exactly one thing: a
       chrome surface that gets painted.
       ================================================================ */
    :root {
        --cbp-chrome:      #0e2c4f;
        --cbp-chrome-2:    #0b2440;   /* the scrolled / deeper step */
        /* The same colours as an RGB triplet, so a page that builds its own
           gradient can stay on the palette with rgba(var(--cbp-chrome-rgb), a). */
        --cbp-chrome-rgb:  14,44,79;
        --cbp-chrome-lo:   10,36,68;
        --cbp-chrome-hi:   22,58,106;

        /* The wash over the texture. It was .74 -> .84, which left the contour
           lines barely visible. The texture's MEAN is darker than the brand navy,
           so lifting the wash makes the surface marginally DEEPER (L .0224 ->
           .0198) while raising the contours by about a third. Every text ratio on
           the bar goes up, not down. */
        --cbp-chrome-wash:   linear-gradient(180deg, rgba(14,44,79,.52), rgba(14,44,79,.66));
        --cbp-chrome-wash-2: linear-gradient(180deg, rgba(11,36,64,.66), rgba(11,36,64,.78));
        --cbp-footer-wash:   linear-gradient(120deg, rgba(10,36,68,.58) 0%, rgba(14,44,79,.54) 55%, rgba(22,58,106,.58) 120%);
        --cbp-panel-wash:    linear-gradient(120deg, rgba(8,33,61,.62) 0%, rgba(14,44,79,.58) 52%, rgba(29,63,114,.62) 120%);

        --cbp-chrome-topo: url('/assets/images/brand/topo-texture.webp');
        /* TWO SIZES, and the difference matters. The texture is one image, 1920x520,
           and `cover` fits it to the BOX rather than holding it at a size — so the same
           asset becomes a different material depending on the shape it lands in.

             a full-bleed bar   -> about native scale, fine contour lines. Right.
             a 248x1080 rail    -> blown up 2.1x to reach the height. Big soft blobs.
             a 360x60 header    -> shrunk to 0.19x. Invisible; the panel looks flat.

           So: FULL-WIDTH surfaces keep `cover`, because they are close to the image's
           own proportions and because the image does NOT tile cleanly sideways — there
           is a visible seam if you repeat it across a wide monitor. Everything BOUNDED
           pins the width instead, which holds the contours at one size and, for a panel
           narrower than the image, never has to repeat at all.
           Both checked by rendering the options at real sizes and looking at them. */
        --cbp-chrome-size:       auto, cover;
        --cbp-chrome-size-fixed: auto, 1920px auto;
        --cbp-chrome-edge: rgba(255,255,255,.07);
        /* One entry per background layer: the wash, then the texture. Daylight leaves
           both alone -- the texture is navy and so is the surface, which is the point. */
        --cbp-chrome-blend: normal, normal;
        /* The texture is anchored to the VIEWPORT rather than to each element, which is
           what makes the pattern continue across the seam where the top bar meets the
           side rail. They are two elements showing the same wall through two windows,
           instead of two elements each starting the pattern again at their own corner. */
        --cbp-chrome-attach: scroll, fixed;
        --cbp-chrome-size-chrome: auto, 1920px auto;
        /* The site's muted label colour. #8295ad measured 3.06:1 on white and #7a8aa0
           3.52:1 -- both under AA, in DAYLIGHT, on about eighty labels: "Office address",
           "Log in to manage your cars", every KPI caption, every table sub-heading.
           Neither was a dark-mode problem; both already had night overrides. #607086 is
           5.05:1 on white and keeps the same blue-grey character, just deeper.
           It is a token so the night value comes with it, and so any existing
           html[data-theme="dark"] rule still outranks it. */
        --cbp-muted-ink: #5c6b80;
        /* The red that CARRIES WHITE TEXT, which is a different job from the red that
           is a dot, a border or a word. White on #e2304e measures 4.41:1 -- under AA, on
           the most-pressed button on the site, in daylight. (Night already had its own
           darker value for exactly this reason; daylight never got one.)

           It cannot simply go darker, because the same button also has to keep a visible
           EDGE against the chrome it sits on, and that rule wants 3:1 the other way. The
           squeeze is real: at #d92846 white reads a comfortable 4.84 but the edge falls
           to 2.91 and fails. #e02b4a is the value that clears BOTH -- white 4.55, edge
           3.09 on navy and 3.32 on the night grey -- and it is two units of red away
           from where it was, which nobody will see.

           Red used as TEXT, as a dot or as a border is untouched: those have their own
           rules and they already pass. */
        --cbp-red-fill: #e02b4a;

        /* And its blue counterpart: the fill of a PRIMARY action -- Log in, Search, Save.
           Same idea, opposite problem. The red already had a night value everywhere; the
           blue had one in three places and nowhere else, so a control coloured for a
           WHITE page was still wearing that colour on a grey one. On white, #2f5496 is a
           solid confident button. On a #292929 card the luminance barely differs from
           the card at all -- 1.96 to 1 -- so nothing separates them except HUE, and a
           saturated indigo bar is the only coloured object left on an otherwise neutral
           page. That is the "blue bar on a grey background" and it is a real fault, not
           a preference.
           Night drops the saturation from 0.52 to 0.17. It reads as slate rather than as
           blue, which is what the page around it now is, and it still says "this is the
           button" -- a fully grey primary action stops looking like the main thing to
           press. White on it reads 7.04 against 7.42 before: a hair down, both far above
           AA, and the button/card edge goes the other way, 1.96 to 2.07.
           The GLOW moves too: a navy-tinted drop shadow under a button on a graphite page
           is a blue smudge, not depth. */
        --cbp-blue-fill: #2f5496;
        --cbp-blue-fill-hi: #24406f;   /* its hover */
        --cbp-blue-fill-glow: 0 10px 24px -10px rgba(47,84,150,.9);
        /* A transparent shadow, NOT `none`. These two tokens are composed into one
           box-shadow list, and `none` is only legal as the SOLE value of box-shadow --
           `box-shadow: none, 0 10px ...` is invalid, so the browser throws the whole
           declaration away and the daylight button loses its shadow entirely. Caught by
           reading the computed style rather than by looking at it. */
        --cbp-blue-fill-ring: 0 0 0 0 rgba(0,0,0,0);

        /* The light. Peak alpha is a hard ceiling, not a starting point: at .10 a
           lit chrome surface reads L=.0351 and white on it is still 11.8:1. The
           phone app's own login shader blooms its high ground at 0.11 of the same
           blue, so this is the app's number, not a new one. */
        --cbp-aurora-peak: .10;
        --cbp-aurora-1: 91,187,232;    /* --cbp-sky  */
        --cbp-aurora-2: 47,147,207;    /* --cbp-blue */
        --cbp-aurora-mask: none;

        /* ---- The coloured lights ----
           These are the coral and sky blooms sitting in the corner of a hero, a page
           head or a panel. Six of them, each typed by hand, each tuned against NAVY,
           and none of them moving.

           Two things were wrong with that. On grey at night the same alpha reads far
           stronger — a saturated red on a colourless ground has nothing to sink into,
           so a warm bloom becomes a pink stain. And a hard, still blob sitting next to
           a slowly breathing blue light reads as a mark on the page rather than as
           light falling on it.

           One token each, two values, a softer falloff at night so there is no visible
           edge to the bloom, and a drift slow enough that you notice the room has
           changed rather than the animation. */
        --cbp-glow-red:   rgba(226,48,78,.26);
        /* The hero's pair, and they are a PAIR: one warm light low on the right, one
           cool light low on the left, meant to answer each other. They never did. Both
           were on the same layer as the hero's dark veil, and the browser paints in
           document order, so the BLUE ended up under the veil and the RED over it --
           about seven parts of red reaching the eye for every one part of blue. That is
           the single biggest reason the light looked like a stain coming from one side.
           The layering is fixed where the hero is drawn; these two come down and MATCH,
           because the blue is about to be present for the first time. */
        --cbp-glow-red-2: rgba(232,51,78,.20);   /* the hero: the largest of them */
        --cbp-glow-blue:  rgba(91,187,232,.18);
        --cbp-glow-sky:   rgba(91,187,232,.18);  /* matched to the red, now that both land */
        --cbp-glow-fade:  66%;
    }

    /* ---- Night ----
       The chrome goes GREY, everywhere, in one place. The page ground was already
       #1c1c1c while the bar, the footer, the dealer rail and every navy panel
       stayed full brand navy, so turning dark mode on left large blue slabs
       pasted onto a black page — it never "turned grey".

       This costs no contrast. #262626 and #0e2c4f are luminance twins (0.0194 vs
       0.0246), so everything sitting ON the chrome keeps its ratio, and the two
       biggest buttons a dealer presses actually improve: the Copart blue goes
       2.85 -> 3.06 and the IAAI red 2.82 -> 3.06, crossing the 3:1 boundary rule
       for the first time. White on the bar goes 14.4 -> 15.1.

       What grey DOES cost is separation: chrome and page are now both grey, and
       no fill can separate them by more than about 1.2:1. So the edge does that
       job instead, and it is brighter at night for exactly that reason. The
       texture stays and the light stays, which is what keeps the chrome from
       reading as a dead flat slab. */
    html[data-theme="dark"] {
        --cbp-chrome:      #262626;
        --cbp-chrome-2:    #1f1f1f;
        --cbp-chrome-rgb:  38,38,38;
        --cbp-chrome-lo:   30,30,30;
        --cbp-chrome-hi:   52,52,52;
        /* Heavier than the light-mode wash on purpose: the texture asset is
           navy-toned, and at a lighter wash its contours would tint the grey bar
           blue. At .72 they read as cool detail on grey rather than as navy. */
        --cbp-chrome-wash:   linear-gradient(180deg, rgba(38,38,38,.72), rgba(38,38,38,.84));
        --cbp-chrome-wash-2: linear-gradient(180deg, rgba(31,31,31,.80), rgba(31,31,31,.90));
        --cbp-footer-wash:   linear-gradient(120deg, rgba(30,30,30,.78) 0%, rgba(38,38,38,.74) 55%, rgba(52,52,52,.78) 120%);
        --cbp-panel-wash:    linear-gradient(120deg, rgba(30,30,30,.80) 0%, rgba(38,38,38,.76) 52%, rgba(52,52,52,.80) 120%);
        --cbp-chrome-edge: rgba(255,255,255,.13);
        /* `luminosity` on the texture layer: keep the image's light and shade, take the
           hue from the grey underneath. That is what turns navy contours into grey ones
           without touching the wash, the colour, or anything in daylight. */
        --cbp-chrome-blend: normal, luminosity;
        --cbp-muted-ink: #9b9b9b;
        --cbp-blue-fill: #4c5a6b;
        --cbp-blue-fill-hi: #5b6b80;
        --cbp-blue-fill-glow: 0 10px 24px -12px rgba(0,0,0,.65);
        /* The fill and the card it sits on are 2.07 apart -- under the 3 to 1 a control's
           edge needs, and that was true before this change too. A 1px inset ring gives the
           edge back without changing the button's size the way a border would. */
        --cbp-blue-fill-ring: inset 0 0 0 1px rgba(255,255,255,.22);
        /* Blue on grey reads more strongly than blue on navy, so the light is
           pulled back a little — but not switched off. It is the only colour left
           in the chrome at night and it is what the owner asked to see moving. */
        --cbp-aurora-peak: .09;
        /* Roughly half. Measured by eye against the grey: at the daylight alpha the
           hero's corner bloom read as magenta smeared across the page, which is the
           single loudest thing left in dark mode. The falloff also widens, so what is
           left has no edge to it. */
        --cbp-glow-red:   rgba(226,48,78,.15);
        /* Night keeps the pullback that was already here and adds the same balancing.
           On grey there is no blue in the ground for a warm light to sink into, so the
           two have to be near-equal or the hero simply reads pink. */
        --cbp-glow-red-2: rgba(232,51,78,.14);
        --cbp-glow-blue:  rgba(91,187,232,.13);
        --cbp-glow-sky:   rgba(91,187,232,.13);
        --cbp-glow-fade:  76%;
    }

    /* ---- The light itself ----
       Only opacity / translate / scale animate, so this never leaves the
       compositor: no layout, no repaint, no main-thread work per frame. translate
       and scale are used as INDEPENDENT properties rather than transform, so the
       three animations can run at once without overwriting each other; where they
       are unsupported those keyframe sets are simply dropped and the breath still
       runs. Three co-prime periods (17 / 23 / 31s) mean the pattern does not
       repeat for 12,121 seconds, so it never reads as a loop. */
    .cbp-chrome-lit::before {
        content: ''; position: absolute; inset: 0; z-index: 0;
        pointer-events: none; border-radius: inherit;
        opacity: calc(var(--cbp-aurora-peak) * .7);
        background-image:
            radial-gradient(58% 190% at 12% 118%, rgba(var(--cbp-aurora-1), 1),   rgba(var(--cbp-aurora-1), 0) 60%),
            radial-gradient(44% 165% at 46% -34%, rgba(var(--cbp-aurora-2), .82), rgba(var(--cbp-aurora-2), 0) 58%),
            radial-gradient(52% 200% at 79% 128%, rgba(var(--cbp-aurora-1), .62), rgba(var(--cbp-aurora-1), 0) 62%);
        -webkit-mask-image: var(--cbp-aurora-mask);
                mask-image: var(--cbp-aurora-mask);
        animation:
            cbpAuroraBreathe 17s ease-in-out infinite alternate,
            cbpAuroraDrift   23s ease-in-out infinite alternate,
            cbpAuroraSwell   31s ease-in-out infinite alternate;
    }
    /* The bars are full-bleed and CANNOT take overflow:hidden — it would clip the
       signed-in user dropdown, which hangs below the bar. So they drift sideways
       only, where the overflow goes off-screen, and they do not swell. */
    .cbp-chrome-lit--bar::before {
        animation:
            cbpAuroraBreathe 17s ease-in-out infinite alternate,
            cbpAuroraDriftX  23s ease-in-out infinite alternate;
    }
    @keyframes cbpAuroraBreathe { from { opacity: calc(var(--cbp-aurora-peak) * .34); }
                                  to   { opacity: var(--cbp-aurora-peak); } }
    /* The light's SHAPE is a percentage of whatever surface it lands on, but its TRAVEL
       was a flat 26 pixels. On the 1920px top bar that is two percent of the light's own
       width -- nothing appears to move. On the 330px calculator answer panel it is
       twelve percent: a blob visibly sliding back and forth beside a five-figure number.
       It was backwards, loudest where there is least room. A percentage in `translate`
       measures the element's own box, so one number now means the same amount of
       movement everywhere. Only the sideways travel changes; the vertical stays in
       pixels so the dealer rail, the one tall surface, keeps its character. */
    @keyframes cbpAuroraDrift   { from { translate: 0 0; }  to { translate: -1.4% 7px; } }
    @keyframes cbpAuroraDriftX  { from { translate: 0; }    to { translate: -1.4%; } }
    @keyframes cbpAuroraSwell   { from { scale: 1; }        to { scale: 1.09; } }
    /* The corner blooms drift too, on their own period so they never march in step with
       the chrome's light. Slower and shorter than the aurora: this is a light source
       shifting, not something sliding across the page. */
    @keyframes cbpGlowDrift { from { translate: 0 0; scale: 1; } to { translate: -18px 12px; scale: 1.06; } }

    /* Degrade, do not disable. The light stays, at the value it would average to;
       only the movement goes. Nothing changes size, position or contrast. */
    @media (prefers-reduced-motion: reduce) {
        .cbp-chrome-lit::before, .cbp-chrome-lit--bar::before {
            animation: none; opacity: calc(var(--cbp-aurora-peak) * .7); }
        .cbp-glow { animation: none !important; }
    }
    /* Phones drop the viewport-anchored texture. iOS has never handled
       background-attachment: fixed well -- it jitters or drops the image outright -- and
       there is nothing to gain here anyway: the side rail is hidden at this width, so
       there is no seam for the bar to line up with. */
    @media (max-width: 991px) {
        :root, html[data-theme="dark"] { --cbp-chrome-attach: scroll, scroll; }
    }
    /* Phones: keep the light, halve the compositor work, and remove the one case
       where a drifting layer's leading edge could reach a rounded corner. */
    @media (max-width: 991px) {
        .cbp-chrome-lit::before, .cbp-chrome-lit--bar::before {
            animation: cbpAuroraBreathe 17s ease-in-out infinite alternate; }
    }

    /* Theme toggle control: moon shows in light ("go dark"), sun shows in dark. */
    .cbp-theme-toggle { cursor: pointer; }
    .cbp-theme-toggle svg { width: 18px; height: 18px; display: block; }
    .cbp-theme-toggle .cbp-tt-sun { display: none; }
    .cbp-theme-toggle .cbp-tt-moon { display: block; }
    html[data-theme="dark"] .cbp-theme-toggle .cbp-tt-sun { display: block; }
    html[data-theme="dark"] .cbp-theme-toggle .cbp-tt-moon { display: none; }

    /* Admin navbar variant (navy top bar) */
    .main-header .cbp-theme-toggle {
        display: inline-flex; align-items: center; justify-content: center;
        width: 38px; height: 38px; border: 0; border-radius: 10px; padding: 0;
        color: #cfe0f2; background: rgba(255,255,255,.06);
        transition: background .15s ease, color .15s ease;
    }
    .main-header .cbp-theme-toggle:hover { background: rgba(91,187,232,.22); color: #fff; }

    /* Dealer/public navbar variant (mirrors .cbp-bell) */
    .cbp-nav .cbp-theme-toggle {
        display: inline-flex; align-items: center; justify-content: center;
        width: 42px; height: 42px; border-radius: 50%; padding: 0;
        border: 1px solid rgba(255,255,255,.16); background: rgba(255,255,255,.07); color: #eaf2fc;
        transition: background .18s ease, border-color .18s ease, transform .18s ease;
    }
    .cbp-nav .cbp-theme-toggle:hover { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.3); transform: translateY(-1px); }
    @media (max-width: 991px) {
        .cbp-nav .cbp-theme-toggle { width: 100%; border-radius: 11px; min-height: 46px; }
    }

    /* Guest (auth pages) floating variant */
    .cbp-theme-toggle--float {
        position: fixed; top: 16px; right: 16px; z-index: 50;
        display: inline-flex; align-items: center; justify-content: center;
        width: 40px; height: 40px; border-radius: 50%;
        border: 1px solid #e3e8ef; background: #fff; color: #46586f;
    }
    /* The auth pages are a coherent graphite --g-* palette at night; this button was
       the one navy survivor on an otherwise fully neutral page. #bababa on #292929
       is 6.9:1, well clear of AA. */
    html[data-theme="dark"] .cbp-theme-toggle--float {
        background: var(--g-card, #292929); border-color: var(--g-line, #434343); color: var(--g-body, #bababa); }
