/*
  Bridge layer: the ONLY place that maps the Kendo theme onto app surfaces.
  App CSS references --wp-* (never raw --kendo-* or --tb-*), so a Kendo variable rename
  is a one-file change.

  This file carries NO literal colors, by rule. The Check-ThemeColors gate that enforced that is
  temporarily removed on this branch (see WebPortal.csproj) and will be re-added. Every value
  below resolves to the theme:
    --kendo-*  standard slots. The vendored stock Kendo theme defines every default;
               the brand file (wwwroot/themes/<name>.css) overrides the handful that differ.
    --tb-*     the app surfaces and control geometry Kendo models no slot for, defined
               entirely by the brand file. The bridge var()s them; nothing else may.

  There are deliberately no var() fallbacks. A fallback only fires when a variable is
  UNDEFINED, so it cannot rescue a wrong value -- it can only hide a broken theme behind a
  plausible-looking one, which is how a broken theme ships unnoticed. eng/Check-ThemeSlots.ps1
  asserted at build time that every variable referenced here is defined by every theme; that
  gate is temporarily removed on this branch (see WebPortal.csproj) and will be re-added.

  Browser baseline: the DERIVED tokens below use relative-color oklch(from ...) and
  color-mix() (--wp-primary-dark, --wp-row-disabled, --wp-overlay, --wp-hover-bg,
  --wp-highlight, --wp-coachmark-fill). Those require a modern engine (Chromium/Edge 119+, Firefox 128+,
  Safari 16.4+; Baseline 2024). This is a documented assumption for the controlled
  modern-Edge fleet -- an older/embedded engine would drop those surfaces to their initial
  value rather than degrade to a brand color.
*/
:root {
    /* ---- Action: "what you do" ----
       Kendo's primary slot carries the action blue. Kendo's "primary" IS its action
       color -- it fills solid primary buttons, draws focus rings and tints links -- so
       aliasing it here makes those follow the theme instead of a per-component override
       list. Named by ROLE, not color: the theme-color gate matches forbidden color names
       as \b substrings, so --wp-blue would trip on every usage. */
    --wp-action:       var(--kendo-color-primary);

    /* Kendo derives --kendo-color-primary-hover as oklch(l + .029) -- far too subtle for
       the designed action-blue step (delta L ~ .082), so the hover is a designed value
       the theme carries rather than one Kendo computes. */
    --wp-action-hover: var(--tb-action-hover);

    /* Label/glyph color for anything the app fills with --wp-action itself. Kendo's own
       solid-primary button gets this for free from --kendo-color-on-primary; app-authored
       action surfaces (the drafts Item Search / Full Cart segmented control) had no bridged
       token for it and would otherwise pin a literal white -- which is a contrast bug waiting
       for the first theme whose action color is light. Reads on-PRIMARY, matching --wp-action's
       primary source above, and Kendo derives it as black-or-white by the fill's lightness, so
       it flips on its own when the action color moves. */
    --wp-on-action:    var(--kendo-color-on-primary);

    /* ---- Navigation: "where you are" ----
       Three distinct PANTONEs, NOT a lightness ramp: measured OKLCH hues are 204 / 183 /
       174 with differing chroma, so deriving two from one would visibly distort them.
       Each is carried by the theme as its own value.

       --wp-primary sources from Kendo's TERTIARY slot, not primary: primary now means
       action (above). Tertiary is referenced only by opt-in .k-*-tertiary utility classes
       and by zero component defaults, so brand green parked there colors nothing by
       accident -- while the chrome stays theme-swappable rather than hard-coded. */
    --wp-primary:      var(--kendo-color-tertiary);

    /* A genuinely darker shade of the primary, derived so it tracks any theme swap.
       NOT --kendo-color-primary-active: Kendo Material computes that as a LIGHTER
       tint (calc(l + .062)), which made the "dark" surfaces that consume this (the footer
       and the nav menu-popup hover) render lighter than the base primary. Deriving a
       lower-lightness OKLCH keeps them darker in every theme; the -0.16 is a visual knob
       — nudge for more/less contrast. */
    --wp-primary-dark: oklch(from var(--wp-primary) calc(l - 0.16) c h);
    --wp-accent:       var(--kendo-color-secondary);

    --wp-nav:          var(--tb-nav-green);
    --wp-primary-deep: var(--tb-nav-deep);
    --wp-nav-divider:  var(--tb-nav-divider);

    /* ---- Field neutrals ----
       Not brand colors, and Kendo has no slot for them, so the brand file carries them.
       Both are contrast FLOORS rather than free knobs: the field border is a control
       boundary separating the white field interior from the cream page and must clear 3:1
       against both; the hint paints placeholder text and must clear 4.5:1. The values in
       the brand file are the lightest grays that do. */
    --wp-field-border: var(--tb-field-border);
    --wp-hint:         var(--tb-hint);

    /* Cancel/tertiary button fill. NOT theme-derived from Kendo's "base" variant: that
       resolves to --kendo-color-base, which is the app's cream page background -- so a
       base-variant Cancel button renders invisible against the page it sits on. The
       design specifies its own neutral, so the theme carries one.
       Role-named, not color-named: the theme-color gate matches forbidden color names as
       \b substrings, so --wp-gray would trip on every usage. */
    --wp-neutral:       var(--tb-neutral);
    --wp-neutral-hover: var(--tb-neutral-hover);
    /* Reads on-TERTIARY, matching --wp-primary's tertiary source (line 49): this token
       labels the brand-green nav/footer surfaces, so its contrast must track that
       surface. Reading on-primary tied it to the action (blue) slot instead, silently
       flipping chrome text contrast whenever the action color moved. */
    --wp-on-primary:   var(--kendo-color-on-tertiary);
    --wp-surface:      var(--kendo-color-surface);
    --wp-body-bg:      var(--kendo-color-base);
    --wp-text:         var(--kendo-color-on-app-surface);

    /* A chart's totals line (the velocity report's Total): the body text colour, as in the
       design, so it reads the same in every chart and never takes a series colour that an
       account or item is using. The series themselves take the theme's palette
       (--kendo-color-series-a..f in the brand file). */
    --wp-chart-total:  var(--wp-text);
    --wp-border:       var(--kendo-color-border);

    /* ---- Grid surfaces ----
       The zebra alt row was a 12% wash of the SUCCESS green over the surface. The color
       roles reserve green for navigation, and the complaint being fixed is precisely that
       status flags fight the alternating fill -- so the zebra goes neutral and the status
       tint below keeps its meaning. Kendo has no grid-header/-hover slot, so these come
       from the theme's token block.
       --wp-hover-bg is deliberately NOT reused here: it is the list-item hover wash, an
       8% text mix, and the grid's hover is a designed surface. */
    --wp-grid-header:  var(--tb-grid-header);
    --wp-grid-hover:   var(--tb-grid-hover);
    --wp-row-alt:      var(--tb-grid-row-alt);
    --wp-row-disabled: color-mix(in srgb, var(--kendo-color-error) 14%, var(--wp-surface));

    /* Loading scrim: a neutral veil (text mixed into surface) that dims content
       while busy. A dedicated token, not --wp-border — the border color is far too
       transparent (~8%) to mask anything. The .loadingPanel veil mixes it 60% toward
       transparent, so this stays opaque here and reads as a translucent gray/dark veil. */
    --wp-overlay:      color-mix(in srgb, var(--wp-text) 20%, var(--wp-surface));
    /* Coachmark card fill: a light wash of the action colour over the surface, so the card
       reads as "the app is pointing something out" rather than as another white panel. Blended
       with the surface (not transparent) so the beak can overlap the card edge seamlessly and
       text keeps full contrast over busy grids. Follows the theme: a dark surface gets a dark
       wash. */
    --wp-coachmark-fill: color-mix(in srgb, var(--wp-action) 10%, var(--wp-surface));

    /* Typography routing: each brand file sets a concrete --kendo-font-family (onbrand:
       the brand face; hotpink: rounded display). Aliasing it here and applying it to body
       lets a theme swap change the font app-wide, not only color. */
    --wp-font:         var(--kendo-font-family);

    /* Attention/flag wash: a PALE tint of the warning color over the surface (not the
       saturated status color itself), so highlighted text stays readable and a semantic
       status color isn't reused as a decorative background. */
    --wp-highlight:    color-mix(in srgb, var(--kendo-color-warning) 18%, var(--wp-surface));

    /* Validation-error backgrounds outside the text-status-bad class */
    --wp-error:        var(--kendo-color-error);

    /* Status FILL/emphasis tokens. The bridge exposed success/error/info only as TEXT colors
       (the .text-status-* classes below); a page needing a success FILL (a done-step mark)
       had to reach past the bridge to var(--kendo-color-success) directly. These give that
       surface a bridged token. Role-named (success/warning are roles, not color names) so the
       theme-color gate's \b-substring match does not trip. */
    --wp-success:      var(--kendo-color-success);

    /* Info, bridged as a fill/emphasis color for the same reason as success: the toast's info
       icon and tint (site.css, "Toast notifications") need the saturated color itself. */
    --wp-info:         var(--kendo-color-info);

    /* Warning was reachable only as --wp-highlight, the pale WASH. A rule needing the
       saturated warning itself -- the impersonation banner's edge -- had to reach past the
       bridge to var(--kendo-color-warning). This gives it a bridged token, matching how
       success is exposed. Still a role name, not a color name, so the theme-color gate's
       -substring match does not trip. Note the pairing rule the wash comment states:
       --wp-warning is an EDGE/fill color, and text sits on --wp-highlight rather than on
       this, because the saturated orange does not clear 4.5:1 against white. */
    --wp-warning:      var(--kendo-color-warning);

    /* ---- Shape, elevation & interaction ----
       --wp-radius aliases Kendo's medium corner so the custom chrome (the vanilla
       dropdown) rounds in step with Kendo widgets AND tracks a theme swap. Shadows are
       NOT brand-themed — Kendo's elevation values are identical across themes — so
       --wp-shadow/-popup are centralized app tokens (one knob for chrome vs floating
       elevation) that keep their current look, not --kendo-* aliases. Their rgba() is
       pure black at low alpha: a neutral, carrying no brand, which is why the color gate
       permits it where a chromatic rgba() would fail. --wp-hover-bg mixes the theme's
       TEXT color instead of a fixed black, so the pointer wash stays visible on light AND
       dark surfaces. */
    --wp-radius:       var(--kendo-border-radius-md);
    /* A soft, card-like corner for floating surfaces that should read as friendly rather than as
       chrome (the toasts). Kendo's xxl step, so it still tracks a theme's base radius. */
    --wp-radius-lg:    var(--kendo-border-radius-xxl);
    --wp-shadow:       0 .25rem .75rem rgba(0, 0, 0, .05);
    --wp-shadow-popup: 0 .25rem .75rem rgba(0, 0, 0, .12);
    --wp-hover-bg:     color-mix(in srgb, var(--wp-text) 8%, transparent);

    /* ---- Control geometry ----
       Aliases of the theme's geometry values, so a theme swap changes shape and not only
       colour. Kendo models no slot for these (its own metrics derive from a spacing ramp
       the designed values are not on), which is why they arrive as --tb-*.

       --wp-control-height is deliberately ONE token for buttons and fields: they share a
       height so a button and a field sitting on the same row align. Radius is NOT shared --
       fields are 10px and buttons are a pill; one slot cannot serve both. */
    --wp-control-height:   var(--tb-control-height);
    --wp-button-pad-x:     var(--tb-button-pad-x);
    --wp-button-gap:       var(--tb-button-gap);
    --wp-button-radius:    var(--tb-button-radius);
    --wp-disabled-opacity: var(--tb-disabled-opacity);
    --wp-field-radius:     var(--tb-field-radius);
    --wp-field-pad-block:  var(--tb-field-pad-block);
    --wp-field-pad-inline: var(--tb-field-pad-inline);

    /* Grid row density -- ONE token with several consumers, which is the reason it is a token
       rather than a literal in site.css. Kendo builds a grid header's full-cell click target by
       negating the header cell's own padding on an inner link and re-applying it there, so the
       padding and a negative margin have to agree EXACTLY or the link overflows its cell. Both
       sides read this alias, so they cannot disagree. */
    --wp-grid-cell-pad-block: var(--tb-grid-cell-pad-block);

    /* Shared by the field border and the checkbox/radio outline -- one "how thick is a
       control boundary" decision, two consumers. */
    --wp-border-width:     var(--tb-border-width);
    --wp-control-box-size: var(--tb-control-box-size);

    /* ---- Header chrome ----
       App furniture, so none of it has a Kendo slot to alias -- these pass the theme's
       values straight through. --wp-header-space carries the band inset AND the brand
       strip's item gap: one rhythm decision, three consumers. */
    --wp-header-utility-height: var(--tb-header-utility-height);
    --wp-header-brand-height:   var(--tb-header-brand-height);
    --wp-header-space:          var(--tb-header-space);
    --wp-header-gap:            var(--tb-header-gap);
    --wp-header-logo-height:    var(--tb-header-logo-height);
    --wp-header-product-size:   var(--tb-header-product-size);

    --wp-hamburger-size:        var(--tb-hamburger-size);
    --wp-hamburger-radius:      var(--tb-hamburger-radius);
    --wp-hamburger-inset:       var(--tb-hamburger-inset);
    --wp-hamburger-bar-width:   var(--tb-hamburger-bar-width);
    --wp-hamburger-bar-height:  var(--tb-hamburger-bar-height);
    --wp-hamburger-bar-gap:     var(--tb-hamburger-bar-gap);
    --wp-hamburger-bar-radius:  var(--tb-hamburger-bar-radius);

    /* Off-canvas nav drawer width. One knob, two consumers: the drawer's own width and
       the left offset the page content is pushed by when the drawer opens. */
    --wp-drawer-width:          var(--tb-drawer-width);

    --wp-pill-radius:           var(--tb-pill-radius);
    --wp-pill-max-width:        var(--tb-pill-max-width);

    /* ---- Type scale ----
       Two heading levels are specified -- page title 32px Regular and section header 18px
       Bold -- so h3-h6 are interpolated and let weight, not size, carry the hierarchy
       below h2. The scale is rem against an untouched 16px root, so it is independent of
       the base size below.

       App-owned, NOT aliased onto --kendo-font-size-*. That is a deliberate asymmetry with
       the geometry above, and the reason is that Kendo's seven font-size steps are flat
       literals with no base and no calc(), so overriding one moves one step and cascades to
       nothing -- unlike --kendo-border-radius-*, where every step derives from a base.
       Aliasing would buy no themeability, and only two of the sizes below have a matching
       Kendo step at all (Kendo's ramp is 8/10/12/14/16/20px; the design's is 32/18/14/13/12).

       --wp-font-size-base is applied to body in THIS file because this layer owns the body
       rule. It has to be applied somewhere explicitly: Kendo parks its 14px on
       .k-body/.k-typography, classes no layout emits, so without this line base prose falls
       to the browser's 16px while every Kendo widget renders its own text at 14 -- a
       mismatch that shipped for exactly as long as a comment here claimed "the Kendo
       font-size slot already sets it". It does not. */
    --wp-font-size-base:  .875rem;   /* 14px  body prose, field text, field label */
    --wp-font-size-table: .8125rem;  /* 13px  grid content + column title */
    --wp-font-size-sm:    .75rem;    /* 12px  error/validation banner */

    /* Glyph size for icons that sit in a grid ROW: the compact row-action buttons, the
       favourite heart and the on-special tag. One value because they sit side by side in the
       order grids, where two separately stated sizes had already drifted (18.4px glyphs
       beside 16px ones). 18px -- the same as a full-size button's glyph -- because at 16px
       the row icons read as too small to scan. */
    --wp-row-icon-size:   1.125rem;  /* 18px */

    --wp-h1: 2rem;      /* 32px  page title (Regular -- see site.css) */
    --wp-h2: 1.125rem;  /* 18px  section header (Bold via site.css) */
    --wp-h3: 1rem;      /* 16px */
    --wp-h4: var(--wp-font-size-base);
    --wp-h5: var(--wp-font-size-base);
    --wp-h6: var(--wp-font-size-base);
}

