@layer components {
  /* ---------------------------------------------------------------- Buttons */
  .btn {
    --btn-bg: var(--blue);
    --btn-fg: #fff;
    --btn-bg-hover: var(--blue-hover);
    --btn-ring: transparent;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2xs);
    min-height: 3rem;
    padding: 0.75rem 1.5rem;
    border-radius: var(--r-s);
    background: var(--btn-bg);
    color: var(--btn-fg);
    box-shadow: inset 0 0 0 2px var(--btn-ring);
    font-family: var(--font-display);
    font-weight: 800;
    font-size: var(--fs-cta);
    line-height: 1.2;
    letter-spacing: var(--ls-caps);
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    user-select: none;
    transition:
      background-color var(--dur-fast) ease,
      color var(--dur-fast) ease,
      box-shadow var(--dur-fast) ease,
      transform var(--dur-press) var(--ease-out);
  }

  .btn .icon {
    width: 1.1em;
    height: 1.1em;
  }

  @media (hover: hover) and (pointer: fine) {
    .btn:hover {
      background: var(--btn-bg-hover);
    }
  }

  .btn:active {
    transform: scale(0.97);
  }

  .btn--accent {
    --btn-bg: var(--yellow);
    --btn-fg: var(--navy);
    --btn-bg-hover: var(--yellow-hover);
  }

  .btn--dark {
    --btn-bg: var(--navy);
    --btn-fg: #fff;
    --btn-bg-hover: var(--navy-raised);
  }

  .btn--outline {
    --btn-bg: transparent;
    --btn-fg: var(--navy);
    --btn-bg-hover: var(--navy-tint);
    --btn-ring: var(--navy);
  }

  .btn--outline-light {
    --btn-bg: transparent;
    --btn-fg: #fff;
    --btn-bg-hover: rgb(255 255 255 / 0.12);
    --btn-ring: #fff;
  }

  .btn--quiet {
    --btn-bg: var(--surface-2);
    --btn-fg: var(--navy);
    --btn-bg-hover: var(--surface-3);
  }

  .btn--danger {
    --btn-bg: var(--danger);
    --btn-fg: #fff;
    --btn-bg-hover: #a51f19;
  }

  .btn--sm {
    min-height: 2.5rem;
    padding: 0.5rem 1rem;
    font-size: 1.0625rem;
  }

  .btn--lg {
    min-height: 3.5rem;
    padding: 0.875rem 1.75rem;
    font-size: 1.375rem;
  }

  /* Full-width buttons may wrap: some Uzbek labels are longer than a phone screen. */
  .btn--block {
    width: 100%;
    white-space: normal;
    text-wrap: balance;
  }

  .btn--icon {
    padding: 0;
    width: 3rem;
  }

  .btn--icon.btn--sm {
    width: 2.5rem;
  }

  .btn:disabled,
  .btn[aria-disabled="true"] {
    --btn-bg: var(--surface-3);
    --btn-fg: var(--ink-3);
    --btn-bg-hover: var(--surface-3);
    --btn-ring: transparent;
    cursor: not-allowed;
    transform: none;
  }

  .btn[data-loading] {
    color: transparent;
    pointer-events: none;
    position: relative;
  }

  .btn[data-loading]::after {
    content: "";
    position: absolute;
    width: 1.25rem;
    height: 1.25rem;
    border-radius: 50%;
    border: 2px solid var(--btn-fg);
    border-right-color: transparent;
    animation: spin 700ms linear infinite;
  }

  /* Text call to action with an arrow (Goodyear "Select Services") */
  .link-cta {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    font-weight: 600;
    text-decoration: none;
    min-height: 2.75rem;
  }

  .link-cta .icon {
    transition: transform var(--dur-base) var(--ease-out);
  }

  @media (hover: hover) and (pointer: fine) {
    .link-cta:hover {
      text-decoration: underline;
    }

    .link-cta:hover .icon {
      transform: translateX(4px);
    }
  }

  .link {
    color: var(--blue);
    font-weight: 600;
    text-decoration: underline;
    text-decoration-color: rgb(34 79 242 / 0.35);
  }

  .link:hover {
    text-decoration-color: currentColor;
  }

  /* Round icon button (header icons, close buttons) */
  .icon-btn {
    display: inline-grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--r-pill);
    color: inherit;
    position: relative;
    transition:
      background-color var(--dur-fast) ease,
      transform var(--dur-press) var(--ease-out);
  }

  .icon-btn .icon {
    width: 1.5rem;
    height: 1.5rem;
  }

  @media (hover: hover) and (pointer: fine) {
    .icon-btn:hover {
      background: rgb(11 29 69 / 0.08);
    }

    .on-dark .icon-btn:hover {
      background: rgb(255 255 255 / 0.14);
    }
  }

  .icon-btn:active {
    transform: scale(0.94);
  }

  .icon-btn--ring {
    box-shadow: inset 0 0 0 2px currentColor;
  }

  .count-badge {
    position: absolute;
    top: 0.125rem;
    right: 0.0625rem;
    min-width: 1.25rem;
    height: 1.25rem;
    padding-inline: 0.3rem;
    border-radius: var(--r-pill);
    background: var(--yellow);
    color: var(--navy);
    font-size: 0.75rem;
    font-weight: 900;
    line-height: 1.25rem;
    text-align: center;
    font-variant-numeric: tabular-nums;
  }

  .count-badge[data-bump] {
    animation: bump 360ms var(--ease-out);
  }

  /* ---------------------------------------------------------------- Chips and status */
  .chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs);
    padding: 0;
    list-style: none;
  }

  .chip {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.125rem 0.5rem;
    border-radius: var(--r-xs);
    background: var(--line);
    color: var(--navy);
    font-size: var(--fs-small);
    line-height: 1.25rem;
    white-space: nowrap;
  }

  .chip .icon {
    width: 1rem;
    height: 1rem;
  }

  /* Stock and "fits" lines are plain text (client feedback: no yellow tags). The brand yellow
     sits only in the tick: a small yellow disc with a navy check. Never green. */
  .stock,
  .fit-line {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    font-size: var(--fs-small);
    font-weight: 700;
    line-height: 1.25rem;
    font-variant-numeric: tabular-nums lining-nums;
  }

  .stock {
    color: var(--ink-3);
    white-space: nowrap;
  }

  .stock .icon {
    flex: none;
    width: 1.125rem;
    height: 1.125rem;
  }

  .stock--in,
  .stock--low,
  .fit-line {
    color: var(--navy);
  }

  /* The tick disc is for positive states only; low stock keeps a plain icon (alerts, waiting). */
  .stock--in .icon,
  .fit-line .icon {
    flex: none;
    box-sizing: content-box;
    width: 0.75rem;
    height: 0.75rem;
    padding: 0.1875rem;
    border-radius: 50%;
    background: var(--yellow);
    color: var(--navy);
  }

  .stamp {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 0.625rem;
    border-radius: var(--r-xs);
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 0.9375rem;
    letter-spacing: var(--ls-caps);
    text-transform: uppercase;
    line-height: 1.2;
    white-space: nowrap;
    background: var(--surface-3);
    color: var(--navy);
  }

  .stamp[data-tone="new"] {
    background: var(--blue-soft);
    color: var(--blue-press);
  }

  .stamp[data-tone="paid"] {
    background: var(--yellow-soft);
    color: var(--navy);
  }

  .stamp[data-tone="progress"] {
    background: var(--navy-tint);
    color: var(--navy);
  }

  .stamp[data-tone="done"] {
    background: var(--navy);
    color: #fff;
  }

  .stamp[data-tone="cancelled"] {
    background: var(--danger-soft);
    color: var(--danger);
  }

  /* ---------------------------------------------------------------- Price */
  .price {
    font-weight: 700;
    font-variant-numeric: tabular-nums lining-nums;
    white-space: nowrap;
  }

  .price-from {
    font-size: var(--fs-small);
    font-weight: 600;
    color: var(--ink-2);
  }

  /* ---------------------------------------------------------------- Forms */
  .field {
    display: grid;
    gap: 0.375rem;
    align-content: start;
  }

  .field__label {
    font-size: var(--fs-small);
    font-weight: 700;
    color: var(--navy);
  }

  .field__label .optional {
    font-weight: 400;
    color: var(--ink-3);
  }

  .field__help {
    font-size: var(--fs-small);
    color: var(--ink-2);
  }

  .field__error {
    display: flex;
    gap: 0.375rem;
    align-items: flex-start;
    font-size: var(--fs-small);
    font-weight: 600;
    color: var(--danger);
  }

  .field__error .icon {
    width: 1.1rem;
    height: 1.1rem;
    margin-top: 0.0625rem;
  }

  .input,
  .select,
  .textarea {
    width: 100%;
    min-height: 3rem;
    padding: 0.6875rem 0.875rem;
    border: 1px solid var(--line-3);
    border-radius: var(--r-s);
    background: var(--surface);
    color: var(--navy);
    font-size: 1rem;
    line-height: 1.5;
    transition:
      border-color var(--dur-fast) ease,
      box-shadow var(--dur-fast) ease;
  }

  .textarea {
    min-height: 6.5rem;
    resize: vertical;
  }

  .input:hover,
  .select:hover,
  .textarea:hover {
    border-color: var(--ink-3);
  }

  .input:focus,
  .select:focus,
  .textarea:focus {
    outline: none;
    border-color: var(--blue);
    box-shadow: 0 0 0 3px rgb(34 79 242 / 0.2);
  }

  .input[aria-invalid="true"],
  .select[aria-invalid="true"] {
    border-color: var(--danger);
  }

  .input[aria-invalid="true"]:focus {
    box-shadow: 0 0 0 3px rgb(195 38 31 / 0.18);
  }

  .input:disabled,
  .select:disabled {
    background: var(--surface-2);
    color: var(--ink-3);
    cursor: not-allowed;
  }

  .select {
    appearance: none;
    padding-right: 2.75rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230b1d45' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6l6 -6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.875rem center;
    background-size: 1.25rem;
  }

  /* Custom dropdown (shared/select.js) drawn over a hidden native select */
  .cselect {
    position: relative;
    min-width: 0;
  }

  .cselect__native {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    pointer-events: none;
  }

  .cselect__button {
    display: block;
    overflow: hidden;
    text-align: left;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: pointer;
  }

  .cselect__button[aria-expanded="true"] {
    border-color: var(--blue);
    box-shadow: 0 0 0 3px rgb(34 79 242 / 0.2);
  }

  /* The list: a popover in the top layer, tied to its field (shared/select.js). Directly under the
     field, or directly above it when select.js sets data-up; always exactly the field's width.
     Client feedback: no dark outline, never detached from the field, never covering it. Tall enough to show
     a dozen options without an inner scrollbar (the owner saw one on a 12-option filter); a scrollbar
     only appears for longer lists or when the window is really too short. */
  .cselect__list {
    position: fixed;
    inset: auto;
    box-sizing: border-box;
    width: 12rem;
    max-height: 32rem;
    margin: 0;
    padding: 0.375rem;
    overflow-y: auto;
    overscroll-behavior: contain;
    list-style: none;
    border: none;
    outline: none;
    border-radius: var(--r-s);
    background: var(--surface);
    color: var(--navy);
    box-shadow: 0 0 0 1px var(--line-2), 0 12px 28px -14px rgb(11 29 69 / 0.22);
    transition:
      opacity var(--dur-fast) ease,
      transform var(--dur-fast) var(--ease-out);
    @starting-style {
      opacity: 0;
      transform: translateY(-4px);
    }
  }

  @supports (position-area: block-end) and (width: anchor-size(width)) {
    .cselect__list {
      position-area: block-end span-inline-end;
      position-visibility: anchors-visible;
      width: anchor-size(width);
      max-height: min(32rem, calc(100% - 0.75rem));
      margin-top: 0.25rem;
    }

    .cselect__list[data-up] {
      position-area: block-start span-inline-end;
      margin-top: 0;
      margin-bottom: 0.25rem;
    }
  }

  .cselect__list[data-up] {
    @starting-style {
      transform: translateY(4px);
    }
  }

  .cselect__option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-s);
    min-height: 2.5rem;
    padding: 0.375rem 0.625rem;
    border-radius: 6px;
    color: var(--navy);
    cursor: pointer;
    font-variant-numeric: tabular-nums lining-nums;
  }

  .cselect__option[data-active] {
    background: var(--blue-soft);
  }

  .cselect__option[aria-selected="true"] {
    font-weight: 700;
    color: var(--blue-press);
  }

  .cselect__option[aria-disabled="true"] {
    color: var(--ink-3);
    cursor: not-allowed;
  }

  .cselect__option .icon {
    width: 1rem;
    height: 1rem;
  }

  .input-group {
    display: flex;
    align-items: stretch;
  }

  .input-group__prefix {
    display: grid;
    place-items: center;
    padding-inline: 0.875rem;
    border: 1px solid var(--line-3);
    border-right: 0;
    border-radius: var(--r-s) 0 0 var(--r-s);
    background: var(--surface-2);
    color: var(--ink-2);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
  }

  .input-group .input {
    border-radius: 0 var(--r-s) var(--r-s) 0;
  }

  /* The unit or prefix belongs to the field (client feedback): hover, focus and errors colour the whole
     group, and the focus ring goes round both parts instead of stopping at the unit. */
  .input-group:hover :is(.input, .input-group__prefix) {
    border-color: var(--ink-3);
  }

  .input-group:focus-within {
    border-radius: var(--r-s);
    box-shadow: 0 0 0 3px rgb(34 79 242 / 0.2);
  }

  .input-group:focus-within :is(.input, .input-group__prefix) {
    border-color: var(--blue);
    box-shadow: none;
  }

  .input-group:has(.input[aria-invalid="true"]) :is(.input, .input-group__prefix) {
    border-color: var(--danger);
  }

  .input-group:has(.input[aria-invalid="true"]):focus-within {
    box-shadow: 0 0 0 3px rgb(195 38 31 / 0.18);
  }

  .check {
    display: flex;
    gap: var(--space-xs);
    align-items: flex-start;
    font-size: var(--fs-small);
    line-height: 1.45;
    cursor: pointer;
  }

  .check input {
    flex: none;
    width: 1.25rem;
    height: 1.25rem;
    margin-top: 0.0625rem;
    accent-color: var(--blue);
  }

  /* Selectable card (delivery method, payment method) */
  .choice {
    position: relative;
    display: flex;
    gap: var(--space-s);
    align-items: center;
    padding: var(--space-s) var(--space-m) var(--space-s) var(--space-s);
    border-radius: var(--r-m);
    background: var(--surface);
    box-shadow: inset 0 0 0 2px var(--line-2);
    cursor: pointer;
    transition:
      box-shadow var(--dur-fast) ease,
      background-color var(--dur-fast) ease;
  }

  .choice:hover {
    box-shadow: inset 0 0 0 2px var(--line-3);
  }

  .choice:has(input:checked) {
    box-shadow: inset 0 0 0 2px var(--blue);
    background: var(--blue-soft);
  }

  .choice:has(input:focus-visible) {
    outline: 3px solid var(--blue);
    outline-offset: 2px;
  }

  .choice input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
  }

  .choice__mark {
    flex: none;
    display: grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    box-shadow: inset 0 0 0 2px var(--line-3);
    color: #fff;
    transition:
      background-color var(--dur-fast) ease,
      box-shadow var(--dur-fast) ease;
  }

  .choice__mark .icon {
    width: 1rem;
    height: 1rem;
    opacity: 0;
    transform: scale(0.6);
    transition:
      opacity var(--dur-fast) ease,
      transform var(--dur-base) var(--ease-out);
  }

  .choice:has(input:checked) .choice__mark {
    background: var(--blue);
    box-shadow: none;
  }

  .choice:has(input:checked) .choice__mark .icon {
    opacity: 1;
    transform: scale(1);
  }

  .choice__body {
    display: grid;
    gap: 0.125rem;
    min-width: 0;
  }

  .choice__title {
    font-weight: 700;
  }

  .choice__text {
    font-size: var(--fs-small);
    color: var(--ink-2);
  }

  /* Segmented control (finder tabs, rim picker) */
  .segmented {
    display: inline-flex;
    gap: 0.25rem;
    padding: 0.25rem;
    border-radius: var(--r-pill);
    background: var(--line);
  }

  .segmented__item {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    min-height: 2.5rem;
    padding: 0.375rem 1rem;
    border-radius: var(--r-pill);
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 1rem;
    letter-spacing: var(--ls-caps);
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--navy);
    transition:
      background-color var(--dur-fast) ease,
      color var(--dur-fast) ease;
  }

  .segmented__item .icon {
    width: 1.15rem;
    height: 1.15rem;
  }

  .segmented__item[aria-selected="true"],
  .segmented__item[aria-pressed="true"] {
    background: var(--navy);
    color: #fff;
  }

  /* Option pills (rim sizes, tyre sizes) */
  .option-pills {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs);
    padding: 0;
    list-style: none;
  }

  .option-pill {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 0.125rem;
    min-height: 2.75rem;
    padding: 0.5rem 0.875rem;
    border-radius: var(--r-s);
    box-shadow: inset 0 0 0 2px var(--line-2);
    background: var(--surface);
    color: var(--navy);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: left;
    transition:
      box-shadow var(--dur-fast) ease,
      background-color var(--dur-fast) ease,
      transform var(--dur-press) var(--ease-out);
  }

  .option-pill:hover {
    box-shadow: inset 0 0 0 2px var(--line-3);
  }

  .option-pill:active {
    transform: scale(0.97);
  }

  .option-pill[aria-pressed="true"],
  .option-pill[aria-checked="true"] {
    box-shadow: inset 0 0 0 2px var(--blue);
    background: var(--blue-soft);
  }

  .option-pill[data-unavailable] {
    color: var(--ink-3);
    background: var(--surface-2);
  }

  .option-pill__meta {
    font-size: var(--fs-xs);
    font-weight: 600;
    color: var(--ink-2);
  }

  /* Quantity stepper: one outlined field like the size pills. The minus and plus are drawn as
     2px bars (the icon inside is hidden) so they stay crisp and optically centred at any size.
     Client feedback: no background blob on hover, only the bars change colour. */
  .qty {
    display: inline-flex;
    align-items: stretch;
    height: 3rem;
    border-radius: var(--r-s);
    box-shadow: inset 0 0 0 2px var(--line-2);
    background: var(--surface);
    transition: box-shadow var(--dur-fast) ease;
  }

  .qty__btn {
    position: relative;
    width: 3rem;
    color: var(--navy);
    border-radius: var(--r-s);
  }

  .qty__btn .icon {
    display: none;
  }

  .qty__btn::before,
  .qty__btn::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0.875rem;
    height: 2px;
    margin: -1px 0 0 -0.4375rem;
    border-radius: 1px;
    background: currentColor;
    transition:
      background-color var(--dur-fast) ease,
      scale var(--dur-press) var(--ease-out);
  }

  .qty__btn[data-qty="-1"]::after,
  .qty__btn[data-step="-1"]::after {
    content: none;
  }

  .qty__btn[data-qty="1"]::after,
  .qty__btn[data-step="1"]::after {
    rotate: 90deg;
  }

  @media (hover: hover) and (pointer: fine) {
    .qty__btn:not(:disabled):hover {
      color: var(--blue);
    }
  }

  .qty__btn:not(:disabled):active::before,
  .qty__btn:not(:disabled):active::after {
    scale: 0.8;
  }

  .qty__btn:focus-visible {
    outline-offset: -3px;
  }

  .qty__btn:disabled {
    color: var(--line-3);
    cursor: not-allowed;
  }

  .qty__value {
    width: 2.75rem;
    border: 0;
    background: none;
    color: var(--navy);
    text-align: center;
    font-weight: 700;
    font-size: 1.125rem;
    font-variant-numeric: tabular-nums;
    -moz-appearance: textfield;
    appearance: textfield;
  }

  .qty__value::-webkit-inner-spin-button,
  .qty__value::-webkit-outer-spin-button {
    -webkit-appearance: none;
  }

  .qty__value:focus {
    outline: none;
  }

  @media (hover: hover) and (pointer: fine) {
    .qty:hover {
      box-shadow: inset 0 0 0 2px var(--line-3);
    }
  }

  .qty:has(.qty__value:focus-visible) {
    box-shadow: inset 0 0 0 2px var(--blue);
  }

  .qty--sm {
    height: 2.5rem;
  }

  .qty--sm .qty__btn {
    width: 2.5rem;
  }

  .qty--sm .qty__value {
    width: 2.25rem;
    font-size: 1rem;
  }

  /* ---------------------------------------------------------------- Breadcrumbs */
  .breadcrumbs ol {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 0.5rem;
    padding: 0;
    list-style: none;
    font-size: var(--fs-small);
  }

  .breadcrumbs li {
    display: inline-flex;
    gap: 0.5rem;
    align-items: center;
  }

  .breadcrumbs li + li::before {
    content: "/";
    color: var(--ink-3);
  }

  .breadcrumbs a {
    text-decoration: underline;
    text-decoration-color: rgb(11 29 69 / 0.35);
  }

  .breadcrumbs [aria-current] {
    color: var(--ink-2);
  }

  /* ---------------------------------------------------------------- Product card
     Goodyear "Shop all tires" card: white, 16px radius, 2px ring + soft shadow, a portrait tyre
     standing over the top-left edge on a soft elliptical floor shadow, grey tags beside it.
     Client feedback: identical tyre size, bigger tags, little empty space, no hover motion.
     Tiles (NN-tile.webp) come from data/scripts/fit_product_images.py: transparent, the tyre
     at one size standing on the bottom edge, so one CSS shadow fits every photo. */
  .pcard {
    --pcard-lift: 3.25rem;
    position: relative;
    display: flex;
    flex-direction: column;
    margin-top: var(--pcard-lift);
    padding: 0 var(--space-m) var(--space-m);
    border-radius: var(--r-l);
    background: var(--surface);
    box-shadow: var(--shadow-card);
  }

  .pcard__top {
    display: grid;
    grid-template-columns: minmax(0, 0.82fr) minmax(0, 1fr);
    gap: var(--space-s);
    align-items: start;
  }

  .pcard__media {
    position: relative;
    isolation: isolate;
    aspect-ratio: 4 / 5;
    margin-top: calc(var(--pcard-lift) * -1);
    margin-left: -0.375rem;
  }

  /* Floor shadow: a dark core where the tread meets the ground inside a wide soft falloff. */
  .pcard__media::before {
    content: "";
    position: absolute;
    z-index: -1;
    left: -2%;
    right: -2%;
    bottom: -3.5%;
    height: 12%;
    background:
      radial-gradient(38% 34% at 50% 50%, rgb(6 18 46 / 0.3), rgb(6 18 46 / 0) 100%),
      radial-gradient(closest-side, rgb(6 18 46 / 0.16), rgb(6 18 46 / 0.06) 62%, rgb(6 18 46 / 0) 100%);
  }

  .pcard__media img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: 50% 100%;
  }

  /* Room for four tags (season, type, rims, sizes) so titles line up across a row. */
  .pcard__chips {
    flex-direction: column;
    align-items: stretch;
    gap: 0.5rem;
    min-height: calc(4 * 2rem + 3 * 0.5rem + var(--space-s));
    padding-top: var(--space-s);
  }

  .pcard__chips .chip {
    gap: 0.5rem;
    padding: 0.375rem 0.625rem;
    font-size: var(--fs-body);
    line-height: 1.25rem;
    white-space: normal;
  }

  .pcard__chips .chip .icon {
    flex: none;
    width: 1.25rem;
    height: 1.25rem;
  }

  .pcard__brand {
    margin-top: var(--space-s);
  }

  .pcard__title {
    margin-top: 0.125rem;
    font-size: clamp(1.5rem, 1.25rem + 0.6vw, 1.875rem);
    line-height: 1.15;
  }

  .pcard__title a {
    text-decoration: none;
  }

  .pcard__title a::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
  }

  .pcard__meta {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-2xs) var(--space-s);
    margin-top: var(--space-xs);
  }

  .pcard__price {
    font-size: 1.375rem;
    line-height: 1.2;
  }

  /* Tyres sell only in packs of 2 or 4, so the price says what it buys. */
  .pcard__unit {
    color: var(--ink-2);
    font-size: var(--fs-small);
    font-weight: 600;
    white-space: nowrap;
  }

  .pcard__fit {
    margin-top: var(--space-xs);
  }

  .pcard__foot {
    margin-top: auto;
    padding-top: var(--space-m);
  }

  .pcard__rule {
    margin: 0;
  }

  .pcard__actions {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-2xs);
    padding-top: var(--space-m);
  }

  .pcard__actions--contact {
    grid-template-columns: 1fr;
  }

  .pcard__actions .btn {
    padding-inline: 0.75rem;
  }

  /* Phones: a compact card, about a third shorter. The tyre stands on the left with the name, price
     and stock beside it; the tags run in one wrapped row underneath, then the buttons. */
  @media (max-width: 42rem) {
    .pcard {
      --pcard-lift: 1.25rem;
      display: grid;
      grid-template-columns: 7.25rem minmax(0, 1fr);
      grid-template-rows: auto auto 1fr auto auto auto;
      grid-template-areas:
        "media brand"
        "media title"
        "media meta"
        "chips chips"
        "fit fit"
        "foot foot";
      column-gap: var(--space-s);
      padding: 0 var(--space-s) var(--space-s);
    }

    .pcard__top {
      display: contents;
    }

    .pcard__media {
      grid-area: media;
      align-self: start;
      margin-left: -0.25rem;
    }

    .pcard__brand {
      grid-area: brand;
      margin-top: var(--space-s);
    }

    .pcard__title {
      grid-area: title;
      font-size: 1.3125rem;
    }

    .pcard__meta {
      grid-area: meta;
      flex-direction: column;
      align-items: flex-start;
      justify-content: flex-start;
      gap: 0.25rem;
      margin-top: var(--space-2xs);
    }

    .pcard__price {
      font-size: 1.25rem;
    }

    .pcard__chips {
      grid-area: chips;
      flex-direction: row;
      flex-wrap: wrap;
      gap: 0.375rem;
      min-height: 0;
      padding-top: var(--space-s);
    }

    .pcard__chips .chip {
      gap: 0.375rem;
      padding: 0.25rem 0.5rem;
      font-size: var(--fs-small);
    }

    .pcard__chips .chip .icon {
      width: 1.05rem;
      height: 1.05rem;
    }

    /* The sizes count is left to the product page on phones (client feedback). */
    .pcard__chip-sizes {
      display: none;
    }

    .pcard__fit {
      grid-area: fit;
    }

    .pcard__foot {
      grid-area: foot;
      padding-top: var(--space-s);
    }

    .pcard__actions {
      padding-top: var(--space-s);
    }
  }

  @media (hover: hover) and (pointer: fine) {
    .pcard:hover {
      box-shadow: var(--shadow-card-hover);
    }
  }

  /* ---------------------------------------------------------------- Empty panel
     "Nothing here" moments: the empty cart and a catalog search with no tyres. Client feedback: solid
     brand navy with everything centred and no photo. An icon in a raised navy disc, a condensed
     headline, the italic lead, then a yellow main button with outlined-light buttons or white links. */
  .empty-panel {
    display: grid;
    justify-items: center;
    padding: clamp(var(--space-xl), 1.5rem + 4vw, var(--space-3xl)) clamp(var(--space-m), 1rem + 4vw, var(--space-3xl));
    border-radius: var(--r-l);
    background: var(--navy);
    color: #fff;
    text-align: center;
  }

  .empty-panel__body {
    display: grid;
    justify-items: center;
    gap: var(--space-s);
    width: 100%;
    max-width: 46rem;
  }

  .empty-panel__icon {
    display: grid;
    place-items: center;
    width: 4.5rem;
    height: 4.5rem;
    margin-bottom: var(--space-2xs);
    border-radius: var(--r-pill);
    background: var(--navy-raised);
    color: var(--yellow);
  }

  .empty-panel__icon .icon {
    width: 2.125rem;
    height: 2.125rem;
  }

  .empty-panel__title {
    font-family: var(--font-display);
    font-size: clamp(2.5rem, 1.5rem + 3.2vw, 4.75rem);
    font-weight: 800;
    line-height: 0.95;
    letter-spacing: var(--ls-display);
    text-transform: uppercase;
    text-wrap: balance;
  }

  .empty-panel__title:focus {
    outline: none;
  }

  .empty-panel__text {
    max-width: 40ch;
    color: #fff;
    font-size: clamp(1.125rem, 1rem + 0.5vw, 1.5rem);
    text-wrap: balance;
  }

  .empty-panel__foot {
    display: grid;
    justify-items: center;
    gap: var(--space-s);
    width: 100%;
    margin-top: var(--space-m);
  }

  .empty-panel__actions,
  .empty-panel__links {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
  }

  .empty-panel__actions {
    gap: var(--space-xs);
  }

  .empty-panel__actions .btn {
    white-space: normal;
    text-align: center;
    text-wrap: balance;
  }

  /* A white link beside the main button (the cart) keeps more air than two buttons side by side. */
  .empty-panel__actions > .link-cta {
    margin-left: var(--space-s);
  }

  .empty-panel__links {
    gap: 0 var(--space-l);
  }

  .empty-panel__link {
    color: #fff;
    font-size: var(--fs-body-l);
  }

  /* Long headlines and explanations (catalog searches): a step smaller so they stay in two or three lines. */
  .empty-panel--long .empty-panel__title {
    max-width: 20em;
    font-size: clamp(1.875rem, 1.3rem + 2vw, 3.25rem);
  }

  .empty-panel--long .empty-panel__text {
    max-width: 50ch;
    font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.25rem);
  }

  /* Phones: buttons span the panel, links are centred under them. */
  @media (max-width: 48rem) {
    .empty-panel {
      padding: var(--space-xl) var(--space-m);
    }

    .empty-panel__icon {
      width: 4rem;
      height: 4rem;
    }

    .empty-panel__actions {
      display: grid;
      grid-template-columns: minmax(0, 1fr);
      justify-items: center;
      width: 100%;
      gap: var(--space-2xs);
    }

    .empty-panel__actions .btn {
      width: 100%;
    }

    .empty-panel__actions > .link-cta {
      margin-left: 0;
    }

    .empty-panel__links {
      flex-direction: column;
    }
  }

  /* ---------------------------------------------------------------- Pager
     Catalog pages in the button language: 8px squares, condensed display numerals, the current
     page solid navy, previous and next outlined like .btn--outline, the range in small print. */
  .pager {
    display: grid;
    justify-items: center;
    gap: var(--space-s);
  }

  .pager__list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-2xs);
    padding: 0;
    list-style: none;
  }

  .pager__item {
    display: inline-grid;
    place-items: center;
    min-width: 3rem;
    height: 3rem;
    padding-inline: 0.75rem;
    border-radius: var(--r-s);
    color: var(--navy);
    font-family: var(--font-display);
    font-size: 1.375rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: var(--ls-caps);
    font-variant-numeric: tabular-nums lining-nums;
    text-decoration: none;
    transition:
      background-color var(--dur-fast) ease,
      color var(--dur-fast) ease,
      box-shadow var(--dur-fast) ease,
      transform var(--dur-press) var(--ease-out);
  }

  .pager__item .icon {
    width: 1.35rem;
    height: 1.35rem;
  }

  @media (hover: hover) and (pointer: fine) {
    a.pager__item:hover {
      background: var(--navy-tint);
    }
  }

  a.pager__item:active {
    transform: scale(0.96);
  }

  .pager__item[aria-current="page"] {
    background: var(--navy);
    color: #fff;
  }

  .pager__step {
    width: 3rem;
    padding-inline: 0;
    box-shadow: inset 0 0 0 2px var(--navy);
  }

  .pager__step--prev {
    margin-right: var(--space-2xs);
  }

  .pager__step--next {
    margin-left: var(--space-2xs);
  }

  .pager__step[aria-disabled="true"] {
    color: var(--line-3);
    box-shadow: inset 0 0 0 2px var(--line-2);
  }

  .pager__gap {
    min-width: 1.5rem;
    color: var(--ink-3);
    font-weight: 700;
    text-align: center;
  }

  .pager__range {
    color: var(--ink-3);
    font-size: var(--fs-small);
    font-variant-numeric: tabular-nums lining-nums;
  }

  /* ---------------------------------------------------------------- Tyre thumbnail
     Product photo in cart, checkout, confirmation and tracking lists: the transparent portrait
     tile (NN-tile.webp) with no box or background, the whole tyre visible (never cropped or
     zoomed) on the same soft floor shadow as the product cards. The parent sets the width. */
  .tyre-thumb {
    position: relative;
    isolation: isolate;
    display: block;
    aspect-ratio: 4 / 5;
  }

  .tyre-thumb::before {
    content: "";
    position: absolute;
    z-index: -1;
    left: 0;
    right: 0;
    bottom: -4%;
    height: 13%;
    background:
      radial-gradient(38% 34% at 50% 50%, rgb(6 18 46 / 0.28), rgb(6 18 46 / 0) 100%),
      radial-gradient(closest-side, rgb(6 18 46 / 0.14), rgb(6 18 46 / 0) 100%);
  }

  .tyre-thumb img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: 50% 100%;
  }

  /* Every card in the grid is the same height, whatever the chips or title length. */
  .product-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-auto-rows: 1fr;
    gap: var(--space-l) var(--space-m);
    padding: 0;
    list-style: none;
  }

  .product-grid > li {
    display: flex;
    flex-direction: column;
  }

  .product-grid > li > .pcard {
    flex: 1;
    height: auto;
  }

  @media (max-width: 68rem) {
    .product-grid {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
  }

  @media (max-width: 42rem) {
    .product-grid {
      grid-template-columns: minmax(0, 1fr);
      grid-auto-rows: auto;
    }
  }

  /* ---------------------------------------------------------------- Accordion (Goodyear FAQ) */
  .accordion {
    border-bottom: 2px solid var(--line);
  }

  .accordion__item {
    border-top: 2px solid var(--line);
  }

  .accordion__trigger {
    display: flex;
    width: 100%;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-m);
    padding: var(--space-s) 0;
    min-height: 4rem;
    text-align: left;
    color: var(--navy);
    font-size: var(--fs-h4);
    font-weight: 700;
    line-height: 1.35;
  }

  .accordion__trigger .icon {
    width: 1.5rem;
    height: 1.5rem;
    transition: transform var(--dur-base) var(--ease-standard);
  }

  .accordion__trigger[aria-expanded="true"] .icon {
    transform: rotate(180deg);
  }

  .accordion__panel {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--dur-base) var(--ease-standard);
  }

  .accordion__item:has(.accordion__trigger[aria-expanded="true"]) .accordion__panel {
    grid-template-rows: 1fr;
  }

  .accordion__inner {
    overflow: hidden;
  }

  .accordion__content {
    max-width: var(--text-max);
    padding-bottom: var(--space-m);
    color: var(--ink-2);
    font-size: var(--fs-body-l);
  }

  .accordion__content > * + * {
    margin-top: 0.75em;
  }

  .accordion__content ul,
  .accordion__content ol {
    padding-left: 1.25em;
  }

  .accordion__content li + li {
    margin-top: 0.35em;
  }

  /* ---------------------------------------------------------------- Overlay, sheet, dialog */
  .overlay {
    position: fixed;
    inset: 0;
    z-index: var(--z-overlay);
    background: rgb(6 18 46 / 0.56);
    opacity: 0;
    visibility: hidden;
    transition:
      opacity var(--dur-base) ease,
      visibility 0s linear var(--dur-base);
  }

  .overlay[data-open] {
    opacity: 1;
    visibility: visible;
    transition:
      opacity var(--dur-base) ease,
      visibility 0s;
  }

  .sheet {
    position: fixed;
    z-index: var(--z-sheet);
    display: flex;
    flex-direction: column;
    background: var(--surface);
    box-shadow: var(--shadow-pop);
    visibility: hidden;
    transition:
      transform var(--dur-panel) var(--ease-drawer),
      visibility 0s linear var(--dur-panel);
  }

  .sheet[data-open] {
    visibility: visible;
    transform: none;
    transition:
      transform var(--dur-panel) var(--ease-drawer),
      visibility 0s;
  }

  @media (min-width: 48.0625rem) {
    .sheet {
      top: 0;
      right: 0;
      bottom: 0;
      width: min(32rem, 100vw);
      transform: translateX(100%);
    }
  }

  @media (max-width: 48rem) {
    .sheet {
      left: 0;
      right: 0;
      bottom: 0;
      max-height: 92dvh;
      border-radius: var(--r-l) var(--r-l) 0 0;
      transform: translateY(100%);
    }

    .sheet::before {
      content: "";
      align-self: center;
      width: 2.5rem;
      height: 0.25rem;
      margin-top: 0.5rem;
      border-radius: var(--r-pill);
      background: var(--line-3);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .sheet {
      transform: none;
      opacity: 0;
      transition:
        opacity var(--dur-base) ease,
        visibility 0s linear var(--dur-base);
    }

    .sheet[data-open] {
      opacity: 1;
      transition:
        opacity var(--dur-base) ease,
        visibility 0s;
    }
  }

  .sheet__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-s);
    padding: var(--space-m) var(--space-m) var(--space-s);
  }

  .sheet__body {
    flex: 1;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 0 var(--space-m) var(--space-m);
  }

  .sheet__foot {
    padding: var(--space-s) var(--space-m) calc(var(--space-m) + env(safe-area-inset-bottom));
    border-top: 1px solid var(--line-2);
    background: var(--surface);
  }

  .dialog {
    width: min(30rem, calc(100vw - 2rem));
    margin: auto;
    padding: 0;
    border: 0;
    border-radius: var(--r-l);
    color: var(--navy);
    box-shadow: var(--shadow-pop);
  }

  .dialog::backdrop {
    background: rgb(6 18 46 / 0.56);
  }

  .dialog[open] {
    animation: dialog-in var(--dur-base) var(--ease-out);
  }

  .dialog__body {
    padding: var(--space-l) var(--space-l) var(--space-m);
  }

  .dialog__foot {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2xs);
    padding: var(--space-s) var(--space-l) var(--space-l);
  }

  /* ---------------------------------------------------------------- Toasts */
  .toasts {
    position: fixed;
    z-index: var(--z-toast);
    right: var(--space-m);
    bottom: var(--space-m);
    display: grid;
    gap: var(--space-2xs);
    width: min(24rem, calc(100vw - 2rem));
    pointer-events: none;
  }

  @media (max-width: 48rem) {
    .toasts {
      left: 50%;
      right: auto;
      bottom: calc(var(--space-s) + env(safe-area-inset-bottom));
      translate: -50% 0;
    }
  }

  /* The panel's save bar sits in the same corner. A toast has to pause on hover, so it cannot
     give up its pointer events, and sitting on top of «Сохранить» made that button do nothing
     for the four seconds a toast was up — which is exactly when someone presses it, because
     the toast that brought it there says a photo was added. So the toasts step aside instead. */
  body:has(.savebar[data-dirty]) .toasts {
    bottom: calc(var(--space-m) + 4.5rem);
  }

  /* Toast in the brand yellow with navy text (client feedback); the action is a small navy button. */
  .toast {
    display: flex;
    gap: var(--space-xs);
    align-items: flex-start;
    padding: var(--space-s);
    border-radius: var(--r-m);
    background: var(--yellow);
    color: var(--navy);
    box-shadow: 0 18px 40px -14px rgb(6 18 46 / 0.45), 0 0 0 1px rgb(11 29 69 / 0.1);
    pointer-events: auto;
    transition:
      opacity var(--dur-base) ease,
      transform var(--dur-base) var(--ease-out);
    @starting-style {
      opacity: 0;
      transform: translateY(12px);
    }
  }

  .toast[data-leaving] {
    opacity: 0;
    transform: translateY(8px);
    transition-duration: 160ms;
  }

  .toast > .icon {
    flex: none;
    width: 1.4rem;
    height: 1.4rem;
    color: var(--navy);
  }

  .toast__title {
    font-weight: 700;
  }

  .toast__text {
    font-size: var(--fs-small);
    color: var(--ink-2);
  }

  .toast__action {
    flex: none;
    display: inline-flex;
    align-items: center;
    min-height: 2.25rem;
    margin-left: auto;
    padding: 0.25rem 0.75rem;
    align-self: center;
    border-radius: var(--r-s);
    background: var(--navy);
    color: #fff;
    font-size: var(--fs-small);
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color var(--dur-fast) ease;
  }

  @media (hover: hover) and (pointer: fine) {
    .toast__action:hover {
      background: var(--navy-raised);
    }
  }

  .toast :focus-visible {
    outline-color: var(--navy);
  }

  /* ---------------------------------------------------------------- Map (shared/yandex-map.js)
     Yandex's promo links ("create your own map", taxi) are hidden. */
  .map {
    position: relative;
    overflow: hidden;
    background: var(--surface-3);
  }

  .map [class*="-gototech"],
  .map [class*="-gototaxi"] {
    display: none !important;
  }

  /* TEST (client request): also hide Yandex's logo, copyright, terms link and "open in Maps" button.
     Yandex Maps API terms 4.1.3.1 and 4.1.3.3 forbid this and it can get the API key blocked; it is
     switched on with HIDE_YANDEX_ATTRIBUTION in shared/yandex-map.js. Decide before going live. */
  .map--bare [class*="-copyrights-pane"] {
    display: none !important;
  }

  /* What covers the map until Yandex have drawn one: the same flat surface as the cards beside
     it, with the loading mark turning on top of it.

     The mark is back at the owner's request (2026-09-19). A prerendered page arrives with the
     map already on it and never shows this, but somebody who clicks the link straight down
     without pausing on it gets no prerender and a real wait, and a wait with nothing in it
     reads worse than a wait with the mark in it. No delay for the same reason: a delay leaves
     exactly that case uncovered.

     Both layers are positioned against .map, which is why .map must keep a position other than
     static on every breakpoint. See .contacts__map in pages/contacts.css. */
  .map::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background: var(--surface-2);
    transition: opacity var(--dur-base) var(--ease-out);
  }

  /* Smaller than the once-a-day screen, which uses the same mark: this one belongs to a panel
     on the page, that one covers the window. */
  .map::after {
    content: "";
    position: absolute;
    z-index: 2;
    left: 50%;
    top: 50%;
    width: 3.5rem;
    height: 3.5rem;
    translate: -50% -50%;
    border-radius: var(--r-m);
    background: url("/static/img/map-loading.75bf78f0e7d5.gif") center / cover no-repeat;
    transition: opacity var(--dur-base) var(--ease-out);
  }

  /* Gone, not merely transparent: a GIF under an invisible layer goes on decoding frames, and
     the map underneath has to be able to take a click. */
  .map[data-map-ready]::before,
  .map[data-map-ready]::after,
  .map[data-map-failed]::after {
    opacity: 0;
    visibility: hidden;
  }

  /* Yandex did not answer. The surface stays, without the mark: nothing is coming, so a
     turning wheel would be a lie. */
  .map[data-map-failed]::before {
    opacity: 1;
  }

  /* A GIF cannot be paused from a stylesheet, so someone who asked their system for less
     motion gets the mark as a still image rather than a turning one. */
  @media (prefers-reduced-motion: reduce) {
    .map::after {
      background-image: url("/static/img/map-loading.b5b06aaa1735.png");
    }
  }

  /* Pin (shared/yandex-map.js): anchored at the tip of the drop, with a soft contact shadow. */
  .map-pin {
    position: absolute;
    left: 0;
    top: 0;
    font-family: var(--font-sans);
    color: var(--navy);
  }

  .map-pin::before {
    content: "";
    position: absolute;
    left: -0.75rem;
    top: -0.3125rem;
    width: 1.5rem;
    height: 0.625rem;
    border-radius: 50%;
    background: radial-gradient(closest-side, rgb(6 18 46 / 0.45), rgb(6 18 46 / 0));
  }

  .map-pin__marker {
    position: absolute;
    left: -22px;
    top: -58px;
    display: block;
    transform-origin: 50% 100%;
    filter: drop-shadow(0 3px 4px rgb(6 18 46 / 0.3));
    cursor: pointer;
    transition: scale var(--dur-fast) var(--ease-out);
  }

  .map-pin--active .map-pin__marker {
    scale: 1.08;
  }

  /* ---------------------------------------------------------------- Tip (shared/tip.js)
     One popover used two ways: an explanation on hover and a short confirmation from script.
     In the top layer, so a scrolling table, a drawer or a modal <dialog> cannot clip or cover
     it. Same treatment as the map's hover card below, at label size. */
  .tip {
    position: fixed;
    inset: auto;                       /* the UA sheet sets inset: 0; margin: auto */
    margin: 0;
    max-width: 20rem;
    padding: 0.4375rem 0.6875rem;
    border: 0;
    border-radius: var(--r-s);
    background: var(--surface);
    color: var(--navy);
    box-shadow: var(--shadow-pop);
    font-size: var(--fs-small);
    font-weight: 600;
    line-height: 1.35;
    text-wrap: pretty;
    overflow: visible;                 /* the arrow sits outside the box */
    opacity: 0;
    transition:
      opacity var(--dur-fast) ease,
      overlay var(--dur-fast) allow-discrete,
      display var(--dur-fast) allow-discrete;
  }

  .tip:popover-open {
    opacity: 1;

    @starting-style {
      opacity: 0;
    }
  }

  .tip::after {
    content: "";
    position: absolute;
    top: -0.1875rem;
    left: var(--tip-arrow, 50%);
    width: 0.5rem;
    height: 0.5rem;
    background: var(--surface);
    border-radius: 2px;
    translate: -50% 0;
    rotate: 45deg;
  }

  .tip[data-up]::after {
    top: auto;
    bottom: -0.1875rem;
  }

  /* Hover card in the site's style: white, 12px radius, pop shadow, display-face title. */
  .map-pin__card {
    --card-shift: 0px;
    position: absolute;
    left: 0;
    bottom: 4.25rem;
    width: max-content;
    max-width: 17rem;
    padding: var(--space-xs) var(--space-s);
    border-radius: var(--r-m);
    background: var(--surface);
    box-shadow: var(--shadow-pop);
    text-align: left;
    white-space: normal;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    translate: calc(-50% + var(--card-shift)) 0.25rem;
    transition:
      opacity 160ms ease,
      translate 160ms var(--ease-out),
      visibility 0s linear 160ms;
  }

  .map-pin__card::after {
    content: "";
    position: absolute;
    left: calc(50% - var(--card-shift));
    bottom: -0.3125rem;
    width: 0.75rem;
    height: 0.75rem;
    background: var(--surface);
    border-radius: 2px;
    translate: -50% 0;
    rotate: 45deg;
  }

  .map-pin--active .map-pin__card {
    opacity: 1;
    visibility: visible;
    translate: calc(-50% + var(--card-shift)) 0;
    transition:
      opacity 160ms ease,
      translate 160ms var(--ease-out),
      visibility 0s;
  }

  .map-pin--below .map-pin__card {
    top: 0.75rem;
    bottom: auto;
  }

  .map-pin--below .map-pin__card::after {
    top: -0.3125rem;
    bottom: auto;
  }

  .map-pin__title {
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: var(--ls-caps);
    text-transform: uppercase;
  }

  .map-pin__address {
    margin-top: 0.25rem;
    color: var(--ink-2);
    font-size: var(--fs-small);
    line-height: 1.4;
  }

  .map-pin__note {
    display: flex;
    align-items: flex-start;
    gap: 0.375rem;
    margin-top: 0.5rem;
    font-size: var(--fs-small);
    font-weight: 700;
    line-height: 1.3;
  }

  .map-pin__note .icon {
    flex: none;
    width: 1rem;
    height: 1rem;
    margin-top: 0.0625rem;
  }

  .map-pin--warehouse .map-pin__note .icon {
    box-sizing: content-box;
    width: 0.625rem;
    height: 0.625rem;
    padding: 0.1875rem;
    margin-top: 0;
    border-radius: 50%;
    background: var(--yellow);
  }

  @media (prefers-reduced-motion: reduce) {
    .map-pin__marker,
    .map-pin__card {
      transition-property: opacity, visibility;
    }
  }

  /* ---------------------------------------------------------------- Misc */
  .notice {
    display: flex;
    gap: var(--space-xs);
    align-items: flex-start;
    padding: var(--space-s);
    border-radius: var(--r-m);
    background: var(--surface-2);
    color: var(--navy);
    font-size: var(--fs-small);
  }

  /* The notice's own icon, not one inside a button in it: «Повторить» under a failed payment took
     the notice's colour and its icon disappeared into the dark button (owner, 2026-09-29). */
  .notice > .icon {
    width: 1.25rem;
    height: 1.25rem;
    margin-top: 0.0625rem;
    color: var(--blue);
  }

  .notice--warning {
    background: var(--warning-soft);
  }

  .notice--warning > .icon {
    color: var(--warning);
  }

  /* The shape of something that is on its way. Four pieces cover every screen: a line, a pill,
     a card and a two-line stack. Widths come from --w per use, so a column of them does not look
     stamped out. base.css already stops every keyframe loop under reduced motion; the rule below
     states the resting appearance rather than relying on the frame the loop freezes on. */
  .skeleton {
    border-radius: var(--r-s);
    background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 37%, var(--surface-2) 63%);
    background-size: 400% 100%;
    animation: shimmer 1.4s ease infinite;
  }

  @media (prefers-reduced-motion: reduce) {
    .skeleton {
      background: var(--surface-2);
      animation: none;
    }
  }

  .skel-line {
    display: block;
    width: var(--w, 6rem);
    height: var(--h, 0.875rem);
    border-radius: var(--r-xs);
  }

  .skel-pill {
    display: block;
    width: var(--w, 5rem);
    height: 1.5rem;
    border-radius: var(--r-pill);
  }

  .skel-card {
    height: var(--h, 6rem);
    border-radius: var(--r-m);
  }

  /* Matches .cell-stack, so a two-line cell keeps its height while it waits. */
  .skel-stack {
    display: grid;
    gap: 0.3125rem;
  }

  /* A table row settles at about this height; holding it stops the page jumping on arrival. */
  .skel-row td {
    height: 3.25rem;
  }

  .empty {
    display: grid;
    justify-items: center;
    gap: var(--space-xs);
    padding: var(--space-2xl) var(--space-m);
    text-align: center;
  }

  .empty .icon {
    width: 3rem;
    height: 3rem;
    color: var(--ink-3);
  }

  .empty__title {
    font-size: var(--fs-h4);
    font-weight: 700;
  }

  .empty__text {
    max-width: 40ch;
    color: var(--ink-2);
  }

  .demo-flag {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.125rem 0.5rem;
    border-radius: var(--r-xs);
    background: var(--yellow-soft);
    color: var(--navy);
    font-size: var(--fs-xs);
    font-weight: 700;
  }

  /* ---------------------------------------------------------------- Size picker */
  .picker__product {
    display: flex;
    gap: var(--space-s);
    align-items: center;
    min-width: 0;
  }

  .picker__image {
    flex: none;
    width: 5rem;
    height: 5rem;
  }

  .picker__image img {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }

  .picker__name {
    font-size: var(--fs-h4);
    line-height: 1.2;
  }

  .picker__fit {
    margin-top: 0.375rem;
  }

  .picker__group + .picker__group {
    margin-top: var(--space-m);
  }

  .picker__legend {
    display: block;
    margin-bottom: var(--space-2xs);
    font-size: var(--fs-small);
    font-weight: 700;
  }

  .picker__sizes {
    display: grid;
    gap: var(--space-2xs);
    padding: 0;
    list-style: none;
  }

  .picker__size {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "label price"
      "stock stock";
    gap: 0.25rem var(--space-s);
    width: 100%;
    padding: var(--space-xs) var(--space-s);
    border-radius: var(--r-m);
    box-shadow: inset 0 0 0 2px var(--line-2);
    text-align: left;
    transition:
      box-shadow var(--dur-fast) ease,
      background-color var(--dur-fast) ease,
      transform var(--dur-press) var(--ease-out);
  }

  .picker__size:hover {
    box-shadow: inset 0 0 0 2px var(--line-3);
  }

  .picker__size:active {
    transform: scale(0.985);
  }

  .picker__size[aria-checked="true"] {
    box-shadow: inset 0 0 0 2px var(--blue);
    background: var(--blue-soft);
  }

  .picker__size-label {
    grid-area: label;
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    align-items: center;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
  }

  .picker__size-price {
    grid-area: price;
    justify-self: end;
    display: grid;
    justify-items: end;
    text-align: right;
  }

  .picker__size-pack {
    color: var(--ink-2);
    font-size: var(--fs-xs);
    font-weight: 600;
  }

  .picker__size .stock {
    grid-area: stock;
    justify-self: start;
  }

  .picker__size[data-unavailable] .picker__size-price .price {
    color: var(--ink-3);
  }

  /* "Fits" next to a size label: text with the car icon; the row's stock line keeps the tick. */
  .picker__fits {
    margin-left: 0.25rem;
    font-weight: 600;
  }

  .picker__fits .icon {
    width: 1.125rem;
    height: 1.125rem;
    padding: 0;
    background: none;
  }

  .picker__unavailable {
    margin-top: var(--space-m);
    font-size: var(--fs-body);
  }

  .picker__unavailable p + p {
    margin-top: 0.25rem;
    color: var(--ink-2);
  }

  /* ---------------------------------------------------------------- Contact dialog
     Opened by "Contact us" wherever a tyre or size is not in stock (site/contact.js). */
  .contact-dialog {
    width: min(28rem, calc(100vw - 2rem));
  }

  .contact-dialog__body {
    position: relative;
    display: grid;
    justify-items: start;
    gap: var(--space-s);
    padding: var(--space-l);
  }

  .contact-dialog__close {
    position: absolute;
    top: var(--space-xs);
    right: var(--space-xs);
  }

  .contact-dialog__icon {
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    background: var(--yellow);
    color: var(--navy);
  }

  .contact-dialog__icon .icon {
    width: 1.5rem;
    height: 1.5rem;
  }

  .contact-dialog__title {
    padding-right: var(--space-l);
  }

  .contact-dialog__subject {
    padding: 0.375rem 0.75rem;
    border-radius: var(--r-xs);
    background: var(--surface-2);
    font-weight: 700;
    font-variant-numeric: tabular-nums lining-nums;
  }

  .contact-dialog__text {
    color: var(--ink-2);
    font-size: var(--fs-body-l);
  }

  .contact-dialog__actions {
    display: grid;
    gap: var(--space-2xs);
    width: 100%;
    margin-top: var(--space-2xs);
  }

  .picker__summary {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-s);
    margin-bottom: var(--space-s);
  }

  .picker__total {
    display: grid;
    justify-items: end;
    text-align: right;
  }

  .picker__total-value {
    font-size: var(--fs-h3);
    line-height: 1.1;
  }

  .picker__each {
    font-size: var(--fs-small);
    color: var(--ink-2);
    font-variant-numeric: tabular-nums;
  }

  /* Bold means the shop sells this size, in stock or not. The note beside it says which:
     the same two tones the product card uses, so «В наличии» reads the same everywhere. */
  .finder-pop__option[data-in-catalog] {
    font-weight: 700;
  }

  .finder-pop__option small[data-tone="stock"] {
    color: var(--navy);
  }

  .finder-pop__option small[data-tone="order"] {
    color: var(--ink-2);
  }

  @keyframes spin {
    to {
      transform: rotate(360deg);
    }
  }

  @keyframes bump {
    40% {
      transform: scale(1.3);
    }
  }

  @keyframes shimmer {
    from {
      background-position: 100% 50%;
    }
    to {
      background-position: 0 50%;
    }
  }

  @keyframes dialog-in {
    from {
      opacity: 0;
      transform: scale(0.96);
    }
  }
}

