*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  font-size: var(--root-font-size);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background-color: var(--color-canvas);
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-size: var(--font-size-base);
  line-height: var(--line-height-normal);
  text-rendering: optimizeLegibility;
}

img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

a {
  color: inherit;
}

/* A book's title often ends on a short word ("Частина I", "№2"), which a
   narrow card would leave alone on the last line. `pretty` lets the browser
   carry a word down instead; a browser without it wraps as before. */
h1,
h2,
h3,
h4,
h5,
h6 {
  text-wrap: pretty;
}

/* The `hidden` attribute is only `display: none` in the UA stylesheet, so any
   author rule that sets `display` beats it and the element stays painted. Make
   `hidden` authoritative, since JS in this theme toggles it to show and hide
   controls (the home "load more" button among them). */
[hidden] {
  display: none !important;
}

.site-wrapper {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.site-main {
  flex: 1 0 auto;
}

.site-main__content {
  width: min(100%, calc(var(--container-max) + 2 * var(--gutter)));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---- Scroll lock ----
   One lock for every overlay that owns the screen (the menu drawer, the filter
   drawer, the phone search); shared/page-backdrop.js holds it per owner.

   The body's overflow is propagated to the viewport, and iOS WebKit (Safari 16
   on) gives a main frame that cannot have scrollbars no pan gesture at all - no
   scrolling and no rubber-banding. The page is not moved or resized to lock it.
   That matters: taking the body out of flow instead left a locked page only one
   screen tall, and iOS neither clamps its stale scroll offset to a page that
   shrinks (a blank screen, then the page sliding in as it revealed the focused
   search field) nor lets fixed layers outgrow the page (a band the backdrop did
   not reach once the keyboard went). */
.no-scroll {
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms;
    animation-iteration-count: 1;
    transition-duration: 0.01ms;
    scroll-behavior: auto;
  }
}

/* ---- Interaction defaults ----
   Project rule: every interactive element has a visible hover state, and that
   state is DARKER than its resting colour (see docs/style-guide.md).

   These live here, at base level, so a control gets its hover for free rather
   than each feature stylesheet reinventing one. `:hover` carries higher
   specificity than the plain class rules in the feature sheets, so these still
   win despite base.css loading first. Everything is gated on a real pointer, so
   touch devices don't get sticky hover states. */