/* App surface: primary brand background with readable on-primary text.
   Used on the no-nav/login body and the cart search panel. */
.wp-bg-primary { background-color: var(--wp-primary) !important; color: var(--wp-on-primary); }

/* ---- Custom chrome ---- */
body { background-color: var(--wp-body-bg); color: var(--wp-text); font-family: var(--wp-font); font-size: var(--wp-font-size-base); }

/* The footer is the same deep green as the header (.wp-header), so the page is framed by one colour.
   Pages/Shared/_Footer.cshtml carries .wp-bg-footer, which site.css sets to the same token with !important. */
footer, .footer { background-color: var(--wp-primary-deep); color: var(--wp-on-primary); }

/* Semantic status text — replaces inline color:green/red/etc. */
.status-yes { color: var(--kendo-color-success); font-weight: bold; }
.status-no,  .text-status-bad { color: var(--kendo-color-error); font-weight: bold; }

/* A read-only attribute grid, the Product Details drawer's label-over-value rows. Responsive rather than a
   fixed 12-column grid: cells auto-fit to as many columns as fit (roughly one column per ~11rem of
   width), which keeps values from colliding in the 1200px drawer and when it is capped to a narrow screen.
   auto-fill rather than auto-fit: the columns are there even when a
   grid has fewer cells than fit, so a short grid lines up under a longer one
   instead of stretching across. Row/column gaps follow the 8px spacing rhythm. Long fields opt
   into a full-width row with .wp-attr-wide. */
