//
// Shoptet brand theme — the admin in the shoptet.cz visual language.
//
// Re-declares both token layers: Layer A (legacyTokens.css --colors-*, the admin
// chrome) and Layer B (tokens.css --*--light, the design system). Everything is
// scoped under body.theme-brand, so the sheet is inert without the class and
// ships everywhere through the package index — the admin gets it via main.less,
// embedded iframes via their own @shoptet/ui CSS; the body classes alone switch
// the design.
//

// @screen-* breakpoints come from ../tokens/dimensions.less, which every consumer
// imports first (index.less, the stylesheet-test preludes).
// The admin's "below the desktop grid" query (v2/variables.less @max-xl):
@screen-max-xl: ~'only screen and (max-width: 1023.89px)';

@brand-blue: #0065f1;
@brand-blue-hover: #0058d4;
@brand-blue-deep: #0b4ba8;
@blue-tint: #e5efff;
@blue-tint-hover: #c9ddfa;
@blue-pale: #f2f7ff;
@ink: #292824;
@ink-deep: #161513;
@gray-100: #efeeed;
@gray-200: #dfdedb;
@gray-350: #918f89;
@gray-400: #82807a;
@gray-500: #65635e;
@critical: #cd1900;
@critical-hover: #a81400;
@critical-pale: #fdf1ef;
@amber: #ffb719;
@amber-ink: #a55a00;
@amber-pale: #fff3dc;
@green-ink: #01782e;
@green-pale: #e4f4e6;
@notice-ink: #0068cc;