@media (hover: hover) and (pointer: fine) {
  /* Filled controls darken their fill. */
  .home-hero__slide:hover .home-hero__action-mark,
  .book-card__add-to-cart:hover,
  .cart-item__add-to-cart:hover,
  .filter-drawer__apply:hover,
  .search-button:hover,
  .book-detail__add-to-cart .add-to-cart-button:hover,
  .account-page .save-customer-info-button:hover,
  .login-page .login-button:hover,
  .login-page .register-button:hover,
  .login-page .checkout-as-guest-button:hover,
  .shopping-cart-page .checkout-button:hover,
  .puzzle-die:hover,
  .chip--selected:hover,
  .confirm-dialog__confirm:hover {
    background-color: var(--color-action-hover);
  }

  .home-curation__tabs:has(.home-curation__tab.is-active:hover)::before {
    background-color: var(--color-action-hover);
  }

  .home-hero__dot:hover::after {
    background-color: var(--color-action-hover);
  }

  .home-hero__nav:hover::before,
  .puzzle-play__step:not(:disabled):hover::before {
    background-color: var(--color-action-hover);
  }

  .site-header__utility-link:hover .die-mark,
  .die-fab:hover .die-mark {
    background-color: var(--color-action-hover);
  }

  .confirm-dialog--danger .confirm-dialog__confirm:hover {
    background-color: var(--color-danger-hover);
  }

  /* `.button-1`/`.button-2` are real classes on the element itself (unlike
     the page-scoped aliases above, which only exist as CSS groupings), so a
     single generic rule covers every one of their ~90 sitewide usages. */
  .button-1:hover,
  .ui-dialog .wishlist-add-custom-button:hover,
  .shopping-cart-page .apply-discount-coupon-code-button:hover,
  .shopping-cart-page .apply-gift-card-coupon-code-button:hover,
  .ui-dialog-titlebar-close:hover,
  .photo-lightbox__close:hover,
  .photo-lightbox__step:hover {
    background-color: var(--color-action-hover);
  }

  .shopping-cart-page .rfq-button-2:hover,
  .filter-drawer-toggle:hover,
  .catalog-sort__toggle:hover,
  .button-2:hover,
  .page-notice .button:hover,
  .btn--outline:hover,
  .chip:not(.chip--selected):hover,
  .confirm-dialog__cancel:hover,
  .puzzle-promotion__choice:hover {
    border-color: var(--color-border-hover);
    background-color: var(--color-surface);
    color: var(--color-ink);
  }

  /* The drawer's Clear is the outline pill below the desktop breakpoint
     (controls.css), so it hovers like one there; the extra class outranks its
     quiet-text hover below. */
  @media (max-width: 61.9375rem) {
    .filter-drawer__actions .filter-drawer__clear:hover {
      border-color: var(--color-border-hover);
      background-color: var(--color-surface);
      color: var(--color-ink);
    }
  }

  /* Icon and text controls on the light surfaces move to the accent, and
     darken further if they already carry it. */
  .header-actions__link:hover,
  .site-header__phone:hover,
  .site-search__submit:hover,
  .brand-mark:hover,
  .site-header__utility-link:hover,
  .book-card__title a:hover,
  .category-tile:hover .category-tile__name,
  .home-curation__more:hover .home-curation__more-label,
  .breadcrumb a:hover,
  .pager a:hover,
  .bar-notification .content a:hover,
  .shopping-cart-page .remove-discount-button:hover {
    color: var(--color-action-hover);
  }

  .admin-header-links a:hover,
  .login-page .forgot-password a:hover,
  .shopping-cart-page .product-name:hover,
  .shopping-cart-page .continue-shopping-button:hover,
  .shopping-cart-page .estimate-shipping-button:hover {
    color: var(--color-action-hover);
  }

  .login-page input[type="checkbox"]:hover,
  .account-page input[type="checkbox"]:hover,
  .account-page input[type="radio"]:hover,
  .shopping-cart-page
    input[type="checkbox"]:not([name="removefromcart"]):hover {
    border-color: var(--color-action-hover);
  }

  /* The cart badge is already amber, so it darkens rather than changing hue. */
  .header-actions__link:hover .header-actions__badge {
    background-color: var(--color-action-hover);
  }

  /* Footer sits on charcoal: its links lift to the accent, then darken. */
  .footer a:hover {
    color: var(--color-action-hover);
  }

  /* Quiet text actions. */
  .product-filter__title:hover,
  .filter-more__toggle:hover,
  .filter-option:not(:has(> input:disabled)):hover,
  .filter-drawer__clear:hover,
  .puzzle-solution__summary:hover,
  .drawer-close:hover,
  .styled-select__trigger:hover,
  .overview-buttons button:hover {
    color: var(--color-action-hover);
  }

  .drawer-close:hover {
    border-color: var(--color-border-hover);
    background-color: var(--color-brand-soft);
  }

  /* The heart moves to the favourite red, and darkens once it already is. */
  .favorite-toggle:hover {
    color: var(--color-favorite-hover);
  }

  /* Listbox options take the active highlight under the pointer, as the
     styled-select script does for keyboard and pointer alike. */
  .search-suggest__option:hover,
  .puzzle-play__move:hover {
    background-color: var(--color-action);
  }

  .puzzle-play__move[aria-current="step"]:hover {
    background-color: var(--color-action-hover);
  }

  /* A square the visitor can act on darkens under the pointer, whether it is
     dark or light: a piece to pick up, or a square the picked piece can take. */
  .puzzle-board.is-playable .puzzle-board__square.is-movable:hover,
  .puzzle-board.is-playable .puzzle-board__square.is-target:hover,
  .puzzle-board.is-playable .puzzle-board__square.is-capture-target:hover {
    box-shadow: inset 0 0 0 100vmax var(--color-board-hover);
  }

  /* Product photo thumbnails darken their frame: grey, or the accent on the
     photo already on show. */
  .book-detail__gallery .thumb-item:hover {
    border-color: var(--color-border-hover);
  }

  .book-detail__gallery .thumb-item[aria-pressed="true"]:hover {
    border-color: var(--color-action-hover);
  }

  .catalog-selectors__direction:not(:disabled):hover {
    background-color: var(--color-brand-soft-hover);
  }

  .language-switch__option:not(.language-switch__option--current):hover {
    color: var(--color-action-hover);
  }

  /* A muted aside stays an aside: it darkens its grey rather than taking the
     accent, which would promote it to the price's rank. */
  .price-approx__summary:hover,
  .puzzle-key__toggle:hover {
    color: var(--color-muted-hover);
  }

  .price-approx__summary:hover .price-approx__amount {
    background-color: var(--color-brand-soft-hover);
  }

  /* An unfilled tab has no fill to darken, so it darkens its ink instead. It
     gets no tinted fill of its own: inside the switch's white track that reads
     as a washed-out second pill competing with the amber one. */
  .home-curation__tab:not(.is-active):hover {
    color: var(--color-ink-hover);
  }
}

