﻿/* ---------------------------------------------------------
   CBS Tenant Design System
   --------------------------------------------------------- */

/* CBSInvoices: toolbar height (36px buttons + 16px/16px padding + 1px divider) */
body.cbs-invoices .right-rail {
    --rr-toolbar-h: 69px;
    --rr-actions-height: 65px;
}

/* =================================================================================================
   TL-166 SUPERSEDED AND REMOVED 2026-09-30 - the rule that was here is gone, and this note records
   why so it is not put back.

   IT CAPPED THE CENTRE TRACK at --content-max-width for this page and let the last gutter take the
   slack, which closed the gap between the grid and the rail. It worked, and it was the wrong shape
   for two reasons:
     - IT WAS SCOPED TO A TENANT. body.cbs-invoices does not describe the problem. Edit Users, Delete
       Users, Store Info, Commission Plans and Store Groups are all grid pages with rails and none of
       them is a CBS page, so a CBS-scoped fix left every one of them detached.
     - IT KEPT THE CAP. Closing the gap by moving the empty space to the outside still left the grid
       stopping at 1600 while columns truncated.

   THE ANSWER IS IN layout.css NOW, keyed on grid-wide: a grid page has no maximum content width, so
   the content's right edge IS the track's right edge, which is where the rail begins. The gap cannot
   open because there is nothing left to be short of. See the block at body.grid-wide .main-content.

   THE 1968px DERIVATION IS STILL THE USEFUL PART OF THIS ROW and is kept here because it explains
   the threshold anyone will observe: 16px gutter + 56px collapsed nav + 1600px cap + 280px rail +
   16px gutter = 1968. Below that the track is narrower than the cap so the content fills it and the
   rail sits against the grid; above it the cap bound and the gap opened at half the rate the window
   widened. With the cap gone the arithmetic no longer has a threshold in it.
   ================================================================================================= */

/* The removed rule, for reference - DO NOT REINSTATE, see above:
   body.cbs-invoices .layout-body { grid-template-columns: ... minmax(0, var(--content-max-width)) ... }

   =================================================================================================
   ORIGINAL TL-166 ANALYSIS, kept because the reasoning about WHY the fix could not be applied to the
   rail itself is still true and would otherwise be rediscovered:

   THE THRESHOLD IS DERIVED, NOT OBSERVED. layout.css gives .layout-body:
       grid-template-columns: var(--shell-gutter) var(--layout-leftnav-col)
                              minmax(0, 1fr) var(--layout-rail-col) var(--shell-gutter);
   The CENTRE track is minmax(0, 1fr) - uncapped since TL-71 made the chrome full width - while the
   CONTENT inside it caps at max-width: var(--content-max-width) and is centred with margin-inline:
   auto. With theme.css's --shell-gutter: 16px, --leftnav-collapsed-width: 56px, --rail-width: 280px
   and --content-max-width-grid-wide: 1600px:

       16 + 56 + 1600 + 280 + 16 = 1968px

   Below that the centre track is narrower than 1600 and the grid fills it, so the rail sits against
   the grid. Above it the track keeps growing, the grid stays 1600 and centred, and the rail stays at
   the track's right edge - so a gap opens between them and widens at half the rate the window does.
   The developer reported "roughly 1968"; it is exactly 1968.

   THE FIX IS TO THE TRACK, NOT TO THE RAIL, and that is the part worth explaining. The rail lives in
   grid column 4 at exactly --rail-width, so there is no room inside its own track to shift it left:
   margin cannot move it and the track cannot absorb it.
     - A transform WOULD move it and is the wrong tool here: .right-rail-header is position: sticky,
       and a transform on its ancestor becomes that sticky element's containing block. That is the
       TL-113 trap, and it would trade a gap for a broken sticky header.
     - Right-aligning the grid inside the track would close the gap too, by pushing the content away
       from the left nav instead. That moves the problem rather than solving it.
   So the centre track is CAPPED at the content width and the LAST GUTTER takes the slack. The grid
   then ends where the rail begins, at every width, and the pair stays together.

   THE LEFT SIDE IS DELIBERATELY UNTOUCHED. TL-71 records what happens when the left gutter is made
   flexible: it grew to absorb slack while the appbar's stayed fixed, so the left nav started 84px to
   the right of the logo. Only the RIGHT gutter here is flexible, so the left edge still lines up with
   the chrome and TL-71 holds.

   IT WAS SCOPED TO body.cbs-invoices, and that scoping is exactly what made it the wrong answer -
   every other grid page with a rail was left detached.
   ================================================================================================= */

/* ---------------------------------------------------------
   CBS Card Component (refined layout)
   --------------------------------------------------------- */

#pnlCBS {
    padding-bottom: 24px;
}

/* Keep CBS panel sizing tenant-specific (authenticated CBS path) */
body.page-narrow.is-auth .page-centered #pnlCBS {
    width: 100%;
    max-width: var(--single-focus-card-width);
}

/* CBS card surface + internal rhythm */
.cbs-card {
    background: var(--cbs-bg-tint);
    border-radius: var(--cbs-radius);
    padding: var(--cbs-padding);
    box-shadow: var(--cbs-shadow);
    border-top: 4px solid var(--cbs-accent);
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* Logo */
.cbs-logo img {
    height: 40px;
    width: auto;
    display: block;
    opacity: 0.9;
    margin: 0;
}

/* Dark mode: the logo is an <img> (so page custom properties cannot reach inside the SVG), and the brand green and the charcoal wordmark
   sink into a dark card. CBSLogo_Dark.svg is the same artwork with the colours baked in (wordmark white, green #2fa14d); this one switch,
   html[data-theme="dark"] (written by Site.master and theme-init.js), swaps the picture and keeps the element, its alt text and the link.
   Relative to this file, like the MG logo rule in layout.css. Covers the header band (.cbs-topband-left) and the Tech Support card (.cbs-logo).
   Emails and the PNG stay light. See docs/current/queue/cbs-logo-dark_handoff.md. */
html[data-theme="dark"] .cbs-topband-left .cbs-logo-row img,
html[data-theme="dark"] .cbs-logo img {
    content: url("../../../Images/CBS/CBSLogo_Dark.svg");
}
/* Headings */
.cbs-heading {
    color: var(--cbs-accent);
    font-weight: 700;
    margin: 0;
}

.cbs-sub {
    color: var(--muted);
    font-size: 0.9rem;
    margin: 0;
}

/* Divider */
.cbs-card hr {
    border-color: rgba(39, 174, 96, 0.15);
    margin: 6px 0;
}

/* Info rows (Support hours / Phone / Email / Website) */
.cbs-card p {
    margin: 0;
    line-height: 1.35;
    font-size: 0.95rem;
    color: var(--ink);
}

    /* Turn "Label:<br>Value" into "Label: Value" */
    .cbs-card p br {
        display: none;
    }

    /* Make labels align; values line up visually */
    .cbs-card p strong {
        display: inline-block;
        min-width: 120px;
        font-weight: 700;
        color: var(--ink);
    }

/* Links */
.cbs-card a {
    color: var(--cbs-accent);
    font-weight: 600;
    text-decoration: none;
}

    .cbs-card a:hover {
        color: var(--brand-ink);
    }

/* ---------------------------------------------------------
   TechSupport.aspx — Local refinements (kept)
   --------------------------------------------------------- */

/* Improve spacing inside the dropdown card */
#ddlProblem.input {
    margin-top: 6px;
}

/* Improve label spacing for consistency in auth-card forms */
.auth-card .form-row label {
    display: block;
    margin-bottom: 6px;
}

/* =========================================================
   CBS — AutoPay Component (GLOBAL)
   Moved from components.css (CBS-only concept)
   Notes:
   - Avoids global .status-on collision by scoping to .autopay-indicator.status-on
   - Keeps link styling for pages that still render links in AutoPay detail
   ========================================================= */

.autopay-card {
    background: var(--surface);
    border-radius: 14px;
    box-shadow: var(--shadow-2);
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    margin: 0;
}

.autopay-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 8px;
}

.autopay-title-text {
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--ink);
}

.autopay-detail {
    font-size: .95rem;
    color: var(--ink);
    line-height: 1.3;
}

    .autopay-detail a {
        color: var(--accent);
        text-decoration: none;
        font-weight: 600;
    }

        .autopay-detail a:visited {
            color: var(--brand-ink);
        }

        .autopay-detail a:hover {
            color: var(--brand-ink);
        }

.autopay-indicator {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--muted);
    box-shadow: var(--shadow-2);
    transform: translateY(-1px);
}

    /* IMPORTANT: scoped (no global .status-on) */
    .autopay-indicator.status-on {
        background: var(--success);
        box-shadow: var(--shadow-3);
    }

    /* CBS-62: AutoPay is on, but the last run failed or the next run date has passed.
       Amber, not red - nothing is broken and no money is missing; something needs a look.
       Deliberately NOT pulsing: the pulse below means "running normally", and a failed
       schedule that pulses reads as healthy from across a room. */
    .autopay-indicator.status-warn {
        background: var(--warning);
        box-shadow: var(--shadow-3);
    }


/* =========================================================
   CBSInvoices — Top Band (40/60   Goals:   CBSInvoices — Top Band (40/60) Standard (CLEAN)
   - Keep current layout (company left, chips stacked right)
   - Chips same width and compact
   - No redundant overrides / no conflicting legacy rules
   - Includes prefers-reduced-motion-friendly AutoPay pulse
   ========================================================= */

/* Top band outer shell */
.cbs-topband.card {
    padding: 0;
    margin-bottom: 16px !important;
    overflow: hidden;
    flex: 0 0 auto;
    /* Ensure header band behaves like a normal centered card when page-body is a flex rail */
    width: 100%;
    max-width: var(--single-focus-card-width);
    align-self: center; /* explicit: avoid any shrink-to-fit surprises */
    /* CBS-35 2026-09-20: the band is its own container, so everything below compresses on the
       BAND's width rather than the viewport's. Those are not the same number and never were -
       the band's width is set by the content cap, the left-nav state and the rail strip, so at
       one viewport it can be 1200 wide with the nav collapsed and 1016 with it open. */
    container-type: inline-size;
    container-name: cbsband;
}

/* 40/60 layout. minmax(0, ...) on both lanes because the default min-width: auto let the left
   lane's min-content win: measured, below a band width of about 940 it stopped shrinking and
   held a 376px floor, so every pixel lost came out of the cards' lane. */
.cbs-topband-grid {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    align-items: stretch;
}

.cbs-topband--compact .cbs-topband-grid {
    grid-template-columns: 1fr;
}

/* CBS-04 2026-09-18: the mirror of --compact. Every card in the right lane
   (account, payment method, AutoPay) is CBSFleetManager-only, so for CBS staff
   and franchisees the band was rendering a 60%-wide empty white half. */
.cbs-topband--brand-only .cbs-topband-grid {
    grid-template-columns: 1fr;
}

.cbs-topband--brand-only .cbs-topband-right {
    display: none;
}

/* LEFT: CBS brand/contact */
.cbs-topband-left {
    padding: var(--tb-pad-y) var(--tb-pad-x);
    background: var(--cbs-bg-tint);
    display: flex;
    flex-direction: column;
    gap: var(--tb-gap);
    font-size: 0.80rem;
    color: var(--muted);
    line-height: 1.18;
}

.cbs-topband--compact .cbs-topband-left {
    display: none;
}

.cbs-topband-left img {
    max-height: 54px;
    width: auto;
    display: block;
    opacity: 0.96;
}

.cbs-topband-left a {
    color: var(--cbs-accent);
    font-weight: 600;
    text-decoration: none;
}

    .cbs-topband-left a:hover {
        color: var(--brand-ink);
    }

.cbs-topband-left .cbs-contact {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

.cbs-topband-left strong {
    font-weight: 700;
    color: color-mix(in srgb, var(--ink) 40%, var(--muted));
}

/* Contact row: phone fixed, email truncates */
.cbs-contact-row {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: nowrap;
    min-width: 0;
    max-width: 100%;
}

    .cbs-contact-row a {
        color: var(--cbs-accent);
        font-weight: 600;
        text-decoration: none;
        white-space: nowrap;
    }

        .cbs-contact-row a:hover {
            color: var(--brand-ink);
        }

        .cbs-contact-row a[href^="tel:"] {
            flex: 0 0 auto;
        }

        .cbs-contact-row a[href^="mailto:"] {
            flex: 1 1 auto;
            min-width: 0;
            overflow: hidden;
            text-overflow: ellipsis;
            display: block;
        }

.cbs-contact-sep {
    flex: 0 0 auto;
    white-space: nowrap;
    color: var(--muted);
    opacity: 0.8;
    line-height: 1;
}

.cbs-hours {
    margin-top: 4px;
    color: var(--muted);
    font-size: 0.82rem;
    line-height: 1.15;
}

/* =========================================================
   CBS Top Band — Right side (Company + Tiles)
   Goal:
   - Row 1: Company name full width
   - Row 2: 3 equal tiles with aligned internal rows:
       Title row
       Text row (reserved even if empty)
       Action row (aligned across tiles)
   Notes:
   - This block is designed to REPLACE the existing .cbs-topband-right / .cbs-topband-right-grid /
     .cbs-company-* / tile-detail rules in cbs.css.
   ========================================================= */

/* RIGHT container (no layout responsibility; inner grid owns layout) */
.cbs-topband-right {
    padding: var(--tb-pad-y) var(--tb-pad-x);
    background: var(--surface);
    border-left: 1px solid color-mix(in srgb, var(--border) 75%, var(--cbs-accent));
    /* chip size knobs */
    --topband-chip-w: 164px;
    --topband-chip-h: 81px;
}

/* UpdatePanel wrapper: remove layout interference */
.upTopBandRight {
    display: contents;
}

/* Inner row: the company name, then the cards.
   CBS-35 2026-09-20: a WRAPPING FLEX ROW, not three fixed columns. It used to be
   "var(--topband-chip-w) x3" with a media query at 1200 switching to a single column, which is
   what put three cards in three rows and made the band 330px tall - two and a quarter times
   its normal height - at 1200, 1140 and 1024 alike. Nothing decides the number of rows now:
   three cards fit or they do not, then two, and one only under about 290px of lane. */
.cbs-topband-right-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 12px;
    align-items: flex-start;
}

/* Row 1: company name. flex: 1 0 100% keeps it on a line of its own. */
.cbs-company-name {
    flex: 1 0 100%;
    font-size: 1.3rem;
    font-weight: 900;
    line-height: 1.12;
    min-width: 0;
    word-break: break-word;
}

/* -----------------------------
   TILE SURFACE (shared)
   ----------------------------- */
.cbs-company-meta,
.cbs-topband-right .paymentmethod-card,
.cbs-topband-right .autopay-card {
    width: var(--topband-chip-w);
    height: var(--topband-chip-h);
    max-width: none;
    padding: 8px 10px; /* align title indent across tiles */
    border-radius: var(--radius);
    box-shadow: none;
    border: 1px solid var(--border);
    background: var(--surface-subtle);
    box-sizing: border-box;
}

    .cbs-topband-right .paymentmethod-card:hover,
    .cbs-topband-right .autopay-card:hover {
        box-shadow: 0 2px 6px rgba(var(--shadow-rgb-neutral), 0.12);
        transition: box-shadow 0.15s ease;
    }

/* -----------------------------
   TILE PLACEMENT
   CBS-35: flex items now, not grid areas. At full width they keep their 164px and do not grow,
   so the wide layout is exactly what it was; below the compression threshold they are allowed
   to flex (see the container query at the foot of this section).
   ----------------------------- */
.cbs-company-meta,
.cbs-paymentmethod-wrap,
.cbs-autopay-wrap {
    flex: 0 0 auto;
}

/* -----------------------------
   TITLE ROW (shared cadence)
   ----------------------------- */
.cbs-company-meta-title-row,
.cbs-topband-right .paymentmethod-title-row,
.cbs-topband-right .autopay-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 2px;
}

.cbs-company-meta-title-text,
.cbs-topband-right .paymentmethod-title-text,
.cbs-topband-right .autopay-title-text {
    font-size: 0.92rem;
    font-weight: 800;
    color: var(--ink);
    white-space: nowrap;
}

/* Top band indicator size */
.cbs-topband-right .autopay-indicator {
    width: 10px;
    height: 10px;
}

/* -----------------------------
   DETAIL AREA: 2 rows
   Row 1 = Text (reserved height)
   Row 2 = Action (CTA/value) bottom-aligned
   ----------------------------- */
.cbs-company-meta-detail,
.cbs-topband-right .paymentmethod-detail,
.cbs-topband-right .autopay-detail {
    display: flex;
    flex-direction: column;
    gap: 8px;
    font-size: 0.82rem;
    line-height: 1.15;
    min-height: 0;
}

/* Row 1 (Text) — reserve one line even when empty so CTAs align */
.cbs-company-meta-text,
.cbs-topband-right .paymentmethod-text,
.cbs-topband-right .autopay-text {
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--muted);
    min-height: 1.15em;
}