.wp-item-attrs {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
    gap: 0.5rem 1.5rem;
    align-items: start;
}
.wp-item-attrs .wp-attr-wide { grid-column: 1 / -1; }

/* One attribute: a small bold label over its value. Shared by the Product Details drawer (on spans) and
   the item preview card's details (on its dt / dd, item-hover-card.js), so the drawer reads as the
   card's fuller version. Label over value, not beside it, so a long value can never squeeze its
   label. The value's margin is reset for the card's dd, which browsers indent. */
.wp-item-attr__label {
    display: block;
    font-size: var(--wp-font-size-sm);
    font-weight: 700;
}

.wp-item-attr__value {
    display: block;
    margin: 0;
    font-size: var(--wp-h2);
    overflow-wrap: anywhere;
}

/* A section with nothing to show, said in a sentence rather than left blank. */
.wp-item-empty {
    margin: 0;
    color: var(--wp-hint);
}

/* The badges under the Product Details drawer's heading (Rx / OTC, brand or generic, the DEA schedule, obsolete), each
   drawn only when it applies -- an absent badge is simply not shown. The text carries the meaning; a status badge's
   colour only backs it up. */
.wp-item-flags {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .5rem;
    margin-top: .5rem;
}

.wp-item-flag {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: .125rem .5rem;
    border: 1px solid var(--wp-border);
    border-radius: var(--wp-pill-radius);
    font-size: var(--wp-font-size-sm);
    font-weight: 700;
}