/* Transitions are declared unconditionally so they also cover :focus-visible,
   and are removed wholesale by the reduced-motion block above. */
.home-hero__action-mark,
.book-card__add-to-cart,
.cart-item__add-to-cart,
.favorite-toggle,
.filter-drawer__apply,
.filter-drawer__clear,
.drawer-close,
.catalog-selectors__direction,
.language-switch__option,
.search-button,
.book-detail__add-to-cart .add-to-cart-button,
.account-page .save-customer-info-button,
.login-page .login-button,
.login-page .register-button,
.login-page .checkout-as-guest-button,
.login-page .forgot-password a,
.shopping-cart-page .checkout-button,
.shopping-cart-page .apply-discount-coupon-code-button,
.shopping-cart-page .apply-gift-card-coupon-code-button,
.shopping-cart-page .continue-shopping-button,
.shopping-cart-page .estimate-shipping-button,
.shopping-cart-page .rfq-button-2,
.btn--outline,
.chip,
.puzzle-die,
.puzzle-solution__summary,
.confirm-dialog__cancel,
.confirm-dialog__confirm,
.ui-dialog .wishlist-add-custom-button,
.ui-dialog-titlebar-close,
.shopping-cart-page .product-name,
.admin-header-links a,
.home-curation__tab,
.header-actions__link,
.header-actions__badge,
.die-mark,
.site-header__phone,
.site-search__submit,
.brand-mark,
.site-header__utility-link,
.book-card__title a,
.category-tile__name,
.home-curation__more-label,
.breadcrumb a,
.pager a,
.footer a,
.overview-buttons button,
.search-suggest__option,
.puzzle-play__move,
.puzzle-promotion__choice {
  transition:
    background-color var(--motion-card) var(--ease-out),
    color var(--motion-card) var(--ease-out);
}

.book-detail__gallery .thumb-item {
  transition: border-color var(--motion-card) var(--ease-out);
}

.home-hero__dot::after,
.home-hero__nav::before,
.puzzle-play__step::before {
  transition: background-color var(--motion-card) var(--ease-out);
}

.product-filter__title,
.filter-more__toggle,
.filter-option,
.price-approx__summary,
.puzzle-key__toggle,
.price-approx__amount {
  transition: color var(--motion-card) var(--ease-in),
              background-color var(--motion-card) var(--ease-in);
}