@layer components {
  /* ---------------------------------------------------------------- First visit of the day
     A curtain over the whole page while it loads, once a day (client request). The server
     decides whether it is rendered at all; shared/splash.js decides when it goes.

     White, not navy. The mark is drawn on a navy square, so on a navy ground its edges vanish
     and the thing reads as a hole rather than as an object — the owner's point, and correct.
     On white the tile is a tile. */
  .splash {
    position: fixed;
    inset: 0;
    z-index: 9000;
    display: grid;
    place-items: center;
    background: var(--surface);
    /* No entrance: it is already there when the first pixel is painted. Only the exit is
       animated, and only opacity, so it costs one compositor layer and no layout. */
    transition: opacity var(--dur-panel) var(--ease-out);
  }

  .splash::before {
    content: "";
    width: 5.5rem;
    height: 5.5rem;
    border-radius: var(--r-m);
    background: url("/static/img/map-loading.75bf78f0e7d5.gif") center / cover no-repeat;
  }

  .splash[data-splash-done] {
    opacity: 0;
    pointer-events: none;
  }

  /* A GIF cannot be paused from a stylesheet, so a still frame instead. The curtain itself
     still fades: base.css says in as many words that reduced motion keeps fades. */
  @media (prefers-reduced-motion: reduce) {
    .splash::before {
      background-image: url("/static/img/map-loading.b5b06aaa1735.png");
    }
  }
}