/* The drawer's sections are cards, as in the design: each panel a rounded card of its own, 16px apart.
   The panel bar's own frame goes and each top-level item takes the card; the header's chevron
   moves to the left of its title; an open card's content sits under an inset rule. */
.wp-item-detail .k-panelbar {
    margin-top: 1rem;
    border: 0;
    background: none;
}

.wp-item-detail .k-panelbar > .k-panelbar-header {
    border: 1px solid var(--wp-border);
    border-radius: var(--wp-radius-lg);
    background: var(--wp-surface);
    overflow: hidden;
}

.wp-item-detail .k-panelbar > .k-panelbar-header + .k-panelbar-header {
    margin-top: 1rem;
}

.wp-item-detail .k-panelbar > .k-panelbar-header > .k-link {
    gap: .5rem;
    padding: 1rem;
}

.wp-item-detail .k-panelbar > .k-panelbar-header > .k-link .k-panelbar-toggle {
    order: -1;
    margin: 0;
}

/* Selection means nothing in an accordion, and the theme's selected header is a gold band across
   the card, so it is not drawn. Keyboard focus still is: the ring, inside the card's edge. */
.wp-item-detail .k-panelbar > .k-panelbar-header > .k-link.k-selected {
    background: none;
    color: inherit;
}

.wp-item-detail .k-panelbar > .k-panelbar-header > .k-link.k-focus {
    outline: 2px solid var(--wp-action);
    outline-offset: -2px;
}

.wp-item-detail .k-panelbar-content {
    margin: 0 1rem;
    padding: 1rem 0;
    border-top: 1px solid var(--wp-border);
}

/* The panels' headers are the drawer's section headers, as in the design: bold, at the section
   header size. The item text is a row, so what a header carries (its icon, its title) lines up on
   the text's baseline. */
.wp-item-detail .k-panelbar > .k-panelbar-header > .k-link {
    font-size: var(--wp-h2);
    font-weight: 700;
}

.wp-item-detail .k-panelbar > .k-panelbar-header > .k-link .k-panelbar-item-text {
    display: flex;
    flex: 1;
    align-items: baseline;
    gap: 1rem;
}

/* ---- Product Details drawer (product-detail-pane.js, _ProductDetailPane) ----
   Built from the site's item parts (heading, badges, panel cards, label-over-value rows). These rules
   add only what this drawer has of its own: the muted "Not supplied", the obsolete badges, banner and row, the
   two price tiles and the tables. */

/* A value FDB does not supply, muted so it never reads like a value. */
.wp-fdb-missing {
    color: var(--wp-hint);
}

/* Where Hamacher's facts come from (the Retail card's foot, the top of the Label tab): a muted caption, set off from
   what it describes. */
.wp-product-source {
    color: var(--wp-hint);
    font-size: var(--wp-font-size-sm);
}

    .wp-item-attrs ~ .wp-product-source,
    .wp-product-source ~ [data-product-tab-empty],
    .wp-product-source ~ .k-panelbar {
        margin-top: .5rem;
    }

/* The M&D card's first line, whose account its prices are for (or that they are not available): muted like a caption
   (.wp-item-empty), at body size, with the rows' own gap under it so it reads as the card's heading line, not a row. */
.wp-product-account {
    margin-bottom: .5rem;
}

/* A Label tab card's text, drawn in full as prose: its line breaks kept, a long word (a URL, a chemical name) wrapped
   rather than widening the drawer. */
.wp-product-prose {
    margin: 0;
    white-space: pre-line;
    overflow-wrap: anywhere;
}

/* The Images tab's pictures (_ProductImages): the pictures row (.wp-item-pictures, site.css) in the Pictures card, a
   third of the row each. The tab's sentence for an item with no picture is longer than the engine's own, so it is
   centred and kept off the edges of its box. */
.wp-product-pictures .wp-pictures__placeholder-text {
    padding-inline: .75rem;
    text-align: center;
}

/* Obsolete is a status, so it takes the error pairing: text on a pale wash of the error colour, the saturated
   colour on the edge only (as text it does not clear 4.5:1). "Becomes obsolete" is a warning, paired the way the
   storage badge is. */
.wp-item-flag--obsolete {
    border-color: var(--wp-error);
    background: color-mix(in srgb, var(--wp-error) 12%, var(--wp-surface));
}

.wp-item-flag--becomes-obsolete {
    border-color: var(--wp-warning);
    background: var(--wp-highlight);
}

/* The note under the heading of an NDC with an obsolete date. It takes the same status colour as the badge above
   it: the error pairing once the NDC is obsolete, the warning pairing while it only becomes obsolete. The edge is
   on the left; the layout is shared. */
.wp-fdb-banner {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem 1rem;
    margin: 1rem 0;
    padding: .75rem 1rem;
    border-left: 4px solid var(--wp-warning);
    border-radius: var(--wp-radius);
    background: var(--wp-highlight);
}

.wp-fdb-banner--obsolete {
    border-left-color: var(--wp-error);
    background: color-mix(in srgb, var(--wp-error) 12%, var(--wp-surface));
}

/* The Regulatory tab's obsolete date, washed like the badge. */
.wp-fdb-row--obsolete {
    padding: .25rem .5rem;
    border-radius: var(--wp-radius);
    background: color-mix(in srgb, var(--wp-error) 12%, var(--wp-surface));
}

/* A script focus after a mouse click (the drawer heading or the no-record sentence taking focus once a record is in)
   draws no box; keyboard users keep the browser's focus ring, which :focus-visible still matches. */
.wp-product-fragment [data-product-focus]:focus:not(:focus-visible),
#productTitle:focus:not(:focus-visible) {
    outline: none;
}

/* Pricing's two headline figures, side by side while they fit. */
.wp-fdb-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
    gap: .75rem;
    margin-bottom: 1rem;
}

.wp-fdb-tile {
    padding: .75rem 1rem;
    border: 1px solid var(--wp-border);
    border-radius: var(--wp-radius);
    background: var(--wp-surface);
}

.wp-fdb-tile__label {
    display: block;
    font-size: var(--wp-font-size-sm);
    font-weight: 700;
}