/* Row 2 (Action) — push to bottom of the tile */
.cbs-company-meta-value,
.cbs-topband-right .paymentmethod-cta,
.cbs-topband-right .autopay-cta {
    margin-top: auto;
    display: flex;
    align-items: center;
    height: 32px; /* match btn-sm height */
}



/* Meta value: align visually with btn-sm height (32px) */
.cbs-company-meta-value {
    display: flex;
    align-items: center;
    height: 32px;
    font-size: 0.92rem;
    font-weight: 900;
    font-variant-numeric: tabular-nums;
    color: var(--ink);
    white-space: nowrap;
    transform: translateY(-1px); /* nudge up to match button visual baseline */
}

/* CTA rows: left-aligned */
.cbs-topband-right .paymentmethod-cta,
.cbs-topband-right .autopay-cta {
    display: flex;
    justify-content: flex-start;
}

    .cbs-topband-right .paymentmethod-cta .btn,
    .cbs-topband-right .autopay-cta .btn {
        flex: 0 0 auto;
        width: fit-content;
    }

/* =========================================================
   CBS-35 2026-09-20 — THE BAND COMPRESSES ON ITS OWN WIDTH
   ---------------------------------------------------------
   REPLACES "@media (max-width: 1200px)", which stacked the three cards one per row and made
   the band 330px tall - 2.2x its normal height - at 1200, 1140 and 1024 alike, while the brand
   block kept its full-size logo, its contact details and 40% of the width throughout.

   Two things were wrong with it and both are fixed here:

   THE AXIS. It keyed on the VIEWPORT while the constraint is the BAND's width, and those are
   different numbers: at one viewport the band is 1200 wide with the left nav collapsed and
   1016 with it open, and the rail strip moves it again. On this page the 1200 breakpoint
   happened to land close to where three cards genuinely stop fitting (a band of about 940), so
   it was a latent mismatch rather than a visible one - but it was going to become visible the
   first time the nav state or the content cap changed. .cbs-topband is now a container and
   everything below asks it how wide IT is.

   THE ORDER. It compressed the cards and never the brand block, so the lane that had spare
   room kept it. The brand block gives ground first now - 40/60 becomes 33/67, the logo goes to
   32px and the contact block to one line - and that alone buys the cards enough room to stay
   on ONE row down to a band of about 744px, which is roughly 944px of page. Measured, fleet
   manager: 1400 -> 148, 1200 -> 136, 1140 -> 136, 1024 -> 136, 768 -> 227. Was 148 / 330 /
   330 / 330 / 354.

   The declarations here are the ones that used to live in @media (max-height: 900px) below.
   There is one copy and it is on the width axis; see the note on that block for what that
   costs on a short but wide screen.
   ========================================================= */

/* =========================================================
   CBS-37 2026-09-20 — THE COMPRESSION HAS TO BE MONOTONIC
   ---------------------------------------------------------
   THE DEFECT the developer reported, narrowing the window as CBSEmployee: the band went short
   at about 1530, TALL AGAIN at 1439, short again at about 1300. A band that GROWS as the window
   SHRINKS reads as broken, whatever the reason for it.

   THE REASON is CBS-21. At 1439 the right rail stops taking layout width and becomes an
   overlay - "@media (max-width: 1439px) { ... --layout-rail-col: var(--rail-strip-width, 48px) }"
   further down this file - so the content column, and with it the band, gets 232px WIDER. The
   band then crosses back ABOVE the 1100 container threshold and un-compresses.
   MEASURED on the developer's captured pages, one pixel apart:
     CBS staff      1440: rail 280, band 1008 wide,  43 tall, compressed
                    1439: rail  48, band 1239 wide, 142 tall, NOT compressed
     Fleet manager  1440: rail 280, band 1008 wide, 136 tall, compressed
                    1439: rail  48, band 1239 wide, 148 tall, NOT compressed
   231px wider and, for CBS staff, 99px taller, for one pixel of window.

   THE FIX, and why it cannot be done with the container query alone. "Once compressed, stays
   compressed as the window narrows" is a statement about the VIEWPORT, and the band's width is
   not monotonic in the viewport on this page - that is the whole defect. No single container
   threshold can both engage at 1534 and survive a 232px jump at 1439. So the container query
   keeps its job, and a VIEWPORT FLOOR is added beneath it: below 1560 the compression is
   unconditional, and nothing the rail or the nav does to the band's width can lift it.

   1560 is chosen just ABOVE the width at which the container query first fires on this page -
   measured at 1534, band 1102 - so the two conditions OVERLAP rather than leaving a gap. An
   overlap is the safe direction: the worst it can do is compress a band that is 26px wider than
   it strictly had to be.

   WHY THIS COVERS THE OTHER TRANSITIONS TOO. Everything below 1560 is unconditional, and the
   only rail transition is at 1439, which is below it. Above 1560 the band is wider than 1100 on
   this page, so compression is off and there is nothing to lose. The one remaining way to change
   the band's width above the floor is a user collapsing or expanding the left nav, which is a
   deliberate action rather than a resize - and even then the container query only ever turns
   compression ON when the band is genuinely narrow, so it cannot produce the "narrower window,
   taller band" the report is about.

   ---------------------------------------------------------------------------------------------
   CBS-69 2026-09-28 - THE FLOOR MOVED FROM 1560 TO 1326, BECAUSE THE RAIL TRANSITION MOVED OUT
   FROM UNDER IT.
   ---------------------------------------------------------------------------------------------
   The paragraph above rests on one thing: "the only rail transition is at 1439, which is below
   it". CBS-69 raised the rail float to 1765, which is ABOVE 1560 - so that premise no longer
   holds and the floor had to be re-derived rather than left alone.

   WHAT WOULD HAVE HAPPENED IF IT HAD BEEN LEFT AT 1560. With the rail floating from 1765, the
   band at 1560 is about 1360 wide instead of about 1128 - it gained the rail's 232px. The floor
   would then compress a band with 260px of spare room instead of 26px, on every screen from 1560
   down. That is the same overlap the note above calls "the safe direction", stretched ten times
   further than it was chosen to be.

   THE DERIVATION, so the number is not a guess. With the rail floating, the band is roughly
   viewport - 136 (gutters and the 56px nav icon rail and the 48px strip) - 64 (page inset), i.e.
   viewport - 200. The container query fires at a band of 1100, so it now first fires at about
   1300 of viewport rather than 1534. Keeping the SAME 26px overlap the original choice used puts
   the floor at 1326. Cross-check: with the rail docked the band was viewport - 432, so a band of
   1100 fell at 1532 and the floor sat 28px above it at 1560. 1326 reproduces that relationship.

   MONOTONICITY IS STILL SATISFIED, which is the invariant this whole block exists for - and it is
   worth stating why, because the rail transition is now above the floor rather than below it.
   Crossing 1765 the band jumps from about 1565 to about 1334; BOTH are above the 1100 threshold,
   so the compression state does not change and the band's HEIGHT does not change. The reported
   defect was a band that grew TALLER as the window shrank; a width change that does not cross the
   threshold cannot produce it. Below 1326 compression is unconditional and stays on.

   WHAT IS STILL VISIBLE AND IS ACCEPTED: the three cards get WIDER by about 232px as the window
   narrows through 1765, because the rail stops taking a column. No height change, no re-flow, no
   compression change - the cards simply have more room. It is the unavoidable cost of floating the
   rail at a width where the band is not already compressed, and at 1439 it was invisible only
   because the old 1560 floor had already compressed everything below it.

   DERIVED, NOT MEASURED. The band arithmetic above uses the shell chrome widths from
   docs/uat/inventory/cbs_grid_widths.md, which that document now flags as describing the
   pre-TL-71 grid. The RELATIONSHIP is sound; the exact pixel may be a few out. Tweak 1326 rather
   than re-deriving it.

   THE TWO BLOCKS BELOW MUST BE KEPT IDENTICAL. They are the same declarations under two
   different triggers, the same arrangement as the compact chrome in nav.css, and for the same
   reason: a media query and a container query cannot be ORed into one rule.
   ========================================================= */
@container cbsband (max-width: 1100px) {

    /* The brand block gives ground first. */
    .cbs-topband-grid {
        grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    }

    .cbs-topband-left {
        --tb-pad-y: 10px;
        --tb-gap: 6px;
    }

    .cbs-topband-right {
        --tb-pad-y: 10px;
    }

    .cbs-topband-left img {
        max-height: 32px;
    }

    /* phone, separator and email on one line instead of stacked */
    .cbs-topband-left .cbs-contact {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: baseline;
        column-gap: 12px;
        row-gap: 0;
    }

    .cbs-topband-left .cbs-hours {
        margin: 0;
    }

    /* The cards may now flex, so they fill the row they are on rather than leaving a ragged
       gap, and they wrap when the next one will not fit. 140px is the basis, not the floor a
       card renders at - three of them fill a 516px lane exactly as before. */
    .cbs-company-meta,
    .cbs-paymentmethod-wrap,
    .cbs-autopay-wrap {
        flex: 1 1 140px;
        min-width: 0;
    }

    .cbs-topband-right {
        --topband-chip-w: 100%;
    }

        .cbs-topband-right .paymentmethod-card,
        .cbs-topband-right .autopay-card {
            width: 100%;
        }
}

/* The viewport floor. Identical to the block above - see the note.
   CBS-69 2026-09-28: WAS 1560, now 1326, because the rail float moved from 1439 to 1765 and is no
   longer below this floor. The derivation and the invariant it protects are in the CBS-37 note
   above - do not change this number without reading the CBS-69 section of it. */
@media (max-width: 1326px) {

    /* The brand block gives ground first. */
    .cbs-topband-grid {
        grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    }

    .cbs-topband-left {
        --tb-pad-y: 10px;
        --tb-gap: 6px;
    }

    .cbs-topband-right {
        --tb-pad-y: 10px;
    }

    .cbs-topband-left img {
        max-height: 32px;
    }

    /* phone, separator and email on one line instead of stacked */
    .cbs-topband-left .cbs-contact {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: baseline;
        column-gap: 12px;
        row-gap: 0;
    }

    .cbs-topband-left .cbs-hours {
        margin: 0;
    }

    /* The cards may now flex, so they fill the row they are on rather than leaving a ragged
       gap, and they wrap when the next one will not fit. 140px is the basis, not the floor a
       card renders at - three of them fill a 516px lane exactly as before. */
    .cbs-company-meta,
    .cbs-paymentmethod-wrap,
    .cbs-autopay-wrap {
        flex: 1 1 140px;
        min-width: 0;
    }

    .cbs-topband-right {
        --topband-chip-w: 100%;
    }

        .cbs-topband-right .paymentmethod-card,
        .cbs-topband-right .autopay-card {
            width: 100%;
        }
}

/* Tighter side padding once the band is genuinely narrow: 16px a side gives the cards 32px. */
@container cbsband (max-width: 900px) {
    .cbs-topband-left,
    .cbs-topband-right {
        --tb-pad-x: 16px;
    }
}

/* Below this the contact block crowds the logo, so it goes and the mark stands alone. The
   phone number and the address are also in the app footer and in the help panel, so nothing
   is only here. */
@container cbsband (max-width: 820px) {
    .cbs-topband-left .cbs-contact {
        display: none;
    }
}


/* =========================================================
   Chips (Saved Payment Method + AutoPay) — shared visual rules
   ========================================================= */

.cbs-topband-right .paymentmethod-card,
.cbs-topband-right .autopay-card {
    width: var(--topband-chip-w);
    height: var(--topband-chip-h);
    max-width: none;
    padding: 8px 10px;
    border-radius: var(--radius);
    box-shadow: none;
    border: 1px solid var(--border);
    background: var(--surface-subtle);
}

    .cbs-topband-right .paymentmethod-card:hover,
    .cbs-topband-right .autopay-card:hover {
        box-shadow: 0 2px 6px rgba(var(--shadow-rgb-neutral), 0.12);
        transition: box-shadow 0.15s ease;
    }

/* Titles (keep compact + consistent) */
.cbs-topband-right .paymentmethod-title-text,
.cbs-topband-right .autopay-title-text {
    font-size: 0.92rem;
    font-weight: 800;
}

/* Title row layout (explicit, so we don't rely on components.css) */
.cbs-topband-right .paymentmethod-title-row,
.cbs-topband-right .autopay-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 2px;
}

/* Indicators (top band size) */
.cbs-topband-right .autopay-indicator {
    width: 10px;
    height: 10px;
}

/* =========================================================
   AutoPay pulse (enabled only) — respects reduced motion
   ========================================================= */

@media (prefers-reduced-motion: no-preference) {
    .cbs-topband-right .autopay-indicator.status-on {
        animation: cbs-autopay-pulse 1.8s ease-out infinite;
    }

    @keyframes cbs-autopay-pulse {
        0% {
            box-shadow: 0 0 0 0 color-mix(in srgb, var(--cbs-accent) 45%, transparent);
        }

        70% {
            box-shadow: 0 0 0 6px color-mix(in srgb, var(--cbs-accent) 0%, transparent);
        }

        100% {
            box-shadow: 0 0 0 0 color-mix(in srgb, var(--cbs-accent) 0%, transparent);
        }
    }
}

/* Grid card should remain the dominant work surface */
body.cbs-invoices .cbs-grid-card {
    flex: 1 1 auto;
    min-height: 0;
}

/* =========================================================
   CBSInvoices — Grid Header Action Bar (Stage 2)
   Source of truth for CBSInvoices action bar styling.
   Notes:
   - Page-specific styles live here (cbs.css).
   - Reusable controls (segmented-toggle) live in controls.css.
   ========================================================= */

body.cbs-invoices .cbs-grid-header {
    padding: 0;
    margin: 0;
}

/* Header row: left | center | right */

/* -------------------------
   Action bar: tighter left+center behavior
   Replace existing header-row / center / filter-pill rules
   ------------------------- */

/* Tunable gap between toggle and filter pill */
:root {
    --filter-gap: 0px;
    --cbs-accent: #23953c;
    --cbs-bg: #aac527;
    --cbs-bg-tint: color-mix(in srgb, #f5f9e8 85%, white);
    --cbs-radius: 12px;
    --cbs-padding: 24px;
    --cbs-shadow: 0 2px 6px rgba(16, 24, 40, 0.08);
}

/* Dark theme (theme.css, html[data-theme="dark"]): the tenant tokens above are defined on :root AFTER theme.css, so they are re-pointed here.
   The CBS green is lifted 15% toward white so it reads as text (links, headings) on a dark card (5.1:1). The logo does not use this token: it has its own dark file, CBSLogo_Dark.svg (see the .cbs-logo rule above). */
html[data-theme="dark"] {
    --cbs-accent: #44A559;
    --cbs-bg-tint: color-mix(in srgb, var(--cbs-accent) 10%, var(--surface));
    --cbs-shadow: 0 2px 6px rgba(0, 0, 0, 0.45);
}

/* Header row: left | center | right
   - left: intrinsic (search + toggle)
   - center: placed immediately after left (start), constrained
   - right: max-content (selection + actions)
*/
/* CBS-04 2026-09-18: the bar is its own query container. The three clusters have hard
   minimum widths (a search field, a three-way toggle, a selection chip, Pay and export), and
   at 1280 they did not fit: the grid tracks held their places and the clusters painted over
   each other, with the search button ending up behind the Open/Paid/All control. The card's
   own width is the right input - the action bar is in .card-header, a sibling of the scroll
   owner, so the grid's cbsgrid container cannot see it. */
body.cbs-invoices .cbs-grid-header {
    container-type: inline-size;
    container-name: cbsbar;
}

body.cbs-invoices .cbs-grid-header-row {
    display: grid;
    grid-template-columns: auto auto max-content;
    grid-template-areas: "left center right";
    gap: clamp(8px, 0.8vw, 14px);
    align-items: center;
    padding: 8px 15px 8px 0; /* Fixes alignment with the reserved gutter */
    width: 100%;
    box-sizing: border-box;
    font-size: 14px;
}

/* Threshold from the evidence: the bar is one clean line at a header width of 974px (the
   1440 rail-open screenshots) and overlaps at 814px (the 1280 rail-open screenshot), so it
   stacks at 970 and below. Filter pill drops under the search and toggle; the actions stay
   on the first line at the right. */
@container cbsbar (max-width: 970px) {
    body.cbs-invoices .cbs-grid-header-row {
        grid-template-columns: auto max-content;
        grid-template-areas:
            "left   right"
            "center center";
        row-gap: 10px;
    }

    body.cbs-invoices .cbs-grid-center {
        margin-left: 0;
        justify-self: stretch;
    }

    body.cbs-invoices .cbs-filter-pill {
        max-width: 100%;
    }
}

/* Narrower still: each cluster gets its own line and the left cluster wraps internally, so
   the search field and the toggle can never overlap. */
@container cbsbar (max-width: 600px) {
    body.cbs-invoices .cbs-grid-header-row {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas:
            "left"
            "center"
            "right";
        row-gap: 10px;
    }

    body.cbs-invoices .cbs-grid-left {
        flex-wrap: wrap;
        gap: 8px;
    }

    body.cbs-invoices .cbs-grid-right {
        justify-content: flex-start;
    }
}

/* LEFT cluster: keep intrinsic width */
body.cbs-invoices .cbs-grid-left {
    grid-area: left;
    display: flex;
    gap: 12px;
    align-items: center;
    min-width: 0;
    flex: 0 0 auto;
}

/* CENTER: place immediately after left and allow it to shrink before right overlaps */
body.cbs-invoices .cbs-grid-center {
    grid-area: center;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    min-width: 0;
    justify-self: start;
    margin-left: var(--filter-gap);
}

/* Constrain the pill so it cannot push the right cluster away */

/* Inner text ellipsize */

/* RIGHT cluster remains compact */
body.cbs-invoices .cbs-grid-right {
    grid-area: right;
    display: flex;
    gap: clamp(6px, 0.7vw, 12px);
    align-items: center;
    justify-content: flex-end;
    min-width: 0;
    flex: 0 0 auto;
}

/* Responsive adjustments preserved */
@media (max-width: 900px) {
    body.cbs-invoices .cbs-grid-header-row {
        grid-template-columns: auto 1fr max-content;
    }

    body.cbs-invoices .cbs-filter-pill {
        max-width: 48%;
    }
}

@media (max-width: 640px) {
    body.cbs-invoices .cbs-grid-header-row {
        grid-template-columns: 1fr;
        grid-template-areas: "left" "center" "right";
        gap: 8px;
    }

    body.cbs-invoices .cbs-grid-left {
        flex-wrap: wrap;
        gap: 6px;
    }

    body.cbs-invoices .cbs-filter-pill {
        max-width: 100%;
    }
}

/* =========================================================
   Search (input + button)
   - Uses a 2-col grid so the search button can never slide under the input.
   ========================================================= */

body.cbs-invoices .cbs-grid-search {
    display: grid;
    grid-template-columns: minmax(150px, 220px) 36px;
    column-gap: 8px;
    align-items: center;
    min-width: 0;
}

body.cbs-invoices .cbs-search-wrap {
    display: block; /* the wrap is exactly the input's height, so 50% below is the input's middle */
    position: relative;
    width: 100%;
    min-width: 0;
}

body.cbs-invoices .cbs-search-input {
    display: block; /* no inline-block baseline slack under the input: the wrap is exactly 36px */
    width: 100%;
    height: 36px;
    padding: 6px 36px 6px 10px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
    font-size: 14px;
    min-width: 0;
}

    /* Hide native browser clear (Chrome/Safari) */
    body.cbs-invoices #cbsGridSearchInput::-webkit-search-cancel-button,
    body.cbs-invoices #cbsGridSearchInput::-webkit-search-decoration {
        -webkit-appearance: none;
    }

