/* Separates stacked sections on a detail page — Modules, Licensing, Mobile Credentials all run
   grid-after-grid and blur together otherwise. A hairline rule plus breathing room above the
   heading, so the split reads without drawing attention to itself. The first section on a page
   keeps the rule too: it divides the heading from the summary card above it. */
.section-heading {
    margin-top: 2rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--rz-base-300, rgba(0, 0, 0, 0.12));
}

/* Audit-entry JSON in the system log detail dialog. */
.dt-json {
    margin: 0;
    padding: 0.75rem;
    background: var(--rz-base-200, #f5f5f5);
    border-radius: 4px;
    font-size: 0.8125rem;
    line-height: 1.4;
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 14rem;
    overflow: auto;
}

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

:root {
    font-size: var(--rz-root-font-size);
}

/* ── Brand → Radzen color bridge ────────────────────────────
   Ties all Radzen component colors (buttons, tabs, inputs,
   checkboxes, etc.) to the active brand palette.
   The main primary and darkest shade reference --brand-*
   variables so they update automatically with brand changes.
   Intermediate light/dark shades are approximated for the
   default Malibu brand (#015CEC) and should be updated when
   adding additional brands.
   ─────────────────────────────────────────────────────────── */
:root {
    --rz-primary:            var(--brand-primary,       #015CEC);
    --rz-primary-light:      #4085F1;
    --rz-primary-lighter:    rgba(1, 92, 236, 0.12);
    --rz-primary-dark:       #0049BF;
    --rz-primary-darker:     var(--brand-primary-hover, #002E63);
    --rz-on-primary:         #ffffff;
    --rz-on-primary-light:   #ffffff;
    --rz-on-primary-lighter: var(--brand-primary,       #015CEC);
    --rz-on-primary-dark:    #ffffff;
    --rz-on-primary-darker:  #ffffff;
}

/* ───────────────────────────────────────────────────────────
   CORNER RADIUS
   The Material theme ships 4px corners, square inputs and a
   square grid. These soften that to the rounded look of the
   tools dealers already use all day.

   Variables only — no component markup changes anywhere, and
   nothing here is Radzen-version-specific beyond the names.
   Loaded after <RadzenTheme>, so these win.

   Buttons are full pills, which also turns icon-only buttons
   into circles. Inputs are deliberately NOT pills: rounding
   every field on a data-entry dialog costs scanability and
   makes a row of fields read as unrelated blobs. A pill is
   right for a lone search box and wrong for a form.
   ─────────────────────────────────────────────────────────── */
:root {
    --rz-border-radius:             6px;      /* global default, was 4px  */
    --rz-button-border-radius:      9999px;   /* pill, incl. icon buttons */
    --rz-pager-button-border-radius: 9999px;
    --rz-card-border-radius:        12px;
    --rz-panel-border-radius:       12px;
    --rz-grid-border-radius:        12px;     /* was 0 */
    --rz-input-border-radius:       8px;      /* was 0 — rounded, not pill */
    --rz-menu-border-radius:        8px;
    --rz-notification-border-radius: 10px;
    --rz-tabs-border-radius:        8px;
}

/* ───────────────────────────────────────────────────────────
   HEADER DIVIDER
   Radzen 11.4.1 has no divider component — the only thing named
   like one, .rz-separator, is a timepicker colour. So the rule
   between the appearance toggle and the account menu is this
   one span. Flagged rather than silent: the house rule is Radzen
   components wherever they exist, and here one does not.
   ─────────────────────────────────────────────────────────── */
/* A collapsible panel's toggle ships as + / −, while the account menu in the
   header uses a chevron. Same gesture, so it should be the same glyph.

   RadzenPanel has no icon parameter for the toggler, but the glyph is just a
   ligature name in `content` on a Material Symbols font — `.rzi-plus:before
   {content:"add"}` — so naming a different ligature is all it takes. Scoped to
   the toggler, because .rzi-plus is used elsewhere. */
.rz-panel-titlebar-toggler .rzi-plus::before  { content: "keyboard_arrow_down"; }
.rz-panel-titlebar-toggler .rzi-minus::before { content: "keyboard_arrow_up"; }

/* ───────────────────────────────────────────────────────────
   CONTENT TUCKS UNDER THE HEADER
   The sidebar and body get rounded top corners, and the header
   colour shows through the notch — the Shopify admin look.

   It needs three changes together, not just a radius:
     1. .rz-layout is painted the header colour. It is the only
        thing behind the content, and a radius on its own would
        just reveal the same grey it already shows.
     2. .rz-body is given an explicit background. It ships
        TRANSPARENT and borrows the layout's grey, so once the
        layout turns blue the whole page would too.
     3. only then do the radii read as a notch.

   Sidebar takes the left corner and body the right. When the
   sidebar is collapsed Radzen drops .rz-body-expanded, and the
   body is then hard against the left edge, so it takes both.
   ─────────────────────────────────────────────────────────── */
:root {
    /* The layout is the only thing behind the content, so it supplies the
       notch colour. */
    --rz-layout-background-color: var(--rz-header-background-color);

    /* Ships transparent, which is how the body borrowed the layout's colour.
       Now that the layout is the header colour it needs its own, and it has
       to be the SAME variable the layout defaulted to — --rz-layout-background-color
       is var(--rz-body-background-color), so that is what the page has always
       been painted with.

       NOT --rz-base-100. That matches in the light theme by coincidence
       (#f5f5f5) and is #a0a0a0 in the dark one, which turned the whole content
       area into a washed-out mid-grey panel. --rz-body-background-color is
       base-100 in light and base-900 in dark, which is the actual page colour
       in both. */
    --rz-layout-body-background-color: var(--rz-body-background-color);

    /* Top-right only; the sidebar owns the left corner. */
    --rz-layout-body-border-radius: 0 12px 0 0;
}

/* No --rz-sidebar-border-radius exists in 11.4.1, so this one is a direct
   rule rather than a variable. */
.rz-sidebar {
    border-top-left-radius: 12px;
}

/* Sidebar collapsed or overlaying: the body owns the left edge too. */
.rz-body:not(.rz-body-expanded) {
    border-top-left-radius: 12px;
}

@media (max-width: 768px) {
    .rz-body { border-top-left-radius: 12px; }
}

/* The account menu's TRIGGER sits on the primary-coloured header, so it needs the header's
   contrast colour; the theme leaves it at the menu's default dark. The popup below it keeps
   the dark text, because that is on a white surface.

   The direct-child chain is what separates the two. Radzen renders:
       ul.rz-profile-menu > li.rz-navigation-item
           > div.rz-navigation-item-wrapper > div.rz-navigation-item-link   <- trigger
           > ul.rz-navigation-menu > li.rz-navigation-item ...              <- popup items
   so stopping at the first .rz-navigation-item-link leaves the popup untouched. The .rzi rule
   catches the avatar and the chevron, which are icons rather than text. */
.rz-header .rz-profile-menu > .rz-navigation-item > .rz-navigation-item-wrapper > .rz-navigation-item-link,
.rz-header .rz-profile-menu > .rz-navigation-item > .rz-navigation-item-wrapper > .rz-navigation-item-link .rzi,
.rz-header .rz-profile-menu > .rz-navigation-item > .rz-navigation-item-wrapper > .rz-navigation-item-link .rz-text-subtitle2 {
    color: var(--rz-header-color);
}

.header-divider {
    display: inline-block;
    width: 1px;
    height: 1.5rem;
    margin-inline: 0.25rem;
    background: var(--rz-header-color, currentColor);
    opacity: 0.25;
    flex: 0 0 auto;
}

/* The one place a pill IS right: the lone search box above a grid,
   which is a search affordance rather than part of a form.
   .dt-search sits on the input itself (RadzenTextBox renders
   <input class="rz-textbox dt-search">), so no descendant selector.
   DataTableGrid.razor.css scopes .dt-search too, but only for width,
   so there is nothing to out-specify here. */
.dt-search {
    border-radius: 9999px;
    padding-inline: 0.85rem;
}

body {
    font-family: var(--brand-font, var(--rz-text-font-family));
    color: var(--rz-text-color);
    font-size: var(--rz-body-font-size);
    line-height: var(--rz-body-line-height);
    background-color: var(--rz-body-background-color);
}

h1, h2, h3, h4, h5, h6,
.rz-text-h1, .rz-text-h2, .rz-text-h3,
.rz-text-h4, .rz-text-h5, .rz-text-h6,
.rz-text-display-h1, .rz-text-display-h2,
.rz-text-display-h3, .rz-text-display-h4,
.rz-text-display-h5, .rz-text-display-h6 {
    font-family: var(--brand-font, var(--rz-text-font-family));
}

.rz-body {
    --rz-body-padding: 0;
}

a {
    color: var(--rz-link-color);
}

a:hover,
a:focus {
    color: var(--rz-link-hover-color);
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

.blazor-error-boundary::after {
    content: "An error has occurred."
}

.loading-progress {
    position: relative;
    display: block;
    width: 8rem;
    height: 8rem;
    margin: 20vh auto 1rem auto;
}

.loading-progress circle {
    fill: none;
    stroke: #e0e0e0;
    stroke-width: 0.6rem;
    transform-origin: 50% 50%;
    transform: rotate(-90deg);
}

.loading-progress circle:last-child {
    stroke: #1b6ec2;
    stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
    transition: stroke-dasharray 0.05s ease-in-out;
}

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

.loading-progress-text:after {
    content: var(--blazor-load-percentage-text, "Loading");
}
/* ANCHORS STYLED AS BUTTONS MUST ALIGN WITH REAL ONES.
   A few places need a genuine <a> rather than a RadzenButton -- the module Connect link and the
   resource download links -- because the browser only treats a real link click as a user gesture, so
   a new tab opened any other way risks being blocked. Radzen's button styling assumes a <button>,
   which participates in vertical alignment differently from an inline anchor, so such a link sits a
   few pixels above the buttons beside it in the same cell.
   inline-flex with centred items makes the anchor lay out like the button it is imitating. */
a.rz-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: middle;
    text-decoration: none;
}

/* NARROWER SIDEBAR, so the body gets the difference.
   Radzen's default is 300px, which is generous for six menu items whose longest labels are 16
   characters ("Manage Resources", "Licensing Report", "Dealer Dashboard"). At 240px those still sit
   on one line beside their icons, and the grids next to them gain 60px -- which on the dealer
   dashboard is most of a column.

   ONE VARIABLE IS ENOUGH. RadzenLayout is a CSS grid with `grid-template-columns: auto 1fr` and the
   sidebar and body as separate areas, so the sidebar column sizes to the sidebar and the body takes
   the remainder. Nothing offsets the body by a second hardcoded value, so there is no matching change
   to make and no chance of the two disagreeing. */
:root {
    --rz-sidebar-width: 240px;
}

/* GRID COLUMN SIZING, global rather than scoped to DataTableGrid: the licensing table on the
   customer page is a plain RadzenDataGrid with no wrapper, and these apply to any of them.
   Both are opt-in -- the heading rule only stops truncation, and dt-nowrap has to be asked for
   with CssClass/HeaderCssClass on the column. */

/* A COLUMN HEADING SHOULD SET ITS COLUMN'S WIDTH, NOT BE TRUNCATED TO FIT IT.
   Radzen's `.rz-column-title` ships `white-space: nowrap; overflow: hidden; text-overflow: ellipsis`
   and `width: 100%`. Together those mean a heading can never widen its column -- it is clipped
   instead, so "Doors" renders as "D..." and "Licensing" as "Lice...". The width:100% is the
   load-bearing half: it pins the title to whatever the cell already is, so the heading contributes
   nothing to the table's intrinsic width and the auto-layout algorithm never learns it needs more.

   `min-width: max-content` reverses that. The title's minimum contribution becomes its full text,
   which auto table layout does respect, so the column grows to fit its heading -- including the space
   Radzen reserves for the sort caret, which is why a narrow sortable column loses so much. Past the
   wrapper the table scrolls, which it already knew how to do.

   The effect is that a heading is always legible without any page having to guess the pixel width of
   its own words. */
.rz-datatable-thead th .rz-column-title {
    width: auto;
    min-width: max-content;
    overflow: visible;
    text-overflow: clip;
}


/* Columns whose CONTENT should set their width, applied with CssClass + HeaderCssClass.
   A wrapping cell's minimum width is its longest WORD, so "Sun City Hilton Head" will happily
   collapse to the width of "Hilton" and the column looks crushed while the table still claims to fit.

   BUT nowrap on the cell is not enough on its own, which is what made a first attempt at this look
   like it had done nothing. Radzen wraps every value in `.rz-cell-data`, which is
   `display: block; overflow: hidden; text-overflow: ellipsis` -- a block that takes the cell's width
   and CLIPS. So the value is ellipsised instead of wrapped, and either way contributes nothing to the
   column's intrinsic width, so auto layout never learns the column needs more. Exactly the same trap
   as `width: 100%` on the header title.

   `min-width: max-content` on that block is the fix, as it was for the header: its minimum becomes
   the full value, the cell has to accommodate it, and the column grows. Then the table is as wide as
   the real data needs and no wider, and scrolls only when that genuinely exceeds the viewport. */
td.dt-nowrap,
th.dt-nowrap {
    white-space: nowrap;
}

td.dt-nowrap .rz-cell-data {
    min-width: max-content;
    overflow: visible;
    text-overflow: clip;
}

/* Horizontal overflow for a grid that is not inside DataTableGrid.
   The wrapped grids get this from the component's own stylesheet; a plain RadzenDataGrid has no
   wrapper, so without it a table wide enough to show its headings takes the PAGE's scrollbar with
   it and the whole page slides sideways instead of the table. */
.dt-scroll {
    overflow-x: auto;
}