.wp-fdb-tile__value {
    display: block;
    font-size: var(--wp-h2);
    font-weight: 700;
}

/* The drawer's tables (ingredients, classes, prices, attributes): the velocity report's header and zebra, but text
   wraps, since FDB's descriptions are long and the drawer is narrow. Scrolls sideways rather than squeezing. */
.wp-fdb-table-wrap {
    overflow-x: auto;
}

.wp-fdb-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--wp-font-size-table);
}

.wp-fdb-table th,
.wp-fdb-table td {
    padding: .5rem .75rem;
    text-align: left;
    vertical-align: top;
    overflow-wrap: break-word;
}

.wp-fdb-table thead th {
    background: var(--wp-grid-header);
    font-weight: 700;
}

/* Every other VISIBLE row: a price row the user hid (hidden) must not break the stripes. */
.wp-fdb-table tbody tr:nth-child(even of :not([hidden])) td {
    background: var(--wp-row-alt);
}

.wp-fdb-table .wp-fdb-num {
    text-align: right;
}

/* A date stays on one line ("Nov 23, 2015"); the long price type names wrap instead. */
.wp-fdb-table .wp-fdb-date {
    white-space: nowrap;
}

/* The icon before each card's title, as in the design: the action colour, a little larger than the title, close to it.
   The panel header's own flex gap (1rem, for the velocity panel's subtitle) is too wide between an icon and its title. */
.wp-product-detail .k-panelbar > .k-panelbar-header > .k-link .k-panelbar-item-text {
    gap: .5rem;
}

.wp-product-card-icon {
    color: var(--wp-action);
    font-size: 1.25em;
    line-height: 1;
}

/* The Morris & Dickson Details card's icon is the M&D monogram, an image (img/md-monogram.png, drawn at a third of its
   height for high-DPI screens) in place of a Material Design glyph: the glyphs' 1em box, widened to the monogram's
   proportions. It keeps its brand colour, so the action colour above has nothing to paint. */
.wp-icon-md-monogram {
    display: inline-block;
    width: 2.6em;
    height: 1em;
    background: url("../img/md-monogram.png") no-repeat center / contain;
}

/* The drawer layout. Hidden data points, price rows, tiles and sentences use the hidden attribute; some of them set
   their own display, which outranks the browser's [hidden] rule, so it is restated here (the same pairing as
   .wp-filters [hidden]). */
.wp-product-fragment [hidden] {
    display: none;
}

/* A table whose every row the user hid shows no orphan header, and two hidden tiles leave no empty gap. */
.wp-fdb-table-wrap:not(:has(tbody tr:not([hidden]))),
.wp-fdb-tiles:not(:has(> :not([hidden]))) {
    display: none;
}

/* The drag handle before each card's icon (product-drawer-customize.js sorts by it), in the card icon's colour. Shown on
   hover, while dragging, when the panel bar's keyboard focus is on the card (.k-focus on its link: the panel bar keeps
   DOM focus on its root) and while the card's ⋯ button has focus; invisible, not removed, otherwise, so the title never
   shifts. */
.wp-product-drag {
    visibility: hidden;
    color: var(--wp-action);
    font-size: 1.25em;
    line-height: 1;
    cursor: grab;
}

.wp-product-detail .k-panelbar-header:hover .wp-product-drag,
.wp-product-detail .k-panelbar-header > .k-link.k-focus .wp-product-drag,
.wp-product-detail .k-panelbar-header:has(> .wp-product-card-menu:focus) .wp-product-drag,
.wp-product-sort-hint .wp-product-drag {
    visibility: visible;
}

/* The ⋯ button of each card (product-drawer-customize.js): a real button beside the header link, not inside it, at the
   header's right edge (the theme moves the expand arrow to the left, so nothing else is there). 28px square: above
   the 24px minimum target.
   The header item also holds the open card's content, so a percentage top would centre on the whole card. Instead
   the link gets a fixed minimum height and the button's top is derived from that same value, so the two stay centred
   together; the 3.5rem equals the link's natural height (1rem padding twice around a 1.5rem line). The right inset
   is the link's own 1rem padding, and the link reserves the button's width plus an 8px gap so a title never touches it. */
.wp-product-detail .k-panelbar > .k-panelbar-header {
    --wp-product-header-height: 3.5rem;
    --wp-product-header-inset: 1rem;
    --wp-product-menu-size: 1.75rem;
    position: relative;
}

.wp-product-detail .k-panelbar > .k-panelbar-header > .k-link {
    box-sizing: border-box;
    min-height: var(--wp-product-header-height);
    align-items: center;
    padding-inline-end: calc(var(--wp-product-header-inset) + var(--wp-product-menu-size) + .5rem);
}

.wp-product-card-menu {
    position: absolute;
    top: calc((var(--wp-product-header-height) - var(--wp-product-menu-size)) / 2);
    right: var(--wp-product-header-inset);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--wp-product-menu-size);
    height: var(--wp-product-menu-size);
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--wp-action);
    cursor: pointer;
}

    .wp-product-card-menu:hover,
    .wp-product-card-menu[aria-expanded="true"] {
        background: color-mix(in srgb, var(--wp-action) 10%, transparent);
    }

    .wp-product-card-menu:focus-visible {
        outline: 2px solid var(--wp-action);
        outline-offset: 1px;
    }

    .wp-product-card-menu .mdi {
        font-size: 1.25rem;
        line-height: 1;
    }

/* A custom tab's foot, under its cards: a dashed Add card that fills the row, the muted note, and Delete this tab… as a
   text button. Deleting is not an error, so it keeps the action colour. Add card is aria-disabled (still focusable, so
   it can say why) at the limit of cards. */
.wp-product-custom-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem;
    margin-block-start: .75rem;
}