/* Clear button anchored to input */
body.cbs-invoices .cbs-search-clear {
    position: absolute;
    right: 8px;
    top: 50%; /* centred on the input at any height, width or zoom (was top: 4px, which assumed a 36px input) */
    transform: translateY(-50%);
    margin: 0;
    height: 28px;
    width: 28px;
    padding: 0;
    border-radius: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    color: var(--muted);
}

    body.cbs-invoices .cbs-search-clear:hover {
        color: var(--brand-ink);
        transform: translateY(calc(-50% - 1px));
    }

/* Hint (overlay — no layout shift) */
body.cbs-invoices .cbs-search-hint {
    display: none;
    position: absolute;
    left: 0;
    top: calc(100% + 6px);
    z-index: 1001;
    font-size: 0.82rem;
    color: var(--muted);
    white-space: nowrap;
    pointer-events: none;
}

body.cbs-invoices .cbs-search-wrap:focus-within .cbs-search-hint {
    display: block;
}

/* Suggestions dropdown (absolute) */
body.cbs-invoices .cbs-search-suggest {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 1000;
    padding: 6px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-2);
    max-height: 320px;
    overflow: auto;
}

/* When hint is visible, drop suggestions below it */
body.cbs-invoices .cbs-search-wrap:focus-within .cbs-search-suggest {
    top: calc(100% + 28px);
}

/* Suggestion item */
body.cbs-invoices .cbs-suggest-item {
    padding: 8px 10px;
    border-radius: 10px;
}

    body.cbs-invoices .cbs-suggest-item:hover {
        background: color-mix(in srgb, var(--cbs-bg-tint) 55%, var(--surface));
    }

body.cbs-invoices .cbs-suggest-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

body.cbs-invoices .cbs-suggest-main {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

body.cbs-invoices .cbs-suggest-kind {
    font-size: 0.75rem;
    font-weight: 800;
    color: var(--cbs-accent);
    border: 1px solid color-mix(in srgb, var(--border) 60%, var(--cbs-accent));
    background: color-mix(in srgb, var(--cbs-bg-tint) 70%, var(--surface));
    padding: 2px 8px;
    border-radius: 999px;
    white-space: nowrap;
}

body.cbs-invoices .cbs-suggest-divider {
    height: 1px;
    background: var(--border);
    margin: 6px 6px;
    opacity: 0.7;
}

body.cbs-invoices .cbs-suggest-footer {
    padding: 6px 10px 2px;
    font-size: 0.78rem;
    font-weight: 800;
    color: var(--muted);
}

body.cbs-invoices .cbs-suggest-scope .cbs-suggest-kind {
    color: var(--muted);
    border-color: var(--border);
}

/* =========================================================
   Action bar / RR toolbar icon buttons (Search, Download, RR tabs)
   ========================================================= */

body.cbs-invoices .cbs-action-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border-radius: 10px;
    border: 1px solid;
    border-color: var(--icon-btn-border);
    background: var(--icon-btn-bg);
    color: var(--brand-ink);
    cursor: pointer;
}

    /* Hover: keep lift ONLY (no color change, per your request) */
    body.cbs-invoices .cbs-action-btn:hover {
        transform: translateY(-1px);
    }

    /* Accent stroke on hover: apply to SVG ONLY, and NOT when the tab is active */
    body.cbs-invoices .cbs-action-btn.icon-btn:hover:not(.is-active) svg.icon {
        stroke: currentColor;
        stroke-width: var(--icon-accent-stroke-width, 0);
    }

    /* If the hovered button is active, force no accent stroke */
    body.cbs-invoices .cbs-action-btn.icon-btn.is-active:hover svg.icon {
        stroke-width: 0;
    }

    /* ...but NEVER on request/status icons (they are fill-based status indicators) */
    body.cbs-invoices .cbs-action-btn.icon-btn:hover svg.cbs-rr-status-icon,
    body.cbs-invoices .cbs-action-btn.icon-btn:hover #RR_Tab_Request svg.icon {
        stroke-width: 0 !important;
    }

    body.cbs-invoices .cbs-action-btn:disabled,
    body.cbs-invoices .cbs-action-btn[disabled] {
        opacity: 0.55;
        cursor: not-allowed;
        transform: none !important;
        filter: none; /* cancels any hover brightness */
        pointer-events: none;
    }

/* =========================================================
   RR Toolbar request states — ensure they override base button color
   ========================================================= */

/* Keep the rr toolbar sticky */
.cbs-rr-header {
    background: var(--surface);
    position: sticky;
    top: 0;
    z-index: 3;
    /* Make toolbar height deterministic so the header offset matches perfectly */
    height: var(--rr-toolbar-h);
    box-sizing: border-box;
    background: var(--surface);
}

.cbs-action-btn.icon-btn.request-state-none {
    color: var(--icon-muted, var(--muted)) !important;
}

.cbs-action-btn.icon-btn.request-state-open {
    color: var(--icon-warning, var(--warning)) !important;
}

.cbs-action-btn.icon-btn.request-state-resolved {
    color: var(--icon-success, var(--success)) !important;
}

/* =========================================================
   Grid request status icon colors (data attribute is most reliable)
   ========================================================= */

body.cbs-invoices #GridView1 td.col-reqstate svg.cbs-rr-status-icon[data-rr-request="none"] {
    color: var(--icon-muted, var(--muted));
}

body.cbs-invoices #GridView1 td.col-reqstate svg.cbs-rr-status-icon[data-rr-request="open"] {
    color: var(--icon-warning, var(--warning));
}

body.cbs-invoices #GridView1 td.col-reqstate svg.cbs-rr-status-icon[data-rr-request="resolved"] {
    color: var(--icon-success, var(--success));
}

/* =========================================================
   RR Tabs — Active state (is-active)
   Works with: .rr-tab + .icon-btn + optional .cbs-action-btn
   ========================================================= */

.rr-tabs .rr-tab.is-active {
    /* Subtle tint so active reads even without relying only on outline */
    background: color-mix(in srgb, var(--brand-primary) 8%, var(--surface));
    /* Active ring (inset so it doesn't change layout) */
    box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--brand-primary) 35%, var(--shade-toward));
    /* Keep active tab stable (don’t “lift” if your hover lifts buttons) */
    transform: translateY(0);
}

    /* Active + hover should not change position OR color */
    .rr-tabs .rr-tab.is-active:hover {
        color: var(--brand-ink);
        transform: translateY(0);
    }

/* =========================================================
   Invoice Status Toggle
   - Uses the reusable segmented-toggle control (controls.css)
   - Only theme/layout tweaks live here.
   ========================================================= */

body.cbs-invoices .segmented-wrap {
    display: flex;
    align-items: center;
    min-width: 0;
}

body.cbs-invoices .segmented-toggle--invoice-status {
    display: grid;
    width: auto;
}

/* =========================================================
   Filter pill (active filters summary)
   ========================================================= */

body.cbs-invoices .cbs-filter-pill {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-radius: var(--cbs-radius);
    background: var(--surface-subtle);
    border: 1px solid var(--border);
    color: var(--muted);
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
    height: 40px;
    min-width: 0;
    max-width: 100%;
    transition: color 140ms ease, transform 120ms ease;
    width: auto;
    box-sizing: border-box;
}

    body.cbs-invoices .cbs-filter-pill:hover {
        background: color-mix(in srgb, var(--pill-bg) 80%, var(--icon-accent) 8%);
        color: var(--ink);
        transform: translateY(-1px);
    }

    body.cbs-invoices .cbs-filter-pill .cbs-active-summary-text {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        min-width: 16ch;
        display: inline-flex;
        align-items: center;
        line-height: 3;
        gap: 4px;
        max-width: 100%;
    }

    #cbsActiveFiltersPill.is-active,
    body.cbs-invoices .cbs-filter-pill:focus {
        outline: 2px solid color-mix(in srgb, var(--brand-primary) 50%, var(--shade-toward));
        outline-offset: 2px;
    }

/* =========================================================
   Selection pill
   ========================================================= */

body.cbs-invoices .cbs-grid-selected {
    color: var(--muted);
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 6px 12px;
    height: 40px;
    border: 1px solid var(--border);
    border-radius: var(--cbs-radius);
    background: var(--surface-subtle);
    white-space: nowrap;
    min-width: max-content;
    overflow: clip;
}

    body.cbs-invoices .cbs-grid-selected .sep {
        color: var(--muted);
        opacity: .8;
    }

body.cbs-invoices .cbs-pill-clear-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    flex: 0 0 auto;
}

    /* Hover only when the control is not disabled */
    body.cbs-invoices .cbs-pill-clear-btn:not(:disabled):hover,
    body.cbs-invoices .cbs-pill-clear-btn:not([disabled]):hover,
    body.cbs-invoices .cbs-pill-clear-btn:not([aria-disabled="true"]):hover {
        color: var(--brand-ink);
        transform: translateY(-1px);
    }

    /* Disabled state: no hover, no pointer, no transform */
    body.cbs-invoices .cbs-pill-clear-btn:disabled,
    body.cbs-invoices .cbs-pill-clear-btn[disabled],
    body.cbs-invoices .cbs-pill-clear-btn[aria-disabled="true"] {
        opacity: 0.55;
        cursor: not-allowed;
        transform: none !important;
        filter: none; /* cancels any hover brightness */
        pointer-events: none;
    }

/* =========================================================
   Pay button (CTA)
   ========================================================= */

/* Pay button — corrected and robust */
body.cbs-invoices .cbs-pay-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0 14px;
    height: 40px;
    border-radius: 10px;
    background: var(--brand-primary);
    color: var(--brand-on-primary);
    font-weight: 700;
    border: none;
    cursor: pointer;
    transition: background-color 160ms ease, box-shadow 160ms ease, transform 120ms ease;
    box-shadow: var(--shadow-1);
    box-sizing: border-box;
}

    /* Hover only when not disabled (use :not(:disabled) for robustness) */
    body.cbs-invoices .cbs-pay-btn:not(:disabled):hover,
    body.cbs-invoices .cbs-pay-btn:not([aria-disabled="true"]):hover {
        background: var(--accent);
        box-shadow: var(--shadow-2);
        transform: translateY(-1px);
    }

    /* Disabled states — cover attribute, aria, and pseudo-class */
    body.cbs-invoices .cbs-pay-btn:disabled,
    body.cbs-invoices .cbs-pay-btn[disabled],
    body.cbs-invoices .cbs-pay-btn[aria-disabled="true"] {
        background: color-mix(in srgb, var(--accent) 20%, var(--surface));
        color: color-mix(in srgb, var(--accent) 40%, var(--muted));
        cursor: not-allowed;
        opacity: 0.9;
        box-shadow: none;
        transform: none;
        pointer-events: none;
        filter: none; /* cancels any hover brightness */
    }

        /* If you want the icon inside to also change color when disabled */
        body.cbs-invoices .cbs-pay-btn:disabled .icon,
        body.cbs-invoices .cbs-pay-btn[disabled] .icon,
        body.cbs-invoices .cbs-pay-btn[aria-disabled="true"] .icon {
            color: color-mix(in srgb, var(--accent) 40%, var(--muted));
        }

/* GRID - based styles come from table-modern in datagrid.css */

/* =========================================================
   CBSInvoices Grid — tighten + prevent early horizontal scroll
   ========================================================= */

:root {
    --grid-cell-padding-x: 8px;
    --grid-cell-padding-y: 10px;
    --grid-border-spacing: 0px;
    --tb-pad-y: 16px;
    --tb-pad-x: 24px;
    --tb-gap: 16px;
}

body.cbs-invoices .card-content {
    scrollbar-gutter: stable;
}

/* Override datagrid.css width:max-content for CBSInvoices */
body.cbs-invoices .grid-wrapper .table-modern {
    width: 100%;
    max-width: 100%;
    min-width: 100%;
    border-spacing: 0;
    border-collapse: collapse;
}

body.cbs-invoices #GridView1 tr.selected-row {
    background-color: var(--grid-row-selected-bg);
}

body.cbs-invoices invoice-selector-all {
}

/* =========================================================
   CBSInvoices — Grid column styling (GridView1)
   Requires: ItemStyle-CssClass="col-..." on each field
   ========================================================= */
body.cbs-invoices #GridView1 {
}

    /* Make numeric columns align nicely */
    body.cbs-invoices #GridView1 td.col-amount,
    body.cbs-invoices #GridView1 td.col-adjustment,
    body.cbs-invoices #GridView1 td.col-latefee,
    body.cbs-invoices #GridView1 td.col-payment,
    body.cbs-invoices #GridView1 td.col-balance,
    body.cbs-invoices #GridView1 td.col-invoice,
    body.cbs-invoices #GridView1 td.col-date {
        text-align: right;
        font-variant-numeric: tabular-nums;
        white-space: nowrap;
    }

/* TL-21: the sort-icon kill switch was removed here too; the shared glyph applies. */


    /* Sortable header affordance */
    body.cbs-invoices #GridView1 th.sortable {
        cursor: pointer;
        user-select: none;
    }

        body.cbs-invoices #GridView1 th.sortable .sort-icon {
            margin-left: 6px;
            color: var(--muted);
            font-size: 0.85em;
        }

    /* Money columns: alignment + tabular digits */
    body.cbs-invoices #GridView1 td.money {
        text-align: right;
        font-variant-numeric: tabular-nums;
        white-space: nowrap;
    }

        body.cbs-invoices #GridView1 td.money.is-neg {
            color: var(--danger);
        }

        /* CBS-04 2026-09-18: colour only, never opacity. Opacity on a cell makes its
           BACKGROUND translucent too, so on the pinned totals rows the scrolling body
           showed through in exactly the columns displaying 0.00 - which is what the
           ghosting was. */
        body.cbs-invoices #GridView1 td.money.is-zero {
            color: color-mix(in srgb, var(--muted) 85%, var(--grid-header-bg));
        }

    /* footer emphasis */
    body.cbs-invoices #GridView1 tfoot td,
    body.cbs-invoices #GridView1 tr.gridview-footer td {
        font-weight: 700;
    }

    /* Checkbox visual alignment */
    body.cbs-invoices #GridView1 input.invoice-selector,
    body.cbs-invoices #GridView1 #chkall {
        margin: -2.5px;
        transform: scale(1.01);
    }

    /* The selection boxes state their own geometry: 16px, no margin (the 28px column is 16px control + 2 x 6px padding), centred on the row. They used to get the
       margin, the lift and the vertical-align from a bare rightrail.css rule that restyled every checkbox in the app (checkbox-leaks_handoff.md). */
    body.cbs-invoices #GridView1 input[type="checkbox"] {
        accent-color: var(--brand-primary);
        width: 16px;
        height: 16px;
        margin: 0;
        vertical-align: middle;
    }