body.theme-brand {
  // Marketing surfaces read the opposite way from toolbars: there the tinted CTA is
  // the card's one action, so it promotes to the action pair (dark-correct, since it
  // routes through the same tokens). The working admin keeps the calm tint.
  @promoted-cta: ~':not(:disabled):not([disabled]):not(.disabled):not(.btn-disabled)';

  // Layout — the design's floating chrome, measured off the frames at their own
  // 1470px width: a 228px rail with no surface of its own, a 44px stadium bar 12px
  // below the top, 12px of desk under it, and a card hinged at the rail that bleeds
  // off the right edge (left corners 32, right square, 24px inset, 12px apart).
  // Both floating-toolbar rules solve the same geometry, so it lives once.
  @floating-toolbar-inset: ~'clamp(var(--spacing-xl), calc(50vw - 810px), 90000px)';

  // --- Inputs: one step darker than the container hairline ---
  // Fields re-declare the hairline token so 'editable' reads distinct from
  // 'container' without turning dense filter grids into wireframes. Focus and
  // error borders use separate tokens and stay loud.
  // The text-and-select family, shared by the four field blocks below. One
  // LESS list so a field added to the DS is added to the theme exactly once;
  // blocks that reach further (textarea, toggles, checkboxes) append openly.
  // The control's box: --size--formField is its content height, the DS adds the
  // two borders. Held here because a scoped override of the size (the in-row tier)
  // only reaches an expression evaluated at the point of use.
  @field-box: ~'calc(var(--size--formField) + 2 * var(--borderWidth--line))';

  @field-family: ~"input[type='text'], input[type='number'], select, .textField, .passwordField, .emailField, .phoneField, .numberField, .searchField, .dateField, .colorField, .selectField, .multiSelectField";

  --colors-interactive-primary-enabled: @brand-blue;
  --colors-interactive-primary-hover: @brand-blue-hover;
  --colors-interactive-primary-disabled: @gray-350;
  --colors-interactive-focus-primary: @brand-blue;
  --colors-interactive-action-enabled: @brand-blue;
  --colors-interactive-action-hover: @brand-blue-hover;
  --colors-interactive-action-disabled: @gray-350;
  --colors-interactive-content-secondary: @ink;
  --colors-interactive-secondary-enabled: @gray-500;
  --colors-interactive-secondary-hover: @ink;
  --colors-interactive-secondary-activated: @brand-blue;
  --colors-interactive-secondary-disabled: @gray-350;
  --colors-interactive-tertiary-enabled: @ink;
  --colors-interactive-tertiary-hover: @ink-deep;
  --colors-interactive-tertiary-activated: @brand-blue;
  --colors-interactive-ghost-hover: @gray-100;
  --colors-interactive-ghost-activated: @ink;
  --colors-interactive-ghost-activated-hover: @ink-deep;
  --colors-interactive-ghost-subtle: @blue-tint;
  --colors-interactive-ghost-subtle-hover: @blue-tint-hover;
  --colors-interactive-destructive-enabled: @critical;
  --colors-interactive-destructive-hover: @critical-hover;
  --colors-interactive-destructive-disabled: @gray-350;

  // Interactive — links, tabs, loader. blue-800, not blue-700: links land on
  // white, on #efeeed and on the error tint, where #0065f1 is 3.88:1.
  --colors-interactive-links-enabled: @brand-blue-hover;
  --colors-interactive-links-hover: @brand-blue-deep;
  --colors-interactive-links-disabled: #0065f10d;
  --colors-interactive-tabs-border: transparent;
  --colors-interactive-tabs-background-enabled: @gray-100;
  --colors-interactive-tabs-background-hover: @brand-blue;
  // Blue means selected in this theme; green stays confirm/save.
  --colors-interactive-tabs-selected-indicator: @brand-blue;
  // The tab strip is one step lighter than ghost-subtle, which is its hover.
  --colors-interactive-tabs-strip: #ebf3ff;
  --colors-interactive-loader-light-background: @blue-tint;
  --colors-interactive-loader-light-foregrounds: @brand-blue;
  --colors-surface-primary: #fafafa;
  // One step under the card's white: at #f7f7f6 a section band read as a smudge.
  --colors-surface-light-gray: @gray-100;
  --colors-surface-light-blue: @blue-pale;
  --colors-surface-inverted: @ink;
  --colors-tables-backgrounds-secondary: #f7f7f6;
  --colors-tables-backgrounds-tertiary: @gray-100;
  --colors-tables-border-primary: #e7e6e4;
  --colors-tables-border-secondary: @brand-blue;
  --colors-tables-states-success: #d5eed8;
  --colors-tables-states-warning: #ffd898;
  --colors-tables-states-critical: #fbd5cf;
  --colors-tables-states-notice: @blue-pale;
  --colors-sidebar-backgrounds-enabled: @gray-100;
  --colors-sidebar-backgrounds-hover: @gray-200;
  --colors-sidebar-backgrounds-activated: #edeae8;
  --colors-sidebar-content-enabled: @ink;
  --colors-sidebar-content-activated: @ink;
  --colors-sidebar-content-disabled: @gray-350;
  --colors-lists-background-hover: @gray-100;
  --colors-lists-background-activated: @blue-tint;
  --colors-lists-content-enabled: @ink;
  --colors-lists-content-activated: @brand-blue;
  --colors-lists-content-disabled: @gray-350;
  --colors-foregrounds-content-primary: @ink;
  --colors-foregrounds-content-secondary: @gray-500;
  --colors-foregrounds-content-tertiary: @gray-400;
  --colors-foregrounds-headlines-primary: @ink-deep;
  --colors-foregrounds-headlines-secondary: @ink;
  --colors-foregrounds-headlines-tertiary: @ink;
  --colors-foregrounds-icons-primary: @ink;
  --colors-foregrounds-icons-secondary: @gray-400;
  --colors-foregrounds-borders-primary: @gray-100;
  --colors-foregrounds-borders-secondary: @gray-200;
  --colors-forms-border: @gray-200;
  --colors-forms-activated: @brand-blue;
  --colors-forms-shadow: @brand-blue;
  --colors-forms-critical: @critical;
  --colors-forms-warning: @amber;
  --colors-forms-disabled: @gray-100;
  --colors-states-primary-success: @green-ink;
  --colors-states-primary-alert: @amber;
  --colors-states-primary-error: @critical;
  // Darker than the site's blue-500: .circled status badges put white text
  // on this fill, which only reached 3.3:1 at #008fff.
  --colors-states-primary-notice: @notice-ink;
  --colors-states-primary-informative: @brand-blue-deep;
  --colors-states-primary-default: @gray-500;
  --colors-states-secondary-success: @green-pale;
  --colors-states-secondary-alert: @amber-pale;
  --colors-states-secondary-error: @critical-pale;
  --colors-states-secondary-notice: @blue-pale;
  --colors-states-secondary-informative: @blue-tint;
  --colors-states-secondary-default: @gray-200;
  --colors-code-snippet-background: #f0f5f9;
  --colors-code-snippet-border: @blue-tint-hover;
  --effect-box-shadow-shadow-focus: 0 0 0 3px rgb(0 101 241 / 35%);
  --effect-box-shadow-shadow-down: 0 2px 16px 0 rgb(35 32 26 / 12%);
  --background--controls-medium-default--light: red(@brand-blue) green(@brand-blue) blue(@brand-blue);
  --background--controls-medium-hovered--light: red(@brand-blue-hover) green(@brand-blue-hover) blue(@brand-blue-hover);
  --background--controls-medium-selected--light: red(@brand-blue) green(@brand-blue) blue(@brand-blue);
  --background--controls-low-default--light: red(@blue-tint) green(@blue-tint) blue(@blue-tint);
  --background--controls-low-hovered--light: red(@blue-tint-hover) green(@blue-tint-hover) blue(@blue-tint-hover);
  --background--blue-low-default--light: red(@blue-pale) green(@blue-pale) blue(@blue-pale);
  --background--main-medium-default--light: red(@brand-blue) green(@brand-blue) blue(@brand-blue);
  --background--main-medium-hovered--light: red(@brand-blue-hover) green(@brand-blue-hover) blue(@brand-blue-hover);
  --background--main-medium-selected--light: red(@brand-blue) green(@brand-blue) blue(@brand-blue);
  --background--neutral-low-default--light: red(@gray-100) green(@gray-100) blue(@gray-100);
  --background--neutral-low-hovered--light: red(@gray-200) green(@gray-200) blue(@gray-200);
  --background--neutral-high-default--light: 137 136 130;
  --background--neutral-strong-default--light: red(@ink) green(@ink) blue(@ink);
  --background--neutral-full-default--light: red(@ink-deep) green(@ink-deep) blue(@ink-deep);
  --background--success-low-default--light: red(@green-pale) green(@green-pale) blue(@green-pale);
  --background--success-high-default--light: 0 165 0;
  --background--warning-low-default--light: red(@amber-pale) green(@amber-pale) blue(@amber-pale);
  --background--warning-medium-default--light: red(@amber) green(@amber) blue(@amber);
  --background--critical-low-default--light: red(@critical-pale) green(@critical-pale) blue(@critical-pale);
  --background--critical-high-default--light: 227 45 25;
  --background--critical-high-hovered--light: red(@critical-hover) green(@critical-hover) blue(@critical-hover);
  --background--critical-xHigh-default--light: red(@critical) green(@critical) blue(@critical);
  --background--informative-low-default--light: red(@blue-pale) green(@blue-pale) blue(@blue-pale);
  --background--informative-xHigh-default--light: red(@brand-blue-deep) green(@brand-blue-deep) blue(@brand-blue-deep);
  --background--notice-medium-default--light: red(@notice-ink) green(@notice-ink) blue(@notice-ink);
  --foreground--neutral-full-default--light: red(@ink) green(@ink) blue(@ink);
  --foreground--neutral-full-hovered--light: red(@ink-deep) green(@ink-deep) blue(@ink-deep);
  --foreground--neutral-high-default--light: red(@gray-500) green(@gray-500) blue(@gray-500);
  --foreground--neutral-medium-default--light: red(@gray-400) green(@gray-400) blue(@gray-400);
  --foreground--neutral-low-default--light: red(@gray-350) green(@gray-350) blue(@gray-350);

  // Headings take the body ink: a heading over a paragraph is one voice at two weights.
  --foreground--blue-medium-default--light: red(@ink) green(@ink) blue(@ink);
  --foreground--controls-medium-default--light: red(@brand-blue) green(@brand-blue) blue(@brand-blue);
  --foreground--controls-medium-hovered--light: red(@brand-blue-hover) green(@brand-blue-hover) blue(@brand-blue-hover);
  --foreground--controls-medium-selected--light: red(@brand-blue) green(@brand-blue) blue(@brand-blue);
  --foreground--links-strong-default--light: red(@brand-blue-hover) green(@brand-blue-hover) blue(@brand-blue-hover);
  --foreground--links-strong-hovered--light: red(@brand-blue-deep) green(@brand-blue-deep) blue(@brand-blue-deep);
  // Read only by <strong> accents inside headings (the order/document number).
  --foreground--green-medium-default--light: red(@ink) green(@ink) blue(@ink);
  --foreground--main-medium-default--light: red(@brand-blue-hover) green(@brand-blue-hover) blue(@brand-blue-hover);
  --foreground--main-medium-hovered--light: red(@brand-blue-deep) green(@brand-blue-deep) blue(@brand-blue-deep);

  // Foregrounds — states. Each has to clear 4.5:1 on its own *-low tint, not just
  // on white: the notice surfaces put it on amber/green/red.
  --foreground--success-high-default--light: 0 117 43;
  --foreground--warning-medium-default--light: red(@amber-ink) green(@amber-ink) blue(@amber-ink);
  --foreground--notice-medium-default--light: 0 110 196;
  --foreground--critical-high-default--light: red(@critical) green(@critical) blue(@critical);
  --foreground--critical-high-hovered--light: red(@critical-hover) green(@critical-hover) blue(@critical-hover);
  --foreground--informative-strong-default--light: red(@brand-blue-deep) green(@brand-blue-deep) blue(@brand-blue-deep);
  --border--neutral-low-default--light: red(@gray-200) green(@gray-200) blue(@gray-200);
  --border--neutral-medium-default--light: red(@gray-350) green(@gray-350) blue(@gray-350);
  --border--neutral-high-default--light: red(@gray-200) green(@gray-200) blue(@gray-200);
  --border--neutral-full-hovered--light: red(@ink) green(@ink) blue(@ink);
  --border--controls-low-default--light: red(@blue-tint-hover) green(@blue-tint-hover) blue(@blue-tint-hover);
  --border--controls-medium-default--light: red(@brand-blue) green(@brand-blue) blue(@brand-blue);
  --border--controls-medium-hovered--light: red(@brand-blue-hover) green(@brand-blue-hover) blue(@brand-blue-hover);
  --border--controls-medium-selected--light: red(@brand-blue) green(@brand-blue) blue(@brand-blue);
  --border--blue-medium-default--light: red(@brand-blue) green(@brand-blue) blue(@brand-blue);
  --border--links-strong-default--light: red(@brand-blue) green(@brand-blue) blue(@brand-blue);
  --border--main-medium-default--light: red(@brand-blue) green(@brand-blue) blue(@brand-blue);
  --border--main-medium-hovered--light: red(@brand-blue-hover) green(@brand-blue-hover) blue(@brand-blue-hover);
  --border--success-high-default--light: red(@green-ink) green(@green-ink) blue(@green-ink);
  --border--warning-medium-default--light: red(@amber) green(@amber) blue(@amber);
  --border--critical-high-default--light: red(@critical) green(@critical) blue(@critical);
  --border--critical-high-hovered--light: red(@critical-hover) green(@critical-hover) blue(@critical-hover);
  --border--informative-strong-default--light: red(@brand-blue-deep) green(@brand-blue-deep) blue(@brand-blue-deep);
  --border--notice-medium-default--light: 0 143 255;
  --shadow--focus--light: 0 0 0 3px rgb(0 101 241 / 35%);
  --shadow--high-sharp--light: 0 2px 16px 0 rgb(35 32 26 / 12%);
  --fontWeight--headline-h1: 700;
  --fontWeight--headline-h2: 700;
  --fontWeight--headline-h3: 700;
  --fontWeight--headline-h4: 700;
  --fontWeight--headline-h5: 700;
  --fontWeight--headline-h1--sm: 700;
  --fontWeight--title-large: 700;
  --fontWeight--title-medium: 700;
  --fontWeight--title-small: 700;
  --fontWeight--controls-large: 500;
  --fontWeight--controls-medium: 500;
  --fontWeight--controls-small: 500;

  // Heading scale measured off the frames. h1 reads its --sm variant from @screen-sm
  // up, so the desktop size is the one to move.
  --fontSize--headline-h1: 22px;
  --fontSize--headline-h1--sm: 28px;
  --fontSize--headline-h2: 20px;
  --fontSize--headline-h3: 16px;
  --fontSize--headline-h4: 14px;
  --lineHeight--headline-h1: 28px;
  --lineHeight--headline-h1--sm: 36px;
  --lineHeight--headline-h2: 26px;
  --lineHeight--headline-h3: 22px;
  --lineHeight--headline-h4: 20px;
  --borderRadius--xs: 4px;
  --borderRadius--sm: 8px;
  --borderRadius--md: 12px;

  // Component tokens. The defaults mirror the historical hardcoded values and are
  // generated into tokens.css from tokens.config.ts; the theme only re-points them.
  // --size--formField is the control's content height (the DS adds the borders).
  --borderRadius--button: var(--borderRadius--sm);
  --borderRadius--formField: var(--borderRadius--sm);
  --borderRadius--checkboxField: var(--borderRadius--xs);
  // The token is the field's content height; the DS adds the two borders, so
  // 30 is the design's 36px control (and 30 is the 32px in-row tier below).
  --size--formField: 30px;

  // Theme knobs — colours the rules below need at a depth no token declaration
  // reaches (a component-scoped re-declaration, an alpha overlay, a filter, a
  // data-URI fill). Dark mode re-declares these names and never restates a rule.
  // header.less fills the bar from --user-color, which header.tpl emits only for a
  // merchant's pick; this is the fill and the ink staircase's fallback without one.
  --brand-header-fill: #fff;
  // Row rule between table cells — one step down from the container hairline.
  --brand-table-hairline: 219 218 215;
  --brand-field-frame: 145 143 137;
  --brand-field-frame-hover: 145 143 137;
  // The label on the strongest neutral fill (interactive-ghost-activated): the
  // selected tariff card, the picked day, the active wizard step, the chosen flag.
  --brand-ghost-activated-ink: #fff;
  // The offer card's fill (designer's F3F2F1).
  --brand-card-fill: 243 242 241;
  // The perex band's fill (designer's EBF3FF / 001638).
  --brand-perex-fill: 235 243 255;
  // The quiet button's hairline.
  --brand-btn-quiet-frame: 223 222 219;
  // The tinted button tier — fill, hover fill and label.
  --brand-btn-tinted-fill: 229 239 255;
  --brand-btn-tinted-fill-hovered: 201 221 250;
  --brand-btn-tinted-ink: 0 88 212;
  --brand-btn-tinted-ink-hovered: 0 61 166;
  // Interaction overlays, composed over whatever the surface under them is.
  --brand-overlay-row-hover: 22 21 19 / 4%;
  --brand-overlay-page-hover: 22 21 19 / 6%;
  // The shop pill: the bar, one shade deeper.
  --brand-shop-pill-fill: 0 0 0 / 10%;
  --brand-img-ink: brightness(0);
  // The whole image is the knob: a data-URI cannot read a token.
  --brand-caret: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M4.00011 7.93933L12.0001 15.9393L20.0001 7.93933L21.0608 8.99999L12.0001 18.0607L2.93945 8.99999L4.00011 7.93933Z' fill='%23292824'/%3E%3C/svg%3E");
  // The fixed action bar's edge and lift.
  --brand-bar-shadow-up: 0 -1px 0 rgb(22 21 19 / 6%), 0 -8px 24px rgb(0 0 0 / 6%);
  // The header search field, whose fill no rule sets — it is the engine's own
  // for an input, so it has to be stated to be themeable at all.
  --brand-search-fill: 255 255 255;
  --brand-control-ink: 41 40 36;

  h1:has(strong),
  .h1:has(strong) {
    font-weight: var(--fontWeight--display-medium);
  }

  .systemMessage__content h2,
  .systemMessage__content .typography__headline2 {
    text-transform: none;
  }

  // The notice inherited the page's 18px lines under its own 14px size (SystemMessage
  // reads body-large, the admin body stays at medium), so a notice beside a perex was
  // two voices in one text stack. The title keeps strong-large as its step up.
  .systemMessage {
    font-size: var(--fontSize--body-large);
    line-height: var(--lineHeight--body-large);
  }

  .modal__body {
    border: 1px solid rgb(var(--border--neutral-low-default--light));
    box-shadow: var(--shadow--high-soft--light);
  }
  .modal__close {
    top: 24px;
    right: 24px;
  }
  .modal #modal-controller-name {
    top: 10px;
    left: 24px;
  }

  // The DS has no :focus-visible rule and .btn draws `outline`, not the focus
  // shadow token — so the ring has to be restated rather than re-pointed.
  .btn:focus-visible,
  a:focus-visible {
    outline: 2px solid rgb(var(--border--controls-medium-default--light));
    outline-offset: 2px;
  }

  // Data-surface refinements
  // Table.less draws a 1px grid on every cell and a 3px rule under thead, widths
  // hardcoded — so the horizontal-hairline table means overriding widths, not just
  // colours. Every cell border routes through the neutral-low token, and the
  // vertical rules are zero-width here, so the scoped re-declaration reaches the
  // row rules only.
  .table td,
  .table th {
    --border--neutral-low-default--light: var(--brand-table-hairline);

    padding: var(--padding--md);
    border-right-width: 0;
    border-left-width: 0;
  }

  .table .table__cell--sorting {
    padding-right: calc(var(--padding--md) * 2 + 6px);
  }


  // The band's 8px ends are progressive: CSS Backgrounds 3 §5.3 lets a UA ignore
  // cell radii under border-collapse (Chrome paints them), and the separate model
  // would cost tfoot's border. Header and footer are both standalone strips, and a
  // tfoot cell can be td or th.
  .table thead tr:first-child > *:first-child,
  .table tfoot td:first-child {
    border-top-left-radius: var(--borderRadius--sm);
  }

  .table thead tr:first-child > *:last-child,
  .table tfoot td:last-child {
    border-top-right-radius: var(--borderRadius--sm);
  }

  .table thead:has(tr:only-child) th:first-child,
  .table tfoot td:first-child {
    border-bottom-left-radius: var(--borderRadius--sm);
  }

  .table thead:has(tr:only-child) th:last-child,
  .table tfoot td:last-child {
    border-bottom-right-radius: var(--borderRadius--sm);
  }

  .table th {
    padding-top: 6px;
    padding-bottom: 6px;
    border-top-width: 0;
    border-bottom-width: 0;
  }

  .table td {
    border-top-width: 0;
  }

  .table thead {
    border-bottom-width: 0;
  }

  .table tfoot {
    background-color: transparent;
    border-top-width: 0;
  }

  .table tfoot td,
  .table tfoot th {
    background-color: rgb(var(--background--neutral-low-default--light));
    border-bottom-width: 0;
  }

  .table tfoot + tbody tr:last-child > *,
  .table tbody:has(+ tfoot) tr:last-child > * {
    border-bottom-width: 0;
  }

  // The 40px plate on a 72px row: the size goes on the .imagePreview wrapper, which
  // is pinned to 30px in Table.less:244 and main_smarty.less:5191 — the latter at
  // (0,3,0), hence the td in the selector.
  .table td .imagePreview {
    overflow: hidden;
    display: block;

    width: var(--size--3xl);
    height: var(--size--3xl);

    background-color: rgb(var(--background--neutral-low-default--light));
    border-radius: var(--borderRadius--sm);
  }

  .table td .imagePreview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  // The cell needs the td to outrank the 12px shorthand set on every cell above.
  .table td.table__cell--preview {
    padding-top: var(--padding--lg);
    padding-bottom: var(--padding--lg);
  }

  // 16px at the row's outer edges, measured off the checkbox ink; the columns
  // between keep the 12px that sets the row height.
  .table td:first-child,
  .table th:first-child {
    padding-left: var(--padding--lg);
  }

  .table td:last-child,
  .table th:last-child {
    padding-right: var(--padding--lg);
  }

  // The tag palette from the designer's frame (Adhoc-UI 255-4361): one set of fills
  // for both modes with white labels (4.5:1+), the outline variant in the same hues —
  // so the tokens are pinned here rather than following the theme swap.
  .tag {
    --background--neutral-high-default--light: 114 113 113;
    --background--notice-medium-default--light: 0 101 241;
    --background--success-high-default--light: 34 135 61;
    --background--warning-medium-default--light: 189 87 0;
    --background--critical-high-default--light: 213 0 23;
    --border--neutral-high-default--light: 114 113 113;
    --border--notice-medium-default--light: 0 101 241;
    --border--success-high-default--light: 34 135 61;
    --border--warning-medium-default--light: 189 87 0;
    --border--critical-high-default--light: 213 0 23;
  }

  .btn-primary.help-anchor,
  .content-buttons .btn-primary,
  .section__controlsHeader .btn-primary,
  .section__controlsFooter .btn-primary,
  .systemMessage .btn-primary {
    --border--neutral-low-default--light: var(--brand-field-frame);

    color: rgb(var(--foreground--neutral-full-default--light)) !important;
    background-color: rgb(var(--background--neutral-base-default--light));
    border-color: rgb(var(--border--neutral-low-default--light));
  }

  .btn-primary.help-anchor:hover,
  .content-buttons .btn-primary:hover,
  .section__controlsHeader .btn-primary:hover,
  .section__controlsFooter .btn-primary:hover,
  .systemMessage .btn-primary:hover {
    --border--neutral-medium-default--light: var(--brand-field-frame-hover);

    background-color: rgb(var(--background--neutral-low-default--light));
    border-color: rgb(var(--border--neutral-medium-default--light));
  }

  .btn-secondary {
    --border--neutral-high-default--light: var(--brand-field-frame);
  }
  .btn-secondary:hover {
    --border--neutral-full-hovered--light: var(--brand-field-frame-hover);
  }

  // Disabled: pale fill, hairline, muted label. Every variant routes its disabled
  // fill and label through these two tokens. [disabled] included because :disabled
  // matches form elements only, and Button.less styles <a class="btn" disabled>.
  .btn:disabled,
  .btn[disabled],
  .btn.disabled,
  .btn.btn-disabled {
    --background--neutral-high-default--light: var(--background--neutral-low-default--light);
    --foreground--neutral-full-default--dark: var(--foreground--neutral-medium-default--light);
  }

  // The tinted tier — the middle of three levels. The demotion and disabled blocks
  // above out-rank it ((0,1,1)/(0,2,0) over (0,1,0)), so toolbars stay quiet.
  .btn-primary {
    --background--controls-medium-default--light: var(--brand-btn-tinted-fill);
    --background--controls-medium-hovered--light: var(--brand-btn-tinted-fill-hovered);
    --foreground--neutral-full-default--dark: var(--brand-btn-tinted-ink);
    --foreground--neutral-full-hovered--dark: var(--brand-btn-tinted-ink-hovered);
  }

  .landingPage .btn-primary@{promoted-cta},
  .promoHero .btn-primary@{promoted-cta},
  .ctaBanner .btn-primary@{promoted-cta},
  .actionCard .btn-primary@{promoted-cta} {
    --background--controls-medium-default--light: var(--background--main-medium-default--light);
    --background--controls-medium-hovered--light: var(--background--main-medium-hovered--light);
    --foreground--neutral-full-default--dark: 255 255 255;
    --foreground--neutral-full-hovered--dark: 255 255 255;
  }

  .actionCard {
    background-color: rgb(var(--brand-card-fill));
  }

  // Stock disabled fill is one step off white; on the card's fill it needs the next
  // step down to stay visible, with the muted label the disabled block already sets.
  .actionCard .btn:disabled,
  .actionCard .btn[disabled],
  .actionCard .btn.disabled,
  .actionCard .btn.btn-disabled {
    --background--neutral-low-default--light: 223 222 219;
  }

  // Both control pairs, because a button's size class decides which one it reads:
  // Button.less takes controls-small, while the React section controls take
  // controls-medium (Section.less:165) — which left Uložit at 12px next to a 14px
  // Filtrovat on the same page.
  .btn {
    gap: var(--gap--xs);
    min-height: 32px;
  }

  // .btn-sm's 7px is the one inset that does not match what btn-md computes (11px).
  .btn-sm {
    // Button.less:93 computes the inset as calc(var(--padding--sm) - 1px).
    --padding--sm: 12px;
  }

  // Section headings — the hairline beside a title (headings.less:50-62) stays: it
  // was dropped here for a while and the designer asked for it back.

  // The info mark ships at two sizes — .tooltip-icon at 26px (tooltip.less:52) and
  // the DS Icon at md (24px). Production size stays, so the React one is pointed at
  // the same 26px; the legacy mark keeps its stock rule.
  .iconButton .shp-info {
    --size: 26px;
  }
  .shoptet-icon,
  .tooltip-icon {
    --colors-interactive-primary-enabled: rgb(var(--foreground--controls-medium-default--light));
  }

  .massAction .btn,
  .toggle-button .btn,
  .massAction select {
    height: 26px;
    min-height: 26px;
    padding: 2px 10px;
  }

  // The mass-action dropdowns trade their frame for the quiet fill. Hover is
  // restated because the DS hover darkens the border this rule just removed.
  .massAction .btn {
    background-color: rgb(var(--background--neutral-low-default--light));
    border-color: transparent;
  }

  .massAction .btn:hover {
    background-color: rgb(var(--background--neutral-low-hovered--light));
    border-color: transparent;
  }

  // The React icon button ships square (IconButton.less) and every bordered variant
  // shows it — the filter's clear on React listings is one of them.
  .iconButton {
    border-radius: var(--borderRadius--md);
  }

  // The indeterminate dash reads the card token (CheckboxField.less:101), which dark
  // mode turns into the card itself; the mark on a controls fill takes the checkmark's
  // token instead — stock white in both modes.
  .checkboxField--indeterminate::before {
    background-color: rgb(var(--foreground--neutral-full-default--dark));
  }

  // The filter's own actions belong to the dense strip above the table, not to the page
  // toolbar, so they keep production's 26.
  .filter__actions .btn,
  .filter__actions .iconButton {
    height: 26px;
    min-height: 26px;
    padding: 2px 10px;
  }

  // The reset is icon-only and came out a rectangle: main_smarty leaves it at 4px of
  // inset (main_smarty.less:1042), 26 wide by 36 tall, and React listings draw it as the
  // DS icon button at 32. Both become the square beside Filtrovat.
  #filter .btn.shp-cross,
  .filter__actions .btn.shp-cross,
  .filter__actions .iconButton {
    width: 26px;
    min-width: 26px;
    height: 26px;
    min-height: 26px;
    padding: 0;

    border-radius: var(--borderRadius--sm);
  }

  // The jump-to-page arrow is a filled 32px squircle (12px corner, measured), and
  // .btn-sm's 11px inset would push the box open — the flex centring places the glyph.
  .pagination__jumpForm .btn {
    width: calc(var(--size--formField) + 2 * var(--borderWidth--line));
    height: calc(var(--size--formField) + 2 * var(--borderWidth--line));
    min-height: 32px;
    padding: 0;

    border-radius: var(--borderRadius--md);
  }

  // White on the alert fill is 2.08:1, so the glyph flips dark instead (7.7:1).
  // Re-declaring the custom property rather than the colour leaves nothing to
  // out-rank: main_smarty's own rule resolves to the new value.
  .circled.alert {
    --colors-foregrounds-content-inverted: var(--colors-foregrounds-content-primary);
  }

  .section {
    border-radius: var(--borderRadius--2xl);
  }

  .section__navigationLink {
    --borderRadius: var(--borderRadius--lg);
  }

  // The landing family (Balíky, Campaigns, the waitlist pages) ships square: the
  // sheet is the .section card's equivalent and takes its corner; the tinted bands
  // inside step down once and clip their full-bleed artwork.
  .landingPage {
    border-radius: var(--borderRadius--2xl);
  }

  .promoHero,
  .ctaBanner,
  .landingPage video {
    overflow: hidden;
    border-radius: var(--borderRadius--xl);
  }

  // Column headers as quiet labels, written as authored: muted grey (4.65:1
  // on the header fill, AA) at 600 instead of the inherited UA bold.
  .table th {
    font-weight: var(--fontWeight--title-small);
    color: rgb(var(--foreground--neutral-high-default--light));
  }

  // Rail items are inset rounded pills: 44px tall on a 44px pitch, 12px corner, the
  // icon 12px in and the label 40px (icon + the component's own 8px gap).
  // navigation.less applies the active/hover tint edge-to-edge, untokenised.
  .navigation__link {
    margin-right: var(--margin--sm);
    margin-left: var(--margin--sm);
    border-radius: var(--borderRadius--md);
  }

  // The rail icon is 20px, which is also what puts the label 40px in;
  // navigation.less draws 24. A literal: the size scale steps 16 → 24.
  .navigation .navigation__link::before {
    width: 20px;
    height: 20px;
    font-size: 20px;
  }

  // margin-bottom and min-height answer navigation.less's own (0,2,0) rule
  // (navigation.less:33-45, and :183 for the nested level) at equal specificity.
  .navigation .navigation__link {
    min-height: 44px;
    margin-bottom: 0;
  }

  .navigation ul ul .navigation__link {
    min-height: 36px;
    padding-left: 36px;
  }

  .navigation ul ul .navigation__link--hasSubmenu::before {
    width: 4px;
    height: 8px;
  }

  .navigation ul ul .navigation__link--active {
    // Re-pointing the hover token instead of restating the fill covers
    // navigation.less's own hover (:196) in the same breath.
    --colors-sidebar-backgrounds-hover: var(--colors-sidebar-backgrounds-activated);

    font-weight: var(--fontWeight--navigation-medium-selected);
    background-color: var(--colors-sidebar-backgrounds-activated);
  }

  // ...and only the deepest: the parent of an open submenu is --active too, and the
  // design draws it bare. Engines without :has() keep both pills.
  .navigation li:has(ul .navigation__link--active) > .navigation__link--active {
    background-color: transparent;
  }

  // Header — per-user colour fill, white default
  // header.less fills the bar from var(--user-color) (white out of the box), and the
  // fill is arbitrary, so no fixed ink works: the lch staircase derives black or
  // white from the fill's own lightness (L≷49.44, clamped by ±infinity), and the
  // hover overlay flips by the same trick.
  .header {
    // Fallback for engines without relative color syntax: correct for the
    // white default; dark user picks degrade there.
    --colors-header-hover: #0000000d;
    --colors-foregrounds-content-inverted: var(--colors-foregrounds-content-primary);

    background-color: var(--user-color, var(--brand-header-fill));
    border-bottom: 1px solid rgb(var(--border--neutral-low-default--light));
  }

  // The logo is a monochrome white SVG and a filter can only be a fixed recolour, so
  // a merchant's dark bar carried a dark mark. The anchor masks the bar's own ink
  // through the logo's shape instead; :has() picks the premium asset.
  .header .header__logo {
    background-color: var(--colors-foregrounds-content-inverted);

    mask-image: url('../assets/logo/shoptet-logo-white.svg');
    mask-position: center;
    mask-repeat: no-repeat;
    mask-size: 92px auto;
  }

  .header .header__logo:has(.shoptetLogo[src*='premium']) {
    mask-image: url('../assets/logo/shoptet-premium-logo-white.svg');
  }

  .header .header__logo .shoptetLogo {
    visibility: hidden;
  }

  .headerNavigation__item--superadmin {
    --colors-foregrounds-content-inverted: #fff;
  }

  // The shop link is a pill inset in the bar. Translucent black, not a tint: on a
  // merchant's coloured bar a light-blue block looks pasted on, while black makes the
  // pill the bar one shade deeper whatever the bar is (stock's own idiom, lighter).
  .headerNavigation__item--eshop {
    // headerNavigation.less:56 fills the item from this token — its only
    // consumer repo-wide.
    --colors-header-shop: rgb(var(--brand-shop-pill-fill));
  }

  // The counter sits on a red fill but reads the inverted-content token, which the
  // .header scope flips to dark; a direct colour wins the tie on source order.
  .headerNavigation__itemCounter {
    --colors-foregrounds-content-inverted: rgb(var(--foreground--neutral-full-default--dark));
  }

  // searchForm.less leaves the field borderless, relying on the coloured band for its
  // edge. A stated fill plus a hairline makes it an input on the canvas — stated
  // because the fill was the engine's own, white here and a gray chip in dark.
  .header .searchForm__searchQuery {
    background-color: rgb(var(--brand-search-fill));
    border: 1px solid rgb(var(--border--neutral-low-default--light));
    border-radius: var(--borderRadius--formField);
  }

  .header .searchForm__searchButton {
    --colors-forms-background: transparent;
  }

  // searchForm.less strips border and shadow on :focus at (0,2,1), which leaves an
  // invisible white box on the light chrome; (0,3,1) restores an edge.
  .header input.searchForm__searchQuery:focus {
    border: 1px solid rgb(var(--border--controls-medium-default--light));
  }

  // Patterns adopted from major CMS admin systems (Polaris, Atlassian, SLDS, WP)

  .table tbody tr:hover td {
    background-image: linear-gradient(rgb(var(--brand-overlay-row-hover)), rgb(var(--brand-overlay-row-hover)));
  }

  // Zebra retired — hairlines and hover carry the row structure. The selector mirrors
  // Table.less:54, so the tie falls on source order.
  .table tr:nth-child(2n) td:where(:not([style*='background-color'])) {
    background-image: none;
  }

  .table td[style*='background-color'] {
    --foreground--neutral-full-default--light: red(@ink) green(@ink) blue(@ink);
    --foreground--neutral-high-default--light: red(@gray-500) green(@gray-500) blue(@gray-500);
    --foreground--neutral-medium-default--light: red(@gray-400) green(@gray-400) blue(@gray-400);
    --foreground--links-strong-default--light: red(@brand-blue-hover) green(@brand-blue-hover) blue(@brand-blue-hover);
    --foreground--links-strong-hovered--light: red(@brand-blue-deep) green(@brand-blue-deep) blue(@brand-blue-deep);

    color: rgb(var(--foreground--neutral-full-default--light));
  }

  .table
    td[style*='background-color']
    :is(select, input, textarea, .selectField, .multiSelectField, .singleSelectField, .btn) {
    --foreground--neutral-full-default--light: var(--brand-control-ink);
  }

  // Row links keep the link colour: dark ink and then an underline were both tried
  // and reverted by direction, so the theme says nothing about them at all.

  // Sortable-header hover affordance, one step calmer than the DS near-black.
  .table th:hover {
    color: rgb(var(--foreground--neutral-full-default--light));
  }

  // Order detail — the address boxes keep their heading bands, rounded.
  // main_smarty routes their geometry through knobs with stock defaults (added with
  // this theme), so the treatment is one scoped re-declaration: the band flush with
  // the box's top edge, its corners concentric with the 12px panel.
  #t-order-contact {
    --order-contact-heading-padding: 6px 15px;
    --order-contact-heading-borderRadius: var(--borderRadius--md) var(--borderRadius--md) 0 0;
    --order-contact-cell-padding: 0 0 var(--padding--md);
    --order-contact-cell-borderRadius: var(--borderRadius--md);
    // The 26px edit affordance parks on the flush band's centre line.
    --order-contact-modify-top: 6px;
    --order-contact-modify-right: 6px;
    .btn-sm {
      min-height: unset;
    }
  }

  // The frame reveals in borders-primary (main_smarty.less:2461), which this theme
  // holds at #efeeed — invisible against the white card.
  #t-order-contact td {
    --colors-foregrounds-borders-primary: rgb(var(--border--neutral-low-default--light));
  }

  // Tabs — pill style: a light-blue strip hugging a row of pills, the active one
  // filled, no baseline and no indicator bar. The strip IS the list (`width:
  // fit-content` capped at 100%).
  :is(body .tabs, .v2tabs) > ul {
    width: fit-content;
    max-width: 100%;
    height: 40px;
    padding: 2px;

    background-color: var(--colors-interactive-tabs-strip);
    border-bottom: 0;
    border-radius: var(--borderRadius--4xl);
  }

  // The folder geometry goes with it: stock overlaps adjacent borders with
  // margin-right:-1px and tops the label with `padding: 8px 18px 0`, where the
  // design centres a 20px label in a 36px pill with 4px between pills. That gap
  // lives as margin on the ANCHOR of each following li, not on the li: both
  // overflow mechanisms measure the li, and a float's shrink-to-fit width includes
  // its child's margins — so the gap still counts into the fold budget while the
  // strip keeps no dead padding after the last pill.
  :is(body .tabs, .v2tabs) > ul > li {
    margin-right: 0;
  }

  :is(body .tabs, .v2tabs) > ul > li + li > :is(a, button) {
    margin-left: var(--margin--xs);
  }

  :is(body .tabs, .v2tabs) > ul > li > :is(a, button),
  :is(body .tabs, .v2tabs) > ul > li:is(.active, .ui-tabs-active) > :is(a, button) {
    height: 36px;
    padding: 8px 14px;
  }

  :is(body .tabs, .v2tabs) > ul > li > :is(a, button) {
    color: rgb(var(--foreground--neutral-full-default--light));
    background-color: transparent;
    border-color: transparent;
    border-radius: var(--borderRadius--4xl);
  }

  :is(body .tabs, .v2tabs) > ul > li:is(.active, .ui-tabs-active) > :is(a, button) {
    color: rgb(var(--foreground--neutral-full-default--dark));
    background-color: rgb(var(--background--controls-medium-default--light));
  }

  // Chained :not() on purpose: the merged :not(a, b) form counts one class
  // where stock's chained hover carries two, and the hover would lose to
  // main_smarty's (0,4,3).
  :is(body .tabs, .v2tabs) > ul > li:not(.active):not(.ui-tabs-active) > :is(a, button):hover {
    color: rgb(var(--foreground--neutral-full-default--light));
    background-color: var(--colors-interactive-ghost-subtle);
  }

  :is(body .tabs, .v2tabs) > ul > li:is(.active, .ui-tabs-active)::before {
    display: none;
  }

  // The error state was the same 4px bar hung above a folder tab (main_smarty.less:
  // 555, Tabs.less:90), which in a strip of pills floats over the pill instead of
  // capping it. The tab wears the state instead: the critical tint pair the theme
  // already uses for state surfaces (#fdf1ef behind #cd1900), where the "!" both
  // layers append needs nothing — it resolves to the same ink.
  :is(body .tabs, .v2tabs) > ul > li.ui-tabs-validation-error::before {
    display: none;
  }

  :is(body .tabs, .v2tabs) > ul > li.ui-tabs-validation-error:not(.active):not(.ui-tabs-active) > :is(a, button) {
    color: rgb(var(--foreground--critical-high-default--light));
    background-color: var(--colors-states-secondary-error);
  }

  // The tab you are on takes the filled critical pill: on its blue fill the red "!"
  // sat at 1.4:1, and a white "!" alone whispers the state on the one tab where it
  // matters. White on #cd1900 is 5.0:1, and selection still reads — it is the only
  // filled pill in the strip.
  :is(body .tabs, .v2tabs) > ul > li.ui-tabs-validation-error:is(.active, .ui-tabs-active) > :is(a, button) {
    color: rgb(var(--foreground--neutral-full-default--dark));
    background-color: rgb(var(--background--critical-xHigh-default--light));
  }

  :is(body .tabs, .v2tabs) > ul > li.ui-tabs-validation-error:is(.active, .ui-tabs-active) > :is(a, button)::after {
    color: inherit;
  }

  .systemMessage {
    border-radius: var(--borderRadius--md);
  }

  .systemMessage--error {
    --message-color: rgb(var(--border--critical-high-default--light));
  }

  .systemMessage--alert {
    --message-color: rgb(var(--border--warning-medium-default--light));
  }

  .systemMessage--success {
    --message-color: rgb(var(--border--success-high-default--light));
  }

  .systemMessage--notice {
    --message-color: rgb(var(--border--notice-medium-default--light));
  }

  .systemMessage__content h2,
  .systemMessage__content .typography__headline2 {
    color: rgb(var(--foreground--neutral-full-default--light));
  }

  // The banner glyph rides the flex row's top and the text centres itself
  // (SystemMessage.less: __text is align-self: center). For a text-only banner
  // that IS the master behaviour to keep — a multi-line message reads with the
  // icon on its first line. Only a banner carrying a button grows past its
  // text and floated the glyph above the line, so only that case centres.
  .systemMessage__content:has(> .systemMessage__buttons)::before {
    align-self: center;
  }

  @{field-family},
  textarea,
  .textareaField,
  .toggleField,
  .checkboxField,
  .radioField,
  input[type='checkbox'].switch,
  .v2MultipleBox input[type='checkbox'],
  .v2MultipleBox input[type='radio'] {
    --border--neutral-low-default--light: var(--brand-field-frame);
  }

  // --- Field metrics: the designer's 36px control (designer v2) ---
  // Stock fields are 26px, sized for the old dense grid; the vision draws one
  // control size throughout, so the box grows to 36px while the type stays at
  // production's own step — single-line inputs centre their text in whatever box
  // they get, so the height is the whole change.
  // The DS field family reads --size--formField natively; this rule exists for
  // the ELEMENT selectors in the list — legacy Smarty prints bare inputs and
  // selects with no field class, and those have no DS height rule to follow.
  @{field-family} {
    height: @field-box;
  }

  // The inset is 4px everywhere (every field declares `padding:
  // var(--padding--xs)`), which left the text almost against the border — at
  // 36px with an 8px corner the value needs the vision's 8px to sit inside the
  // box rather than on its edge. Re-declaring the token on the fields
  // themselves is enough: their own padding rule then resolves to 8px, and the
  // 4px step keeps its global meaning everywhere else.
  @{field-family},
  textarea,
  .textareaField {
    --padding--xs: 8px;
  }

  .v2FormField__input:has(> .colorFieldPicker) {
    display: flex;
    align-items: center;
  }

  .v2FormField .staticField {
    padding-top: var(--padding--sm);
    padding-bottom: var(--padding--sm);
  }

  // Form.less:73-76 nudges the wrapper with `:not(:has(.btn))`, so the theme has
  // to match that shape to answer it at equal specificity (source order then
  // decides); a plain two-class selector loses.
  .v2FormField .v2FormField__static:not(:has(.btn)) {
    margin-top: 0;
  }

  // jQuery UI's calendar trigger is an <img>: reset.less hangs images from the top of
  // the line box while the input is vertical-align: middle, a 6px error at 36px. Its
  // cyan is baked into the asset (calendar.svg), and an <img>-referenced SVG is an
  // isolated document with nothing to mask, so a filter is the recolour left.
  .ui-datepicker-trigger {
    vertical-align: middle;
    filter: var(--brand-img-ink);
  }

  input.selectField {
    background-image: none;
  }

  // The legacy phone widget overlaps its flag box and input by -1px so their borders
  // share a seam (main_smarty.less:4979); with corners and a hairline they read as two
  // boxes jammed together, so the seam becomes the React field's 8px gap.
  .v2FormField__phone {
    gap: var(--gap--sm);
  }

  .v2FormField__phone .country-flags {
    margin-right: 0;
  }

  // The phone country picker is pinned to 44px, cut for a 4px inset (Form.less:291).
  // The 8px the 36px controls want leaves 10px of a flag and an ellipsis.
  .v2FormField--phoneField .singleSelectField__inputTrigger,
  .v2FormField--phoneField select {
    --padding--xs: 4px;
  }

  .singleSelectField__inputTrigger {
    align-items: center;
  }

  .singleSelectField__inputTrigger--picker .typography {
    line-height: var(--lineHeight--caption-small);
  }

  .imageSelect__action .btn-sm {
    padding-right: var(--padding--sm);
    padding-left: var(--padding--sm);
  }

  // The WYSIWYG (.mce-tinymce) rides along: its chrome is page DOM even though its
  // content is an iframe — the container takes the field corner and clips, and its
  // hard black hairline steps down to the field frame.
  select.xs,
  .selectField.xs,
  .textField.xs,
  .numberField.xs,
  input[type='text'].xs,
  input[type='number'].xs,
  .mce-tinymce.mce-panel {
    overflow: hidden;
    border-color: rgb(var(--brand-field-frame));
    border-radius: var(--borderRadius--formField);
  }

  .field-pieces-wrap {
    --size: calc(var(--size--formField) + 2 * var(--borderWidth--line));
  }

  .field-pieces-wrap .pcs {
    min-width: calc(74px + var(--size));
    padding: 0 24px;
    text-align: center;
  }

  .field-pieces-wrap a.add-pcs,
  .field-pieces-wrap a.remove-pcs {
    top: 0;
    bottom: 0;

    width: var(--size);
    height: var(--size);

    line-height: var(--size--formField);
    vertical-align: middle;

    background-color: transparent;
    border-color: transparent;
  }

  .field-pieces-wrap a.add-pcs {
    right: 0;
    left: unset;
    border-top-right-radius: var(--borderRadius--formField);
    border-bottom-right-radius: var(--borderRadius--formField);
  }

  .field-pieces-wrap a.remove-pcs {
    right: unset;
    left: 0;
    border-top-left-radius: var(--borderRadius--formField);
    border-bottom-left-radius: var(--borderRadius--formField);
  }

  // The native colour input draws its swatch in an inner box with its own padding;
  // element, wrapper and swatch all take the field corner or the square shows through.
  // The checkbox-group box wore the hairline with square corners beside 8px fields.
  .v2MultipleBox {
    --border--neutral-low-default--light: var(--brand-field-frame);

    border-radius: var(--borderRadius--formField);
  }

  input[type='color'].colorFieldPicker {
    overflow: hidden;
    border-radius: var(--borderRadius--formField);
  }

  input[type='color'].colorFieldPicker::-webkit-color-swatch-wrapper {
    padding: 0;
  }

  input[type='color'].colorFieldPicker::-webkit-color-swatch {
    border-radius: var(--borderRadius--formField);
  }

  input[type='color'].colorFieldPicker::-moz-color-swatch {
    border-radius: var(--borderRadius--formField);
  }

  input.colorField {
    --padding--xs: 4px;
  }

  .v2FormField {
    --fontSize--label-small: 14px;
    --lineHeight--label-small: 20px;
  }

  .v2FormField .v2FormField__label {
    padding-top: var(--padding--sm);
    padding-bottom: var(--padding--sm);
  }

  .filter__grid .v2FormField,
  .filter__gridContainer .v2FormField {
    --fontSize--label-small: 12px;
    --lineHeight--label-small: 18px;
  }

  // The select chevron is the --brand-caret knob (a data-URI cannot read a token, so
  // the image is the themeable value; the glyph is shp-down.svg's path). The DS loads
  // first, so an equal-specificity restatement wins. The 4px inset is what fits the
  // 24px gutter — widening it clipped the value in the narrow sizes.
  select,
  .selectField,
  .multiSelectField,
  .searchField.singleSelectField__inputTrigger--picker {
    background-image: var(--brand-caret);
    background-position: calc(100% - 4px) center;
    background-size: 20px;
  }

  .table td {
    --size--formField: 30px;
  }

  .table td select,
  .table td .selectField {
    padding-top: 5px;
    padding-right: 32px;
    padding-bottom: 5px;
    background-position: calc(100% - 8px) center;
  }

  .table td select.sm {
    width: auto;
    min-width: 130px;
  }

  .multi-add > .multi-add-icon {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    min-height: @field-box;
  }

  .section .section {
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }

  // jQuery Chosen — main_smarty routes the widget's colours and corners through
  // tokens (the corner knobs went in with this theme), so this is re-declarations.
  .chosen-container {
    --colors-foregrounds-borders-secondary: rgb(var(--foreground--neutral-low-default--light));
    --chosen-borderRadius: var(--borderRadius--sm);
    --chosen-open-borderRadius: var(--borderRadius--sm) var(--borderRadius--sm) 0 0;
    --chosen-drop-borderRadius: 0 0 var(--borderRadius--xs) var(--borderRadius--xs);
  }

  .chosen-container-active {
    --colors-foregrounds-borders-secondary: var(--colors-forms-activated);
  }

  // Chosen is a sibling DOM tree the hidden <select> never styles, so no field rule
  // reaches it and it stayed at chosen.css's 26px. Heights are not pinned anywhere.
  .chosen-container-single .chosen-single {
    height: 32px;
    line-height: 32px;
    color: rgb(var(--foreground--neutral-full-default--light));
    border-color: rgb(var(--brand-field-frame)) !important;
  }

  .chosen-container-multi .chosen-choices {
    min-height: 32px;

    color: rgb(var(--foreground--neutral-full-default--light));

    background-color: var(--colors-forms-background);
    background-image: none;
    border-color: rgb(var(--brand-field-frame)) !important;
    border-radius: var(--borderRadius--sm);
  }

  // The drop panel darkens one step against the field frame it hangs off
  // (main_smarty.less:1359 paints it from this token).
  .chosen-drop {
    --colors-foregrounds-borders-secondary: rgb(var(--foreground--neutral-medium-default--light));
  }

  // Highlighted option: the sidebar selection pair, #0058d4 on #e5efff = 5.8:1.
  // Beats the vendor gradient (0,3,1) on specificity (0,3,2).
  & .chosen-container .chosen-results li.highlighted {
    color: var(--colors-interactive-links-enabled);
    background: var(--colors-interactive-ghost-subtle);
  }

  // The rest of the panel is vendor CSS with literal fills (chosen.css:35,118,170,184),
  // which a palette swap never reaches — dark mode showed a white panel, a white
  // search box and pale labels. Everything reads the form tokens instead.
  .chosen-container .chosen-drop {
    color: var(--colors-foregrounds-content-primary);
    background: var(--colors-forms-background);
  }

  .chosen-container .chosen-search input[type='text'] {
    color: var(--colors-foregrounds-content-primary);
    background-color: var(--colors-forms-background);
    border-color: rgb(var(--brand-field-frame));
  }

  .chosen-container-single .chosen-default {
    color: var(--colors-foregrounds-content-tertiary);
  }

  .chosen-container .chosen-results li.disabled-result {
    color: var(--colors-foregrounds-content-tertiary);
  }

  .chosen-container .chosen-results li.no-results {
    background: var(--colors-surface-light-gray);
  }

  // Menus and dropdown panels — a menu is the button's own surface continued, so it
  // takes the control corner; at 4px it read as an older component than its trigger.
  // None of these panels declares a radius, so plain rules win.
  .open-menu ul,
  .dropdown-list {
    border-radius: var(--borderRadius--sm);
  }

  // The React popovers are the same object (select drop panel, menu, context menu,
  // colour picker): one corner and the panel's lift instead of two medium shadows.
  // They scroll themselves, and a scroll container clips to its rounded padding box.
  .dropdownButton__list,
  .singleSelectField__popover,
  .multiSelectField__popover,
  .menu__popover,
  .contextMenu__popover,
  .colorSelect__popover {
    border-radius: var(--borderRadius--sm);
    box-shadow: var(--shadow--high-sharp--light);
  }

  // Item density: the stock 4px 6px / 18px is cramped for a pointer target.
  // main_smarty reads the knobs with those literals as defaults, so this is a
  // scoped re-declaration, not an override.
  .open-menu {
    --menu-item-padding: 8px 12px;
    --menu-item-lineHeight: 20px;
  }

  // The DS dropdown draws a rule under every item but the last
  // (DropdownButton.less:191) — the same table-like look the legacy menus had, so a
  // listing whose mass actions come from React showed lines where the same menu on
  // another page has none.
  .dropdownButton__listItem:not(:last-child) {
    border-bottom-width: 0;
  }

  .dropdownButton__listItemLabel {
    padding: var(--padding--sm) var(--padding--md);
    line-height: 20px;
  }

  // The drawer sets body-medium and a plain .btn brings no size of its own, so the
  // university CTA read 12/18 next to the archive button's 14/20.
  .headerDropdown__showMoreBtn {
    font-size: var(--fontSize--controls-small);
    font-weight: var(--fontWeight--controls-small);
    line-height: var(--lineHeight--controls-small);
  }

  .massAction ul {
    padding: var(--padding--xs) 0;
    border-color: rgb(var(--border--neutral-low-default--light));
    border-radius: var(--borderRadius--sm);
    box-shadow: var(--shadow--high-sharp--light);
  }

  .massAction ul > li > a,
  .massAction ul > li > .massAction__submenuHeader {
    padding: var(--padding--sm) var(--padding--md);
    line-height: var(--lineHeight--body-medium);
    text-indent: 0;
    border-bottom-width: 0;
  }

  // Every image rounds by default, capped by its own size: a 16px pictogram keeps a
  // 2px corner while a photo or preview takes the full one. Transparent artwork is
  // unaffected (nothing to clip against).
  img:not([class]) {
    border-radius: ~'min(var(--borderRadius--sm), 12.5%)';
  }

  .articleList__content {
    overflow: hidden;
    border-radius: var(--borderRadius--sm);
  }

  .perexBox {
    --background--blue-low-default--light: var(--brand-perex-fill);

    border-radius: var(--borderRadius--md);
  }

  #category-nav {
    border-radius: var(--borderRadius--sm);
  }

  // React listings paint the same breadcrumb as a filled band (CategoryFilter.less)
  // with hard corners; overflow keeps the end items' hover fill inside the corner.
  .categoryFilter__list {
    overflow: hidden;
    border-radius: var(--borderRadius--sm);
  }

  // The band rounds but an item's own hover fill inside it stayed square (designer
  // note) — the interactive pieces take the corner one step down.
  #category-nav > .item > a,
  #category-nav .item .category-nav__toggle,
  .categoryFilter__itemLabel,
  .categoryFilter__itemLabel--button,
  .categoryFilter__item a,
  .categoryFilter__separatorButton {
    border-radius: var(--borderRadius--xs);
  }

  #category-nav .item > .category-nav__subitems ul {
    padding: var(--padding--xs) 0;
    border-radius: var(--borderRadius--sm);
    box-shadow: var(--shadow--high-sharp--light);
  }

  #category-nav .item > .category-nav__subitems ul li a {
    padding: var(--padding--sm) var(--padding--md);
  }

  #category-nav .item > .category-nav__subitems ul li:not(:last-child) {
    border-bottom-width: 0;
  }

  // The strongest neutral fill carries its label through content-primary and
  // content-inverted, and both of those are white because a brand-blue fill needs them
  // white — so the two tokens cannot follow this fill when dark mode mirrors it to a
  // light one. The label reads the knob instead.
  .list-order-box-active label,
  .ui-datepicker td a.ui-state-active,
  .step-bar li.active .step-box,
  .country-flags.active .country-flag.selected .shp-flag-label {
    color: var(--brand-ghost-activated-ink);
  }

  // Active overflow-tab row: main_smarty paints it ghost-activated (remapped
  // to solid #0065f1) with white text — too loud for a menu. Scoped
  // re-declaration steps it down to the sidebar's quiet pair (5.8:1).
  .dropdown-list {
    --colors-interactive-ghost-activated: var(--colors-interactive-ghost-subtle);
    --colors-interactive-ghost-activated-hover: var(--colors-interactive-ghost-subtle-hover);
    --colors-interactive-content-primary: var(--colors-interactive-links-enabled);
  }

  // Non-solid dropdown triggers inherit a WHITE caret via icons-tertiary, invisible
  // on white and on tint fills. Tinted triggers take their own text blue; the demoted
  // contexts follow at equal specificity, so source order hands them the gray.
  .btn-primary.dropdown-trigger {
    --colors-foregrounds-icons-tertiary: rgb(var(--brand-btn-tinted-ink));
  }

  .btn-combobox,
  .content-buttons .btn-primary,
  .systemMessage .btn-primary {
    --colors-foregrounds-icons-tertiary: var(--colors-foregrounds-content-secondary);
  }

  // The corner ladder, measured: 8px on controls and small bubbles, 12px on panels
  // (banner, address boxes, in-row selects), 24px on the modal, 32px on the page card.
  // None of the surfaces below declares a radius — they are the square stragglers.

  .flag-order::before {
    border-radius: var(--borderRadius--4xl);
  }

  #item-preview {
    border-radius: var(--borderRadius--lg);
  }

  .headerNavigation__submenu {
    border-radius: var(--borderRadius--md);
  }

  // The datepicker is the same kind of floating panel.
  .ui-datepicker {
    border-radius: var(--borderRadius--md);
  }

  .headerDropdown {
    overflow: hidden;
    border-radius: var(--borderRadius--md);
    box-shadow: var(--shadow--high-sharp--light);
  }

  .tooltip {
    border-radius: var(--borderRadius--sm);
  }

  .tooltip--enhanced .tooltip-content,
  .tooltip:has(.tooltip-footer) .tooltip-content {
    border-radius: var(--borderRadius--sm);
  }

  .card,
  .actionCard,
  .reviewCard,
  .statsCard {
    --borderRadius: var(--borderRadius--md);
  }

  .tabs-dashboard.std-tabs > ul::before {
    content: '';

    position: absolute;
    inset: 12px 0 0;

    display: block;

    width: auto;
    height: auto;

    background-color: var(--colors-interactive-tabs-background-enabled);
    border-top: 0;
    border-radius: var(--borderRadius--md);
  }

  .tabs-dashboard.std-tabs > ul > li:not(.ui-tabs-active):not(.ui-state-active) > a {
    background-color: transparent;
  }

  .tabs-dashboard.std-tabs > ul > li:not(.ui-tabs-active):not(.ui-state-active) > a:hover {
    color: var(--colors-foregrounds-content-inverted);
    background-color: var(--colors-interactive-tabs-background-hover);
    border-color: transparent;
  }

  .tabs-dashboard.std-tabs > ul > li:first-child > a {
    border-top-left-radius: var(--borderRadius--md);
    border-bottom-left-radius: var(--borderRadius--md);
  }

  .tabs-dashboard.std-tabs > ul > li:last-child > a {
    border-top-right-radius: var(--borderRadius--md);
    border-bottom-right-radius: var(--borderRadius--md);
  }

  .list-statistics-outer {
    border-radius: var(--borderRadius--md);
  }

  // Row actions (PDF export, invoice, print) are hidden until the row is hovered
  // (main_smarty.less:841 visibility: hidden), which hides what a listing is for
  // and leaves the column looking empty. Shown by default inside tables only, so
  // galleries and button rows keep the reveal they were designed with; the glyphs
  // sit flush against each other in the markup, so following ones take a gap.
  .table .hide-on-mouseout {
    visibility: visible;
  }

  .table td.table__cell--actions > span + span {
    margin-left: var(--gap--sm);
  }

  // The row's "..." separators are bare text nodes (Pages.tsx renders the string
  // between anchors), so no selector reaches them; only the row's own alignment can
  // centre them against the taller page buttons.
  .pagination__pages {
    align-items: center;
  }

  .pagination__pages a,
  .pagination__pages strong,
  .pagination__pages button {
    min-width: calc(var(--size--formField) + 2 * var(--borderWidth--line));
    min-height: calc(var(--size--formField) + 2 * var(--borderWidth--line));
    padding: var(--padding--xs) var(--padding--xs);
    border-radius: var(--borderRadius--formField);
  }

  .pagination__pages a:hover {
    background-color: rgb(var(--brand-overlay-page-hover));
  }

  // A column label must not break away from its info mark, which is an inline-flex
  // box (measured on Stáří). Only cells that carry a mark, so long labels still wrap.
  .table th:has(.show-tooltip, .iconButton) {
    white-space: nowrap;
  }

  // --- Fixed action bars ---
  // contentHeader.less (after theme) consumes this token for the mobile bottom
  // bar; re-declaring it scoped to the bar wins regardless of source order.
  .content-header {
    --effect-box-shadow-shadow-up: var(--brand-bar-shadow-up);
  }

  // The `gap: 1px` in both toolbars is a relic of the segmented look where square
  // buttons joined into one control; rounded buttons 1px apart read broken. The React
  // section controls (Section.less:160) carry the same value as the Smarty bar
  // (contentHeader.less:176), so both take the 8px sibling gap — otherwise the
  // spacing depends on which layer a page happens to render its toolbar with.
  .section__controlsHeader,
  .section__controlsFooter {
    gap: var(--gap--sm);
  }

  // The React mobile bar hardcodes `background: white` (Section.less:107), the one
  // fill on the page a palette swap cannot reach.
  .section__controlsFooter {
    background: rgb(var(--background--neutral-base-default--light));
  }

  // Same literal in StatsCard.less:33 — the icon chip masks the card's top border.
  .statsCard__icon {
    background: rgb(var(--background--neutral-base-default--light));
  }

  .content-header-floating {
    border-radius: 0 0 var(--borderRadius--md) var(--borderRadius--md);
  }

  // Checkbox and radio — geometry stays stock: the 16px box was tried and reverted,
  // because these are replaced elements and shrinking them takes the pointer target
  // with them. Only alignment is answered here.
  .checkboxField,
  .v2MultipleBox input[type='checkbox'],
  .radioField {
    margin-top: 0;
  }

  .v2FormField__checkbox,
  .v2FormField__radio:not([data-version='radio-option-react']) {
    align-items: center;

    // CheckboxField.less:134 zeroes the label's top margin, tuned to the row its
    // grid measures at stock sizes; against the theme's row the label sat 2px above
    // the box. Form.less's own 4px (the value the zero removed) is what centres it.
    > .v2FormField__labelAfter {
      margin-top: var(--margin--xs);
    }
  }

  // The trailing note (Form.less:149) wears a 4px margin tuned to the 26px control:
  // against the design's row it sat 5px above the label. It centres on the row like
  // the label's own padding does.
  .v2FormField > .unsupported {
    align-self: center;
    margin-block: 0;
  }

  // The category tree pins its node markers to the top of the row (main_smarty.less:
  // 1807-1815: absolute, top: 0), which was centred while a row was 26px and leaves
  // them 10px above the checkbox at the design's row height. Centred on the row
  // instead, so the connector and the +/- box line up with the box they belong to.
  .tree li span.node,
  .tree li span.node-closed,
  .tree li span.node-opened {
    top: 50%;
    transform: translateY(-50%);
  }

  // A row whose control is a single 16-20px box takes the centring the 36px floor
  // would leave it out of. Direct children only: a React radio GROUP nests its
  // options three levels down, and centring that row dropped its label mid-stack.
  .v2FormField:has(
    > .v2FormField__checkbox,
    > .v2FormField__radio,
    > .checkboxField,
    > .radioField,
    > .switch,
    > .toggleField
  ) {
    align-items: center;
  }

  // The mark in such a row centres with it. It carries the control's height so a
  // validation error cannot push it down (see below), and against a centred row
  // that parked it above the box as soon as the label wrapped — 10px on a checkbox
  // row whose label runs to two lines (mobile widths, order settings).
  .v2FormField:has(
      > .v2FormField__checkbox,
      > .v2FormField__radio,
      > .checkboxField,
      > .radioField,
      > .switch,
      > .toggleField
    )
    > :is(.show-tooltip, .iconButton) {
    align-self: center;
    min-height: 0;
  }

  .table td .v2FormField {
    min-height: 0;
  }

  .v2FormField > .show-tooltip,
  .v2FormField > .iconButton {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    min-height: @field-box;
  }

  // The same for a row that keeps them OUTSIDE the field: .v2formRow's own bits carry
  // a 4px margin that centred an 18px label against a 26px control (Form.less:369), so
  // against the design's control they sit 5px high — the price rows on a product, where
  // the currency, the VAT note and the mark all rode above the input.
  .v2formRow > .v2formRow__label,
  .v2formRow > .show-tooltip,
  .v2formRow > .iconButton,
  .v2formRow > a:not(.btn),
  .v2formRow > em:not([class]),
  .v2formRow > span:not([class]) {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;

    min-height: @field-box;
    margin-block: 0;
  }

  // A unit suffix is prose, so it keeps its inline flow (a flex box would eat the
  // spaces around its own markup) and takes the label's box instead of the 4px
  // margins left from the 26px era.
  .v2FormField > .v2FormField__labelAfter {
    margin-top: 0;
    margin-bottom: 0;
    padding-top: var(--padding--sm);
    padding-bottom: var(--padding--sm);
  }

  // Nested beside the control it belongs to, it is not a flex item at all but an
  // inline sibling, so the box does nothing and the baseline decides — 2px above the
  // control's centre line (the price rows on a product). Same axis as the control.
  .v2FormField
    :is(.v2FormField__input, .v2FormField__select, .v2FormField__singleSelect, .v2FormField__multiSelect)
    > .v2FormField__labelAfter {
    margin-block: 0;
    padding-block: 0;
    vertical-align: middle;
  }

  // The mark's own box is what puts it on that centre line, so it follows the control
  // height; the glyph stays centred in it (tooltip.less:59-62). Not in the filter
  // grids, where the label is stacked above the field and the mark rides its line.
  .v2FormField > .show-tooltip.tooltip-icon {
    height: @field-box;
  }

  // min-height too: the rule below gives every mark the control's height, which in a
  // stacked grid inflated the LABEL's line from 20 to 36px and started the whole
  // column 16px below its neighbours (measured on Číslo zásilky, .grid--v2form).
  .filter__grid .v2FormField > .show-tooltip.tooltip-icon,
  .filter__grid .v2FormField > .iconButton,
  .grid--v2form .v2FormField > .show-tooltip.tooltip-icon,
  .grid--v2form .v2FormField > .iconButton {
    height: auto;
    min-height: 0;
  }

  // In a filter column the label is content-sized, so one that nearly fills the column
  // (169px of 178) left no room beside it — and a wrapping flex line moves the next
  // item down rather than shrinking the one before it. Basis 0 lets the label take the
  // line and wrap its own text, so the mark rides the first line.
  .filter__grid .v2FormField > .v2FormField__label {
    flex: 1 1 0;
    min-width: 0;
  }

  .filter__grid
    .v2FormField
    > :is(
      .v2FormField__input,
      .v2FormField__select,
      .v2FormField__singleSelect,
      .v2FormField__multiSelect,
      .v2FormField__static
    ) {
    flex: 0 0 100%;
  }

  // The filter grids stack the label above its field and zero its padding on purpose
  // (main_smarty.less:918-931); this file ties that selector and loads later, so the
  // 8px the beside-field layout needs was adding dead air to every filter row.
  .filter__grid .v2FormField .v2FormField__label,
  .filter__gridContainer .v2FormField .v2FormField__label,
  .grid--v2form .v2FormField .v2FormField__label {
    padding-top: 0;
    padding-bottom: 0;
  }

  // The mail toggle is bottom-aligned to its grid cell (main_smarty.less:5333), which
  // lined its 26px box up with the control it was drawn for; half the difference to
  // the current control height puts it back on the line.
  .preventEmail__icon {
    margin-bottom: calc((var(--size--formField) + 2 * var(--borderWidth--line) - 26px) / 2);
  }

  .v2MultipleBox {
    max-height: 252px;
  }

  // The mass-action row stacks a 16px checkbox against 32px controls and aligns
  // them at the top (Form.less:364 via .v2formRow, and the row's own flex-start).
  .massAction,
  .massAction__wrap {
    align-items: center;
  }

  .btn:active:not(:disabled):not(.disabled):not(.btn-disabled) {
    transform: translateY(1px);
  }

  .box-variant-3 {
    border-radius: var(--borderRadius--sm);
  }

  .box-variant-3:has(+ .tableWrapper) {
    border-bottom-right-radius: 0;
    border-bottom-left-radius: 0;
  }
  .box-variant-3 + .tableWrapper .table thead tr:first-child > *:first-child {
    border-top-left-radius: 0;
  }
  .box-variant-3 + .tableWrapper .table thead tr:first-child > *:last-child {
    border-top-right-radius: 0;
  }

  @media @screen-xl {
    .section {
      padding-right: var(--padding--xl);
      padding-bottom: var(--padding--xl);
      padding-left: var(--padding--xl);
      box-shadow: var(--shadow--high-sharp--light);
    }
  }

  // headerNavigation.less widens the shop pill to 24px sides at xxl; the pill reads
  // better at the spacing step below (designer's devtools pick).
  @media @screen-xxl {
    .headerNavigation__item--eshop > .headerNavigation__link {
      padding: var(--spacing-lg);
    }
  }

  @media @screen-xl {
    .pageGrid {
      grid-template-columns: 228px 1fr;
    }

    .header {
      height: 44px;
      margin: var(--margin--md) var(--margin--md) 0;

      border-bottom-width: 0;
      border-radius: var(--borderRadius--4xl);
      box-shadow: var(--shadow--high-sharp--light);
    }

    .pageGrid__content {
      gap: var(--gap--lg);
      padding-top: var(--spacing-lg);
    }

    .headerNavigation__item--university > .headerNavigation__link,
    .headerNavigation__item--notifications > .headerNavigation__link,
    .headerNavigation__item--helpdesk > .headerNavigation__link,
    .headerNavigation__item--design > .headerNavigation__link {
      justify-content: center;

      width: 36px;
      height: 36px;
      margin: var(--margin--xs) var(--margin--xxs);
      padding: 0;

      border-radius: var(--borderRadius--4xl);
    }

    // The counter is positioned against the link (headerNavigation.less:249-263: 3px
    // in from its top-right, 22px tall) — 3px into a 36px circle parks the badge on
    // the glyph (85% of the bell covered at three digits). A 16px badge hung off the
    // corner covers 4-15%, all of it where a bell has nothing, and the 2px ring in
    // the bar's own colour keeps it reading as a badge rather than a blob.
    .headerNavigation__itemCounter {
      top: -2px;
      right: -2px;

      min-width: var(--size--lg);
      height: var(--size--lg);
      padding: 0 var(--padding--xs);

      font-size: 10px;
      line-height: 1;

      border-radius: var(--borderRadius--4xl);
      box-shadow: 0 0 0 2px var(--user-color, var(--brand-header-fill));
    }

    // The two tinted blocks (shop link, superadmin) were full-bleed fills that cut
    // the bar's rounded end square; inset they are 36px pills. The radius goes on the
    // link too — it is the hover surface, and the item cannot clip it (overflow:
    // hidden here would eat the shop dropdown).
    .headerNavigation__item--eshop,
    .headerNavigation__item--superadmin {
      margin: var(--margin--xs) var(--margin--xs) var(--margin--xs) 0;
      border-radius: var(--borderRadius--4xl);
    }

    .headerNavigation__item--eshop > .headerNavigation__link,
    .headerNavigation__item--superadmin > .headerNavigation__link {
      border-radius: inherit;
    }

    .headerNavigation__item--user {
      margin: var(--margin--xs) var(--margin--sm) var(--margin--xs) 0;
      border-radius: var(--borderRadius--4xl);
    }

    .headerNavigation__item--user > .headerNavigation__link {
      padding: var(--padding--xs) var(--padding--md);
      border-radius: inherit;
    }

    // header.less:76 sizes the logo block off the old 250px track so the
    // search field starts where the content does — the same arithmetic, 228.
    .header__logo {
      margin-right: calc(228px - 92px - 2 * var(--spacing-xl) + var(--spacing-lg));
    }

    // The rail is the desk with items on it: transparent rather than a matching fill,
    // so the two cannot drift apart and dark mode needs no second answer. The drawer
    // below @screen-xl keeps its own fill and shadow. Losing sidebar.less's shadow is
    // the other half — on the desktop it shaded a seam that does not exist, and it
    // was what killed the card's shadow at the rail (.sidebar's z-index 1003 makes a
    // stacking context, so lifting .section would bury the flyout tooltip).
    .sidebar {
      background-color: transparent;
      box-shadow: none;
    }

    .navigation {
      padding-right: var(--padding--xs);
      padding-left: var(--padding--xs);
    }

    // Toast notifications are fixed and clear the sidebar with a hardcoded
    // 250px (SystemMessage.less:295-300).
    .systemMessage__notification--right,
    .js-notifier.systemMessage {
      left: calc(228px + var(--offset--lg));
    }

    .pageGrid__content,
    &.page-124 .pageGrid__content {
      gap: var(--gap--lg);
      justify-self: center;

      max-width: 1440px;
      padding-right: 0;
      padding-left: 0;
    }

    // Except where the page asked for the full width: fullWidth.tpl is the admin's
    // own opt-out and all 24 pages carrying it are big listings. The cap above is
    // (0,1,0) and later than pageLayout.less's `max-width: none`, so it overruled it.
    .pageGrid__content--fullWidth {
      justify-self: stretch;
      max-width: none;
    }

    .pageGrid__content--fullWidth .content-header.content-header-floating {
      padding-right: var(--spacing-xl);
    }

    .pageGrid__content--fullWidth .section {
      border-radius: var(--borderRadius--2xl) 0 0 var(--borderRadius--2xl);
    }

    .pageGrid__content > :not(.section) {
      margin-right: var(--margin--xl);
      margin-left: var(--margin--xl);
    }

    // The sticky toolbar is a fixed full-width bar whose buttons were pushed in by
    // constants solving for a card centred in the old 1190/1280 cap
    // (contentHeader.less:159/235, pageLayout.less:118 for the order detail). With
    // the card hinged at the rail the answer is what separates its right edge from
    // the viewport plus its own 24px inset: 24px while it bleeds, and 50vw - 810px
    // once the cap binds (the edge sits at 50vw + 834). clamp() switches at 1668px,
    // which is exactly where the cap starts to bind.
    .content-header.content-header-floating,
    &.page-124 .pageGrid__content .content-header.content-header-floating {
      padding-right: @floating-toolbar-inset;
    }

    // The React twin runs the same arithmetic against the old cap
    // (Section.less:210-218).
    .section__controlsHeader--isFloating {
      padding-right: @floating-toolbar-inset;
    }

    .pageGrid__content--fullWidth .section__controlsHeader--isFloating {
      padding-right: var(--spacing-xl);
    }

    // No `only screen` on the nested query: @screen-xl carries it already and LESS
    // concatenates the two into `and only screen and`, which drops the block.
    @media (max-width: 1668px) {
      .section {
        border-radius: var(--borderRadius--2xl) 0 0 var(--borderRadius--2xl);
      }
    }
  }

  @media @screen-xxl {
    .header__logo {
      margin-right: calc(228px - 92px - 2 * var(--spacing-xl) + var(--spacing-xl));
    }

    .systemMessage__notification--right,
    .js-notifier.systemMessage {
      left: calc(228px + var(--offset--xl));
    }
  }

  // Below xl the toolbar is a bottom sheet and its menus are inlined levels, not
  // floating panels — the panel lift has nothing to float above.
  @media @screen-max-xl {
    .content-buttons .open-menu ul {
      box-shadow: none;
    }
  }

  // The help button parks its icon in 35px of right padding (contentHeader.less:212,
  // absolute at right: 5px), so the label reads left of centre; the icon joins the
  // flow after the label instead, which needs the button back to inline-flex — the
  // bar's own rule makes it display: block. Inside @screen-xl, because the same file
  // hides the button entirely below it (contentHeader.less:141) and an unconditional
  // display put it into the mobile action bar.
  @media @screen-xl {
    .content-header .btn-sm.help-anchor {
      display: inline-flex;
      gap: var(--gap--sm);
      align-items: center;
      padding-right: var(--padding--sm) !important;
    }

    .content-header .btn-sm.help-anchor::before {
      position: static;
      transform: none;
      order: 1;
    }
  }

  @media @screen-xl {
    & .content-buttons {
      gap: var(--gap--sm);
    }
  }

  @supports (color: oklch(from red calc(l * infinity) 0 0)) {
    .header {
      --colors-foregrounds-content-inverted: ~'oklch(from var(--user-color, var(--brand-header-fill)) calc((0.71 - l) * infinity) 0 0)';
      --colors-header-hover: ~'oklch(from var(--user-color, var(--brand-header-fill)) calc((0.71 - l) * infinity) 0 0 / 8%)';
    }
  }
}