.wp-product-add-card {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .25rem;
    width: 100%;
    min-height: 2.75rem;
    border: 2px dashed var(--wp-action);
    border-radius: var(--wp-radius);
    background: var(--wp-surface);
    color: var(--wp-action);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

    .wp-product-add-card:hover {
        background: color-mix(in srgb, var(--wp-action) 8%, transparent);
    }

    .wp-product-add-card:focus-visible {
        outline: 2px solid var(--wp-action);
        outline-offset: 2px;
    }

    .wp-product-add-card[aria-disabled="true"] {
        border-color: var(--wp-border);
        background: var(--wp-surface);
        color: var(--wp-hint);
        cursor: not-allowed;
    }

.wp-product-delete-tab {
    min-width: 24px;
    min-height: 24px;
    margin-inline-start: auto;
    padding: .25rem .5rem;
    border: 0;
    background: transparent;
    color: var(--wp-action);
    font: inherit;
    cursor: pointer;
}

    .wp-product-delete-tab:hover {
        text-decoration: underline;
    }

    .wp-product-delete-tab:focus-visible {
        outline: 2px solid var(--wp-action);
        outline-offset: 1px;
    }

    /* While the drawer's operation gate is closed (a save is out) or custom editing is unavailable: still focusable. */
    .wp-product-delete-tab[aria-disabled="true"] {
        color: var(--wp-hint);
        text-decoration: none;
        cursor: not-allowed;
    }

    /* Delete this tab… asks in the foot, in place of its contents (hidden: Add card's own display would otherwise win over
       the hidden attribute). */
    .wp-product-custom-foot > [hidden] {
        display: none;
    }

/* The foot's question: "Delete Purchasing and its 3 cards?" (it holds the user's label, so it wraps anywhere), then
   Delete and Keep. Its buttons share the builder's aria-disabled look while a save is out. */
.wp-product-custom-confirm {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    width: 100%;
}

.wp-product-custom-confirm__question {
    flex: 1 1 12rem;
    margin: 0;
    overflow-wrap: anywhere;
}

/* The + that adds a custom tab (product-custom-tabs.js): the first child of the tab strip's items wrapper, a flex row,
   so it sits first on the tab row, before the custom tabs, outside the tab list, and stays in view when they scroll.
   Kendo prepends its previous-scroll button to the same row whenever the tabs start to overflow, so order: -1 keeps +
   first on screen whichever of the two came first. Dashed like Add card; 28px square, above the 24px minimum target.
   aria-disabled (still focusable, so a press can say why) at the tab limit and while a save is out. */
.wp-product-add-tab {
    order: -1;
    display: inline-flex;
    flex: none;
    align-self: center;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    margin-inline: .5rem;
    padding: 0;
    border: 2px dashed var(--wp-action);
    border-radius: var(--wp-radius);
    background: var(--wp-surface);
    color: var(--wp-action);
    cursor: pointer;
}

    .wp-product-add-tab:hover {
        background: color-mix(in srgb, var(--wp-action) 8%, transparent);
    }

    .wp-product-add-tab:focus-visible {
        outline: 2px solid var(--wp-action);
        outline-offset: 2px;
    }

    .wp-product-add-tab[aria-disabled="true"] {
        border-color: var(--wp-border);
        background: var(--wp-surface);
        color: var(--wp-hint);
        cursor: not-allowed;
    }

    .wp-product-add-tab .mdi {
        font-size: 1.125rem;
        line-height: 1;
    }

/* The tab name box, in place of a custom tab's text while it is named or renamed. A name another tab has is a
   validation error (aria-invalid), so its border takes the status colour. */
.wp-product-tab-name {
    box-sizing: border-box;
    width: 16ch;
    padding: .125rem .375rem;
    border: 1px solid var(--wp-action);
    border-radius: var(--wp-radius);
    background: var(--wp-surface);
    color: var(--wp-text);
    font: inherit;
}

    .wp-product-tab-name:focus-visible {
        outline: 2px solid var(--wp-action);
        outline-offset: 1px;
    }

    .wp-product-tab-name[aria-invalid="true"] {
        border-color: var(--wp-error);
    }

/* The name box's message ("You already have a tab named ..."), at the top of the tab's panel, just under the tab row. */
.wp-product-tab-name__error {
    display: block;
    margin-block-end: .5rem;
    color: var(--wp-error);
    font-size: var(--wp-font-size-sm);
}

/* The card builder (product-custom-builder.js): a card being made, above the tab's foot. Dashed in the action colour,
   like Add card, so it reads as not yet saved. Its icon button, name, rows of values, the value search and its buttons
   stack in one column. */
.wp-product-builder {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    margin-block-start: .75rem;
    padding: .75rem;
    border: 2px dashed var(--wp-action);
    border-radius: var(--wp-radius);
    background: var(--wp-surface);
}

.wp-product-builder__head {
    display: flex;
    align-items: center;
    gap: .5rem;
}

.wp-product-builder__name {
    flex: 1 1 auto;
    min-width: 0;
}

    /* The name while the builder's own save is out: read-only, so it is muted rather than looking editable. The rules
       name the input: a bare :has(> [readonly]) was re-checked for every element added anywhere in the page. */
    .wp-product-builder__name:has(> input[readonly]) {
        background: var(--wp-surface);
        color: var(--wp-hint);
        cursor: not-allowed;
    }

        .wp-product-builder__name > input[readonly] {
            color: var(--wp-hint);
            cursor: not-allowed;
        }

    /* The name or the value search a Create found a problem with: the status colour, as any field in error. */
    .wp-product-builder__name:has(> [aria-invalid="true"]),
    .wp-product-builder__search .k-input:has(> [aria-invalid="true"]) {
        border-color: var(--wp-error);
    }

/* The card's icon (the icon picker opens from it) and each row's Move up, Move down and Remove: 28px square, above the
   24px minimum target. aria-disabled (still focusable) at the ends of the list and while the drawer's gate is closed. */
.wp-product-builder__icon,
.wp-product-builder__button {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    padding: 0;
    border: 0;
    border-radius: var(--wp-radius);
    background: transparent;
    color: var(--wp-action);
    cursor: pointer;
}

.wp-product-builder__icon {
    border: 1px solid var(--wp-border);
}

    .wp-product-builder__icon:hover,
    .wp-product-builder__button:hover {
        background: color-mix(in srgb, var(--wp-action) 10%, transparent);
    }

    .wp-product-builder__icon:focus-visible,
    .wp-product-builder__button:focus-visible {
        outline: 2px solid var(--wp-action);
        outline-offset: 1px;
    }

    .wp-product-builder__icon[aria-disabled="true"],
    .wp-product-builder__icon[aria-disabled="true"]:hover,
    .wp-product-builder__button[aria-disabled="true"],
    .wp-product-builder__button[aria-disabled="true"]:hover {
        background: transparent;
        color: var(--wp-hint);
        cursor: not-allowed;
    }

    .wp-product-builder__icon .mdi,
    .wp-product-builder__button .mdi {
        font-size: 1.25rem;
        line-height: 1;
    }

    /* The picker keeps the chosen glyph in a preview span (.wp-icon-preview, 2rem wide for the coachmark form): here it
       fills the button instead. */
    .wp-product-builder__icon .wp-icon-preview {
        width: auto;
        color: inherit;
    }

/* The rows, as a list with separators; no list at all while the card has no value (the search is right below). */
.wp-product-builder__rows {
    margin: 0;
    padding: 0;
    list-style: none;
}

    .wp-product-builder__rows:empty {
        display: none;
    }

.wp-product-builder__row {
    display: flex;
    align-items: center;
    gap: .25rem;
    padding-block: .375rem;
    border-bottom: 1px solid var(--wp-border);
    background: var(--wp-surface);
}

    .wp-product-builder__row:first-child {
        border-top: 1px solid var(--wp-border);
    }

    /* The handle is the only thing a drag starts from, so it always shows here (a card's shows on hover). */
    .wp-product-builder__row .wp-product-drag {
        visibility: visible;
    }

.wp-product-builder__text {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-width: 0;
}

.wp-product-builder__note {
    color: var(--wp-hint);
    font-size: var(--wp-font-size-sm);
}

.wp-product-builder__search .k-autocomplete {
    width: 100%;
}

    /* At the value limit, or while the gate is closed: read-only, still focusable, and muted. */
    .wp-product-builder__search .k-input:has(> [aria-disabled="true"]:not([aria-invalid="true"])) {
        border-color: var(--wp-border);
        background: var(--wp-surface);
        cursor: not-allowed;
    }

/* The value search's list (a Kendo popup on the page body): each option is the value's label and the item's value for
   it ("Strength: 500 mg"), on one line, cut off with an ellipsis (the option's title holds the whole line). The list item
   lays its text out as a flex item, which grows to its content unless it may shrink and clip. The value is muted, so the
   name reads first. */
.k-list-item-text:has(> .wp-product-builder__option) {
    min-width: 0;
    overflow: hidden;
}

.wp-product-builder__option {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.wp-product-builder__value {
    color: var(--wp-hint);
}

.wp-product-builder__foot {
    display: flex;
    justify-content: flex-end;
    gap: .5rem;
}

    /* Create and Cancel (and the tab foot's Delete and Keep) while the gate is closed (a save is out): still focusable, so
       focus never drops. */
    .wp-product-builder__foot .k-button[aria-disabled="true"],
    .wp-product-custom-confirm .k-button[aria-disabled="true"] {
        opacity: .6;
        cursor: not-allowed;
    }

    /* Dimmed is the whole of the state: a button that does nothing must not react to the pointer. Kendo draws the flat
       button's hover tint as a ::before layer (its background is !important, so it cannot be reset here), and lifts the
       solid one with a shadow and a darker fill. */
    .wp-product-builder__foot .k-button[aria-disabled="true"]:hover::before,
    .wp-product-custom-confirm .k-button[aria-disabled="true"]:hover::before {
        opacity: 0;
    }

    .wp-product-builder__foot .k-button.k-button-solid[aria-disabled="true"]:hover,
    .wp-product-custom-confirm .k-button.k-button-solid[aria-disabled="true"]:hover {
        background-color: var(--kendo-color-primary);
        border-color: var(--kendo-color-primary);
    }

    /* No elevation on hover. Kendo's focus indicator on this button is an inset shadow (it has no outline), so a focused
       Create keeps exactly that ring and drops only the lift. */
    .wp-product-builder__foot .k-button.k-button-solid[aria-disabled="true"]:hover:not(:focus),
    .wp-product-custom-confirm .k-button.k-button-solid[aria-disabled="true"]:hover:not(:focus) {
        box-shadow: none;
    }

    .wp-product-builder__foot .k-button.k-button-solid[aria-disabled="true"]:hover:focus,
    .wp-product-custom-confirm .k-button.k-button-solid[aria-disabled="true"]:hover:focus {
        box-shadow: inset 0 0 0 calc(1px * 3) var(--kendo-color-app-surface), inset 0 0 0 calc(1px * 5) var(--kendo-color-primary);
    }

/* A problem Create found, or why a save failed: validation is a status, so it takes the status colour. */
.wp-product-builder__error {
    margin: 0;
    color: var(--wp-error);
    font-size: var(--wp-font-size-sm);
}

/* The ⋯ dialog: the grid column panel's card (.wp-column-panel), its actions above the data points (a custom card has
   none, so the rule between them belongs to the list). An action the card does not offer is hidden: a Kendo button's
   own display would otherwise win over the hidden attribute. */
.wp-product-menu [hidden] {
    display: none;
}

.wp-product-menu__actions {
    display: flex;
    flex-direction: column;
    padding: .5rem 0;
}

    .wp-product-menu__actions .k-button {
        justify-content: flex-start;
        padding-inline: 1rem;
        border-radius: 0;
    }

.wp-product-menu .wp-column-panel__list {
    border-top: 1px solid var(--wp-border);
}

/* A custom card's Delete card… asks here, in place of the actions: the question (it holds the user's label, so it wraps
   anywhere), then Delete and Keep. */
.wp-product-menu__confirm {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    padding: .75rem 1rem;
}

.wp-product-menu__question {
    margin: 0;
    overflow-wrap: anywhere;
}

.wp-product-menu__answers {
    display: flex;
    justify-content: flex-end;
    gap: .5rem;
}

/* While a card is dragged: a chip that follows the pointer (handle, icon, label; no body), and the gap where it would
   land. Kendo appends the chip to the body, outside .wp-product-detail, so it carries its own look: the card's surface,
   border, radius and title type. Its max-width is set to the card's width in script, so it cannot overflow the page. */
.wp-product-sort-hint {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    box-sizing: border-box;
    padding: .5rem 1rem;
    border: 1px solid var(--wp-border);
    border-radius: var(--wp-radius-lg);
    background: var(--wp-surface);
    box-shadow: var(--wp-shadow-popup);
    font-size: var(--wp-h2);
    font-weight: 700;
    white-space: nowrap;
}

.wp-product-sort-hint__label {
    overflow: hidden;
    text-overflow: ellipsis;
}

.wp-product-sort-placeholder {
    opacity: .4;
}

/* The gear in the drawer's title bar, beside Close (product-detail-pane.js moves it there): Close's colour, so it reads
   the same on the title bar; 28px square. Shown only while the fragment has tabs. */
.wp-product-gear {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: inherit;
    cursor: pointer;
}

    .wp-product-gear[hidden] {
        display: none;
    }

    .wp-product-gear:hover,
    .wp-product-gear[aria-expanded="true"] {
        background: color-mix(in srgb, currentColor 12%, transparent);
    }

    .wp-product-gear:focus-visible {
        outline: 2px solid currentColor;
        outline-offset: 1px;
    }

    .wp-product-gear .mdi {
        font-size: 1.25rem;
        line-height: 1;
    }

/* The gear's dialog: each tab with its cards indented under it. */
.wp-product-gear__cards {
    margin: 0;
    padding: 0 0 0 1.5rem;
    list-style: none;
}

/* An entry this item does not supply, still offered (a choice carries over to the items that have it): a muted note
   after its name. */
.wp-product-gear__note {
    color: var(--wp-hint);
    font-size: var(--wp-font-size-sm);
}

/* What the gear hides with the hidden attribute (a reset's question, a row's Delete… while it asks): a Kendo button's own
   display would otherwise win over it. */
.wp-product-gear-panel [hidden] {
    display: none;
}

/* Your tabs and Start on, under the tree and ruled off from it. The tree scrolls; this part keeps its height. Labels are
   the user's, so a long one wraps anywhere. */
.wp-product-gear__custom {
    flex: none;
    padding: .5rem 1rem .75rem;
    border-top: 1px solid var(--wp-border);
}

.wp-product-gear__heading {
    margin: 0 0 .25rem;
    font-size: var(--wp-h3);
    font-weight: 600;
}

.wp-product-gear__tabs {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* A custom tab: its name and card count, then Delete… (the tab foot's link-like button, pushed to the row's end). While
   it asks, the question and its buttons take the row (.wp-product-custom-confirm). */
.wp-product-gear__custom-tab {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem .5rem;
    min-height: 2rem;
}

.wp-product-gear__tab-name {
    flex: 1 1 8rem;
    min-width: 0;
    overflow-wrap: anywhere;
}

.wp-product-gear__count,
.wp-product-gear__empty {
    color: var(--wp-hint);
}

.wp-product-gear__empty {
    margin: 0;
    font-size: var(--wp-font-size-sm);
}

    /* Delete… in the gear is disabled (the gear's controls use disabled) while the gate is closed. */
    .wp-product-gear__custom .wp-product-delete-tab:disabled {
        color: var(--wp-hint);
        text-decoration: none;
        cursor: not-allowed;
    }

.wp-product-gear__start {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-top: .5rem;
}

    .wp-product-gear__start label {
        flex: none;
        white-space: nowrap;
    }

/* Start on: a native select, drawn with the theme's tokens. */
.wp-product-gear__select {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 2rem;
    padding: .25rem .5rem;
    border: 1px solid var(--wp-border);
    border-radius: var(--wp-radius);
    background: var(--wp-surface);
    color: var(--wp-text);
    font: inherit;
}

    .wp-product-gear__select:hover:not(:disabled) {
        border-color: var(--wp-action);
    }

    .wp-product-gear__select:focus-visible {
        outline: 2px solid var(--wp-action);
        outline-offset: 1px;
    }

    .wp-product-gear__select:disabled {
        color: var(--wp-hint);
        cursor: not-allowed;
    }

/* The gear's foot holds two resets, so it wraps; Reset everything…'s question takes a line of its own above its buttons,
   and a reset that was not sent says so on the line under them (a status, so it takes the status colour). */
.wp-product-gear-panel .wp-column-panel__footer {
    flex-wrap: wrap;
    gap: .5rem;
}

.wp-product-gear__confirm {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: .5rem;
    width: 100%;
}

.wp-product-gear__question {
    flex-basis: 100%;
    margin: 0;
}

.wp-product-gear__error {
    flex-basis: 100%;
    margin: 0;
    color: var(--wp-error);
    font-size: var(--wp-font-size-sm);
}

/* The full Product Velocity Report (velocity-report.js), inline in the Product Details drawer's Velocity tab
   (product-detail-pane.js): a breadcrumb band, the date range and the table / chart toggle, then a
   titled section per table. */
.wp-velocity-body {
    margin-top: .5rem;
}

.wp-velocity-crumbs ol {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin: 0 0 1rem;
    padding: .5rem 1rem;
    list-style: none;
    border-radius: var(--wp-radius);
    background: var(--wp-coachmark-fill);
}

.wp-velocity-crumbs li + li::before {
    content: ">";
    margin-right: .5rem;
}

.wp-velocity-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: .5rem;
}

.wp-velocity-range {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: .5rem 1rem;
}

/* The picker as wide as its two month fields, so the label, the picker and Apply share a line. */
.wp-velocity-range .k-daterangepicker {
    width: auto;
    flex: none;
}

.wp-velocity-section {
    margin-top: 1.5rem;
}

.wp-velocity-title {
    margin: 0 0 .75rem;
    font-size: var(--wp-h2);
    font-weight: 700;
}

/* The months run across, so a long window scrolls sideways inside the section, never the pane;
   the first column (account or item) stays in view while it does. */
.wp-velocity-table-wrap {
    overflow-x: auto;
}

.wp-velocity-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--wp-font-size-table);
    white-space: nowrap;
}

.wp-velocity-table th,
.wp-velocity-table td {
    padding: .5rem .75rem;
    text-align: right;
    vertical-align: top;
}

.wp-velocity-table thead th {
    background: var(--wp-grid-header);
    font-weight: 700;
}

.wp-velocity-table th[scope="row"],
.wp-velocity-table thead th:first-child {
    position: sticky;
    left: 0;
    text-align: left;
    background: var(--wp-surface);
}

.wp-velocity-table thead th:first-child {
    background: var(--wp-grid-header);
}

.wp-velocity-table tbody tr:nth-child(even) td,
.wp-velocity-table tbody tr:nth-child(even) th {
    background: var(--wp-row-alt);
}

.wp-velocity-table__totals th,
.wp-velocity-table__totals td {
    font-weight: 700;
}

/* A month's units over what they were ordered for. */
.wp-velocity-units,
.wp-velocity-amount {
    display: block;
}