body.cbs-invoices .invoice-selector-all {
    margin-left: 4px;
}

/* =========================================================
   CBSInvoices — grid columns (CBS-04, 2026-09-18)

   Widths are px, never ch. `ch` is the advance of "0" in the element's
   own font, so the same "9ch" is 9.234px on the 600-weight header and
   8.831px in the 400-weight body, and money strings are ~10% narrower
   than Nch because the comma and the period are narrow.

   Every width below is  max(widest value, header label + 23.54px sort
   glyph) + 16px padding, measured in Inter 14px:

     sort glyph   3.33 space + 6 margin + 14 box            = 23.54
     999,999.99   80.16   99,999.99 71.08   0.00 31.00      (tabular)
     12/31/26     64.56   9-digit invoice 81.70   CB999999 73.86
     VA-VERNON40 100.39   VIN 17ch 143.66   VIN 8ch 69.03
     entity full 172.66   entity 8ch 68.34   99999 43.42

   min-width / max-width are deliberately absent: Chrome ignores both in a
   fixed-layout table, which is why the old 16ch/20ch floors never
   protected Entity and VIN.
   ========================================================= */

/* Flat padding. The old clamp(6px, 0.45vw, 8px) moved a column's content
   width by 4px between 1280 and 1920, which is what made LATE clip its own
   sort glyph at 1920 and not at 1440. */
body.cbs-invoices #GridView1 th,
body.cbs-invoices #GridView1 td {
    padding-inline: 8px;
    padding-block: 10px;
    box-sizing: border-box;
}

/* Checkbox — 16px control + 2 x 6px */
body.cbs-invoices #GridView1 .col-selector-head,
body.cbs-invoices #GridView1 .col-select {
    width: 28px;
    text-align: center;
    padding-inline: 6px;
}

/* REQ — 16px icon + 2 x 4px, plus room for the focus ring */
body.cbs-invoices #GridView1 .col-reqstate-head,
body.cbs-invoices #GridView1 .col-reqstate {
    width: 40px;
    text-align: center;
    padding-inline: 4px;
    white-space: nowrap;
}

/* ---- Fixed columns: never shrink, never hidden ---------------------- */

/* Store — header-bound: "Store" 35.97 + glyph 23.54 + 16 = 75.5 */
body.cbs-invoices #GridView1 .col-store-head,
body.cbs-invoices #GridView1 .col-store {
    width: 76px;
}

/* Date — "12/31/26" 64.56 + 16 = 80.6 */
body.cbs-invoices #GridView1 .col-date-head,
body.cbs-invoices #GridView1 .col-date {
    width: 81px;
}

/* Invoice — 9 digits 81.70 + 16 = 97.7 */
body.cbs-invoices #GridView1 .col-invoice-head,
body.cbs-invoices #GridView1 .col-invoice {
    width: 98px;
}

/* Fleet # — "CB999999" 73.86 + 16 = 89.9 */
body.cbs-invoices #GridView1 .col-baid-head,
body.cbs-invoices #GridView1 .col-baid {
    width: 90px;
}

/* Money — 999,999.99 is 80.16 + 16 = 96.2, so a future grand total fits.
   At the old 8ch the content box was 60.92px and a four-figure page total
   (9,999.99 = 62.00) already truncated. */
body.cbs-invoices #GridView1 .col-amount-head,
body.cbs-invoices #GridView1 .col-amount,
body.cbs-invoices #GridView1 .col-adjustment-head,
body.cbs-invoices #GridView1 .col-adjustment,
body.cbs-invoices #GridView1 .col-latefee-head,
body.cbs-invoices #GridView1 .col-latefee,
body.cbs-invoices #GridView1 .col-payment-head,
body.cbs-invoices #GridView1 .col-payment,
body.cbs-invoices #GridView1 .col-balance-head,
body.cbs-invoices #GridView1 .col-balance {
    width: 97px;
}

/* ---- The three wide columns ------------------------------------------
   CBS-04 follow-up 2026-09-18: these used to collapse to zero width below a
   container width. That machinery is gone. It depended on a col-*-head class
   that the real page never had - ASP.NET applies HeaderStyle-CssClass with
   MergeStyle, which leaves CssClass alone once GridView1_RowCreated has set
   "sortable" on the cell, so every sortable header rendered as
   <th class="sortable"> with no width and no collapse rule attached. The
   header classes are seeded in code now, but the collapse itself is not coming
   back: every column keeps one width at every size, and when the set does not
   fit, .card-content scrolls sideways - which is what this grid did before and
   is the one behaviour that cannot produce a blank cell or a stray fragment.
   -------------------------------------------------------------------- */

/* Entity - 140px shows about 15 characters and ellipsizes the rest. The full name
   ("Griffin Fast Lube LLC - UT", 172.66 + 16) would need 190px; the 50px buys a column
   for everyone at a narrower viewport, and the full value is in the right rail. */
body.cbs-invoices #GridView1 .col-entity-head,
body.cbs-invoices #GridView1 .col-entity {
    width: 140px;
}

/* License Plate - header-bound: "License Plate" 89.90 + glyph 23.54 + 16 */
body.cbs-invoices #GridView1 .col-tag-head,
body.cbs-invoices #GridView1 .col-tag {
    width: 130px;
}

/* VIN - 130px shows about 12 of the 17 characters and ellipsizes the rest, which the
   column priorities allow ("VIN: important, but truncation is acceptable"). All 17 would
   need 160px.

   TL-169: THE VIN IS RENDERED WITH TABULAR FIGURES AND NO LETTER-SPACING SO EVERY VIN IS THE
   SAME WIDTH. This is the fix for "3GCNWAEF3MG387734 truncates but 1N6BD0CT1JN749877 does
   not" - same 17 characters, different glyph widths, so a single pixel width could fit one
   and clip the other and no single number could ever fit both.

   WHY A FONT CHANGE RATHER THAN A BIGGER NUMBER: the grid is table-layout: fixed
   (datagrid.css:72), which means a column CANNOT size to its content - the width is taken
   from the column definition and content is clipped to it. So "let it size to content" is
   not available here; the only choices are a number that fits the worst case or making every
   case the same width. Widening to the worst case wastes the difference on every other row
   and would need re-measuring whenever the font changes. Making the glyphs uniform makes the
   measurement exact and permanent.

   A VIN IS A CODE, NOT PROSE, so tabular figures are the correct treatment anyway - it is the
   same reason the error reference on Errors.aspx is monospaced. font-variant-numeric only
   equalises digits, so font-feature-settings "tnum" is set alongside it for the letters. */
body.cbs-invoices #GridView1 .col-vin-head,
body.cbs-invoices #GridView1 .col-vin {
    width: 130px;
}

body.cbs-invoices #GridView1 .col-vin {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    letter-spacing: 0;
}

/* Every cell clips. This is what stops a value that is wider than its column
   painting across its neighbour - the "047" and "33" fragments in the 1280
   screenshots were the tails of nine-digit invoice numbers in an 84.5px column,
   because col-invoice had no overflow rule and, at the time, no width either. */
body.cbs-invoices #GridView1 th,
body.cbs-invoices #GridView1 td {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Spacer - the only column with no width, so slack lands here instead of
   stretching VIN. It sits between the last identity column and the money block,
   which keeps the money columns and REQ flush right. */
body.cbs-invoices #GridView1 .col-spacer-head,
body.cbs-invoices #GridView1 .col-spacer {
    padding-inline: 0;
    border: 0;
}

/* ---- TFOOT: page totals and grand total pin above the pager ---------
   The generic sticky rule is in datagrid.css; these supply the offsets.
   MT_CbsSyncTfootOffsets() in cbsinvoices.js keeps --cbs-pager-h in step with
   the pager as it actually renders. */

body.cbs-invoices #GridView1 {
    /* Fixed row height so the two offsets are integers in CSS px and stay
       integers at 110% and 125% zoom. */
    --cbs-totals-row-h: 42px;
}

body.cbs-invoices #GridView1 > tfoot > tr.cbs-totals-row,
body.cbs-invoices #GridView1 > tfoot > tr.cbs-grand-row {
    /* The row carries the colour too, not only the cells: if any cell ever fails to get
       its background the row underneath is still opaque. */
    background-color: var(--grid-header-bg);
}

body.cbs-invoices #GridView1 > tfoot > tr.cbs-totals-row > td,
body.cbs-invoices #GridView1 > tfoot > tr.cbs-grand-row > td {
    height: var(--cbs-totals-row-h);
    background-color: var(--grid-header-bg);
    z-index: calc(var(--grid-header-z) + 2);
    /* Bleeds one pixel above and below. background-clip: padding-box used to sit here and
       was wrong: with border-collapse: collapse it leaves the collapsed border strip
       unpainted, and that strip is exactly where a scrolling row shows through. */
    box-shadow: inset 0 1px 0 var(--grid-border-color),
                0 1px 0 0 var(--grid-header-bg),
                0 -1px 0 0 var(--grid-header-bg);
}

body.cbs-invoices #GridView1 > tfoot > tr.cbs-totals-row > td {
    font-weight: 600;
    color: var(--muted);
}

body.cbs-invoices #GridView1 > tfoot > tr.cbs-grand-row > td {
    font-weight: 700;
    color: var(--ink);
}

body.cbs-invoices #GridView1 > tfoot > tr.gv-pager-row > td {
    background-color: var(--grid-header-bg);
    z-index: calc(var(--grid-header-z) + 1);
}

/* The label is a colspan cell covering everything left of AMT, right-aligned.
   It is no longer allowed to overflow: it used to live in the spacer cell and
   paint leftwards, over cells that are not always empty. */
body.cbs-invoices #GridView1 > tfoot .cbs-totals-label {
    text-align: right;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    padding-inline: 8px;
    direction: ltr;
}

/* CBS Right Rail */
.cbs-rr-lineitem-desc {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Right Rail Filters */
/* =========================================================
   CBSInvoices RR / Filters — Store Picker (NO nested scroll)
   - Keeps RR scroll contract: RightRailContent owns scrolling
   - Fixes indentation + icon/checkbox alignment + density
   ========================================================= */

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .store-picker {
    /* RR density */
    font-size: 13px;
    line-height: 1.25;
}

/* IMPORTANT: do NOT create a nested scroll container */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .StorePickerTree {
    overflow: visible;
    max-height: none;
    border: 0;
    border-radius: 0;
    background: transparent;
    padding: 0;
    margin-left: -19px;
}

    /* Remove default UL indentation and bullets */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .StorePickerTree ul {
        list-style: none;
        margin: 0;
        padding-left: 0;
    }

    /* Knob B1: first nesting level under the root */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"]
    .StorePickerTree > .AspNet-TreeView > ul > li > ul {
        padding-left: 0px; /* smaller first indent */
    }

    /* Knob B2: deeper nesting levels */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"]
    .StorePickerTree li ul ul {
        padding-left: 30px; /* keep deeper levels readable */
    }

    /* Keep each row tight but readable */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .StorePickerTree li {
        margin: 6px 0;
    }

    /* Expand/collapse glyph: consistent hit box and vertical alignment */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .StorePickerTree
    .AspNet-TreeView-Expand,
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .StorePickerTree
    .AspNet-TreeView-Collapse {
        display: inline-block;
        width: 18px;
        height: 18px;
        vertical-align: middle;
        opacity: 0.75;
        top: -1px;
    }

    /* Checkbox alignment and spacing */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .StorePickerTree input[type="checkbox"] {
        vertical-align: middle;
        margin: 0 2px 0 2px;
    }

    /* Label spans: align icon + text and allow ellipsis */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .StorePickerTree
    .AspNet-TreeView-ClickableNonLink,
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .StorePickerTree
    .AspNet-TreeView-NonLink {
        display: inline-flex;
        align-items: center; /* fixes icon sitting “high” */
        gap: 0px;
        min-width: 0;
        max-width: 100%;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        line-height: 1.25;
    }

        /* Tree icons: make them readable and aligned */
        body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .StorePickerTree
        .AspNet-TreeView-ClickableNonLink img,
        body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .StorePickerTree
        .AspNet-TreeView-NonLink img {
            width: 18px;
            height: 18px;
            flex: 0 0 18px;
            display: inline-block;
            vertical-align: middle;
        }

    /* Knob D: checkbox alignment */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"]
    .StorePickerTree input[type="checkbox"] {
        vertical-align: middle;
        position: relative;
        transform: translateY(-5px);
        width: 16px;
        height: 16px;
        accent-color: var(--brand-primary);
    }

    /* Root “Click to choose stores” reads like a lightweight section header */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .StorePickerTree
    .AspNet-TreeView-Root > span.AspNet-TreeView-ClickableNonLink {
        font-weight: 600;
        font-size: 14px;
    }

/* =========================================================
   CBSInvoices RR / Filters — Date Range Picker (RR density)
   Scope: RightRailContent + Filters tab only
   ========================================================= */

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .date-range {
    /* Slightly smaller than the rest of RR content to fit the narrow rail */
    font-size: 13px;
    line-height: 1.25;
    margin-bottom: 16px;
}

/* Tighten the 2-col grid spacing for From/To so dates have more room */

/* RR Filters: From/To stay side-by-side */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"]
.date-range-dates .date-range-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}

/* RR Filters: Report Date Range dropdown gets full width */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"]
.date-range-range .date-range-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px; /* optional; keeps consistent vertical rhythm */
}

/* Labels: compact but still readable; allow wrap if needed */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .date-range-label {
    display: block;
    margin-bottom: 6px;
    font-weight: 700;
    font-size: 13px;
    line-height: 1.15;
    color: var(--ink);
}

/* Inputs and selects: RR-friendly height + padding */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .date-range-input,
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .date-range select,
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .date-range .input {
    width: 100%;
    height: 38px;
    padding: 6px 8px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--surface);
    box-sizing: border-box;
    /* Improves readability of dates and keeps digits aligned */
    font-variant-numeric: tabular-nums;
    font-size: 12px;
}

/* Give the range dropdown its own breathing room */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .date-range-range {
    margin-top: 10px;
}

/* Slightly reduce spacing between the store picker and dates in RR */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .date-range-dates {
    margin-top: 12px;
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .store-picker-validation {
    margin-top: 8px;
    margin-bottom: 8px;
    font-size: 12px;
    font-weight: 600;
    color: var(--danger);
}

/* make date range UC sticky at the bottom */

/* ===========================================================================================
   *** THIS RULE IS VERIFIED LIVE. DO NOT REMOVE IT. ***  (TL-205, corrected 2026-10-02)

   AN EARLIER NOTE HERE SAID THIS RULE HAD NEVER APPLIED. THAT WAS WRONG, and it was proved wrong
   by the rule causing a real defect: the CBS right-rail scroll leak, which the developer traced
   to margin-left: -16px leaking horizontally once a store-list caret scrolled far enough down.
   A rule that causes a bug is a rule that matches.

   WHY IT MATCHES, AND THIS IS THE MECHANISM THE SWEEP MISSED: updDateRange is an UpdatePanel
   inside Controls/ucDateRange.ascx, which is a naming container, so under the application-wide
   clientIDMode="AutoID" it should render prefixed. BUT CBSInvoices.aspx:599 declares the control
   as <uc2:DateRange ID="DateRangePicker1" runat="server" ClientIDMode="Static" /> AND
   ClientIDMode IS INHERITED BY DESCENDANT CONTROLS - a child's default is Inherit. So everything
   inside that user control, including this UpdatePanel, renders Static. The id survives whole.

   THE SWEEP ONLY EVER LOOKED AT THE CONTROL'S OWN TAG. It never looked at the page, and it never
   looked at the control's ANCESTORS. Two different blind spots, both found the same day: a page
   with no master page has nothing to prefix with, and an ancestor carrying Static passes it down.

   WHAT THE RULE DOES, so it can be judged by eye: pin the date range to the BOTTOM of the right
   rail, just above the action buttons, so it stays visible while the rail scrolls. position:
   sticky with bottom set to the action bar's height is the pin; background: var(--surface) stops
   content showing through; border-top draws the divider. The -1px margins with +1px padding are a
   hairline correction - pull one pixel over the neighbours, give it back as padding, so the
   sticky edge meets the rows above and below without a seam or a doubled border. The developer
   added the matching margin-left/padding-left pair for the horizontal case that was leaking.

   IF ANYTHING HERE EVER NEEDS CHANGING, change the declarations - not the control's id. The id is
   the contract every piece of JavaScript on the page relies on, and a grep cannot find all of
   them: selectors get built by concatenation, by ClientID in RegisterStartupScript strings, and
   inside string literals.
   =========================================================================================== */
#updDateRange {
    margin-top: -1px;
    margin-bottom: -1px;
    margin-left: -16px;
    padding-top: 1px;
    padding-bottom: 1px;
    padding-left: 16px;
    background: var(--surface);
    border-top: 1px solid var(--border);
}

/* The date range pins above the action bar only when the rail is tall enough to hold it AND the store list. On a short window the pin left the
   store list a sliver to scroll in while the dates sat still (two scrolls); below 701px tall the date range scrolls with the rail content, and only
   the header, tabs and the action bar stay put. */
@media (min-height: 701px) {
    #updDateRange {
        position: sticky;
        bottom: var(--rr-actions-height);
    }
}

/* =========================================================
   CBSInvoices RR / Invoices
   Scope: RightRailContent + Invoices tab only
   ========================================================= */

/* CBSInvoices RR: render \n in the invoice subtitle as line breaks

   CBS-75 2026-09-28: THE STYLING FOR THESE TWO SUBTITLES LIVES HERE, ON THE IDs,
   AND IT STAYS HERE.

   Both elements also carry the classes rr-subtitle and rr-subtitle-secondary
   (CBSInvoices.aspx). THOSE CLASSES ARE INERT - nothing defines them in any
   stylesheet and no script selects them. They are not a bug and they were
   deliberately not deleted: they are the only hint in the markup that a
   primary/secondary distinction was intended, and without them the next reader
   wonders why one subtitle is muted. Nothing renders unstyled.

   WHY THE TIDY REFACTOR - move these rules onto the classes - WAS CONSIDERED AND
   REJECTED. white-space: pre-line below is BEHAVIOUR, not appearance: it is what
   makes a newline in the subtitle text render as a line break. On a class it
   applies wherever that class appears and nowhere else, so the change is only
   safe if every element carrying the ID also carries the class, in both this
   panel and the Request panel, and stays that way. THE FAILURE MODE IS SILENT AND
   INVISIBLE - text that should break onto two lines simply runs together, with no
   error and nothing obviously wrong on screen. There is no behavioural gain to
   set against that, only tidiness.

   The same pair exists for the Request panel further down this file
   (#RR_Request_Subtitle / #RR_Request_Subtitle2) and the same reasoning applies
   to it. Four ID selectors, two panels, one decision. */
body.cbs-invoices #RR_Inv_Subtitle {
    white-space: pre-line;
    font-weight: 600;
    line-height: 1.15;
}

body.cbs-invoices #RR_Inv_Subtitle2 {
    color: var(--muted);
    font-size: 0.78em; /* slightly smaller than line 1 */
    line-height: 1.15;
    margin-top: 2px;
}

/* =========================================================
   CBSInvoices RR / Details — Line Items (receipt rows)
   ========================================================= */

body.cbs-invoices #RR_LineItems_List .rr-lineitems-v2 {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

body.cbs-invoices #RR_LineItems_List .rr-li-service,
body.cbs-invoices #RR_LineItems_List .rr-li-item {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 10px 10px;
}

body.cbs-invoices #RR_LineItems_List .rr-li-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 10px;
    align-items: start;
}

body.cbs-invoices #RR_LineItems_List .rr-li-desc {
    font-weight: 600;
    font-size: 13px;
    letter-spacing: -0.01em;
    line-height: 1.2;
    color: color-mix(in srgb, var(--ink) 85%, var(--muted));
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

div.rr-section-title {
    font-weight: 700;
    font-size: 15px;
    margin-bottom: 6px;
}

body.cbs-invoices #RR_LineItems_List .rr-li-total {
    font-weight: 800;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

body.cbs-invoices #RR_LineItems_List .rr-li-meta {
    margin-top: 6px;
    color: var(--muted);
    font-size: 12px;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}

/* Toggle row under service header */
body.cbs-invoices #RR_LineItems_List .rr-li-toggles {
    margin-top: 8px;
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

body.cbs-invoices #RR_LineItems_List .rr-li-toggle {
    border: 1px solid var(--border);
    background: var(--surface-subtle);
    color: var(--muted);
    border-radius: 999px;
    padding: 4px 10px;
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
}

    body.cbs-invoices #RR_LineItems_List .rr-li-toggle:hover {
        color: var(--ink);
    }

/* Child containers */
body.cbs-invoices #RR_LineItems_List .rr-li-children {
    margin-top: 10px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

body.cbs-invoices #RR_LineItems_List .rr-li-child {
    border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
    padding-top: 8px;
}

/* Included child styling */
body.cbs-invoices #RR_LineItems_List .rr-li-child--included .rr-li-desc {
    font-weight: 600;
}

body.cbs-invoices #RR_LineItems_List .rr-li-badge {
    font-size: 11px;
    font-weight: 800;
    color: var(--muted);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 2px 8px;
    white-space: nowrap;
    align-self: start;
    opacity: .6;
}

/* A) When children are visible, add a subtle inset panel effect */
body.cbs-invoices #RR_LineItems_List .rr-li-children {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
}

/* B) Indent children a bit so they feel nested */
body.cbs-invoices #RR_LineItems_List .rr-li-child {
    padding-left: 10px;
    border-left: 2px solid color-mix(in srgb, var(--border) 70%, transparent);
}

/* C) Slightly reduce weight for included children so billed stands out */
body.cbs-invoices #RR_LineItems_List .rr-li-child--included {
    opacity: 0.92;
}

/* Visual pressed/active state for toggles */
body.cbs-invoices #RR_LineItems_List .rr-li-toggle[aria-expanded="true"] {
    background: color-mix(in srgb, var(--brand-primary) 5%, var(--surface));
    border-color: color-mix(in srgb, var(--brand-primary) 35%, var(--border));
    color: var(--ink);
}

    /* Optional: add a tiny chevron indicator without adding SVG */
    body.cbs-invoices #RR_LineItems_List .rr-li-toggle[aria-expanded="true"]::after {
        content: " \25B2";
        font-size: 10px;
        opacity: 0.75;
    }

body.cbs-invoices #RR_LineItems_List .rr-li-toggle[aria-expanded="false"]::after {
    content: " \25BC";
    font-size: 10px;
    opacity: 0.6;
}

body.cbs-invoices #RR_LineItems_List .rr-li-children {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
}

body.cbs-invoices #RR_LineItems_List .rr-li-child--included {
    opacity: 0.7;
}

    body.cbs-invoices #RR_LineItems_List .rr-li-child--included .rr-li-desc {
        font-weight: 600;
    }

/* RR Details: the disclosure pill rules moved to App_Themes/Core/rightrail.css, unscoped
   (TL-40 2026-09-19). cbs.css is only emitted for CBS tenants, so keeping them here left
   Commission Plans and Store Groups with a default browser button. */







/* Give the section body a little “belongs to this pill” cue */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] .rr-section > div[id$="_Body"] {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--border);
}


/* =========================================================
   CBSInvoices RR / Details — Totals (Summary) styling
   ========================================================= */

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Summary {
    margin-top: 12px; /* space from header divider */
    margin-bottom: 14px; /* space before Line Items pill */
}

    /* Wrap the Summary body (hero + kv) into a single “card” surface */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Summary .rr-hero,
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Summary .rr-kv {
        background: var(--surface);
        border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
        border-radius: var(--radius);
        padding: 12px;
    }

    /* Avoid double borders: the kv sits right under hero as one visual group */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Summary .rr-kv {
        margin-top: 10px;
    }

    /* Hero */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Summary .rr-hero-label {
        color: var(--muted);
        font-weight: 800;
        font-size: 12px;
        margin-bottom: 6px;
    }

    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Summary .rr-hero-value {
        font-size: 22px;
        font-weight: 900;
        line-height: 1.05;
        font-variant-numeric: tabular-nums;
    }

    /* KV grid */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Summary .rr-kv {
        display: grid;
        gap: 10px;
    }

    /* Each field row becomes a 2-column grid */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Summary .cbs-rr-field {
        display: grid;
        grid-template-columns: 1fr auto;
        align-items: baseline;
        gap: 12px;
    }

        /* Label */
        body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Summary .cbs-rr-field > label {
            margin: 0;
            font-size: 13px;
            font-weight: 700;
            color: var(--muted);
        }

        /* Value */
        body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Summary .cbs-rr-field > div {
            text-align: right;
            font-size: 13px;
            font-weight: 800;
            font-variant-numeric: tabular-nums;
            white-space: nowrap;
        }

/* Emphasize Balance row */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Inv_Balance {
    font-size: 14px;
    font-weight: 900;
    color: var(--ink);
}

/* RR money state styling (Summary + other RR money values) */
body.cbs-invoices #RightRailContent .is-neg {
    color: var(--danger);
}

body.cbs-invoices #RightRailContent .is-zero {
    color: var(--muted);
    opacity: 0.85;
}

body.cbs-invoices #RR_Summary .cbs-rr-field > div {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

body.cbs-invoices #RR_Summary .rr-kv .cbs-rr-field {
    padding: 2px 0;
    border-bottom: 1px solid var(--border);
}

    body.cbs-invoices #RR_Summary .rr-kv .cbs-rr-field:last-child {
        border-bottom: none;
    }

/* =========================================================
   CBSInvoices RR / Details — Fleet Info (Rules) stacked layout
   ========================================================= */

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Rules_Body {
    margin-top: 10px;
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] .cbs-rr-rules {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 12px;
    display: grid;
    gap: 10px;
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] .cbs-rr-rule {
    display: grid;
    gap: 4px;
    padding: 6px 0;
    border-bottom: 1px solid var(--border);
}

    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] .cbs-rr-rule:last-child {
        border-bottom: none;
    }

/* Label: de-emphasized, consistent, readable */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] .cbs-rr-rule-label {
    font-size: 12px;
    font-weight: 900;
    color: var(--muted);
    line-height: 1.1;
}

/* Value: primary content */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] .cbs-rr-rule-value {
    font-size: 14px;
    font-weight: 800;
    color: var(--ink);
    line-height: 1.2;
    /* Helps long IDs / VINs display safely without weird bidi issues */
    unicode-bidi: plaintext;
    word-break: break-word;
}

/* =========================================================
   CBSInvoices RR / Details — Payments styling (card + history rows)
   ========================================================= */

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Payments_Body {
    margin-top: 10px; /* consistent with Fleet Info / Rules body spacing */
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Payments_List .rr-payments {
    border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 0; /* rows will provide their own spacing */
}

/* One payment row */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Payments_List .cbs-rr-item {
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
}

    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Payments_List .cbs-rr-item:last-child {
        border-bottom: none;
        padding-bottom: 0;
    }

/* Top row: date left, amount right */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Payments_List .cbs-rr-item-top {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 10px;
    align-items: baseline;
}

/* Date */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Payments_List .cbs-rr-item-title {
    font-size: 13px;
    font-weight: 800;
    color: var(--ink);
    line-height: 1.15;
}

/* Amount (normalize to Totals scale, not “huge”) */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Payments_List .cbs-rr-item-amt {
    font-size: 14px; /* this is the key reduction */
    font-weight: 900;
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    line-height: 1.15;
}

/* Method line */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Payments_List .cbs-rr-item-sub {
    margin-top: 4px;
    font-size: 12px;
    font-weight: 700;
    color: var(--muted);
    line-height: 1.15;
}

/* Keep the line calm */
#RR_Payments_List .cbs-rr-item-sub2 {
    margin-top: 4px;
    font-size: 12px;
    font-weight: 700;
    color: var(--muted);
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}

    /* Only the number gets the tint */
    #RR_Payments_List .cbs-rr-item-sub2 .cbs-rr-change-amt {
        white-space: nowrap;
    }

        /* Muted red for negative change amount */
        #RR_Payments_List .cbs-rr-item-sub2 .cbs-rr-change-amt.is-neg {
            color: color-mix(in srgb, var(--danger) 45%, var(--muted));
        }

        /* If you ever display 0 for change (rare), keep it muted */
        #RR_Payments_List .cbs-rr-item-sub2 .cbs-rr-change-amt.is-zero {
            color: var(--muted);
            opacity: 0.85;
        }

/* =========================================================
   CBSInvoices RR / Details — Adjustments (match Payments)
   ========================================================= */

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Adjustments_Body {
    margin-top: 10px;
}

/* Card container (keep your existing border/radius tokens) */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Adjustments_List .rr-adjustments {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 12px;
}

/* Match Payments row rhythm: date left, amount right */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Adjustments_List .cbs-rr-item {
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
}

    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Adjustments_List .cbs-rr-item:last-child {
        border-bottom: none;
        padding-bottom: 0;
    }

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Adjustments_List .cbs-rr-item-top {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 10px;
    align-items: baseline;
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Adjustments_List .cbs-rr-item-title {
    font-size: 13px;
    font-weight: 800;
    color: var(--ink);
    line-height: 1.15;
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Adjustments_List .cbs-rr-item-amt {
    font-size: 14px;
    font-weight: 900;
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    line-height: 1.15;
}

/* Description: readable, wraps, clamps; full text available via title tooltip */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Adjustments_List .cbs-rr-item-sub {
    margin-top: 4px;
    font-size: 12px;
    font-weight: 700;
    color: var(--muted);
    line-height: 1.2;
    white-space: normal;
    word-break: break-word;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Fees subsection spacing (keep your border-top setting) */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Adjustments_List .rr-adj-fees-wrap {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
}

/* Reuse existing rr-li-toggle pills (same as Line Items) */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Adjustments_List .rr-li-toggles {
    margin-top: 0;
}

/* Adjustments: make Fees toggle look like Included/Billed pills */
body.cbs-invoices #RR_Adjustments_List .rr-li-toggles {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
}

/* Apply the same pill styling used by line item toggles */
body.cbs-invoices #RR_Adjustments_List .rr-li-toggle {
    border: 1px solid var(--border);
    background: var(--surface-subtle);
    color: var(--muted);
    border-radius: 999px;
    padding: 4px 10px;
    font-size: 12px;
    font-weight: 800;
    cursor: pointer;
    white-space: nowrap;
}

    /* Expanded visual state (matches your other toggles) */
    body.cbs-invoices #RR_Adjustments_List .rr-li-toggle[aria-expanded="true"] {
        background: color-mix(in srgb, var(--brand-primary) 10%, var(--surface));
        border-color: color-mix(in srgb, var(--brand-primary) 35%, var(--border));
        color: var(--ink);
    }

        /* Optional chevrons for consistent affordance */
        body.cbs-invoices #RR_Adjustments_List .rr-li-toggle[aria-expanded="true"]::after {
            content: " \25B2";
            font-size: 10px;
            opacity: 0.75;
        }

    body.cbs-invoices #RR_Adjustments_List .rr-li-toggle[aria-expanded="false"]::after {
        content: " \25BC";
        font-size: 10px;
        opacity: 0.60;
    }

body.cbs-invoices #RR_Adjustments_List .rr-adj-fees-list {
    margin-top: 8px;
    padding-left: 10px;
    border-left: 2px solid color-mix(in srgb, var(--border) 70%, transparent);
}

/* =========================================================
   CBSInvoices RR / Details — Vehicle Info (match Fleet Info)
   ========================================================= */

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Vehicle_Body {
    margin-top: 10px;
    /* IMPORTANT: no border/padding on the body so Loading/Empty are NOT inside a card */
}

/* Card should wrap ONLY the fields */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Vehicle_Fields {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 12px;
}

    /* Each field: stacked label above value */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Vehicle_Fields .cbs-rr-field {
        display: grid;
        gap: 4px;
        padding: 6px 0;
        border-bottom: 1px solid var(--border);
    }

        body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Vehicle_Fields .cbs-rr-field:last-child {
            border-bottom: none;
            padding-bottom: 0;
        }

        /* Label style (consistent with Fleet Info feel) */
        body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Vehicle_Fields .cbs-rr-field > label {
            margin: 0;
            font-size: 12px;
            font-weight: 900;
            color: var(--muted);
            line-height: 1.1;
        }

        /* Value style */
        body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Vehicle_Fields .cbs-rr-field > div {
            font-size: 14px;
            font-weight: 800;
            color: var(--ink);
            line-height: 1.2;
            word-break: break-word;
        }

/* VIN: prevent weird bidi issues and keep it readable */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] #RR_Vehicle_VIN {
    unicode-bidi: plaintext;
}

/* =========================================================
   CBSInvoices RR / Details — Standard Loading / Empty labels
   ========================================================= */

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] .rr-sec-loading,
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] .rr-sec-empty,
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .rr-sec-loading,
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .rr-sec-empty {
    margin-top: 10px;
    margin-bottom: 10px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--muted);
    font-size: 12px;
    font-weight: 700;
    line-height: 1.2;
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] .rr-sec-loading,
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .rr-sec-loading {
    display: flex;
    align-items: center;
    gap: 10px;
}

    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="details"] .rr-sec-loading::before,
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .rr-sec-loading::before {
        content: "";
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background: color-mix(in srgb, var(--brand-primary) 45%, var(--muted));
        opacity: 0.8;
    }

/* =========================================================
   CBSInvoices RR — Help tab (cards + buttons)
   ========================================================= */

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help {
    margin-top: 12px;
    margin-bottom: 12px;
    display: grid;
    gap: 12px;
}

/* Card surface (matches the rest of your RR card language) */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-card {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 12px;
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-card-title {
    font-size: 12px;
    font-weight: 900;
    color: var(--ink);
}

/* Two-button row */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-actions {
    display: grid;
    grid-template-columns: 1fr;
}

/* Primary/secondary button links */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 40px;
    padding: 0 12px;
    margin-top: 10px;
    border-radius: 12px;
    border: 1px solid var(--border);
    background: color-mix(in srgb, var(--brand-primary) 10%, var(--surface));
    color: var(--ink);
    font-weight: 900;
    text-decoration: none;
    white-space: nowrap;
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-btn--secondary {
    background: var(--surface-subtle);
    color: var(--ink);
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-btn:hover {
    filter: brightness(1.02);
}

/* Text blocks */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-text {
    font-size: 13px;
    font-weight: 700;
    color: var(--ink);
    line-height: 1.25;
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-note {
    margin-top: 8px;
    margin-bottom: 8px;
    font-size: 12px;
    font-weight: 700;
    color: var(--muted);
    line-height: 1.25;
}

/* Bullet list */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-list {
    margin: 0;
    padding-left: 18px;
    display: grid;
    gap: 8px;
    color: var(--ink);
    font-size: 13px;
    font-weight: 500;
    line-height: 1.25;
}

    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-list em {
        font-style: italic;
        font-weight: 600;
    }

/* Registration link */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-link {
    display: block;
    margin-top: 10px;
    padding: 10px 12px;
    border-radius: 12px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--ink);
    font-weight: 900;
    text-decoration: none;
}

    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-link:hover {
        filter: brightness(1.02);
    }

/* Safeguards for width */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-card,
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-btn,
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-link {
    max-width: 100%;
    box-sizing: border-box;
}

    /* Help: prevent any child from forcing overflow */
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-card * {
        min-width: 0;
    }

/* Help inline icons */
#cbsRailRoot div.rr-help li svg {
    border: 1px solid var(--icon-outline);
    border-radius: 4px;
    padding: 1px;
    width: 16px;
    height: 16px;
}

/* Remove User Link */
#RR_Help_RemoveUserLink {
    color: var(--cbs-accent);
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    opacity: .9;
}

/* Help: visible copyable URL box (prevents overflow) */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="help"] .rr-help-url {
    max-width: 100%;
    box-sizing: border-box;
    margin-top: 10px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
    font-size: 12px;
    font-weight: 800;
    color: var(--ink);
    /* The actual fix: allow long strings to wrap */
    overflow-wrap: anywhere;
    /* TL-219: break-all, not break-word. An address with no spaces must break at ANY character to stay inside
       a narrow rail; break-word only breaks when a line has nowhere else to go and is not reliable inside a
       shrink-to-fit flex/grid parent. The box also clips rather than spilling past the card. */
    word-break: break-all;
    overflow: hidden;
    line-height: 1.35;
    user-select: all; /* one click selects the whole URL */
}

/* =========================================================
   CBSInvoices RR / Request tab — Styling (RR consistent)
   ========================================================= */

/* Allow ellipsis inside request fields (important for long emails in ResolvedBy) */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .cbs-rr-field > div {
    min-width: 0;
}

/* Render \n in request subtitle as line breaks (matches invoice subtitle behavior) */
body.cbs-invoices #RR_Request_Subtitle {
    white-space: pre-line;
    font-weight: 600;
    line-height: 1.15;
}


body.cbs-invoices #RR_Request_Subtitle2 {
    color: var(--muted);
    font-size: 0.78em;
    line-height: 1.15;
    margin-top: 2px;
}

/* Section cards */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .rr-section {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 12px;
    margin-top: 12px;
    margin-bottom: 16px;
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .rr-section-title {
    font-weight: 900;
    font-size: 12px;
    color: var(--muted);
    margin-bottom: 8px;
}

/* Status value */
body.cbs-invoices #RR_Request_Status {
    font-size: 14px;
    font-weight: 900;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}

/* Request fields (match Vehicle/Fleet stacked label style) */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .cbs-rr-field {
    display: grid;
    gap: 4px;
    padding: 6px 0;
}

    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .cbs-rr-field > label:not(.switch) {
        margin: 0;
        font-size: 12px;
        font-weight: 900;
        color: var(--muted);
        line-height: 1.1;
    }

    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .cbs-rr-field input,
    body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .cbs-rr-field textarea {
        font-size: 13px;
        font-weight: 700;
    }

/* Thread styling */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .rr-thread {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .cbs-rr-msg {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 10px 12px;
}

body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .cbs-rr-msg-text {
    font-size: 13px;
    font-weight: 650;
    color: var(--ink);
    line-height: 1.25;
    white-space: normal;
    word-break: break-word;
}

/* Message meta wrapper: two-line layout (by / when) */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .cbs-rr-msg-meta {
    display: grid;
    gap: 2px;
    margin-bottom: 6px;
}

/* Username line: strong + ellipsis */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .cbs-rr-msg-by {
    font-size: 12px;
    color: color-mix(in srgb, var(--ink) 50%, var(--muted)); /* ink-leaning */
    font-weight: 800; /* not 900 */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

/* Date/time line: lighter */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .cbs-rr-msg-when {
    font-size: 12px;
    font-weight: 700;
    color: var(--muted);
    opacity: 0.9;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

/* Request: make the Message field feel primary (New + Reply) */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] label[for="RR_Request_Comment"],
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] label[for="RR_Request_ReplyText"] {
    color: var(--ink); /* stronger than muted */
    font-weight: 900; /* match your heading weight */
}

/* The Message textareas use the rail's standard input look (rightrail.css: #RightRailContent textarea, the same as Amount and
   every other rail field: --surface background, --border border, the standard focus ring). The page used to give them a grey
   fill, a darker border and its own focus outline, which made them the one odd field in the app (2026-10-16). */

body.cbs-invoices #RR_Request_Status.rr-status-none {
    color: var(--icon-muted, var(--muted));
}

body.cbs-invoices #RR_Request_Status.rr-status-open {
    color: var(--icon-warning, var(--warning));
}

body.cbs-invoices #RR_Request_Status.rr-status-resolved {
    color: var(--icon-success, var(--success));
}

/* Responsive rules preserved (small screens) */
@media (max-width: 1024px) {
    body.cbs-invoices .cbs-grid-right .btn:not(.cbs-pay-btn) {
        display: none;
    }

    body.cbs-invoices .cbs-pay-btn {
        order: 2;
    }
}

/* ============================================================
   CHOICE MODAL (saved profile) – targeted improvements
   ============================================================ */
#authorizeProfilePayment .modal-body .text-muted {
    font-size: 13px;
    line-height: 1.35;
    color: var(--muted);
    margin-top: 10px;
    /* Make it feel like an intentional note */
    background: color-mix(in srgb, var(--surface) 92%, var(--hover-chip));
    border: 1px solid var(--border);
    border-left: 3px solid color-mix(in srgb, var(--brand-primary) 70%, var(--border));
    border-radius: 10px;
    padding: 10px 12px;
}

#authorizeProfilePayment .modal-footer {
    display: grid;
    grid-template-columns: 1fr; /* stack by default (mobile / narrow) */
    gap: 10px;
    margin-top: 14px;
}

    /* Make buttons feel consistent & tap-friendly */
    #authorizeProfilePayment .modal-footer .btn {
        min-height: 44px;
        padding: 10px 14px;
        border-radius: 12px;
        line-height: 1.15;
    }

    /* Primary action: full width and slightly more prominent */
    #authorizeProfilePayment .modal-footer .btn-primary {
        width: 100%;
        font-weight: 700;
        letter-spacing: .1px;
    }

    /* Secondary buttons: allow wrap but avoid “word-per-line” look */
    #authorizeProfilePayment .modal-footer .btn-secondary {
        white-space: normal;
        text-align: center;
    }

/* Two-column layout on wider modals */
@media (min-width: 560px) {
    #authorizeProfilePayment .modal-footer {
        grid-template-columns: 1fr 1fr;
    }

        /* Primary spans both columns */
        #authorizeProfilePayment .modal-footer .btn-primary {
            grid-column: 1 / -1;
        }

    /* Cancel can sit bottom-right without looking like a “big action” */
    #authorizeProfilePayment #authorizeProfileCancelButton {
        grid-column: 2;
    }
}


#authorizeProfilePayment .form-group {
    margin: 14px 0 0;
}

    #authorizeProfilePayment .form-group .switch {
        display: flex; /* use full row */
        align-items: center;
        gap: 12px;
    }

        #authorizeProfilePayment .form-group .switch span:last-child {
            font-weight: 650;
            color: var(--ink);
            line-height: 1.2;
            /* prevent weird micro-wrapping */
            white-space: normal;
        }

/* Ensure slideout positions relative to the chooser modal content */
#authorizeProfilePayment .modal-content {
    position: relative;
    overflow-x: hidden;
    overflow-y: auto; /* keep vertical scrolling for tall content */
    /* PAY-74: the More options flyout is absolutely positioned inside this card, so the card must be
       at least as tall as the flyout (top 66px + header + two buttons + note, about 410px). Removing the
       'Always use saved method' switch made the card shorter than the flyout, which clipped it and
       added a scrollbar. The viewport cap keeps short screens scrolling instead of overflowing. */
    min-height: min(340px, calc(100vh - 32px));
}

/* Tighten footer to a single primary CTA for chooser */
#authorizeProfilePayment .modal-footer {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
}

/* Prefer full-width primary in chooser */
#authorizeProfilePayment .btn.btn-primary,
#authorizeProfilePayment input.btn.btn-primary {
    width: 100%;
}

/* Breathing room for the preference toggle */
#authorizeProfilePayment .pay-pref {
    margin-top: 14px;
}

#authorizeProfilePayment .pay-pref-row {
    gap: 12px;
}

@media (max-width: 640px) {
    body.cbs-invoices .cbs-grid-header-row {
        grid-template-columns: 1fr;
        grid-template-areas: "left" "center" "right";
        gap: 8px;
    }

    body.cbs-invoices .cbs-grid-center {
        justify-content: flex-start;
    }
}

/* =========================================================
   TL-18: CBS AutoPay settings page
   Two settings cards following the CBSBillingContact pattern. The inline styles that used to sit in
   CBSAutoPay.aspx live here instead.
   ========================================================= */

.autopay-form {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.autopay-card .card-content {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

/* The whole form reads as inactive while AutoPay is off (the inputs are disabled by the page script). */
.autopay-form.is-inactive .autopay-card .card-content {
    opacity: .55;
}

.autopay-form.is-inactive .form-row-toggle {
    opacity: 1; /* the switch itself stays fully legible */
}

.form-row-toggle {
    display: flex;
    align-items: center;
    gap: 12px;
}

.autopay-input,
.autopay-field-narrow {
    max-width: 265px;
}

.field-hint {
    display: block;
    margin: 6px 0 0 0;
    font-size: 13px;
    color: var(--muted);
}

/* Frequency choice: a row of radios, not the off-screen list the report scheduler uses. */
.autopay-frequency {
    margin-bottom: 0;
}

/* Revealed sub-options belong to the choice above, so they are shaded and indented. */
.autopay-suboptions {
    margin-top: 12px;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-2);
}

    .autopay-suboptions[hidden] {
        display: none;
    }

.autopay-suboptions-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--muted);
    margin-bottom: 10px;
}

.autopay-nextrun {
    margin: 12px 0 0 0;
    font-size: 14px;
    font-weight: 600;
}

.autopay-nextrun:empty {
    display: none;
}

/* Payment-method requirement: a notice with an action, not a muted line. */
.autopay-notice {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 14px 16px;
    border: 1px solid var(--warning-border);
    border-left-width: 4px;
    border-radius: 8px;
    background: var(--warning-surface);
}

    .autopay-notice .notice-body {
        display: flex;
        flex-direction: column;
        gap: 2px;
    }

    .autopay-notice[hidden] {
        display: none;
    }

/* Footer: Save and Cancel at normal button width, Save last. */
.autopay-actions {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
}

@media (max-width: 640px) {
    .autopay-notice {
        flex-direction: column;
        align-items: flex-start;
    }

    .autopay-actions {
        flex-direction: column-reverse;
        align-items: stretch;
    }
}

/* =========================================================
   CBS-06 2026-09-18: vertical space on a short screen.
   At 1280x800 the grid had 219px of row area and showed five rows.
   (a) short brand band, (c) card padding 24 -> 12 and (d) denser rows are
   all scoped to the same height breakpoint, so nothing changes on a tall
   screen. (b) - one totals row when the result set is a single page - is in
   CBSInvoices.aspx.cs, because it depends on PageCount.
   ========================================================= */

/* (c) The card gives back 24px of its own padding whatever the height. */
body.cbs-invoices .page-body > .card.cbs-grid-card {
    padding-block: 12px;
}

@media (max-height: 900px) {
    /* (a) CBS-35 2026-09-20: the brand-band compression that used to be repeated here - logo
       at 32px, tighter --tb-pad-y and --tb-gap, contact block on one line - now lives ONCE, in
       the @container cbsband (max-width: 1100px) block above, keyed on the band's own width.
       WHAT THAT COSTS, so it is a decision and not an accident: a SHORT BUT WIDE screen - a
       1600x760 laptop, where the band is about 1360 wide - no longer gets it, so the band
       stays at its full 148px there instead of compressing to about 100. Everything narrow is
       better off; only short-and-wide is worse. Restoring it means repeating the five
       declarations here, which is the duplication this removed. */

    body.cbs-invoices .cbs-topband.card {
        margin-bottom: 8px !important;
    }

    /* (d) Denser rows: padding-block 10 -> 6 takes a row from 43px to 35px.
       Scoped to the same breakpoint, so the comfortable row height is still
       what a full-height screen gets. */
    body.cbs-invoices #GridView1 tbody > tr > td {
        padding-block: 6px;
    }

    body.cbs-invoices #GridView1 {
        --cbs-totals-row-h: 34px;
    }
}

/* =========================================================
   CBS-07 the right rail as a 48px icon strip.
   Rewritten 2026-09-19 (CBS-18) after the captures showed why it never appeared.

   Scoped to this page twice over: every selector below starts with
   body.cbs-invoices.cbs-rail-strip, and cbs-rail-strip is only ever added by
   CBSInvoices.aspx.cs. Users Edit, Store Groups and every other page that uses
   the rail are untouched - they never carry the class, so none of these rules
   can match.

   WHY IT NEVER APPEARED, twice reported fixed. The closed-state block used to
   hide everything in the rail except the tabs with

       #RightRailContent > *:not(.rr-tabs) { display: none }

   but .rr-tabs is not a child of #RightRailContent. Site.master:239-243 renders
   #RightRail > #RightRailContent > <ContentPlaceHolder>, and this page's rail
   content begins with <div id="cbsRailRoot" class="cbs-rr"> (CBSInvoices.aspx),
   with .rr-tabs inside THAT. So the selector matched #cbsRailRoot - which is not
   .rr-tabs - and display:none'd the whole rail content, icons included. The rail
   element itself still got its 48px from the rule below, which is exactly what
   the captures show: railWidth 48 with nothing in it. Restoring opacity and
   transform, then visibility and pointer-events, could never have helped; those
   rounds fixed real problems on the wrong element.

   Second, smaller cause, which would have bitten as soon as the first was fixed:
   #RightRailContent carries 24px of side padding (rightrail.css:84) and .rr-tabs
   bleeds out of it with -24px margins. In a 48px strip that leaves no content
   width at all, so the icons had to have their gutters removed too.

   WIDTH RANGE, changed 2026-09-19 on the developer's request: the closed strip
   now applies at EVERY width, not only below 1440. Closing the rail always
   leaves the five icons reachable. The overlay behaviour for the OPEN rail stays
   below a breakpoint - at and above it an open rail is still docked and still
   takes its own column, exactly as before.

   CBS-69 2026-09-28: THAT BREAKPOINT IS NOW 1765, NOT 1439. See the CBS-69 block
   at the media query itself, and the CBS-69 section of the CBS-37 note further up
   for the viewport floor that had to move with it.
   ========================================================= */

/* ---- closed: the strip, at every width -------------------------------- */

/* The closed rail keeps a strip instead of collapsing to 0. This overrides
   body.rr-enabled.close-rail.rr-reclaim from layout.css. */
body.cbs-invoices.cbs-rail-strip.rr-enabled.close-rail.rr-reclaim,
body.cbs-invoices.cbs-rail-strip.rr-enabled.rr-reclaim.rr-closing {
    --layout-rail-col: var(--rail-strip-width, 48px);
}

/* CBS-34 2026-09-19: and the same width for the appbar and the footer, in EVERY rail state.
   Deliberately no state class - this page's closed column is the 48px strip whether the rail is
   open, closed or mid-transition, and the appbar and footer are supposed to hold that value
   throughout so opening the rail moves only the content track. It pairs with the three
   state-independent rules in layout.css; without this one CBS Invoices would fall back to the
   rr-reclaim rule there, take 0, and its appbar would sit 24px off the content at 1920. */
body.cbs-invoices.cbs-rail-strip.rr-enabled.rr-reclaim {
    --layout-rail-col-static: var(--rail-strip-width, 48px);
}

/* rightrail.css:68 hides a closed rail with four properties - opacity, transform,
   visibility and pointer-events. All four have to come back, or the strip is an
   empty column that cannot be clicked. */
body.cbs-invoices.cbs-rail-strip.close-rail .right-rail {
    display: flex;
    flex-direction: column;
    width: var(--rail-strip-width, 48px);
    min-width: var(--rail-strip-width, 48px);
    opacity: 1;
    transform: none;
    visibility: visible;
    pointer-events: auto;
    overflow: visible;
    padding: 0;
}

/* The panel's own gutters do not fit in 48px. */
body.cbs-invoices.cbs-rail-strip.close-rail #RightRailContent {
    padding: 0;
    overflow: visible;
    scrollbar-gutter: auto;
}

/* The page's rail wrapper: keep it, size it to the strip. Hiding it was the bug. */
body.cbs-invoices.cbs-rail-strip.close-rail #cbsRailRoot {
    display: block;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}

/* CBS-20: the rail header is a 69px sticky toolbar (--rr-toolbar-h, cbs.css:7) painted in
   --surface, sized for a 280px panel. In the strip it drew a white block behind the FIRST
   icon - which is also the active one - while the other four overflowed below it, reading as
   active-state styling when it was really the toolbar. In the strip the header IS the strip,
   so it gets no height, no sticky and no background of its own; .right-rail already provides
   the surface, the border and the radius. */
body.cbs-invoices.cbs-rail-strip.close-rail .cbs-rr-header {
    display: block;
    height: auto;
    position: static;
    background: transparent;
    z-index: auto;
}

body.cbs-invoices.cbs-rail-strip.close-rail #cbsRailTitle {
    display: none;
}

/* Hide the PANELS, never the wrapper that holds the tabs. */
body.cbs-invoices.cbs-rail-strip.close-rail .rr-state,
body.cbs-invoices.cbs-rail-strip.close-rail .right-rail-header,
body.cbs-invoices.cbs-rail-strip.close-rail .right-rail-close,
body.cbs-invoices.cbs-rail-strip.close-rail .right-rail-actions {
    display: none;
}

body.cbs-invoices.cbs-rail-strip.close-rail .rr-tabs {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    width: 100%;
    margin: 0;
    padding: 12px 0;
    border-bottom: 0;
    /* CBS-20: no background and no height of its own. Both belonged to the 280px panel and
       both painted the block the developer saw. .right-rail supplies the surface. */
    background: transparent;
    border-left: 0;
    height: auto;
    box-sizing: border-box;
}

/* The icons keep their own focus ring, so keyboard users can tab into the
   strip and open a panel from it exactly as they can when the rail is open. */
body.cbs-invoices.cbs-rail-strip.close-rail .rr-tabs > * {
    flex: 0 0 auto;
}

/* ---- open: overlay, below 1766 ----------------------------------------
   CBS-69 2026-09-28: WAS 1439. Raised to 1765 on the developer's design decision, and the
   rationale is recorded at the CBS-69 block further up this file - read it before changing
   this number, because a floating rail COVERING the grid is the intended behaviour and not a
   compromise. 1765 is the width at which a docked rail first forces a horizontal scrollbar
   on a CBS employee's grid, so from here down the grid keeps its full width instead.
   ---------------------------------------------------------------------- */

@media (max-width: 1765px) {

    /* CBS-21: at overlay widths the rail contributes NO layout width, in any state -
       open, closed, opening or closing. Deliberately no state class in the selector.
       The old rule keyed on .show-rail, and .layout-body transitions
       grid-template-columns, so any frame where the body carries none of show-rail /
       close-rail / rr-closing fell back to the :root default (theme.css:118,
       --rail-width 280px) and the grid started animating towards a docked rail before
       snapping back. MT_OpenRightRail leaves exactly that gap: it removes close-rail and
       adds show-rail one requestAnimationFrame later. Specificity (0,4,1) clears every
       rail rule in layout.css, whose highest is (0,3,1). */
    body.cbs-invoices.cbs-rail-strip.rr-enabled.rr-reclaim {
        --layout-rail-col: var(--rail-strip-width, 48px);
    }

    /* Same reasoning for the element: :not(.close-rail) spans open, closing and the
       in-between frames, so the rail can never fall back to the docked base - position
       sticky at var(--rail-width) inside the 48px track - part way through a transition.
       Only the fully closed state leaves this rule, and that is the strip. */
    body.cbs-invoices.cbs-rail-strip:not(.close-rail) .right-rail {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        width: var(--rail-width);
        z-index: 40;
        background: var(--surface);
        box-shadow: var(--shadow-2);
        overflow: auto;
    }

    body.cbs-invoices.cbs-rail-strip .layout-body {
        position: relative;
    }

    /* Header chip vs the floating card: nothing to do here. appbarAlign.js measures the card wherever it is
       (docked, or this floating one anchored to the viewport edge) and the chip follows it. */
}

/* =========================================================
   CBS-04 round six, 2026-09-18
   ========================================================= */

/* (5) The grid-wrapper draws its border and header band as ::before/::after overlays
   pinned to the wrapper, which is the unscrolled box. When the table is wider than the
   wrapper and the user scrolls sideways, the overlay stays put while the table moves, so
   the right-hand edge lands inside the REQ column. On this page the table carries its own
   edge instead, which scrolls with it. */
body.cbs-invoices .grid-wrapper::before,
body.cbs-invoices .grid-wrapper::after {
    display: none;
}

/* CBS-33 2026-09-19: and that border never drew.

   The rule below has been here since CBS-04 round six and has never rendered a frame.
   It is not a specificity problem - it beats datagrid.css outright - and it is not the
   collapsing border model either, which was the first guess and is wrong: measured
   against the developer's captured DOM, the border stayed at 0px/none with
   border-collapse forced to separate.

   The GridView renders its own INLINE STYLE, and an inline style beats every author
   rule that is not !important. From the capture:

     <table class="table-modern" ... border="0" id="GridView1"
            style="border-width: 0px; border-style: none; border-collapse: collapse; ...">

   which is ASP.NET emitting BorderWidth="0", BorderStyle="None", GridLines="None" and
   CellSpacing="0" from CBSInvoices.aspx:263-274. That inline declaration sets the WIDTH
   and the STYLE but not the COLOUR, which is why the computed border read
   "0px none rgb(230,234,240)" - the colour below was applying, the other two were being
   overruled - and why border-radius applied cleanly at 12px while the border itself
   stayed invisible. It looks exactly like a rule that ought to be working.

   So !important is not decoration here. It is the only way CSS can beat an inline style,
   and the alternative - dropping the four attributes in the markup - cannot be verified
   without re-rendering the page, and would still leave border-collapse inline because
   CellSpacing="0" emits it on its own. Tidying the markup is left as a follow-up.

   border-collapse: separate is TL-49's finding: border-radius has no effect on a table
   in the collapsing border model. border-spacing: 0 keeps the cells flush, so nothing
   moves except the corners. */
body.cbs-invoices #GridView1 {
    border: var(--grid-border-width) solid var(--grid-border-color) !important;
    border-radius: var(--grid-radius);
    border-collapse: separate !important;
    border-spacing: 0;
}

/* The corner CELLS have to be rounded too, or their own backgrounds paint square over
   the curve.

   TOP: already done - datagrid.css:85-91 rounds thead th:first-child and :last-child.
   Those are .col-selector-head and .col-reqstate-head here, and they are the first and
   last visible header cells in ALL THREE ROLES: the role filter hides Entity (column 2)
   for franchisees and Entity plus Fleet # (columns 2 and 6) for fleet managers
   (CBSInvoices.aspx.cs:110 and :114), both interior, and a GridView column with
   Visible = false is not rendered at all rather than display:none'd - so the cells that
   sit at the two ends never change.

   BOTTOM: the last row of this table is in TFOOT, not TBODY - ShowFooter is on and the
   totals, grand-total and pager rows all live there - so datagrid.css:43-49, which
   rounds the last TBODY row, never reaches the bottom edge. The pager row is one
   colspan cell, so first-child and last-child are the same cell and both corners land
   on it; when there is no pager the totals row takes over and the two rules split. The
   :has() pair is the fallback for a table rendered without a footer at all, matching the
   empty-state handling that already uses :has() further down this file. */
body.cbs-invoices #GridView1 > tfoot > tr:last-child > td:first-child {
    border-bottom-left-radius: var(--grid-radius);
}

body.cbs-invoices #GridView1 > tfoot > tr:last-child > td:last-child {
    border-bottom-right-radius: var(--grid-radius);
}

body.cbs-invoices #GridView1:not(:has(> tfoot)) > tbody > tr:last-child > td:first-child {
    border-bottom-left-radius: var(--grid-radius);
}

body.cbs-invoices #GridView1:not(:has(> tfoot)) > tbody > tr:last-child > td:last-child {
    border-bottom-right-radius: var(--grid-radius);
}

/* (1) A single-page result has no pager and no grand-total row, so the one totals row must
   not reserve space for either. Without this it pinned 42px above the bottom and left an
   empty band under itself. The fallback is 0, not 44: if the script has not run yet, no
   gap is better than a phantom pager. */
body.cbs-invoices #GridView1 > tfoot > tr.cbs-totals-row.cbs-totals-only > td {
    --grid-tfoot-offset: var(--cbs-pager-h, 0px);
}

body.cbs-invoices #GridView1 > tfoot > tr.cbs-totals-row > td {
    --grid-tfoot-offset: calc(var(--cbs-pager-h, 0px) + var(--cbs-totals-row-h));
}

body.cbs-invoices #GridView1 > tfoot > tr.cbs-grand-row > td {
    --grid-tfoot-offset: var(--cbs-pager-h, 0px);
}

/* (2) VIN takes the slack before the spacer does. The spacer is still the only column
   without a width, so it absorbs whatever is left - but VIN steps up from its 130px floor
   to its natural 173px as soon as the grid is wide enough to hold the whole set at that
   size. One rule per role, keyed on the role class the page puts on the body:

     with VIN at 173, the full set is  CBS staff 1341   franchisee 1201   fleet 1111
   -------------------------------------------------------------------- */
body.cbs-invoices .card.card-scroll > .card-content {
    container-type: inline-size;
    container-name: cbsgrid;
}

/* TL-169: 190px, up from 173px. 173 was measured from one VIN and did not fit a wide-glyph one
   - the reported "3GCNWAEF3MG387734" against "1N6BD0CT1JN749877". Tabular figures above make
   every VIN the same width; this is the width they all now need, with a little headroom so a
   font change does not silently reintroduce the ellipsis. The tier thresholds below move by the
   same 17px for the same reason. */
@container cbsgrid (min-width: 1358px) {
    body.cbs-cols-staff #GridView1 .col-vin-head,
    body.cbs-cols-staff #GridView1 .col-vin {
        width: 190px;
    }
}

/* TL-169: 173 -> 190 and the threshold up by the same 17, as above. The three thresholds are
   the full column set measured with VIN at its stepped-up width, so they have to move together
   with it or the step-up would fire before the set fits. */
@container cbsgrid (min-width: 1218px) {
    body.cbs-cols-franchisee #GridView1 .col-vin-head,
    body.cbs-cols-franchisee #GridView1 .col-vin {
        width: 190px;
    }
}

@container cbsgrid (min-width: 1128px) {
    body.cbs-cols-fleet #GridView1 .col-vin-head,
    body.cbs-cols-fleet #GridView1 .col-vin {
        width: 190px;
    }
}

/* =========================================================
   CBS-10(a)(b) empty result set, 2026-09-18
   ShowHeaderWhenEmpty is on, so an empty result keeps its column headings and
   puts EmptyDataText in one cell underneath. Two things were wrong with it.
   ========================================================= */

/* (a) The cell now spans the visible columns (GridView1_RowCreated), but the grid's own
   rules put nowrap + overflow:hidden on every td, which would clip a sentence. Let this
   one wrap, centre it, and give it room to read as a state rather than a stray value. */
body.cbs-invoices #GridView1 td.cbs-empty-cell {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    text-align: center;
    padding-block: 32px;
    color: var(--muted);
    font-size: 14px;
}

/* While the list is being fetched (the grid area is the content-area loader host, UI_STANDARDS 4.4.8; cbsinvoices.js sets aria-busy) the
   "Loading invoices..." placeholder is hidden: loaders show only the mark (the hidden status line says it), and visibility keeps the row's
   height so nothing jumps when the rows land. The table's own border is the grid's edge on this page (CBS-33), so while loading the empty table
   is as tall as the loader region (12rem, the content-loader host's minimum): the mark sits INSIDE the bordered grid, not across its edge. */
body.cbs-invoices .grid-wrapper[aria-busy="true"] td.cbs-empty-cell {
    visibility: hidden;
}

body.cbs-invoices .card.card-scroll.cbs-grid-card .grid-wrapper[aria-busy="true"] #GridView1 {
    min-height: 12rem;
}

/* (b) With no rows the card still stretched, leaving a large empty area under the message.
   :has() is evaluated live, so this follows the UpdatePanel without a server class or a
   JS hook - and a browser without :has() simply keeps today's behaviour. The minimum
   stops the card collapsing to a sliver. */
body.cbs-invoices .card.card-scroll.cbs-grid-card:has(.cbs-empty-row) {
    flex: 0 0 auto;
    height: auto;
    min-height: 0;
    max-height: none;
}

body.cbs-invoices .card.card-scroll.cbs-grid-card:has(.cbs-empty-row) > .card-content {
    flex: 0 0 auto;
    height: auto;
    min-height: 0;
    overflow: visible;
}

body.cbs-invoices .card.card-scroll.cbs-grid-card:has(.cbs-empty-row) #GridView1 {
    min-height: 140px;
}

/* =========================================================
   TL-39 store-picker validation in the Filters rail, 2026-09-19
   The card, the .field-error highlight and the wording all come from the report
   parameters pane. Only these three adjustments are new.
   ========================================================= */

/* 1. The summary card sits at the TOP of the panel, above the picker, so the message
      is visible without scrolling - which was the whole complaint. */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] #validationSummary {
    margin-bottom: 12px;
}

/* 2. MT_Validation.highlightFields puts .field-error on the picker's root container. The
      shared rule carries font-size and margin-top as well as the colour, which would nudge
      the tree; inside the rail only the colour is wanted. The node labels set no colour of
      their own, so they inherit it and the tree turns red, which is the cue asked for. */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .store-picker.field-error {
    font-size: inherit;
    margin-top: 0;
}

/* 3. The picker's own inline message is now redundant - the card says it, at the top. Left in
      the control for every other page that uses it, hidden only here. */
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="filters"] .store-picker-validation {
    display: none !important;
}

/* =========================================================
   CBS-23 / CBS-24 REMOVED 2026-09-19 (CBS-32).

   This page used to put the five-column template back for .layout-body, and then
   again for .appbar-inner and .footer-inner, below 1100 - because layout.css
   collapsed all three to a single column there and the strip had no column to sit
   in. layout.css no longer collapses them: the rail column is opt-in and resolves to
   zero for a page that has not asked for one, so the template is correct at every
   width for every page and the override is redundant.

   Keeping it would have been a second mechanism doing the same job, which is how
   this took three rounds in the first place.
   ========================================================= */

/* =========================================================
   PAY-46 - the Pay button after a charged-but-not-recorded
   payment. The card HAS been charged; pressing this again
   would charge it twice, so it is dead for the rest of this
   modal session and must look it. Close is the only action.
   ========================================================= */
.is-sealed .btn,
.is-sealed button,
.is-sealed input[type="button"],
.is-sealed input[type="submit"] {
    opacity: 0.55;
    cursor: not-allowed;
    pointer-events: none;
    filter: grayscale(1);
}

.is-sealed .btn-overlay-text {
    display: none;
}

/* Money field in the request rail (UI_STANDARDS 6.8): the $ sits inside the control. Same look as .rq-money in requests.css (not loaded on this page). */
body.cbs-invoices #RR_Request_New .rr-money { position: relative; }
body.cbs-invoices #RR_Request_New .rr-money-sign { position: absolute; left: 12px; top: 0; bottom: 0; display: flex; align-items: center; color: var(--muted); font-size: 16px; pointer-events: none; }
body.cbs-invoices #RightRailContent .rr-state[data-rr-state="request"] .cbs-rr-field .rr-money input.rr-money-input {
    height: 40px;
    min-height: 40px;
    padding: 0 12px 0 28px;
    font-size: 16px;      /* no iOS zoom */
    font-weight: 700;
    text-align: left;
    font-variant-numeric: tabular-nums;
}

/* CBS-89 NTV (lane N1): the small "Not our vehicle" box in the request form. A quiet checkbox line, not a heading. */
body.cbs-invoices #RR_Request_New .rr-ntv-check {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 400;
    font-size: inherit;    /* the rail's normal size, as the other field labels */
    white-space: nowrap;   /* one line at every rail width: "Not their vehicle (NTV)" */
    opacity: .7;           /* a tertiary option */
    cursor: pointer;
}

body.cbs-invoices #RR_Request_New .rr-ntv-check:hover,
body.cbs-invoices #RR_Request_New .rr-ntv-check:focus-within {
    opacity: 1;
}

body.cbs-invoices #RR_Request_New .rr-ntv-check input[type="checkbox"] {
    width: auto;
    margin: 0;
}

/* The "Include closed / Include snoozed" ticks on the NTV list (CBSNtvList.aspx) state their own look: 16px, brand colour, centred on the label.
   They used to borrow it from a bare rightrail.css rule (checkbox-leaks_handoff.md). */
.ntv-filter-check input[type="checkbox"] {
    width: 16px;
    height: 16px;
    margin: 0 4px 0 0;
    vertical-align: middle;
    accent-color: var(--brand-primary);
}

/* The helper line under the NTV box sits close to it */
body.cbs-invoices #RR_Request_NotRecognizedRow .microtext { margin: 2px 0 0 24px; }

/* Staff NTV status: one quiet chip line, only when a case exists (the script toggles hidden) */
body.cbs-invoices .rr-ntv-line { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
body.cbs-invoices .rr-ntv-line[hidden] { display: none; }

/* CBS-89 K3b: the note after the NTV box is sent; hidden until the script shows it */
body.cbs-invoices #RR_Request_NtvSent { display: none; margin: 0 0 8px; }
body.cbs-invoices #RR_Request_NtvSent.is-shown { display: block; }

/* Request panel header (rr-header, 2026-10-17): the title is "Request {id}" and a link to the full page (mouse and touch only, tabindex -1);
   the explicit "View request details" link under the subtitle is the one tab stop. Both hidden or plain text until the script has a case id the
   person may open. The icon is the Phosphor arrow-up-right (#ph-arrow-up-right in Images/Icons/notice-icons.svg; navigation arrow, UI_STANDARDS 9; same tab, so not an open-in-new-tab glyph). 44px tap row. */
body.cbs-invoices .rr-open-full { display: none; margin: 0; }
body.cbs-invoices .rr-open-full.is-shown { display: flex; align-items: center; min-height: 44px; }
body.cbs-invoices .rr-open-full-link { display: inline-flex; align-items: center; gap: 4px; min-width: 0; opacity: 1; }
body.cbs-invoices .rr-open-full-link .icon { flex: none; width: 14px; height: 14px; }
body.cbs-invoices .rr-title-link { color: inherit; font-weight: inherit; opacity: 1; }
body.cbs-invoices .rr-title-link:hover,
body.cbs-invoices .rr-title-link:focus-visible { font-weight: inherit; text-decoration: underline; }

/* Billing Contact: a 12-column field grid from 640 wide and a wider card from 768 (designer review 2026-10-15). A long single column of 11 fields
 was four screens tall on a short laptop; related fields (city, state, zip; phone, mobile, fax) now share a row. Under 640 it is the single column. */
@media (min-width: 640px) {
    .bc-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 16px 20px; align-content: start; }
    .bc-grid > .form-row { margin-bottom: 0; }
    .bc-grid > .bc-12 { grid-column: span 12; }
    .bc-grid > .bc-6 { grid-column: span 6; }
    .bc-grid > .bc-5 { grid-column: span 5; }
    .bc-grid > .bc-4 { grid-column: span 4; }
    .bc-grid > .bc-3 { grid-column: span 3; }
    .bc-grid > :not(.form-row) { grid-column: span 12; }
}
@media (min-width: 768px) {
    .bc-page.page-form { max-width: 880px; }
    .bc-page .card.card-scroll { max-width: 880px; width: 100%; }
}

/* the State select shows "District of Columbia" in full (City 4, State 5, Zip 3), and the page gets bottom room so Cancel and Save are never flush with the edge */
.bc-page { padding-bottom: 24px; }
.bc-grid select.input { min-width: 0; text-overflow: clip; }

/* Billing Contact: the footer says why Save is off, a token input shows the standard error state, and the sticky footer is opaque across the card */
.bc-page .form-actions { display: flex; gap: 12px; align-items: center; justify-content: flex-end; flex-wrap: wrap; width: 100%; }
.bc-save-hint { margin-right: auto; color: var(--muted); }
.bc-grid .token-input.field-error { border-color: var(--danger); background: var(--surface-danger); }
.bc-grid .token-input.field-error .token-entry { background: transparent; }
.bc-grid .field-error-msg { min-height: 0; color: var(--danger); font-size: 13px; margin-top: 4px; }
.bc-grid .field-error-msg:empty { display: none; }

/* BILLING CONTACT FOOTER (2026-10-15): the sticky footer is the card's own width, no negative margins (they pushed it 16px past the card), opaque with a top line. */

/* CBS HEADER BAND CHIPS (Payment method, AutoPay): the chip grows with its content. A fixed height cut the Replace and Enable buttons by 2px at 1280x574. */
.cbs-topband-right .paymentmethod-card,
.cbs-topband-right .autopay-card { height: auto; min-height: var(--topband-chip-h); }

/* CBS INVOICES: on a short window the grid card no longer keeps a 560px floor (it left a blank area under three rows); it hugs its content with a
   280px minimum for the grid and the page scrolls when it is taller. */

/* BILLING CONTACT, ROUND 3 (2026-10-15). The status band (BAID, payment method, AutoPay) is not needed here, so the page is one card that scrolls
   INSIDE itself with its footer pinned, not a page that scrolls. The card sits inside an UpdatePanel div (display: contents), so the child selectors
   of the shared rules never matched; these are written for that wrapper. */
.bc-page .cbs-topband { display: none; }
.bc-page.page-form > div[id] > .card.card-scroll {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    max-height: 100%;
}
.bc-page.page-form > div[id] > .card.card-scroll > .card-content { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.bc-page.page-form > div[id] > .card.card-scroll > .card-header,
.bc-page.page-form > div[id] > .card.card-scroll > .card-footer { flex: none; }
.bc-page.page-form > div[id] > .card.card-scroll > .card-footer { margin: 0; padding: 8px 0 0; border-top: 1px solid var(--border); }

/* CBS INVOICES: the grid card hugs its rows instead of filling the window with an empty area under three of them (the page scrolls when it is taller) */

/* CBS INVOICES, FLEET VIEW, narrow container (2026-10-15): the column set needs 1069px and a 1280 window gives the grid 1047, which drew a bare
   horizontal scrollbar line under the totals. Below the VIN step-up threshold (1128) the VIN column is 23px narrower, so the set fits. */
.cbs-grid-card > .card-content { min-height: 0; }

/* CBS INVOICES, ROUND 4: the shared short-window rule (layout.css) gives a grid card height 100% and a 560px floor. This page is mostly three to ten
   rows, so the card takes its content height instead and the page scrolls when it is taller. Written with the same body and page-body prefix so
   it wins on specificity, not on order. */
@media (max-height: 700px) {
    body.grid-wide.cbs-invoices .page-body:not(.page-scroll) > .card.card-scroll.cbs-grid-card { height: auto; min-height: 0; flex: 0 0 auto; }
}
/* the grid is 23px wider than the card at 1280 and showed a bare scrollbar line: a little less cell padding makes it fit up to the 1366 laptops */
@media (max-width: 1400px) {
    .cbs-grid-card { --grid-cell-padding-x: 8px; }
}

@container cbsgrid (max-width: 1127.98px) {
    body.cbs-cols-fleet.cbs-invoices #GridView1 .col-amount-head,
    body.cbs-cols-fleet.cbs-invoices #GridView1 .col-amount,
    body.cbs-cols-fleet.cbs-invoices #GridView1 .col-adjustment-head,
    body.cbs-cols-fleet.cbs-invoices #GridView1 .col-adjustment,
    body.cbs-cols-fleet.cbs-invoices #GridView1 .col-latefee-head,
    body.cbs-cols-fleet.cbs-invoices #GridView1 .col-latefee,
    body.cbs-cols-fleet.cbs-invoices #GridView1 .col-payment-head,
    body.cbs-cols-fleet.cbs-invoices #GridView1 .col-payment,
    body.cbs-cols-fleet.cbs-invoices #GridView1 .col-balance-head,
    body.cbs-cols-fleet.cbs-invoices #GridView1 .col-balance { width: 92px; }
}

/* CBS INVOICES, short windows (page scrolls): (1) the sticky action bar covers a 2px strip above itself so no grid row shows over it;
   (2) when the grid fits sideways the card content is released and the column headers pin just under the action bar. */
@media (max-height: 700px) {
    body.cbs-invoices .cbs-grid-card > .card-header { box-shadow: 0 -2px 0 var(--surface); }
    body.cbs-invoices .cbs-grid-card > .card-content.no-hscroll { overflow: visible; }
    body.cbs-invoices .cbs-grid-card > .card-content.no-hscroll .grid-wrapper { overflow: visible; }
    body.cbs-invoices .cbs-grid-card > .card-content.no-hscroll #GridView1 thead th { position: sticky; top: var(--cbs-head-h, 56px); z-index: 3; }
}

/* CBS INVOICES, 1px SEAM (2026-10-15): at a fractional scroll position (a 2x screen, an eased scroll) the sticky action bar and the sticky column
   headers snap to different device pixels and a hairline of row text shows between them. The column headers tuck 1px under the bar (which is the
   higher layer) and the bar paints a 1px skirt below itself, so there is no gap to leak through. */
@media (max-height: 700px) {
    body.cbs-invoices .cbs-grid-card > .card-header { box-shadow: 0 -2px 0 var(--surface), 0 1px 0 var(--surface); }
    body.cbs-invoices .cbs-grid-card > .card-content.no-hscroll #GridView1 thead th { top: calc(var(--cbs-head-h, 56px) - 1px); }
}

/* =========================================================
   CBS Invoices right rail as a PHONE OVERLAY (2026-10-16, lane cbs-rail-phone)

   WHAT WAS WRONG. The overlay rule above (max-width 1765) makes the open rail position: absolute with top:0 and
   bottom:0 inside .layout-body, but the shared .right-rail rule in rightrail.css also sets align-self: start,
   height: auto and a max-height. On a grid item, align-self: start wins over the two insets, so the overlay HUGS
   its content: on a 393x852 phone the Request panel (just its description text) was 280x167 at x=113, with the
   tabs and no form below. It is also anchored to the grid track edge, not the viewport, and its own overflow:auto
   made a second scroller beside #RightRailContent's.

   WHAT THIS DOES, ONLY under 641 wide or on a short landscape phone (up to 900 wide and 500 tall). At 1000x450,
   1024 and wider nothing here applies: the rail behaves exactly as before.
   The open rail is a full-height panel fixed to the right edge of the viewport; the rail itself does not scroll,
   #RightRailContent is the single scroller; the tab row and each panel header stay sticky at the top, and the
   panel's action footer (.right-rail-actions) stays at the bottom of the scrollport. Controls are 40px (small
   form density rule) and 16px text so a phone browser does not zoom on focus.
   ========================================================= */
@media (max-width: 640px), (max-width: 900px) and (max-height: 500px) {

    body.cbs-invoices .right-rail {
        /* tab row: 8px + 40px buttons + 8px + 1px divider */
        --rr-toolbar-h: 57px;
    }

    body.cbs-invoices.cbs-rail-strip:not(.close-rail) .right-rail {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: auto;
        width: min(92vw, 360px);
        min-width: 0;
        height: auto;
        max-height: none;
        margin: 0;
        align-self: auto;
        overflow: hidden;
        z-index: 1100;
        border-radius: var(--radius) 0 0 var(--radius);
    }

    body.cbs-invoices.cbs-rail-strip:not(.close-rail) #RightRailContent {
        overscroll-behavior: contain;
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }

    body.cbs-invoices .rr-tabs {
        gap: 8px;
        padding-top: 8px;
        padding-bottom: 8px;
        box-sizing: border-box;
    }

    body.cbs-invoices .rr-tabs .rr-tab,
    body.cbs-invoices .right-rail-close {
        min-width: 40px;
        min-height: 40px;
    }

    body.cbs-invoices #RightRailContent input[type="text"],
    body.cbs-invoices #RightRailContent select,
    body.cbs-invoices #RightRailContent textarea {
        font-size: 16px;
    }

    body.cbs-invoices #RightRailContent input[type="text"],
    body.cbs-invoices #RightRailContent select {
        min-height: 40px;
    }

    body.cbs-invoices .right-rail .btn.btn-primary,
    body.cbs-invoices .right-rail .btn.btn-secondary {
        height: 40px;
    }

    body.cbs-invoices .right-rail-actions {
        padding-bottom: calc(15px + env(safe-area-inset-bottom, 0px));
    }

    /* Slide in from the right and out again, in the same time as the desktop rail's fly-out (--rails-collapse-expand-time).
       Before this the overlay jumped in: the strip state is opacity 1 / no transform, the open frame resets it to a
       20px fade, and the rail was already at its final place. Resting off-screen while open-but-not-shown makes the
       close a slide (rightrail.css already transitions transform; MT_CloseRightRail waits for that transitionend); the
       entry is a keyframe animation so it always starts from fully off-screen, whatever the one in-between frame did. */
    body.cbs-invoices.cbs-rail-strip:not(.close-rail) .right-rail {
        transform: translateX(100%);
    }

    body.cbs-invoices.cbs-rail-strip.show-rail:not(.close-rail) .right-rail {
        transform: translateX(0);
        animation: cbs-rail-phone-in var(--rails-collapse-expand-time) ease;
    }

    @keyframes cbs-rail-phone-in {
        from { transform: translateX(100%); }
        to { transform: translateX(0); }
    }

    /* A person who asks for less motion gets the fade only (the rail's opacity transition stays, so the close still ends). */
    @media (prefers-reduced-motion: reduce) {
        body.cbs-invoices.cbs-rail-strip:not(.close-rail) .right-rail,
        body.cbs-invoices.cbs-rail-strip.show-rail:not(.close-rail) .right-rail {
            transform: none;
            animation: none;
        }
    }

    /* The shared tooltip engine (#app-tooltip, site.core.js) never hides after a tap on touch and sat over the
       rail icons. While the rail is an overlay on a phone nothing in it needs a hover tip: every tab and button
       carries an aria-label. */
    body.cbs-invoices.cbs-rail-strip.show-rail:not(.close-rail) #app-tooltip {
        display: none;
    }
}

/* =========================================================
   CBS Invoices right rail on a TABLET (iPad, 2026-10-18): a touch screen 641 to 1765 wide.

   WHAT THE DEVELOPER SAW (iPad Air, Safari, portrait and landscape): the icon strip closed but no rail opened, whichever of the row, the filter chip or a
   strip icon was tapped. It opened on the iPhone, where the phone block above makes the rail a panel FIXED to the viewport.
   WHAT THE EVIDENCE IS. In Chromium with an iPad profile the old rule opens and shows the rail, so the cause could not be reproduced there. The one real
   difference between the phone and the iPad is how the open rail is placed: on the phone it is position: fixed, at the viewport edges, on the iPad band it was
   position: absolute inside the clipped, grid-placed .layout-body, anchored to a grid line, with a height that hugs its content (align-self: start beats the
   top and bottom insets on a grid item). That arrangement is the one thing WebKit could resolve differently, and the phone arrangement is the one that is
   known to work on the device. So the tablet now uses the phone's arrangement: a panel fixed to the viewport, below the app bar, full height, 44px targets.
   Only where the PRIMARY pointer is coarse (a touch screen); a desktop window at the same width keeps the floating card exactly as before.
   ========================================================= */
@media (min-width: 641px) and (max-width: 1765px) and (pointer: coarse) {

    body.cbs-invoices .right-rail {
        --rr-toolbar-h: 61px;
    }

    body.cbs-invoices.cbs-rail-strip:not(.close-rail) .right-rail {
        position: fixed;
        top: var(--appbar-height);
        right: 0;
        bottom: 0;
        left: auto;
        width: min(92vw, 360px);
        min-width: 280px;
        height: auto;
        max-height: none;
        margin: 0;
        align-self: auto;
        overflow: hidden;
        z-index: 1100;
        border-radius: var(--radius) 0 0 var(--radius);
    }

    body.cbs-invoices.cbs-rail-strip:not(.close-rail) #RightRailContent {
        overscroll-behavior: contain;
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }

    body.cbs-invoices .rr-tab,
    body.cbs-invoices .right-rail-close {
        min-width: 44px;
        min-height: 44px;
    }

    body.cbs-invoices .right-rail .btn.btn-primary,
    body.cbs-invoices .right-rail .btn.btn-secondary {
        height: 44px;
    }

    body.cbs-invoices #RightRailContent input[type="text"],
    body.cbs-invoices #RightRailContent select,
    body.cbs-invoices #RightRailContent textarea {
        font-size: 16px;
    }

    body.cbs-invoices.cbs-rail-strip.show-rail:not(.close-rail) #app-tooltip {
        display: none;
    }
}
