/* Scootive design system, ported piece by piece from the static prototype into
   the 'ever' theme. Kept as its own hand-authored file (not part of the
   Tailwind/_dev build output) so it survives a future `npm run build`.
   Currently covers: global type/color base (matches src/assets/css/tokens.css
   + base.css from the prototype) + the mobile nav accordion (see
   initMobileMenu() in theme.js and modules/ps_mainmenu/ps_mainmenu.tpl). */

:root {
  --scootive-ink: #0a0a0a;
  --scootive-line: #dfdfd8;
  --scootive-bg: #f5f5f1;
  --scootive-gray-50: #fafaf8;
  --scootive-gray-100: #f3f3ef;
  --scootive-gray-400: #c8c8c1;
  /* Was a flat #777771 (4.12:1 against the body bg #f5f5f1 - fails WCAG AA's
     4.5:1 minimum for normal text). Re-derived via color-mix() from
     --scootive-ink instead of a new flat hex, following the same pattern
     --scootive-green-hover already uses below - this stays correct
     regardless of which shop's own accent color is active, since it's
     computed from the ink/white neutrals, not the per-shop green/blue
     accent. 60% ink / 40% white = #6c6c6c, verified at 4.80:1 against the
     real body background (comfortably over 4.5:1, computed exactly via the
     WCAG relative-luminance formula, not estimated). Found + fixed via a
     site-wide accessibility audit, 2026-10-02. */
  --scootive-gray-600: color-mix(in srgb, var(--scootive-ink) 60%, white);
  --scootive-gray-700: #555550;
  --scootive-gray-800: #333330;
  --scootive-green: #a0e01c;
  --scootive-green2: #7eb617;
  /* Derived FROM --scootive-green (not a second static color) so it stays
     correct on any shop, not just the default Scootive green - real bug
     found live on AveBmx: .mega a:hover/.mobile-nav-sub a:hover had their
     own hardcoded #3d6c00 (a manually pre-darkened shade of the DEFAULT
     green only), so every shop showed the same green hover regardless of
     its own configured accent color. color-mix recomputes against
     whatever --scootive-green currently resolves to (it's overridden
     per-shop by a later :root rule in head.tpl), so this now darkens
     THAT shop's real color instead. */
  --scootive-green-hover: color-mix(in srgb, var(--scootive-green) 65%, black);
  --scootive-max: 1760px;
  /* Order/return status colors (account area - src/pages/account.html's own
     .status.processing/.shipped/.delivered), a real semantic scale the
     prototype's tokens.css already defines - added here since nothing on
     this site needed order-status colors before now. */
  --scootive-state-success: #367c38;
  --scootive-state-success-bg: #eaf5e1;
  --scootive-state-warning: #9c5f08;
  --scootive-state-warning-bg: #fbeed9;
  --scootive-state-danger: #c33333;
  --scootive-state-danger-bg: #f8e6e6;
  --scootive-state-info-bg: #eeeee9;
}

.wrap {
  width: min(var(--scootive-max), calc(100% - 64px));
  margin: auto;
}

/* Prototype's base.css halves .wrap's side gutter below 1100px (28px total
   instead of 64px) - this theme's .wrap never got that mobile override, so
   every .wrap-based section (header included) sits with a full 32px gutter
   per side on mobile instead of the intended 14px, visibly too padded next
   to the prototype. */
@media (max-width: 1100px) {
  .wrap {
    width: calc(100% - 28px);
  }
}

/* Header chrome: logo, category row, search, icon buttons (see header.tpl). */
.mainnav {
  height: 74px;
  background: #fff;
  border-bottom: 1px solid var(--scootive-line);
  position: sticky;
  top: 0;
  z-index: 100;
}

.mainnav .wrap {
  height: 100%;
  display: grid;
  grid-template-columns: auto auto minmax(140px, 1fr) auto;
  gap: 18px;
  align-items: center;
}

.logo {
  font-family: "Arial Black", Arial, sans-serif;
  font-size: 25px;
  letter-spacing: -.08em;
  /*
   * Explicit width, not just on the <img>: CSS Grid's "auto" track sizing
   * for this column measured a much smaller intrinsic size than the image
   * actually renders at (a replaced-element-in-grid sizing quirk), leaving
   * the track too narrow and the logo overflowing into the icons next to
   * it. Sizing the grid ITEM itself removes the ambiguity. 124px fits the
   * current logo file's aspect ratio at 24px tall (~122px); revisit if the
   * logo image changes to a very different aspect ratio.
   */
  width: 124px;
}

.logo img {
  display: block;
  height: 24px;
  width: auto;
}

.hamburger {
  display: none;
  width: 40px;
  height: 40px;
  border: 0;
  background: transparent;
  place-items: center;
  cursor: pointer;
  padding: 0;
  color: var(--scootive-ink);
}

.hamburger svg {
  width: 22px;
  height: 22px;
  stroke-width: 1.6;
}

/*
 * Only the top-level category label is uppercase — the expanded mega-menu
 * dropdown keeps normal case, per the prototype. Targeted structurally
 * (#top-menu > li > a) rather than by ps_mainmenu.tpl's own data-depth
 * attribute: that attribute is the same "0" at every nesting level (looks
 * like $node.depth never actually increments in the module's own PHP), so
 * a data-depth selector would (wrongly) catch the nested dropdown links too.
 */
/*
 * ps_mainmenu.tpl's #top-menu <ul> carries Tailwind's `text-sm font-semibold
 * text-slate-700` directly (14px/600/gray) — an explicit value on that exact
 * element, so it wins over `.navcats`'s own font-size/weight/color below no
 * matter the cascade order (inherited values always lose to a value set
 * directly on the element). Overriding it here, on #top-menu itself, is what
 * actually reaches the nav text.
 */
/*
 * Hover dead-zone bug: ps_mainmenu.tpl's <li> has Tailwind's `h-full`, but
 * `.navcats{align-items:center}` (a separate flex context) never actually
 * gave #top-menu a height to be "full" OF — so the <li> was only as tall as
 * its own text (~20px), centered within the 74px-tall row. Moving the mouse
 * straight down from the trigger crossed a real gap where NEITHER the <li>
 * (:hover ended above it) NOR .mega (starts at top:74px) was hovered, so the
 * dropdown closed before the cursor ever reached it — and if the cursor then
 * drifted over a neighboring trigger's <li>, THAT item's mega-menu opened
 * instead. Fix: make the whole chain genuinely 74px tall so hovering
 * anywhere in that column (not just the text) keeps .mega open with no gap
 * before it.
 */
.navcats #top-menu {
  display: flex;
  gap: 10px;
  font-size: 11px;
  font-weight: 900;
  color: var(--scootive-ink);
}

/*
 * height:100% doesn't actually reach 74px here: .navcats/#top-menu sit in a
 * grid row sized `auto` (align-items:center on .mainnav .wrap means the row
 * itself shrinks to content instead of stretching to the container's own
 * 74px) — percentage height with no definite reference collapses back to
 * auto. The prototype sidesteps this by hardcoding .navitem{height:74px}
 * directly rather than inheriting it, so doing the same here instead.
 */
.navcats #top-menu > li {
  flex-shrink: 0;
  height: 74px;
}

.navcats #top-menu > li > a {
  text-transform: uppercase;
  white-space: nowrap;
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
  text-decoration: none;
  height: 74px;
  display: flex;
  align-items: center;
  position: relative;
}

/*
 * Animated underline — prototype-exact behavior, including WHERE it appears:
 * in the prototype, plain links ARE the .navitem (`<a class="navitem">`, no
 * nested anchor), while only items with a dropdown wrap a plain `<a>` inside
 * `<div class="navitem hasmega">` — so `.navitem>a:after` structurally only
 * ever matches items that have a mega-menu. Every item here has the same
 * <li><a> shape regardless, so that has to be spelled out explicitly with
 * :has(.mega) instead of falling out of the structure for free.
 *
 * Driven ONLY by .active (JS-tracked, see initMegaMenu() in theme.js), not a
 * plain :hover variant — a `li:has(.mega):hover` selector used to also show
 * this, and it had the exact same Firefox-only bug as the dropdown itself
 * (see initMegaMenu()'s comment on `trigger.matches(':hover')`): .mega is a
 * position:absolute, full-width descendant of the <li>, and Firefox's :hover
 * computation for the <li> factors in that descendant's full (invisible,
 * pointer-events:none) box, so the underline stayed lit any time the pointer
 * was anywhere within .mega's footprint (well past the header row itself),
 * confirmed via a user screen recording after the dropdown-open bug was
 * fixed but this lingering underline wasn't. Since .active already tracks
 * real hover intent correctly (dwell + a properly-scoped :hover recheck),
 * there's no reason for a second, redundant, less-correct trigger here.
 */
.navcats #top-menu > li:has(.mega) > a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: #111;
  transform: scaleX(0);
  transition: transform .18s;
}

.navcats #top-menu > li.active:has(.mega) > a::after {
  transform: scaleX(1);
}

/*
 * overflow-x:auto here would clip the mega-menu dropdown (position:absolute
 * descendants are clipped by ANY ancestor with overflow != visible, even
 * though .mega's own containing block is further up at .mainnav) — CSS also
 * won't let overflow-x:auto coexist with overflow-y:visible on the same box,
 * so the horizontal-scroll safety net from the earlier width fix and a
 * working dropdown are mutually exclusive here. Dropped the scroll fallback;
 * the tighter gap/search-floor/nowrap changes made earlier are enough to fit
 * real content at normal desktop widths, and the dropdown is the far more
 * important thing to keep working.
 */
.navcats {
  display: flex;
  gap: 10px;
  align-items: center;
  font-size: 11px;
  font-weight: 900;
  flex-shrink: 1;
  min-width: 0;
}

.navitem {
  height: 74px;
  display: flex;
  align-items: center;
  position: static;
  white-space: nowrap;
}

.navitem > a {
  height: 74px;
  display: flex;
  align-items: center;
  position: relative;
}

.navitem.builder {
  height: auto;
  background: var(--scootive-green);
  padding: 10px 14px;
}

.navitem.builder > a {
  height: auto;
}

.search-wrap {
  min-width: 0;
}

/*
 * ps_searchbar ships its own core stylesheet (modules/ps_searchbar/ps_searchbar.css,
 * loaded regardless of theme) targeting #search_widget by ID — higher specificity
 * than any class selector, so it wins over the plain `.search`/`.search input`
 * rules below unless explicitly neutralized here. Left unfixed, it caused a grey
 * input background fighting the pill background, ~40px of dead left padding meant
 * for its own absolutely-positioned icon (this template uses an inline <svg>
 * sibling instead), and — because #search_widget itself has a fixed height plus
 * overflow:auto — an internal scrollbar once the input's own intrinsic height
 * exceeded it.
 */
#search_widget {
  overflow: visible !important;
  height: auto !important;
  margin-bottom: 0 !important;
  width: 100%;
}

#search_widget form input {
  width: auto !important;
  padding: 0 !important;
  background-color: transparent !important;
  border-radius: 0 !important;
}

.search {
  height: 42px;
  background: #f3f3ef;
  border: 1px solid #e4e4de;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  color: var(--scootive-gray-700);
  font-size: 12px;
}

.search svg {
  width: 17px;
  flex-shrink: 0;
}

.search input {
  flex: 1;
  border: 0;
  background: transparent;
  font-size: 12px !important;
  font-family: inherit;
  color: var(--scootive-ink);
  min-width: 0;
  height: auto !important;
}

.search input::placeholder {
  color: var(--scootive-gray-700);
}

.search:focus-within {
  outline: 2px solid #111;
  outline-offset: 2px;
}

.search .clear {
  border: 0;
  background: transparent;
  cursor: pointer;
  color: var(--scootive-gray-600);
}

.header-icons {
  display: flex;
  align-items: center;
  gap: 2px;
}

.icon-btn {
  width: 40px;
  height: 40px;
  border: 0;
  background: transparent;
  display: grid;
  place-items: center;
  position: relative;
  cursor: pointer;
  padding: 0;
  color: var(--scootive-ink);
  text-decoration: none;
}

.icon-btn:hover {
  background: #f2f2ee;
}

.icon-btn svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.55;
}

.count {
  position: absolute;
  right: 1px;
  top: 1px;
  background: #111;
  color: #fff;
  border: 2px solid #fff;
  border-radius: 20px;
  min-width: 18px;
  height: 18px;
  font-size: 9px;
  font-weight: 900;
  display: grid;
  place-items: center;
}

/*
 * <select> elements render with the platform's own control font by default
 * and don't reliably pick up author font-size the way other elements do —
 * needs font-family:inherit and !important to actually land.
 */
.lang-select {
  height: 40px;
  flex-shrink: 0;
  background: transparent;
  border: 0;
  color: var(--scootive-ink);
  font-family: inherit;
  font-size: 12px !important;
  font-weight: 800;
  padding: 0 4px;
  margin-right: 2px;
  cursor: pointer;
}

.lang-select:hover {
  background: var(--scootive-gray-100);
}

.lang-select:focus {
  outline: 2px solid #111;
  outline-offset: 2px;
}

.subnav {
  height: 36px;
  background: #fafaf8;
  border-bottom: 1px solid var(--scootive-line);
  position: relative;
}

.subnav .wrap {
  height: 100%;
  display: flex;
  gap: 29px;
  align-items: center;
  font-size: 10px;
  font-weight: 800;
  color: #555;
  text-transform: uppercase;
}

.subnav .label {
  color: var(--scootive-gray-700);
  letter-spacing: .12em;
}

@media (max-width: 1100px) {
  .mainnav .wrap {
    grid-template-columns: auto auto 1fr auto;
  }

  .hamburger {
    display: grid;
    grid-column: 1;
  }

  .logo {
    grid-column: 2;
  }

  .header-icons {
    grid-column: 4;
  }

  .navcats {
    display: none;
  }

  .search-wrap {
    grid-row: 2;
    grid-column: 1 / -1;
    margin-bottom: 12px;
  }

  .mainnav {
    height: auto;
    padding: 12px 0;
  }

  .subnav {
    display: none;
  }

  .mega {
    display: none;
  }
}

/* Smallest phones: hamburger + logo + 4 icons doesn't fit at 124px logo
   width + full 40px icon buttons, so trim a little further. */
@media (max-width: 380px) {
  .logo {
    width: 100px;
  }

  .logo img {
    height: 20px;
  }

  .header-icons {
    gap: 0;
  }

  .icon-btn {
    width: 34px;
    height: 34px;
  }

  .icon-btn svg {
    width: 18px;
    height: 18px;
  }

  .lang-select {
    padding: 0 2px;
    margin-right: 0;
  }
}

/*
 * The theme's base layout sets `class="font-sans text-slate-900 ..."` on
 * <body> (Tailwind utilities, specificity (0,1,0)) which doesn't match the
 * prototype's plain Arial stack + pure-black ink. Overriding needs the same
 * specificity plus !important to reliably win regardless of Tailwind's own
 * cascade/load order — same reasoning as the earlier checkbox-inline fix.
 */
body {
  font-family: Arial, Helvetica, sans-serif !important;
  color: var(--scootive-ink) !important;
  background: var(--scootive-bg) !important;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Generic show/hide utility - several real, live features (checkout
   voucher/address error messages, the cart-summary product list toggle)
   still add/remove this exact class name via JS, previously relying on
   Tailwind's own CDN-injected `.hidden{display:none}` utility. !important
   for the same reason as the body override above: a plain single-class
   selector has to reliably beat component classes like .csp-list
   (display:flex) or .checkout-notice (no display override) regardless of
   stylesheet load order. */
.hidden {
  display: none !important;
}

/* Minimal Tailwind-compatible spacing shims for the handful of stray
   Bootstrap-style module overrides never touched by the main conversion
   pass (blockwishlist's modals, ps_shoppingcart's modal.tpl,
   ps_emailsubscription-column.tpl, ps_viewedproduct.tpl) - these specific
   class names happen to also be valid Tailwind utility names (unlike their
   neighbouring genuine-Bootstrap classes such as col-xs-12/d-flex/w-100/
   border-1, which were never styled by Tailwind's CDN either and are left
   alone), so they were quietly getting real spacing from the CDN. Matches
   Tailwind's own default 0.25rem-step scale exactly. */
.mb-0 { margin-bottom: 0; }
.mb-1 { margin-bottom: 0.25rem; }
.mb-3 { margin-bottom: 0.75rem; }
.mt-3 { margin-top: 0.75rem; }
.m-0 { margin: 0; }
.px-3 { padding-left: 0.75rem; padding-right: 0.75rem; }

.mobile-nav-overlay {
  position: fixed;
  inset: 0;
  background: #0008;
  z-index: 350;
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s, visibility .2s;
}

.mobile-nav-overlay.open {
  opacity: 1;
  visibility: visible;
}

.mobile-nav {
  position: fixed;
  left: 0;
  top: 0;
  bottom: 0;
  width: min(360px, 86vw);
  background: #fff;
  display: flex;
  flex-direction: column;
  transform: translateX(-100%);
  transition: transform .24s;
  z-index: 351;
}

.mobile-nav.open {
  transform: translateX(0);
}

.mobile-nav-head {
  height: 74px;
  padding: 0 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 2px solid var(--scootive-ink);
  flex-shrink: 0;
}

/* A generic reset elsewhere gives every <img> max-width:100%/height:auto,
   which wins over this element's own height="20" HTML attribute and
   stretched the logo to fill the drawer's whole width instead (found
   live, 2026-10-04 - prototype's equivalent renders at 20px tall). */
.mobile-nav-head img {
  height: 20px;
  width: auto;
}

.mobile-nav-close {
  width: 38px;
  height: 38px;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  font-size: 22px;
  cursor: pointer;
}

.mobile-nav-close:hover {
  background: var(--scootive-ink);
  color: #fff;
  border-color: var(--scootive-ink);
}

.mobile-nav-list {
  padding: 6px 0;
  overflow: auto;
  flex: 1;
}

.mobile-nav-list > a {
  display: block;
  padding: 15px 20px;
  font-size: 15px;
  font-weight: 900;
  letter-spacing: .01em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--scootive-line);
  border-left: 4px solid transparent;
  transition: border-color .15s, background .15s;
  color: inherit;
}

.mobile-nav-list > a:hover,
.mobile-nav-list > a:focus-visible {
  border-left-color: var(--scootive-green);
  background: var(--scootive-gray-50);
}

.mobile-nav-group {
  border-bottom: 1px solid var(--scootive-line);
}

.mobile-nav-toggle {
  width: 100%;
  padding: 15px 20px;
  border: 0;
  border-left: 4px solid transparent;
  background: transparent;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 15px;
  font-weight: 900;
  letter-spacing: .01em;
  text-transform: uppercase;
  text-align: left;
  cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}

.mobile-nav-toggle span {
  font-size: 16px;
  font-weight: 900;
  transition: transform .15s;
}

.mobile-nav-group.open .mobile-nav-toggle {
  background: var(--scootive-ink);
  color: #fff;
  border-left-color: var(--scootive-green);
}

.mobile-nav-sub {
  display: none;
  padding: 2px 20px 16px 32px;
  background: var(--scootive-gray-50);
}

.mobile-nav-group.open .mobile-nav-sub {
  display: block;
}

.mobile-nav-group.open .mobile-nav-toggle span {
  transform: rotate(45deg);
}

.mobile-nav-sub a {
  display: block;
  padding: 10px 0;
  font-size: 13px;
  color: #555;
  font-weight: 800;
  letter-spacing: .01em;
}

.mobile-nav-sub a:hover,
.mobile-nav-sub a:focus-visible {
  color: var(--scootive-green-hover);
  text-decoration: underline;
}

.mobile-nav-builder {
  display: block;
  margin: 16px 20px;
  background: var(--scootive-green);
  color: var(--scootive-ink);
  text-align: center;
  padding: 14px;
  font-size: 12px;
  font-weight: 900;
  letter-spacing: .02em;
  cursor: pointer;
}

.mobile-nav-builder:hover {
  background: var(--scootive-ink);
  color: #fff;
}

.mobile-nav-foot {
  border-top: 2px solid var(--scootive-ink);
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  flex-shrink: 0;
}

.mobile-nav-account-btn {
  display: block;
  text-align: center;
  background: var(--scootive-ink);
  color: #fff;
  padding: 14px;
  font-size: 12px;
  font-weight: 900;
  letter-spacing: .02em;
}

.mobile-nav-account-btn:hover {
  background: var(--scootive-green);
  color: var(--scootive-ink);
}

.mobile-nav-foot-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* Deliberately its own row, not a second .mobile-nav-foot-row stacked
   under the account/logout one with the parent's generic 14px gap as the
   only separation - that read as one undifferentiated pile of small gray
   text (found live, 2026-10-04). A divider + its own top spacing marks
   this as a distinct "legal links" group instead. */
.mobile-nav-foot-links {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 2px;
  padding-top: 14px;
  border-top: 1px solid var(--scootive-line);
}

.mobile-nav-foot-link {
  font-size: 12px;
  font-weight: 800;
  color: #555;
}

.mobile-nav-foot-link:hover,
.mobile-nav-foot-link:focus-visible {
  color: var(--scootive-ink);
  text-decoration: underline;
}


/*
 * ship-timer.tpl's outer wrapper used Tailwind's bg-slate-950 (#020617, a
 * cold blue-black) — prototype's .utility bar is #0b0b0b (neutral warm
 * black). Renamed its class from bg-slate-950 to utility-bar so this can be
 * targeted directly instead of fighting the Tailwind utility everywhere else
 * that class might be reused.
 */
.utility-bar {
  background-color: #0b0b0b;
}

/*
 * Desktop mega-menu dropdown. The prototype's real version has hand-curated
 * column groupings (e.g. "GŁÓWNE CZĘŚCI" / "KOMPRESJA" / "WYKOŃCZENIE") that
 * don't exist as data in a plain PrestaShop category tree — ps_mainmenu.tpl
 * only gives us a flat list of subcategories per parent. Rather than fabricate
 * editorial groupings, the flat list flows into CSS columns (visually similar
 * density, honestly real data). The .mega-feature panel falls back to a
 * plain dark block, or shows the category's own real thumbnail (ps_mainmenu.
 * php's $node.image_urls, scanned from _PS_CAT_IMG_DIR_) as its background
 * when one is configured — see ps_mainmenu.tpl's mega-feature markup.
 */
/*
 * ps_mainmenu.tpl's top-level <li> carries Tailwind's `relative` class
 * (position:relative), which makes IT the containing block for .mega's
 * position:absolute — so `width:100%` resolved to 100% of that narrow,
 * content-sized <li> instead of the full header width. The prototype relies
 * on .navitem staying position:static so .mega bubbles up to .mainnav
 * (position:sticky) as its containing block instead. Forcing it back to
 * static here (higher specificity than Tailwind's single .relative class).
 */
.navcats .nav-item {
  position: static;
}

.mega {
  position: absolute;
  top: 74px;
  left: 0;
  width: 100%;
  background: #fff;
  border-top: 1px solid var(--scootive-line);
  border-bottom: 1px solid var(--scootive-line);
  box-shadow: 0 24px 45px rgba(0, 0, 0, .09);
  opacity: 0;
  pointer-events: none;
  transform: translateY(-8px);
  transition: opacity .16s, transform .16s;
  z-index: 120;
}

/*
 * Driven by initMegaMenu() in theme.js (JS-tracked .active), not :hover —
 * with plain :hover, moving the mouse diagonally toward a link on the far
 * side of the panel can briefly cross a NEIGHBORING trigger's own full-height
 * hit box (each is a sibling in the same 74px-tall row), opening that one's
 * mega on top since both would be independently :hover-true at once. JS
 * guarantees only one .nav-item is ever "active".
 */
.nav-item.active .mega {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}

.mega-inner {
  width: min(var(--scootive-max), calc(100% - 64px));
  margin: auto;
  padding: 32px 0 36px;
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 40px;
}

.mega-links {
  column-width: 200px;
  column-gap: 32px;
}

.mega .mega-col-label {
  font-size: 9px;
  letter-spacing: .16em;
  color: var(--scootive-gray-700);
  margin: 0 0 12px;
  text-transform: uppercase;
  column-span: all;
}

.mega a {
  display: block;
  font-size: 13px;
  padding: 6px 0;
  font-weight: 750;
  line-height: 1.25;
  break-inside: avoid;
  color: var(--scootive-ink);
}

.mega a:hover,
.mega a:focus {
  color: var(--scootive-green-hover);
  text-decoration: underline;
}

/* `.mega a { color: ink }` above has higher specificity (0,1,1) than a bare
   `.mega-feature` class (0,1,0) would, and .mega-feature IS an <a> — so the
   ink color would otherwise win over this panel's intended white text. */
.mega .mega-feature {
  background: #111;
  color: #fff;
  min-height: 215px;
  padding: 25px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  text-decoration: none;
}

.mega-feature .eyebrow {
  font-size: 9px;
  letter-spacing: .16em;
  text-transform: uppercase;
  opacity: .7;
}

.mega-feature b {
  font-family: "Arial Black", Arial, sans-serif;
  font-size: 22px;
  line-height: .95;
  margin-top: 8px;
}

.mega-feature span:last-child {
  font-size: 10px;
  margin-top: 12px;
}

@media (max-width: 1100px) {
  .mega {
    display: none;
  }
}

/*
 * Shared typography/button utilities from the prototype (base.css/buttons.css)
 * — reused across every homepage section and beyond, so defined once here
 * rather than per-component.
 */
.eyebrow {
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  font-weight: 900;
}

.display {
  font-family: "Arial Black", Arial, sans-serif;
  font-weight: 950;
  letter-spacing: -.055em;
  line-height: .9;
  text-transform: uppercase;
  overflow-wrap: break-word;
  word-break: break-word;
}

.btn {
  display: inline-flex;
  height: 48px;
  align-items: center;
  justify-content: center;
  padding: 0 22px;
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  border: 1px solid #111;
  background: #111;
  color: #fff;
  text-decoration: none;
}

.btn.green {
  background: var(--scootive-green);
  color: #111;
  border-color: var(--scootive-green);
}

.hero {
  height: 690px;
  background: #141414;
  color: #fff;
  position: relative;
  overflow: hidden;
}

.hero-track {
  display: flex;
  height: 100%;
  transition: transform .6s ease;
}

.hero-slide {
  position: relative;
  min-width: 100%;
  height: 100%;
}

.hero-img {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  filter: saturate(.72) contrast(1.08);
}

.hero-slide .wrap {
  height: 100%;
  display: flex;
  align-items: center;
  position: relative;
}

.hero-copy {
  max-width: 690px;
  min-width: 0;
}

.hero-copy .eyebrow {
  color: #fff;
  text-shadow: 0 2px 6px rgba(0, 0, 0, .4), 0 6px 20px rgba(0, 0, 0, .35);
}

/* Was ".hero h1" - the slide title is now a <p class="display"> (see
   modules/wetwohero/views/templates/hook/slider.tpl), not a real page
   heading, so every slide no longer produces its own <h1>. The extra
   ".display" class keeps this selector more specific than the plain
   ".hero p" rule below, so the title still gets this large styling
   instead of the small description-paragraph one. */
.hero p.display {
  /* EVERY property below is an explicit override of something the
     sibling ".hero p" rule (meant for the slide DESCRIPTION, right below
     this one) would otherwise apply - since the title is now also a bare
     <p> (it used to be <h1>, which never matched ".hero p" at all, so none
     of this leakage was possible before). Took three separate live fixes
     to get the full list right (2026-10-02, "rozjebales teksty"):
     - max-width/color: ".hero p" sets 440px/#d4d4d4 - without an explicit
       override here the 92px title wrapped inside a narrow box in the
       wrong color.
     - line-height: ".hero p" sets 1.55 directly - NOT just something
       inherited that leaving this property unset would have avoided. An
       intermediate fix set 1.5 (reasoning: "restore whatever the old
       <h1> inherited from app.css's Tailwind html{line-height:1.5} reset,
       since neither rule touched it directly") - technically accurate
       about what the LIVE theme's own pre-existing <h1> rendered with,
       but wrong about design intent: checked directly against the actual
       static prototype this theme was ported from 1:1 (localhost:8934)
       via computed style - h1.display there measures line-height exactly
       0.9x font-size at both the 58px mobile and 92px desktop sizes
       (52.2px/82.8px respectively). The live theme's own h1 had quietly
       never matched its own design source on this one property, this
       whole time - found only after the "restore the original" fix still
       didn't satisfy the user, prompting a side-by-side check against the
       prototype itself rather than trusting the live theme's own
       pre-existing (apparently already slightly wrong) rendering as the
       ground truth. */
  max-width: none;
  color: #fff;
  line-height: 0.9;
  font-size: 92px;
  margin: 12px 0 18px;
  text-shadow: 0 2px 6px rgba(0, 0, 0, .4), 0 6px 20px rgba(0, 0, 0, .35);
}

.hero p {
  max-width: 440px;
  color: #d4d4d4;
  line-height: 1.55;
  font-size: 15px;
  margin: 0 0 24px;
  text-shadow: 0 2px 6px rgba(0, 0, 0, .4), 0 6px 20px rgba(0, 0, 0, .35);
}

.hero-track {
  cursor: grab;
}

.hero-track.dragging {
  cursor: grabbing;
}

.hero-dots {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 8px;
}

.hero-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  border: 0;
  padding: 0;
  background: rgba(255, 255, 255, .4);
  cursor: pointer;
}

.hero-dot.active {
  background: #fff;
}

/* Pause/play toggle next to the dots - WCAG 2.2.2 (Level A) requires a way
   to stop auto-moving content. Found + added via a site-wide accessibility
   audit, 2026-10-02. */
/* Right edge of the hero, not next to the dots - per the store's own
   preference (2026-10-02). bottom:8px + height:32px gives this the exact
   same vertical center as #heroDots (bottom:20px, 8px-tall dots -> center
   24px from the hero's bottom edge; 8px + 32px/2 = 24px too), so the two
   line up regardless of being different sizes or in different horizontal
   positions. The dark circular backdrop (not just a plain icon) keeps it
   visible on its own against any slide image, light or dark - the dots
   sit over this theme's established left-side text-shadow/gradient area,
   but the right edge isn't guaranteed to be darkened the same way. */
.hero-pause-toggle {
  position: absolute;
  bottom: 8px;
  right: 20px;
  z-index: 20;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  padding: 0;
  background: rgba(0, 0, 0, .35);
  color: #fff;
  cursor: pointer;
}

.hero-pause-toggle:hover,
.hero-pause-toggle:focus-visible {
  background: rgba(0, 0, 0, .55);
}

.hero-pause-toggle svg {
  width: 16px;
  height: 16px;
}

.hero-pause-toggle .icon-play {
  display: none;
}

.hero-pause-toggle.is-paused .icon-pause {
  display: none;
}

.hero-pause-toggle.is-paused .icon-play {
  display: block;
}

@media (max-width: 1100px) {
  .hero {
    height: 590px;
  }

  .hero p.display {
    /* Was ".hero h1" - never updated when the title's tag changed, so this
       whole mobile-size override silently stopped applying at all (title
       stuck at the full 92px on narrow viewports instead of shrinking to
       58px) - found live, 2026-10-02, while fixing the other h1->p
       cascade leaks below. */
    font-size: 58px;
  }
}

/*
 * Section wrapper (see ps_newproducts.tpl and every other homepage section
 * to come — bestsellers, specials, etc. all use the same .section/.section-head
 * shape) and the canonical product card, ported from the prototype's
 * product-card.css. Used on home, category, search, and product-reco grids.
 */
.section {
  padding: 88px 0;
}

.section-head {
  display: flex;
  justify-content: space-between;
  align-items: end;
  margin-bottom: 30px;
}

.section-head h2 {
  font-size: 46px;
  margin: 0;
}

.section-head a {
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  border-bottom: 1px solid;
  text-decoration: none;
  color: inherit;
  white-space: nowrap;
}

/* .social-platforms' "INSTAGRAM · TIKTOK · YOUTUBE" middots inherited the
   section's own (much larger) font-size, so they sat far above the small
   10px uppercase link text instead of centered on it. */
.social-platforms {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 10px;
  font-weight: 900;
  letter-spacing: .02em;
}
.social-platforms-sep {
  color: var(--scootive-gray-400);
}

.products {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 26px;
}

/* Category listing page uses a taller row-gap than home/other grids. */
body#category .products {
  gap: 34px 26px;
}

.card {
  position: relative;
  min-width: 0;
}

.card-link {
  position: absolute;
  inset: 0;
  z-index: 1;
}

.prodimg {
  aspect-ratio: 1;
  background: #ecece7;
  display: grid;
  place-items: center;
  overflow: hidden;
  position: relative;
}

.prodimg img {
  width: 88%;
  height: 88%;
  object-fit: contain;
  mix-blend-mode: multiply;
  transition: transform .28s ease;
}

.card:hover .prodimg img {
  transform: scale(1.04);
}

.badge {
  position: absolute;
  top: 10px;
  left: 10px;
  background: #161614;
  color: #fff;
  padding: 6px 8px;
  font-size: 8px;
  font-weight: 900;
  letter-spacing: .02em;
  text-transform: uppercase;
  z-index: 2;
}

.badge--new {
  background: var(--scootive-green);
  color: #111;
}

.badge--sale {
  background: #c33333;
  color: #fff;
}

.badge--out {
  background: #ecece7;
  color: #161614;
}

.card-body {
  padding-top: 14px;
}

.meta-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  align-items: start;
}

.brand {
  font-size: 9px;
  letter-spacing: .11em;
  color: var(--scootive-gray-700);
  font-weight: 900;
}

.name {
  font-weight: 800;
  font-size: 14px;
  margin: 6px 0 9px;
  line-height: 1.25;
  min-height: 35px;
  color: var(--scootive-ink);
}

.wish {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  border: 0;
  background: transparent;
  display: grid;
  place-items: center;
  position: relative;
  z-index: 2;
  padding: 0;
  margin-top: -5px;
  color: var(--scootive-ink);
  cursor: pointer;
}

.wish:hover {
  background: var(--scootive-gray-100);
}

.wish svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
}

.wish.active {
  color: #c33333;
}

.wish.active svg {
  fill: currentColor;
}

.price {
  font-weight: 900;
  font-size: 14px;
  color: var(--scootive-ink);
}

.price.sale {
  display: flex;
  align-items: baseline;
  gap: 7px;
}

.sale-now {
  font-weight: 950;
}

.sale-old,
.old {
  text-decoration: line-through;
  color: var(--scootive-gray-700);
  font-size: 11px;
  font-weight: 500;
}

.price.out-label {
  color: var(--scootive-gray-700);
  font-weight: 800;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .03em;
}

.omnibus-note {
  font-size: 8px;
  color: var(--scootive-gray-700);
  margin-top: 5px;
  font-weight: 700;
  letter-spacing: .01em;
}

.weight {
  font-size: 9px;
  font-weight: 900;
  color: var(--scootive-gray-700);
  margin-top: 7px;
  letter-spacing: .06em;
}

.variant-line {
  margin-top: 8px;
  font-size: 9px;
  line-height: 1.4;
  color: var(--scootive-gray-700);
  font-weight: 800;
  letter-spacing: .02em;
}

.variant-line .vlabel {
  color: var(--scootive-gray-700);
  margin-right: 6px;
  font-weight: 700;
  text-transform: uppercase;
}

.swatches {
  display: flex;
  gap: 7px;
  margin-top: 12px;
  align-items: center;
  pointer-events: none;
}

.swatch {
  width: 14px;
  height: 14px;
  border-radius: 999px;
  border: 1px solid var(--scootive-gray-600);
  box-shadow: inset 0 0 0 2px #f5f5f1;
}

.more {
  font-size: 9px;
  color: var(--scootive-gray-700);
}

.card.is-out .prodimg img {
  opacity: .45;
  filter: grayscale(.4);
}

@media (max-width: 1100px) {
  .products {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  body#category .products {
    gap: 28px 12px;
  }

  .name {
    font-size: 12px;
  }

  .section {
    padding: 48px 0;
  }

  .section-head h2 {
    font-size: 28px;
  }
}

/*
 * blockwishlist's own add-button.tpl renders `<i class="material-icons">
 * favorite_border</i>` — a ligature that needs Google's Material Icons
 * webfont to render as a glyph. This theme never loads that font (every
 * other icon on the site is a hand-drawn inline SVG instead), so it was
 * rendering as literal visible text. Hiding the ligature text and drawing
 * the prototype's own heart icon via background-image instead, rather than
 * pulling in an extra external font for one icon.
 */
.wish {
  position: relative;
  /* Fallback for a real reliability issue in the module itself (not CSS-
     fixable at the root): this button is mounted by button.bundle.js only
     after a chain of sequential network requests (the bundle itself, then
     vendors.js, then graphql.js, then a live "getAllWishlist" AJAX call) -
     confirmed live via the network panel. On a slow connection, or if any
     link in that chain is slow/fails, the button can sit completely empty
     since the server-rendered markup has no icon of its own to fall back
     on. Painting the exact same heart SVG used below directly on this
     always-present wrapper means something is always visible even if Vue
     never mounts; once it does mount, its own identical, transparent-
     background icon simply sits on top with no visible difference. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0a0a' stroke-width='1.6'%3E%3Cpath d='M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.6l-1-1a5.5 5.5 0 0 0-7.8 7.8l1 1L12 21l7.8-7.6 1-1a5.5 5.5 0 0 0 0-7.8Z'/%3E%3C/svg%3E");
  background-size: 17px 17px;
  background-repeat: no-repeat;
  background-position: center;
}

/*
 * blockwishlist ships its OWN CSS fighting these exact properties at higher
 * specificity: modules/blockwishlist/public/wishlist.css has
 * ".products article .wishlist-button-add{position:absolute;top:.635rem;
 * right:.635rem;z-index:10}" (beats a plain ".wish .wishlist-button-add"
 * rule since it has an extra element selector), and its Vue components
 * inject their own "<style>.wishlist-button-add{display:flex;height:2.5rem;
 * width:2.5rem;background:#fff;box-shadow:...;border-radius:50%}" at
 * runtime. Together these turned the button into a floating white circle
 * badge in the image's corner instead of a plain transparent icon button
 * inline in the meta row. !important on every contested property is the
 * only reliable way to win against CSS this module ships and reloads on
 * every version bump.
 */
.wish .wishlist-button-add {
  position: absolute !important;
  inset: 0 !important;
  top: 0 !important;
  right: 0 !important;
  width: 100% !important;
  height: 100% !important;
  min-width: 0 !important;
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  cursor: pointer;
  padding: 0 !important;
  padding-top: 0 !important;
  margin: 0 !important;
  display: grid !important;
  place-items: center;
  align-items: center;
  justify-content: center;
  transition: none;
}

.wish .wishlist-button-add .material-icons {
  font-size: 0;
  width: 17px;
  height: 17px;
  display: inline-block;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0a0a' stroke-width='1.6'%3E%3Cpath d='M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.6l-1-1a5.5 5.5 0 0 0-7.8 7.8l1 1L12 21l7.8-7.6 1-1a5.5 5.5 0 0 0 0-7.8Z'/%3E%3C/svg%3E");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

/*
 * blockwishlist's login/create-list/choose-list popups (mounted via the
 * displayFooter hook) are plain Bootstrap 4 modal markup (.modal/.modal-
 * dialog/.modal-backdrop) — this theme has no Bootstrap CSS at all, so
 * without these rules the elements exist in the DOM (Vue toggles a real
 * "show" class) but render with no positioning, sizing or backdrop at all.
 */
/*
 * blockwishlist's own modules/blockwishlist/public/wishlist.css has
 * ".wishlist-modal.show{z-index:1051}" — equal-or-higher specificity to a
 * plain ".modal"/".modal.show" rule (2 classes vs our 1-2), so it was
 * winning and rendering the backdrop (z-index 1055) ABOVE the modal itself:
 * visually the whole page looked greyed out with no way to click Anuluj/
 * Zaloguj się underneath it. !important forces ours to actually win.
 */
.modal {
  position: fixed !important;
  inset: 0;
  z-index: 1060 !important;
  display: none;
  overflow-y: auto;
}

.modal.show {
  display: block !important;
}

.modal-dialog {
  position: relative;
  width: calc(100% - 32px);
  max-width: 440px;
  margin: 8vh auto;
  pointer-events: none;
}

.modal-content {
  pointer-events: auto;
  background: #fff;
  border: 1px solid var(--scootive-ink);
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 22px;
  border-bottom: 1px solid var(--scootive-line);
}

.modal-title {
  font-size: 13px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: .04em;
  margin: 0;
}

.modal-body {
  padding: 22px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--scootive-ink);
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 16px 22px;
  border-top: 1px solid var(--scootive-line);
}

.modal .close {
  border: 0;
  background: transparent;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  color: var(--scootive-ink);
  padding: 0;
}

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1055;
  background: rgba(10, 10, 10, .55);
  opacity: 0;
  pointer-events: none;
  transition: opacity .15s ease;
}

.modal-backdrop.in,
.modal-backdrop.show {
  opacity: 1;
  pointer-events: auto;
}

.modal .btn-primary,
.modal .btn-secondary {
  display: inline-flex;
  height: 42px;
  align-items: center;
  justify-content: center;
  padding: 0 18px;
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: .04em;
  text-decoration: none;
  border: 1px solid var(--scootive-ink);
  cursor: pointer;
}

.modal .btn-primary {
  background: var(--scootive-ink);
  color: #fff;
}

.modal .btn-secondary {
  background: #fff;
  color: var(--scootive-ink);
}

.modal .form-group {
  margin: 0;
}

.modal .form-control-label {
  display: block;
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--scootive-gray-700);
  margin-bottom: 8px;
}

.modal .form-control {
  width: 100%;
  height: 44px;
  padding: 0 14px;
  font-size: 13px;
  font-family: inherit;
  border: 1px solid var(--scootive-line);
  background: #fff;
  color: var(--scootive-ink);
}

.modal .form-control:focus {
  /* Was outline:none with only a 1px border-color change - much weaker than
     the rest of the site's focus indicators (e.g. .search:focus-within
     below uses a real 2px outline). WCAG 2.4.7 (Focus Visible, Level AA)
     requires a real visible focus indicator - found via a site-wide
     accessibility audit, 2026-10-02. */
  outline: 2px solid var(--scootive-ink);
  outline-offset: 2px;
  border-color: var(--scootive-ink);
}
/*
 * ps_banner (displayHome) — single promotional image banner. The module
 * only stores an image + link (no copy fields), so it reuses the shared
 * .section/.wrap rhythm every other homepage section uses and needs just
 * two new classes for the image/link itself.
 */
.banner-promo__link {
  display: block;
}

/* Full-bleed, native aspect ratio; sharp edges (this theme uses square
   corners everywhere except pill-shaped controls like swatches/dots), no
   invented card shadow for a plain photo. */
.banner-promo__img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 0;
}

/*
 * ps_customtext ("Custom text block", displayHome). The module lets the
 * shop owner enter arbitrary rich HTML via TinyMCE (see
 * modules/ps_customtext/ps_customtext.tpl -> $cms_infos.text nofilter), so
 * this wrapper only needs to be generic and robust for whatever tags show
 * up (headings, paragraphs, bold, links, lists, images) — it is not tied
 * to one fixed layout the way the prototype's other homepage sections are.
 * Reuses .section (vertical rhythm) and .wrap (page gutter) already
 * defined above; only the classes below are new.
 */

/* Subtle background so the free-text block reads as its own section
   between the productised .section blocks above/below it. */
.customtext {
  background: var(--scootive-gray-50);
}

/* Narrower, centered reading column for admin-authored copy — full .wrap
   width (1760px) is too wide a line length for prose. */
.customtext-body {
  max-width: 720px;
  margin: 0 auto;
  text-align: center;
}

.customtext-body > :first-child {
  margin-top: 0;
}

.customtext-body > :last-child {
  margin-bottom: 0;
}

/* Headings inside the free-text HTML echo the site's .display look
   (same family/weight/tracking/case) but at a smaller, secondary scale
   since this block is never the page's primary heading. */
.customtext-body h1,
.customtext-body h2,
.customtext-body h3,
.customtext-body h4,
.customtext-body h5,
.customtext-body h6,
.cms-content h1,
.cms-content h2,
.cms-content h3,
.cms-content h4,
.cms-content h5,
.cms-content h6 {
  font-family: "Arial Black", Arial, sans-serif;
  font-weight: 950;
  letter-spacing: -.03em;
  line-height: 1.05;
  text-transform: uppercase;
  color: var(--scootive-ink);
  margin: 0 0 18px;
}

.customtext-body h1,
.cms-content h1 {
  font-size: 42px;
}

.customtext-body h2,
.cms-content h2 {
  font-size: 34px;
}

.customtext-body h3,
.cms-content h3 {
  font-size: 24px;
}

.customtext-body h4,
.customtext-body h5,
.customtext-body h6,
.cms-content h4,
.cms-content h5,
.cms-content h6 {
  font-size: 18px;
}

.customtext-body p,
.cms-content p {
  margin: 0 0 16px;
  color: var(--scootive-gray-700);
  font-size: 15px;
  line-height: 1.6;
}

.customtext-body strong,
.customtext-body b,
.cms-content strong,
.cms-content b {
  color: var(--scootive-ink);
  font-weight: 900;
}

.customtext-body a,
.cms-content a {
  color: var(--scootive-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.customtext-body a:hover,
.cms-content a:hover {
  color: var(--scootive-green);
}

/* Lists read left-aligned even though .customtext-body itself is centered
   (a homepage blurb) — center-aligned bullet/numbered lists are hard to
   read. .cms-content is already left-aligned by default, so this is just
   a shared declaration, not an override, there. */
.customtext-body ul,
.customtext-body ol,
.cms-content ul,
.cms-content ol {
  text-align: left;
  margin: 0 0 16px;
  padding-left: 22px;
  color: var(--scootive-gray-700);
  font-size: 15px;
  line-height: 1.6;
}

.customtext-body img,
.cms-content img {
  max-width: 100%;
  height: auto;
  margin: 24px 0;
}

.customtext-body blockquote,
.cms-content blockquote {
  margin: 24px 0;
  padding-left: 18px;
  border-left: 3px solid var(--scootive-ink);
  font-style: italic;
  color: var(--scootive-gray-700);
  text-align: left;
}

@media (max-width: 1100px) {
  .customtext-body h1,
  .cms-content h1 {
    font-size: 32px;
  }

  .customtext-body h2,
  .cms-content h2 {
    font-size: 26px;
  }

  .customtext-body h3,
  .cms-content h3 {
    font-size: 20px;
  }
}

/* templates/cms/page.tpl - CMS pages (Terms, Privacy Policy, Delivery,
   etc.) all render through this one shared template with real, admin-
   authored (WYSIWYG) content - shares its element-level typography with
   .customtext-body above (same real-HTML-editor use case) but left-aligned
   and sized for a genuine document, not a centered homepage blurb. Header
   switched from its own one-off .cms-head to the site's real, established
   .cat-head/.cat-copy pair (category/manufacturer/supplier listings,
   contact.tpl, sitemap.tpl...) so a CMS page's title+intro looks the same
   as everywhere else on the site, per explicit request - .cms-head is
   gone from the template now, dropped here as dead CSS. */
.cms-content {
  max-width: 760px;
  padding-bottom: 100px;
}
.cms-content > :first-child {
  margin-top: 0;
}
.cms-content > :last-child {
  margin-bottom: 0;
}

/* cms#6 "Zespół"/Team page - real redesign replacing a raw Tailwind-
   utility-class block (bg-neutral-*/text-neutral-*/max-w-7xl mx-auto etc.)
   that was authored directly into the CMS row via the WYSIWYG editor back
   when the Tailwind CDN was live. That CDN scanned the actual rendered DOM
   at runtime, so it never mattered that these classes lived in the
   database instead of a theme file; the local Tailwind build that
   replaced it only scans files on disk, so DB content is invisible to it
   and this page silently lost its styling. Kept at the same 760px
   .cms-content reading width as every sibling CMS page, but leans into
   full-width action photography instead of a small headshot thumbnail -
   Pro riders get one large, full-bleed landscape shot each (this is a
   showcase page, not a directory); Flow riders share a tighter 2-up grid.
   Placeholder photos are real Unsplash BMX action shots (dynamic resize
   params, ?w=&h=&fit=crop) until real rider photography exists. */
.team-section + .team-section {
  margin-top: 48px;
}
.team-section-head {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 24px;
}
.team-section-head h2 {
  margin: 0 !important;
  white-space: nowrap;
}
.team-section-head-line {
  flex: 1;
  height: 1px;
  background: var(--scootive-line);
}

/* Pro - one full-width feature per rider */
.team-feature + .team-feature {
  margin-top: 40px;
}
.cms-content img.team-feature-photo {
  width: 100%;
  aspect-ratio: 3 / 2;
  margin: 0;
  object-fit: cover;
  background: var(--scootive-gray-100);
}
.team-feature-body {
  padding-top: 18px;
}
.team-feature-body h3 {
  margin: 0 0 8px !important;
  font-size: 26px !important;
}
.team-feature-body p {
  margin: 0 0 12px !important;
}

/* Flow - compact 2-up grid */
.team-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
}
.cms-content img.team-grid-photo {
  width: 100%;
  aspect-ratio: 4 / 3;
  margin: 0;
  object-fit: cover;
  background: var(--scootive-gray-100);
}
.team-grid-body {
  padding-top: 14px;
}
.team-grid-body h3 {
  margin: 0 0 6px !important;
  font-size: 18px !important;
}
.team-grid-body p {
  margin: 0 0 10px !important;
  font-size: 13px !important;
}

.team-links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
}
.team-links a {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
}

@media (min-width: 560px) {
  .team-grid {
    grid-template-columns: 1fr 1fr;
    gap: 24px;
  }
}


/* espepromoduo theme override — additions layered on top of the
   .espe-promo-duo__* rules ALREADY LIVE in scootive-theme.css (grep confirmed
   .espe-promo-duo__grid/__card/.is-small/__image/__overlay/__content/__label/
   __color/__size already exist there, unused until now). Every block below
   either (a) adds properties those existing selectors don't yet set — never
   redeclares background/border-radius/box-shadow/min-height they already have
   — or (b) is a genuinely new selector, each commented. Merge these into the
   existing rule bodies rather than appending a second competing block where
   noted "ADDITION". No new custom properties invented; reuses --scootive-green
   only where noted, otherwise plain values matching the already-live
   .espe-promo-duo__card's own plain-hex convention (#0f172a etc.) so nothing
   here fights the seeded rules on specificity. */

/* ADDITION to existing .espe-promo-duo__grid { display:grid; gap:1.5rem; } */
.espe-promo-duo__grid {
  align-items: stretch;
}

/* NEW: two-card layout — large card gets 3x the width of the small one,
   mirroring the stock module's own lg:grid-cols-[3fr_1fr] ratio. Single-card
   case is left at the grid's default single implicit column. */
.espe-promo-duo__grid.has-two {
  grid-template-columns: 3fr 1fr;
}

/* NEW: full-height clickable wrapper so the <a> (not just the <article>)
   is the grid cell and stretches to the row's height. */
.espe-promo-duo__link {
  display: block;
  width: 100%;
  height: 100%;
  color: inherit;
  text-decoration: none;
}

/*
 * ADDITION to existing .espe-promo-duo__card { position:relative; overflow:hidden;
 * border-radius:2rem; background:#0f172a; box-shadow:...; }
 * height:100% (not just min-height) so both cards genuinely match the grid
 * row's height regardless of the module's own differing is-large/is-small
 * min-heights — .espe-promo-duo__link is the grid item (height:100% of the
 * row), and without an explicit height here the card itself (a plain block)
 * only takes its own min-height/content height, leaving the shorter card
 * looking visibly shorter with empty space below its stretched wrapper.
 */
.espe-promo-duo__card {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 560px;
  color: #fff;
}

@media (max-width: 991.98px) {
  /* the existing seeded rule already drops both .card and .card.is-small to
     420px at this same breakpoint — this just collapses the two-column grid
     to match. */
  .espe-promo-duo__grid.has-two {
    grid-template-columns: 1fr;
  }
}

/* ADDITION to existing .espe-promo-duo__image { transform-origin:center center; } */
.espe-promo-duo__image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s ease;
}

/* NEW: hover zoom on the product photo, matching the product-card component's
   own .card:hover .prodimg img scale(1.04) convention. */
.espe-promo-duo__card:hover .espe-promo-duo__image {
  transform: scale(1.04);
}

/* ADDITION to existing .espe-promo-duo__overlay { background: linear-gradient(...); } */
.espe-promo-duo__overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* ADDITION to existing .espe-promo-duo__content { position:relative; z-index:2; } */
.espe-promo-duo__content {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 12px;
  padding: 32px;
}

@media (max-width: 991.98px) {
  .espe-promo-duo__content {
    padding: 24px;
  }
}

/*
 * ADDITION to existing .espe-promo-duo__label { letter-spacing:.22em; }
 * Matches the real product-card .badge component exactly: same corner
 * position (top-left, absolute) and shape/weight (sharp corners, solid
 * dark fill, tiny uppercase text) instead of a rounded translucent pill
 * anchored at the bottom with the rest of the content.
 */
.espe-promo-duo__label {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 2;
  display: inline-flex;
  padding: 6px 8px;
  border-radius: 0;
  background: var(--scootive-ink);
  color: #fff;
  font-size: 8px;
  font-weight: 900;
  text-transform: uppercase;
}

/* NEW: brand/manufacturer line above the product name. */
.espe-promo-duo__brand {
  margin: 0;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .62);
}

/* NEW: product name — sizing only; type face/weight/case come from the
   .display class already applied on the <h3> in the template. */
.espe-promo-duo__name {
  margin: 0;
  color: #fff;
  font-size: 32px;
}

.espe-promo-duo__card.is-large .espe-promo-duo__name {
  font-size: 46px;
}

/* NEW: price row (current + optional struck-through regular price). */
.espe-promo-duo__price-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.espe-promo-duo__price {
  font-size: 22px;
  font-weight: 900;
  color: #fff;
}

.espe-promo-duo__regular-price {
  font-size: 13px;
  font-weight: 600;
  color: rgba(255, 255, 255, .55);
  text-decoration: line-through;
}

/* NEW: color-swatch row wrapper. */
.espe-promo-duo__colors {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/*
 * ADDITION to existing .espe-promo-duo__color { box-sizing:border-box; }
 * Same technique as the real product-card .swatch (border + inset ring),
 * just sized up for this much bigger card — the inset ring uses the dark
 * card background instead of the page's light --scootive-bg so it still
 * separates the swatch from a busy photo behind it.
 */
.espe-promo-duo__color {
  display: inline-block;
  width: 18px;
  height: 18px;
  border-radius: 999px;
  border: 1px solid var(--scootive-gray-600);
  box-shadow: inset 0 0 0 2px #0a0a0a;
}

/* NEW: "Available options:" sub-label above the size chips. */
.espe-promo-duo__options-label {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  color: rgba(255, 255, 255, .62);
}

/* NEW: size-chip row wrapper. */
.espe-promo-duo__sizes {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* ADDITION to existing .espe-promo-duo__size { line-height:1; } — sharp
   corners, matching the site's square-cornered convention (no rounded
   chips anywhere outside genuinely circular controls). */
.espe-promo-duo__size {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 7px 12px;
  border-radius: 0;
  border: 1px solid rgba(255, 255, 255, .2);
  background: rgba(255, 255, 255, .1);
  color: #fff;
  font-size: 11px;
  font-weight: 900;
}

@media (max-width: 991.98px) {
  /* existing seeded rule already sets .espe-promo-duo__name{font-size:2rem}
     at this breakpoint for both is-large/is-small — nothing further needed
     here beyond the content padding reduction above. */
}


/* Breadcrumb - shared partial used on category, search/manufacturer listing, and product pages.
   Ported 1:1 from the prototype's base.css .breadcrumb rule (var(--gray-700) -> var(--scootive-gray-700)).
   text-transform:uppercase is a deliberate addition: the prototype's ALL-CAPS look there comes from its
   hardcoded demo copy ("STRONA GLOWNA / CZESCI"), not from CSS - real category names are stored in normal
   case ("Czesci"), so this transform is needed to actually match the prototype's visual style with real data. */
.breadcrumb{padding:22px 0 12px;font-size:9px;letter-spacing:.04em;color:var(--scootive-gray-700);text-transform:uppercase}
.breadcrumb a{color:inherit;text-decoration:none}
.breadcrumb a:hover,.breadcrumb a:focus-visible{text-decoration:underline}

/* ===== Category/listing filters — real ps_facetedsearch data, full port of
   the prototype's toolbar-wrap/filter-topbar/quick-filters/filter-overlay/
   filter-drawer (src/pages/category.html + category.css). Was previously
   deliberately deferred ("off-canvas facet redesign... out of scope for this
   pass") — this is that pass. See catalog/_partials/facets.tpl (theme
   override of ps_facetedsearch's own template) for the real markup this
   styles, and [[project-ever-theme-status]] for the interaction-model
   decisions (full-page-reload filtering for now, quick-filter dropdown
   instead of "opens the full drawer", first-5-facets-in-admin-order). */
.toolbar-wrap{
  position:sticky;
  top:74px;
  z-index:50;
  background:rgba(245,245,241,.97);
  backdrop-filter:blur(10px);
  border-top:1px solid var(--scootive-line);
  border-bottom:1px solid var(--scootive-line);
  margin-bottom:26px;
}

.filter-topbar{padding:12px 0 10px}

.quick-filters{display:flex;flex-wrap:wrap;gap:7px}

.quick-filter-wrap{position:relative}

.quick-filter,.more-filters{
  height:42px;
  border:1px solid var(--scootive-gray-600);
  background:#fff;
  padding:0 13px;
  display:flex;
  align-items:center;
  gap:12px;
  font-size:10px;
  font-weight:900;
  letter-spacing:.02em;
  color:var(--scootive-ink);
  text-transform:uppercase;
  white-space:nowrap;
  cursor:pointer;
}
.quick-filter:hover{border-color:var(--scootive-ink)}
.quick-filter[aria-expanded="true"]{background:var(--scootive-ink);border-color:var(--scootive-ink);color:#fff}

.more-filters{background:var(--scootive-ink)!important;color:#fff!important;border-color:var(--scootive-ink)!important}

.quick-filter-dropdown{
  position:absolute;
  top:calc(100% + 8px);
  left:0;
  z-index:2;
  min-width:280px;
  max-width:320px;
  max-height:70vh;
  overflow-y:auto;
  background:#fff;
  border:1px solid var(--scootive-ink);
  padding:16px;
  opacity:0;
  visibility:hidden;
  transition:opacity .15s;
}
/* opacity/visibility (not the `hidden` attribute/display:none) deliberately -
   a hidden slider container would report zero width to jQuery UI on init;
   this way its real layout box always exists, so initFacetedSliders() (see
   theme.js) only ever needs to run once on page load, never re-run on open. */
.quick-filter-dropdown.open{opacity:1;visibility:visible}

.filter-meta{
  min-height:40px;
  padding-top:10px;
  margin-top:10px;
  border-top:1px solid rgba(223,223,216,.7);
  display:flex;
  flex-wrap:wrap;
  justify-content:space-between;
  align-items:center;
  gap:14px 20px;
}

.active-filters{display:flex;flex-wrap:wrap;gap:7px;align-items:center}

.chip{
  height:30px;
  padding:0 10px;
  border:1px solid var(--scootive-gray-600);
  background:#fff;
  font-size:9px;
  font-weight:800;
  letter-spacing:.02em;
  color:var(--scootive-ink);
  text-transform:uppercase;
  white-space:nowrap;
  display:inline-flex;
  align-items:center;
  gap:6px;
  text-decoration:none;
}
.chip:hover{border-color:var(--scootive-ink)}
.chip b{font-weight:400}

.toolbar-right{display:flex;align-items:center;gap:12px;margin-left:auto}

/* Full filter drawer + backdrop - single overlay used identically on mobile
   and desktop (no more separate always-visible desktop sidebar). */
.filter-overlay{
  position:fixed;
  inset:0;
  background:rgba(0,0,0,.53);
  z-index:300;
  opacity:0;
  visibility:hidden;
  transition:.2s;
}
.filter-overlay.open{opacity:1;visibility:visible}

.filter-drawer{
  position:absolute;
  left:0;
  top:0;
  bottom:0;
  width:min(470px,92vw);
  background:#f7f7f3;
  transform:translateX(-100%);
  transition:.24s;
  display:flex;
  flex-direction:column;
}
.filter-overlay.open .filter-drawer{transform:translateX(0)}

.filter-drawer-head{
  height:76px;
  padding:0 24px;
  display:flex;
  align-items:center;
  justify-content:space-between;
  border-bottom:1px solid var(--scootive-line);
  background:#fff;
  flex-shrink:0;
}
.filter-drawer-head h2{font-size:24px;margin:0}

.filter-close{width:38px;height:38px;border:0;background:transparent;font-size:24px;cursor:pointer;color:var(--scootive-ink)}

.filter-drawer-body{overflow-y:auto;padding:0 24px 24px;flex:1}

.facet{border-bottom:1px solid var(--scootive-line)}
.facet-head{
  width:100%;
  height:58px;
  border:0;
  background:transparent;
  display:flex;
  align-items:center;
  justify-content:space-between;
  padding:0;
  font-size:11px;
  font-weight:900;
  letter-spacing:.02em;
  text-transform:uppercase;
  color:var(--scootive-ink);
  cursor:pointer;
}
.facet-body{padding:0 0 18px;display:none}
.facet.open .facet-body{display:block}

.checkrow{display:flex;justify-content:space-between;align-items:center;font-size:11px;padding:7px 0;color:#333}
.checkrow label{display:flex;align-items:center;gap:10px;cursor:pointer}
.checkrow input[type="checkbox"],.checkrow input[type="radio"]{width:15px;height:15px;accent-color:var(--scootive-ink)}
.checkrow .swatch{width:15px;height:15px;border-radius:50%;border:1px solid var(--scootive-line);flex-shrink:0;background-size:cover;background-position:center}
.countf{font-size:9px;color:var(--scootive-gray-700)}

.facet-links{display:flex;flex-direction:column}
.facet-link{display:flex;justify-content:space-between;align-items:center;gap:10px;font-size:11px;padding:7px 0;color:#333;text-decoration:none}
.facet-link.active{font-weight:900;color:var(--scootive-ink)}
.facet-link:hover{color:var(--scootive-ink)}

.filter-drawer-foot{
  margin-top:auto;
  border-top:1px solid var(--scootive-line);
  background:#fff;
  padding:16px 24px;
  display:grid;
  grid-template-columns:1fr 1.4fr;
  gap:8px;
  flex-shrink:0;
}
.clear,.apply{height:46px;border:1px solid var(--scootive-ink);font-size:10px;font-weight:900;letter-spacing:.02em;text-transform:uppercase;display:flex;align-items:center;justify-content:center;text-decoration:none;cursor:pointer}
.clear{background:#fff;color:var(--scootive-ink)}
.apply{background:var(--scootive-ink);color:#fff}

/* Vendor range slider (ps_facetedsearch's own front.css, a real jQuery UI
   slider - the module's own compiled CSS still loads normally, only its
   theme override front.js is a no-op stub, see part 25) - reskin only, kept
   as the real functional widget rather than hand-rebuilding range-URL
   encoding with plain OD/DO inputs like the prototype's own mockup. */
/* !important throughout: jquery.ui.theme.css/jquery.ui.slider.css load AFTER
   scootive-theme.css in head.tpl (core enqueues vendor CSS after the theme's
   own), so on equal selector specificity the vendor's own .ui-slider-handle
   background/border rules win by load order alone - verified live (computed
   background stayed the vendor's default light gray without !important). */
/* jQuery UI's .slider() call adds "ui-slider" to the SAME element .faceted-
   slider is already on (not a wrapper) - a descendant selector here would
   silently never match; verified live (track stayed vendor-default white
   with a space, fixed once changed to a compound .faceted-slider.ui-slider
   selector, no space). .ui-slider-range/-handle genuinely ARE descendants
   (elements jQuery UI creates inside the container), so those keep the
   space. */
.faceted-slider.ui-slider{background:var(--scootive-gray-600)!important;border-radius:0!important;border:0!important;height:3px!important}
.faceted-slider .ui-slider-range{background:var(--scootive-ink)!important;border-radius:0!important}
.faceted-slider .ui-slider-handle{width:16px!important;height:16px!important;border-radius:50%!important;background:var(--scootive-ink)!important;border:2px solid #fff!important;box-shadow:0 0 0 1px var(--scootive-ink)!important;top:-7px!important;outline:none!important}

/* The slider's own layout: everything was rendering with zero spacing
   between the value readout and the track - jammed together at a
   mismatched 16px font. Fixed to the same compact scale as the rest of the
   filter UI, with real breathing room around the track (handles overhang
   it by 7px on each side - top padding on the wrap keeps that from
   crowding the values text above it). */
.js-faceted-filter-slider{padding:6px 4px 2px}
.js-faceted-values{font-size:11px;font-weight:900;letter-spacing:.02em;color:var(--scootive-ink);margin-bottom:22px}
.faceted-slider{margin:0 8px}

/* Each quick-filter dropdown's own single apply button (the drawer's
   equivalent is .apply, in its own footer - this is the same idea, just
   sized for a small ~280-320px dropdown instead of the full drawer). */
.quick-filter-apply{
  display:block;
  width:100%;
  height:32px;
  margin-top:14px;
  border:1px solid var(--scootive-ink);
  background:#fff;
  color:var(--scootive-ink);
  font-size:9px;
  font-weight:900;
  letter-spacing:.06em;
  text-transform:uppercase;
  cursor:pointer;
  transition:background .15s,color .15s;
}
.quick-filter-apply:hover{background:var(--scootive-ink);color:#fff}

/* Category page header (H1 + short description) and the bottom SEO-copy
   block - ported directly from the prototype's .cat-head/.cat-copy/
   .cat-bottom-copy (category.css). .cat-bottom-layout's 2-column photo+copy
   grid IS now ported (see category.tpl) - the photo turned out to be real,
   per-category data after all (core's own $category.cover, i.e. CategoryLazyArray
   ::getCover(), backed by a genuinely uploaded img/c/<id>.jpg - 58 categories
   on this shop have one), not prototype demo filler as first assumed; this
   earlier comment's premise was wrong. */
.cat-head{padding:36px 0 38px}
.cat-head h1{font-size:76px;margin:8px 0 0}
.cat-copy{font-size:14px;line-height:1.65;color:#555;max-width:620px;margin-top:16px}
.cat-copy ul,.cat-copy ol{margin:12px 0;padding-left:22px}
.cat-copy ul{list-style:disc}
.cat-copy ol{list-style:decimal}
.cat-copy li{margin:0 0 6px}

/* margin-top: the prototype gets this same pre-divider breathing room from
   its own .catalog{padding:34px 0 90px} wrapper around the product grid +
   pagination - this theme has no equivalent wrapping element (product-grid.
   tpl/pagination.tpl are shared, unwrapped includes), so the gap is added
   here instead, scoped to just this section rather than the shared grid/
   pagination partials used by other listing pages too. */
.cat-bottom{border-top:1px solid var(--scootive-line);padding:58px 0 80px;margin-top:90px}
.cat-bottom-layout{display:grid;grid-template-columns:minmax(0,700px) 1fr;gap:70px}
.cat-bottom-copy{max-width:700px}
.cat-bottom-copy h2{font-size:20px;font-weight:900;letter-spacing:.01em;margin:0 0 14px}
.cat-bottom-copy h3{font-size:15px;font-weight:900;letter-spacing:.01em;margin:28px 0 12px}
.cat-bottom-copy p{font-size:13px;line-height:1.75;color:#555;margin:0 0 14px}
.cat-bottom-copy a{color:var(--scootive-ink);text-decoration:underline}
.cat-bottom-copy ul,.cat-bottom-copy ol{font-size:13px;line-height:1.75;color:#555;margin:0 0 14px;padding-left:22px}
.cat-bottom-copy ul{list-style:disc}
.cat-bottom-copy ol{list-style:decimal}
.cat-bottom-copy li{margin:0 0 6px}
.cat-bottom-photo{background-position:center;background-size:cover}

/* Real sort-order labels ("Najczęściej kupowane" etc.) aren't stored
   uppercase the way the prototype's hardcoded demo option text is -
   same class of fix as .breadcrumb elsewhere in this file. */
.sort-select{text-transform:uppercase}

.more-filters-label-mobile{display:none}

@media(max-width:1100px){
  .toolbar-wrap{top:137px}
  /* Matches the prototype's own intended mobile behavior (its category.css
     already has this exact rule) - individual quick-filter chips disappear
     entirely on mobile, replaced by ONE full-width button opening the same
     drawer. My first pass instead made the whole chip row horizontally
     scrollable, which isn't what the prototype (or the user) wants here. */
  .quick-filter-wrap{display:none}
  .more-filters{width:100%}
  .more-filters-label-desktop{display:none}
  .more-filters-label-mobile{display:inline}
  .toolbar-right{margin-left:0;width:100%;justify-content:space-between}
  .filter-meta{align-items:flex-start}
  .cat-head h1{font-size:52px}
  .cat-copy{max-width:none}
  .cat-bottom-layout{grid-template-columns:minmax(0,1fr)}
  .cat-bottom-photo{display:none}
}

.result-count{
  font-size:9px;
  letter-spacing:.08em;
  color:var(--scootive-gray-700);
  text-transform:uppercase;
  margin:0;
  white-space:nowrap;
}

.sort-control{
  position:relative;
  height:42px;
  min-width:220px;
  border:1px solid var(--scootive-gray-600);
  background:#fff;
  display:grid;
  grid-template-columns:auto 1fr auto;
  align-items:center;
}

.sort-label{
  height:100%;
  display:flex;
  align-items:center;
  padding:0 11px;
  border-right:1px solid var(--scootive-line);
  font-size:9px;
  font-weight:900;
  letter-spacing:.08em;
  color:var(--scootive-gray-700);
  text-transform:uppercase;
  white-space:nowrap;
}

.sort-select{
  width:100%;
  height:40px;
  border:0;
  background:transparent;
  appearance:none;
  -webkit-appearance:none;
  padding:0 32px 0 12px;
  /* Real sort labels ("Referencje, od A do Z" etc.) run longer than the
     prototype's own demo option text - on mobile's 150px max-width this
     otherwise hard-clips mid-character rather than degrading gracefully. */
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
  /* !important needed: app.css has a sitewide `input,select,textarea{font-size:
     16px!important}` rule (the standard iOS-Safari zoom-on-focus-prevention
     trick - not something to remove) that otherwise wins regardless of this
     rule's own specificity. The prototype's own .sort-select rule already
     carries font-size:10px!important for exactly this reason; this port had
     dropped it, which is why the control rendered at 16px instead of 10px. */
  font-size:10px!important;
  font-weight:900;
  color:var(--scootive-ink);
  cursor:pointer;
}
.sort-select:focus{outline:2px solid var(--scootive-ink);outline-offset:2px}

.sort-chevron{
  position:absolute;
  right:11px;
  top:50%;
  transform:translateY(-56%);
  font-size:15px;
  pointer-events:none;
  color:var(--scootive-gray-700);
}

/* Pagination - ported from the prototype's category.css .pagination rules (var(--gray-600) -> var(--scootive-gray-600),
   #111 -> var(--scootive-ink)). Real PS pagination renders <a href> links (not the prototype's JS-built <button>s),
   so text-decoration/color/centering are added here since anchors don't auto-center text the way buttons do. */
.pagination{display:flex;justify-content:center;align-items:center;gap:8px;margin-top:56px;flex-wrap:wrap}
.pagination .page-num,.pagination .page-arrow{min-width:38px;height:38px;padding:0 6px;border:1px solid var(--scootive-gray-600);background:#fff;font-size:12px;font-weight:900;color:var(--scootive-ink);text-decoration:none;display:flex;align-items:center;justify-content:center;cursor:pointer}
.pagination .page-num:hover,.pagination .page-arrow:hover{border-color:var(--scootive-ink)}
.pagination .page-num.active{background:var(--scootive-ink);border-color:var(--scootive-ink);color:#fff}
.pagination .page-arrow{font-size:16px}
/* Ellipsis between non-adjacent page numbers (core PS's "spacer" link type) - the prototype's static demo
   never had enough pages to need one, so this is a net-new rule for a real state the prototype doesn't show. */
.pagination .page-spacer{border:0;background:transparent;cursor:default;color:var(--scootive-gray-600)}

@media(max-width:1100px){
  .result-count{display:none}
  .sort-control{min-width:158px}
  .sort-label{display:none}
  .sort-select{max-width:150px}
}


/*
 * Product page (catalog/product.tpl + _partials/product-*.tpl) — core buy
 * flow: layout grid, gallery, brand/title/price/stock, variants, qty/add-
 * to-cart. Ported from the prototype's product.css. Not covered in this
 * pass: description/specs accordion, related products, lightbox, the
 * size-guide modal, and the handlebar-cutting/addon service modals (no
 * real backend feature exists for the cutting service yet — see memory).
 */

/* Mobile-first: was previously only the desktop grid here (no media
   query), relying on Tailwind's own "flex flex-col ... lg:grid" utility
   classes on the element itself to handle mobile - removing the Tailwind
   CDN would have silently forced the 2-column desktop grid onto mobile
   too. Real bug found during the Tailwind cleanup (never shipped, caught
   before deploy): mobile also needs the gallery → buy box → specs/reviews
   order this page has always shown (an intentional deviation from the
   prototype's own simpler order, which bundles gallery+info as one block
   before buy - product.css's own .left-flow{order:1}/.buy{order:2} never
   separates the info section out). .left-flow's display:contents on
   mobile "unwraps" it so its two children (gallery, product-info) can be
   individually interleaved with .buy via order, matching the exact visual
   result the old Tailwind order-1/order-2/order-3 classes produced -
   DOM order is untouched (still left-flow, then buy) and still what
   drives the desktop 2-column grid, matching the prototype's own DOM. */
.pdp {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin-top: 32px;
}

.left-flow {
  display: contents;
  min-width: 0;
}

.pdp-gallery-wrap {
  order: 1;
  min-width: 0;
}

.pdp > .buy {
  order: 2;
  padding: 8px 0 0;
}

.pdp .product-info {
  order: 3;
}

@media (min-width: 1101px) {
  .pdp {
    display: grid;
    grid-template-columns: minmax(0, 1.08fr) minmax(430px, .72fr);
    gap: 84px;
    align-items: start;
    padding: 0 0 90px;
    margin-top: 0;
  }
  .left-flow {
    display: block;
  }
  .left-flow > * + * {
    margin-top: 24px;
  }
  .pdp-gallery-wrap,
  .pdp .product-info {
    order: initial;
  }
  .pdp > .buy {
    order: initial;
    position: sticky;
    top: 128px;
    height: fit-content;
  }
}

/*
 * Mobile-only sticky "scroll to buy box" bar (.js-mobile-cta in
 * product.tpl), ported 1:1 from the prototype's .mobile-cta (src/assets/
 * css/product.css) - shown via theme.js's IntersectionObserver once .buy
 * scrolls out of view, and hidden outright at the same >=1101px breakpoint
 * above where .buy goes sticky and no longer needs a scroll-back shortcut.
 * z-index:90 matches the prototype's own --z-mobile-cta (just below the
 * sticky header's 100) - .az-jump-wrap is the only other thing on this
 * site already using 90, and it only ever renders on the brands page, so
 * there's no real overlap to worry about.
 */
.mobile-cta {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 90;
  display: none;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  background: #fff;
  border-top: 1px solid var(--scootive-line);
  box-shadow: 0 -6px 18px rgba(0, 0, 0, .1);
}
.mobile-cta.show {
  display: flex;
}
.mobile-cta-price {
  font-size: 15px;
  font-weight: 900;
  white-space: nowrap;
}
.mobile-cta .btn-black {
  flex: 1;
  justify-content: center;
}
/* Scoped to the same <=1100px range .mobile-cta itself is visible in -
   left unscoped, this padding-bottom reservation survived past 1101px
   even though .mobile-cta is hidden there, leaving a permanent 76px gray
   gap (body's own background peeking through) below the footer on every
   desktop page - found live, 2026-10-05. */
@media (max-width: 1100px) {
  body.has-mobile-cta {
    padding-bottom: 76px;
  }
}
@media (min-width: 1101px) {
  .mobile-cta {
    display: none !important;
  }
}

/* Gallery: thumbs column (left) + main stage (right) */
.gallery.images-container {
  display: grid !important;
  grid-template-columns: 84px 1fr;
  gap: 14px;
  position: relative;
  padding: 0 !important;
}

/*
 * Single-image products never render the .thumbs block at all (the Smarty
 * {if $product.images|count > 1} guard) — with only one grid item left,
 * auto-placement dropped .stage into the first (84px) track instead of
 * stretching it, squashing the whole gallery to a thumbnail-sized sliver.
 * Explicit grid-column assignments make placement deterministic regardless
 * of how many items exist, and the :not(:has()) fallback collapses to a
 * single full-width column when there's truly nothing to show on the left.
 */
.gallery .stage {
  grid-column: 2;
}

.gallery:not(:has(.thumbs)) {
  grid-template-columns: 1fr;
}

.gallery:not(:has(.thumbs)) .stage {
  grid-column: 1;
}

.gallery .thumbs {
  grid-column: 1;
  order: -1;
  display: flex !important;
  flex-direction: column;
  gap: 10px;
  width: auto !important;
  max-width: none !important;
  overflow: visible !important;
  margin-top: 0 !important;
}

.gallery .thumbs ul.product-images {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex-wrap: nowrap;
  overflow: visible;
  padding: 0;
  margin: 0;
  list-style: none;
}

.gallery .thumb-container {
  width: auto !important;
}

.gallery .thumb-container button {
  display: block;
  width: 100% !important;
  aspect-ratio: 1;
  background: #ecece7;
  border: 1px solid var(--scootive-gray-600) !important;
  border-radius: 0 !important;
  padding: 0;
  cursor: pointer;
}

.gallery .thumb-container button:has(.selected) {
  border-color: #111 !important;
}

.gallery img.thumb {
  width: 84% !important;
  height: 84% !important;
  margin: 8% auto;
  object-fit: contain !important;
  mix-blend-mode: multiply;
  border-radius: 0 !important;
  border: 0 !important;
}

.gallery .stage {
  min-height: 720px;
  background: #ecece7;
  display: grid;
  place-items: center;
  position: relative;
  overflow: hidden;
  border-radius: 0 !important;
  border: 1px solid #e1e1db;
}

.gallery .stage > div {
  border-radius: 0 !important;
  background: transparent !important;
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
}

.gallery .stage img.js-product-cover {
  width: 86% !important;
  height: 86% !important;
  object-fit: contain !important;
  mix-blend-mode: multiply;
  border-radius: 0 !important;
  transition: transform .25s;
  aspect-ratio: auto !important;
}

.gallery .stage-note {
  position: absolute;
  right: 16px;
  top: 14px;
  font-size: 9px;
  color: var(--scootive-gray-700);
  letter-spacing: .1em;
  z-index: 1;
}

.gallery .stage .zoom {
  position: absolute;
  left: 16px;
  bottom: 16px;
  right: auto;
  top: auto;
  width: 38px;
  height: 38px;
  background: #fff;
  border: 1px solid #ddd !important;
  border-radius: 0 !important;
  display: grid;
  place-items: center;
  box-shadow: none !important;
}

@media (max-width: 1100px) {
  .gallery.images-container {
    grid-template-columns: 1fr;
  }

  /* .stage keeps the desktop-only grid-column:2 assignment unless reset here
     - with only one explicit column now, that forces an implicit auto-sized
     second column that hogs all the space, starving .thumbs's column
     (grid-column:1) down to 0 width and hiding the thumbnails entirely. */
  .gallery .stage {
    grid-column: 1;
  }

  .gallery .thumbs {
    order: 2;
    flex-direction: row;
  }

  .gallery .thumbs ul.product-images {
    flex-direction: row;
    overflow-x: auto;
  }

  .gallery .thumb-container {
    width: 70px !important;
    flex-shrink: 0;
  }

  .gallery .stage {
    min-height: 380px;
  }
}

/* Brand / title / rating / price / stock */
.brandline {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.brandname {
  font-size: 10px;
  letter-spacing: .13em;
  font-weight: 900;
  color: var(--scootive-gray-700);
  text-transform: uppercase;
}

.buy h1.display {
  font-size: 46px;
  margin: 12px 0 18px;
  max-width: 670px;
}

.price-row {
  display: flex;
  align-items: baseline;
  gap: 9px;
}

.buy .price {
  font-size: 30px;
  font-weight: 900;
  color: var(--scootive-ink);
}

.buy .oldprice {
  font-size: 13px;
  text-decoration: line-through;
  color: var(--scootive-gray-700);
  font-weight: 500;
}

.buy .omnibus-note {
  margin-top: 3px;
  font-size: 9px;
  color: var(--scootive-gray-700);
  font-weight: 700;
}

/* The real text styling comes from the omnifree (VEKIA) module's own
   .omnibus-box/.omnibus-box--classic/.omnibus-price classes nested INSIDE
   .omnibus-note, not from .omnibus-note itself - the rule above has no
   visible effect on the actual text. Overridden here (theme CSS, not the
   vendor module's own files) so a future omnifree update doesn't wipe the
   change; ".buy .omnibus-box" (2 classes) beats the module's own bare
   ".omnibus-box"/".omnibus-box--classic" (1 class) regardless of file
   load order. */
.buy .omnibus-box {
  margin-top: 2px;
  font-size: 0.7rem;
  color: var(--scootive-gray-700);
}
.buy .omnibus-box--classic {
  font-size: 0.7rem;
}
.buy .omnibus-box .omnibus-price {
  font-weight: 500;
}

.buy .unit-price {
  margin-top: 7px;
  font-size: 11px;
  color: var(--scootive-gray-700);
}

.stock {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 13px 0 24px;
  font-size: 11px;
  font-weight: 800;
  color: var(--scootive-ink);
}

.stock .dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: #4d7a0d;
  flex-shrink: 0;
}

.stock .dot.low {
  background: #966000;
}

.stock .dot.out {
  background: #e23a3a;
}

/* Real delivery-estimate line (wetwoshipping's own displayWetwoProductShipping
   hook - built in an earlier session but never actually wired into
   product-prices.tpl until now, per user request to reuse the same module
   already powering checkout's delivery-step date labels). The prototype's
   own two-line "U CIEBIE: X / Szacowana dostawa..." split doesn't map onto
   this module's data model (it only ever produces ONE complete,
   admin-configurable sentence - see WETWOSHIPPING_PRODUCT_TEXT_BEFORE/AFTER),
   so this is a single-line message inside the same icon+border-top/bottom
   strip, not a forced two-line split with invented content. */
.shipline {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  gap: 16px;
  align-items: center;
  padding: 20px 0;
  margin: 0 0 24px;
  border-top: 1px solid var(--scootive-line);
  border-bottom: 1px solid var(--scootive-line);
}
.delivery-icon {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  background: #e9eee0;
}
.delivery-icon svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: var(--scootive-ink);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.delivery-copy-top {
  min-width: 0;
}
.delivery-main {
  margin: 0;
  font-size: 15px;
  line-height: 1.3;
  font-weight: 900;
  color: var(--scootive-ink);
  letter-spacing: -0.01em;
}
.delivery-sub {
  margin: 5px 0 0;
  font-size: 11px;
  line-height: 1.4;
  color: var(--scootive-gray-700);
}

/* condition/reference/ean meta line — not in the prototype's mockup at all,
   kept as real useful info but styled small/muted so it doesn't compete. */
#product-details p {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  font-size: 10px;
  color: var(--scootive-gray-700);
}

/* Variants: option-row / opt-title / color swatches / size buttons */
.option-row {
  margin: 20px 0 0;
}

.opt-title {
  font-size: 10px;
  font-weight: 900;
  margin: 0 0 10px;
  color: var(--scootive-ink);
  letter-spacing: .02em;
}

.opt-title span {
  font-weight: 700;
  color: var(--scootive-gray-700);
  text-transform: none;
}

.color-choices {
  display: flex;
  gap: 9px;
  flex-wrap: wrap;
  padding: 0;
  margin: 0;
  list-style: none;
}

/*
 * Product page color choices: NOT flat color circles — a square photo
 * swatch (product's own image, reused for every color, matching the
 * prototype's actual behavior exactly — see product-variants.tpl for why)
 * with a small color-coded dot badge in the corner. Selection state reacts
 * live to the real radio's :checked state via :has(), no JS class
 * management needed (same pattern as the mega-menu/thumbnail :has() rules
 * elsewhere in this file).
 */
.color-choice {
  width: 68px;
  height: 68px;
  border: 1px solid var(--scootive-gray-600);
  background: var(--scootive-gray-100);
  padding: 5px;
  display: grid;
  place-items: center;
  cursor: pointer;
  position: relative;
}

.color-choice:has(.input-color:checked) {
  border: 2px solid var(--scootive-ink);
}

.color-choice img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
}

.color-dot {
  position: absolute;
  right: 5px;
  bottom: 5px;
  width: 12px;
  height: 12px;
  border-radius: 999px;
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px var(--scootive-gray-600);
}

.input-color:focus-visible ~ .color-dot {
  outline: 2px solid var(--scootive-ink);
  outline-offset: 2px;
}

.sizes {
  display: flex;
  gap: 7px;
  flex-wrap: wrap;
}

.sizes .size {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 49px;
  height: 40px;
  border: 1px solid var(--scootive-gray-600);
  background: transparent;
  color: var(--scootive-ink);
  font-size: 10px;
  font-weight: 900;
  padding: 0 10px;
  cursor: pointer;
}

.input-radio:checked + .size {
  background: var(--scootive-ink);
  color: #fff;
  border-color: var(--scootive-ink);
}

.input-radio:focus-visible + .size,
.input-color:focus-visible + .sw {
  outline: 2px solid var(--scootive-ink);
  outline-offset: 2px;
}

.variant-select {
  height: 44px;
  width: 100%;
  border: 1px solid var(--scootive-gray-600);
  background-color: #fff;
  padding: 0 36px 0 12px;
  font-family: inherit;
  font-size: 12px !important;
  font-weight: 700;
  color: var(--scootive-ink);
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%230a0a0a' stroke-width='1.6'%3E%3Cpath d='M5.5 7.5 10 12l4.5-4.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 14px;
}

.variant-select:focus {
  outline: 2px solid var(--scootive-ink);
  outline-offset: 2px;
}

/* Additional services (avebartrim cutting card, aveaddoncards sticker card)
   share this slot with blockreassurance's own reassurance cards, which keep
   their own module styling untouched. */
.secondary-options {
  display: block;
  width: 100%;
  margin: 28px 0 0;
  padding: 18px 0 0;
  border-top: 1px solid var(--scootive-gray-600);
}

/* .secondary-options is plain block flow, so avebartrim's card (rendered
   just before aveaddoncards' own "DODATKI DO TEGO PRODUKTU" label+list)
   had no breathing room below it at all - scoped to this wrapper only, so
   it doesn't add space above avebartrim itself when it's the first thing
   in .secondary-options (e.g. a product with no color/size variants). */
[data-abt-root] {
  display: block;
  margin-bottom: 24px;
}

.secondary-label {
  display: block;
  margin: 0 0 10px;
  padding: 0;
  font-size: 11px;
  line-height: 1;
  font-weight: 950;
  color: var(--scootive-ink);
  letter-spacing: 0;
  text-transform: uppercase;
}

.service-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}
/* [data-abt-root]'s own margin-bottom:24px (above) predates wetwobartrim's
   card living inside this SAME .service-list alongside wetwoaddoncards' -
   .service-list's own 8px gap now handles spacing between every card
   uniformly, so the old margin just doubles up here. Scoped to only reset
   it when nested in .service-list, leaving the original rule intact for
   any other context that might still rely on it. */
.service-list [data-abt-root] {
  margin-bottom: 0;
}

.service-card {
  position: relative;
  width: 100%;
  min-height: 76px;
  display: grid;
  grid-template-columns: 60px minmax(0, 1fr) 38px;
  grid-template-rows: 1fr;
  column-gap: 14px;
  align-items: center;
  padding: 8px 10px 8px 8px;
  margin: 0;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  border-radius: 0;
}

/* aveaddoncards' cards are fully clickable (data-aac-toggle on the card
   itself, per its front.js) but a plain div never gets a pointer cursor
   just from being clickable via JS - needs it explicitly. Scoped to
   [data-aac-card] rather than the shared .service-card base, since
   avebartrim reuses the same class for a card where only the inner "+"
   button opens anything, not the whole card. */
[data-aac-card] {
  cursor: pointer;
}

.service-visual {
  grid-column: 1;
  grid-row: 1;
  width: 60px;
  height: 60px;
  display: grid;
  place-items: center;
  align-self: center;
  justify-self: start;
  margin: 0;
  padding: 0;
  background: var(--scootive-gray-100);
  overflow: hidden;
}

.service-visual img {
  width: 88%;
  height: 88%;
  object-fit: contain;
  mix-blend-mode: multiply;
}

.service-visual svg {
  width: 29px;
  height: 29px;
  fill: none;
  stroke: var(--scootive-ink);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.service-copy {
  grid-column: 2;
  grid-row: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  margin: 0;
  padding: 0;
}

.service-badge {
  display: block;
  margin: 0 0 2px;
  padding: 0;
  font-size: 10px;
  line-height: 1.2;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--scootive-gray-600);
}

.service-copy strong {
  display: block;
  margin: 0;
  padding: 0;
  font-size: 12px;
  line-height: 1.3;
  font-weight: 950;
  color: var(--scootive-ink);
}

.service-copy .service-price {
  display: block;
  margin: 7px 0 0;
  padding: 0;
  font-size: 11px;
  line-height: 1;
  font-weight: 900;
  color: var(--scootive-ink);
}

/* Same slot as .service-price above, but for a plain description sentence
   (avebartrim's card) rather than a price - matches the site's own muted-
   caption treatment (.cut-intro, the same text shown again inside the
   modal) instead of borrowing the price's bold/dark styling. */
.service-copy .service-desc {
  display: block;
  margin: 6px 0 0;
  padding: 0;
  font-size: 11px;
  line-height: 1.4;
  font-weight: 400;
  color: var(--scootive-gray-700);
}
.service-card.selected .service-copy .service-desc {
  color: var(--scootive-gray-400);
}

.service-price s {
  margin-left: 6px;
  font-weight: 600;
  text-decoration: line-through;
  color: var(--scootive-gray-600);
}

.service-add {
  grid-column: 3;
  grid-row: 1;
  align-self: center;
  justify-self: end;
  width: 34px;
  height: 34px;
  min-width: 34px;
  min-height: 34px;
  margin: 0;
  padding: 0;
  display: grid;
  place-items: center;
  border: 1px solid var(--scootive-ink);
  background: #fff;
  color: var(--scootive-ink);
  border-radius: 0;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}

.service-add:hover {
  background: var(--scootive-ink);
  color: #fff;
}

/* Selected state inverts the whole card (not just the "+"), matching what
   was actually asked for here - the prototype's own .service-card.selected
   only darkens the border, but that read as too subtle to notice at a
   glance, so this goes further: dark card, white text, and the "+"/check
   button flips to a white square so it stays visible against it. */
.service-card.selected {
  background: var(--scootive-ink);
  border-color: var(--scootive-ink);
}
/* .service-visual's own image uses mix-blend-mode:multiply (a standard
   product-shot-on-white trick), which only works over a light backdrop -
   over the dark selected-card background it washed the image out, so the
   thumbnail square stays on its normal light background regardless of
   selection state. */
.service-card.selected .service-badge {
  color: var(--scootive-gray-400);
}
.service-card.selected .service-copy strong,
.service-card.selected .service-copy .service-price {
  color: #fff;
}
.service-card.selected .service-price s {
  color: var(--scootive-gray-400);
}
.service-card.selected .service-add {
  background: #fff;
  border-color: #fff;
  color: var(--scootive-ink);
}

/* Checkout's "Create an account" optional step (customer-form.tpl) - a
   native <details>/<summary> disclosure, styled to match the order
   summary's own .csp-toggle "POKAŻ SZCZEGÓŁY" row (thin border, chevron,
   no icon box) rather than the product-page's heavier .service-card -
   that combination (icon square + badge + "+" toggle) read as too heavy
   for a plain optional form-step prompt once seen live. No JS beyond the
   browser's own <details> behavior; [open] rotates the chevron. */
.account-toggle {
  border: 1px solid var(--scootive-gray-600);
  margin-bottom: 18px;
}
.account-toggle summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 16px;
}
.account-toggle summary::-webkit-details-marker,
.account-toggle summary::marker {
  display: none;
  content: "";
}
.account-toggle-badge {
  display: block;
  margin: 0 0 2px;
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
}
.account-toggle summary strong {
  display: block;
  font-size: 12px;
  font-weight: 900;
  color: var(--scootive-ink);
}
.account-toggle-sub {
  display: block;
  margin-top: 3px;
  font-size: 11px;
  color: var(--scootive-gray-700);
}
.account-toggle-chevron {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  color: var(--scootive-ink);
  transition: transform 0.15s;
}
.account-toggle-chevron svg {
  width: 11px;
  height: 11px;
}
.account-toggle[open] .account-toggle-chevron {
  transform: rotate(180deg);
}
.account-toggle-body {
  padding: 0 16px 18px;
}

/* Breathing room when this hook renders inside the checkout sidebar,
   directly below the cart-summary card (see checkout.tpl) - not needed on
   the product page, where it already sits in its own column slot. */
.cart-summary #block-reassurance {
  margin-top: 24px;
}

/* aveaddoncards' own combination-picker panel, shown once its card is selected */
.aac-panel {
  grid-column: 1 / -1;
  grid-row: 2;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--scootive-gray-600);
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}

.aac-panel label {
  display: block;
  margin: 0 0 6px;
  padding: 0;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--scootive-gray-600);
}

/*
 * avebartrim (Przycięcie kierownicy) - configurator modal, modules/
 * avebartrim/views/templates/hook/trim_card.tpl. This module renders
 * straight from modules/avebartrim/ (no themes/ever/modules/ override), so
 * it was never covered by the theme's own themes/ever/** Tailwind-CLI scan.
 * Its modal was hand-written as raw Tailwind utilities incl. arbitrary
 * values (bg-slate-900/30, backdrop-blur-[2px], rounded-[1.75rem],
 * shadow-[0_20px_60px_rgba(...)], bg-brand-500) that only ever worked by
 * accident of the old Tailwind CDN script, removed earlier today. Confirmed
 * dead live via getComputedStyle: backdropFilter:none, backdrop background
 * transparent, boxShadow:none, plus the confirm button rendering the
 * Tailwind demo green (#20c863, bg-brand-500) instead of the real design.
 *
 * The real design exists in the static prototype: src/pages/product.html's
 * own #cutModal (identical Polish copy - "Uwaga! Przycięcie kierownicy
 * skutkuje..." etc., word for word) plus the shared canonical modal
 * (src/assets/css/modal.css: .modal/.modalbox/.modalhead/.close, reused by
 * every modal on that page - size guide, addons, this one) and its own
 * "handlebar cut configurator" rules (src/assets/css/product.css:
 * .cut-intro/.cut-warning/.cut-field/.cut-slider/.cut-summary/.cut-consent/
 * .cut-actions). Ported 1:1 below, incl. the flat, sharp-corner, no-shadow
 * look - product.css even force-zeroes .modalbox's radius via its shared
 * `border-radius:0!important` list, so this was never meant to have a
 * rounded/shadowed panel; nothing invented here.
 *
 * Renamed the prototype's generic .modal/.modalbox/.modalhead/.close to
 * abt-modal/abt-modalbox/abt-modalhead/abt-close: this theme's own bare
 * `.modal` already means something else (the Bootstrap-shim used by
 * blockwishlist's login/create-list popups, ~line 1429) - same per-module
 * prefixing already used for every other modal-like component here
 * (.wwc-modal, .lightbox-*, .cart-drawer/.cart-overlay). The prototype's
 * own cut-* class names had no collisions (grepped first) so those were
 * kept verbatim. The compression field is a real <select> here (not the
 * prototype's SCS/HIC button pair) - that's existing, working front.js
 * logic this pass does not touch - so it's restyled with the theme's own
 * already-real .variant-select (aveaddoncards' combination dropdown)
 * instead of inventing a one-off select skin.
 *
 * front.js only toggles the `hidden` attribute + a literal "hidden" class
 * + body.abt-modal-open (that body class's own real CSS already lives in
 * this module's front.css, untouched) - not changed here, still targeted
 * as-is below. A separate .abt-modal-backdrop element (not the modalbox,
 * not the outer container) carries data-abt-close for click-outside-to-
 * close, same as before this pass - front.js binds a click listener
 * directly to every [data-abt-close] element, so putting that attribute on
 * the outer container itself would fire on every click bubbling up from
 * inside the box (slider drags, select, checkbox) and close it instantly.
 */
.abt-modal {
  position: fixed;
  inset: 0;
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow-y: auto;
}
.abt-modal.hidden,
.abt-modal[hidden] {
  display: none;
}

.abt-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 10, 10, 0.5);
}

.abt-modalbox {
  position: relative;
  width: min(760px, calc(100% - 32px));
  max-height: 85vh;
  overflow: auto;
  background: #fff;
  padding: 32px;
  margin: 24px 0;
}

.abt-modalhead {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin-bottom: 24px;
}
.abt-modalhead h3 {
  font-size: 30px;
  margin: 0;
}

.abt-close {
  border: 0;
  background: transparent;
  font-size: 24px;
  line-height: 1;
  padding: 4px;
  cursor: pointer;
  color: var(--scootive-ink);
  flex-shrink: 0;
}

.cut-intro {
  font-size: 13px;
  color: var(--scootive-gray-700);
  line-height: 1.6;
  margin: 0 0 20px;
}

.cut-warning {
  background: var(--scootive-gray-100);
  border: 1px solid var(--scootive-line);
  padding: 16px 18px;
  margin-bottom: 22px;
}
.cut-warning b {
  display: block;
  font-size: 12px;
  margin-bottom: 6px;
  color: var(--scootive-ink);
}
.cut-warning p {
  font-size: 11px;
  color: var(--scootive-gray-600);
  line-height: 1.5;
  margin: 0;
}

.cut-field {
  margin: 22px 0;
}
.cut-field-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 10px;
}
.cut-field-row label {
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
}
.cut-field-row b {
  font-size: 14px;
  color: var(--scootive-ink);
  white-space: nowrap;
}

/* Ported 1:1 from the prototype's own .cut-slider (src/assets/css/
   product.css): plain `background` set directly on the input by front.js's
   fillRange() (a linear-gradient string, recomputed on every input event -
   see the prototype's fillCutSlider()), no direction:rtl, no CSS custom
   property, no explicit ::-webkit-slider-runnable-track rule - the
   prototype doesn't use any of those and this now matches it exactly. */
.abt-range {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 4px;
  cursor: pointer;
  background: var(--scootive-gray-600);
}
.abt-range:focus {
  outline: 0;
}
.abt-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--scootive-ink);
  cursor: pointer;
}
.abt-range:focus::-webkit-slider-thumb {
  box-shadow: 0 0 0 3px #fff, 0 0 0 5px var(--scootive-ink);
}
.abt-range::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--scootive-ink);
  cursor: pointer;
}
.abt-range:focus::-moz-range-thumb {
  box-shadow: 0 0 0 3px #fff, 0 0 0 5px var(--scootive-ink);
}
.abt-range::-moz-range-track {
  height: 4px;
  background: transparent;
}
.abt-range::-moz-range-progress {
  height: 4px;
  background: var(--scootive-green2);
}

.cut-summary {
  border-top: 1px solid var(--scootive-line);
  margin-top: 26px;
  padding-top: 18px;
}
.cut-summary-head {
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
  margin-bottom: 12px;
}
.cut-summary-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 12px;
  color: var(--scootive-gray-700);
  padding: 5px 0;
}
.cut-summary-total {
  border-top: 1px solid var(--scootive-line);
  margin-top: 6px;
  padding-top: 10px;
  font-size: 15px;
  font-weight: 900;
  color: var(--scootive-ink);
}

.cut-consent {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 22px 0;
  font-size: 11px;
  color: var(--scootive-gray-700);
  line-height: 1.5;
  cursor: pointer;
}
.cut-consent input {
  margin-top: 2px;
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}

.cut-actions {
  display: flex;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 10px;
}
.cut-cancel {
  border: 1px solid var(--scootive-ink);
  background: transparent;
  height: 46px;
  padding: 0 20px;
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  cursor: pointer;
}
.cut-cancel:hover {
  background: var(--scootive-gray-100);
}

/* Only shown once a trim is already in the cart (server-rendered hidden
   otherwise, JS toggles it live) - margin-right:auto keeps it pinned to the
   opposite side from Anuluj/Przycinam inside the same flex row, reading as
   a distinct, lower-emphasis action rather than grouped with them. */
.cut-remove {
  margin-right: auto;
  border: 1px solid var(--scootive-gray-600);
  background: transparent;
  color: var(--scootive-gray-700);
  height: 46px;
  padding: 0 20px;
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  cursor: pointer;
}
.cut-remove:hover {
  border-color: var(--scootive-ink);
  color: var(--scootive-ink);
}
.cut-remove[hidden] {
  display: none;
}

/* Buy bar: qty stepper + add to cart + wishlist heart */
.buybar {
  display: grid;
  grid-template-columns: 118px minmax(0, 1fr) 52px;
  gap: 8px;
  margin-top: 24px;
  padding: 0 !important;
}

.buybar .qty {
  display: grid;
  grid-template-columns: 36px 1fr 36px;
  border: 1px solid var(--scootive-gray-600);
  height: 52px;
}

.buybar .qty button {
  border: 0;
  background: transparent;
  color: var(--scootive-ink);
  cursor: pointer;
  font-size: 16px;
}

.buybar .qty input {
  border: 0;
  background: transparent;
  text-align: center;
  width: 100%;
  font-size: 13px;
  color: var(--scootive-ink);
  -moz-appearance: textfield;
}

.buybar .qty input::-webkit-outer-spin-button,
.buybar .qty input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.buybar .addcart {
  border: 0;
  background: var(--scootive-ink);
  color: #fff;
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: .02em;
  cursor: pointer;
}

.buybar .addcart:hover {
  background: #222;
}

.buybar .heartbtn.wish {
  width: 52px;
  height: 52px;
  border: 1px solid var(--scootive-gray-600);
  background: transparent;
  display: grid;
  place-items: center;
  padding: 0;
  margin: 0;
  position: relative;
  /* Same JS-mount-reliability fallback as the plain .wish rule above -
     this selector is more specific (.buybar .heartbtn.wish beats a bare
     .wish), so it was winning the cascade and resetting straight back to
     "background: transparent" (the shorthand also clears background-image),
     silently cancelling that fallback specifically in the buybar - exactly
     where the customer's own screenshot showed a completely empty box. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0a0a' stroke-width='1.6'%3E%3Cpath d='M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.6l-1-1a5.5 5.5 0 0 0-7.8 7.8l1 1L12 21l7.8-7.6 1-1a5.5 5.5 0 0 0 0-7.8Z'/%3E%3C/svg%3E");
  background-size: 20px 20px;
  background-repeat: no-repeat;
  background-position: center;
}

.buybar .heartbtn.wish .wishlist-button-add {
  position: absolute !important;
  inset: 0 !important;
  width: 100% !important;
  height: 100% !important;
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  display: grid !important;
  place-items: center;
  padding: 0 !important;
  margin: 0 !important;
  cursor: pointer;
}

.buybar .heartbtn.wish .material-icons {
  font-size: 0;
  width: 20px;
  height: 20px;
  display: inline-block;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0a0a' stroke-width='1.6'%3E%3Cpath d='M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.6l-1-1a5.5 5.5 0 0 0-7.8 7.8l1 1L12 21l7.8-7.6 1-1a5.5 5.5 0 0 0 0-7.8Z'/%3E%3C/svg%3E");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

.product-additional-info-wrap {
  margin-top: 24px;
  padding-top: 18px;
  border-top: 1px solid var(--scootive-line);
  font-size: 11px;
  color: var(--scootive-gray-700);
}

@media (max-width: 1100px) {
  .pdp {
    grid-template-columns: 1fr;
    gap: 30px;
    padding: 0 0 60px;
  }

  .buy h1.display {
    font-size: 32px;
  }
}

/*
 * .container-wrap is a generic Tailwind-scaffold class reused across dozens
 * of templates (footer, checkout, customer pages, ship-timer bar, etc.),
 * each keeping its own Tailwind px-4/sm:px-6/lg:px-8-style padding — this
 * rule only adds the site-wide 1760px cap on top of whatever padding each
 * of those already has, and must stay this simple/safe for all of them.
 */
.container-wrap {
  max-width: var(--scootive-max);
  margin-left: auto;
  margin-right: auto;
}

/*
 * page.tpl's own outer <section> (shared by every non-homepage page:
 * category, product, cart, account, etc.) needs its own dedicated class,
 * NOT .container-wrap above — it must match .wrap's exact formula (width:
 * min(--scootive-max, 100% - 64px)), since .wrap has no inner padding and
 * already nets out to a 32px gutter per side via auto-margin centering. An
 * earlier version of this rule reused .container-wrap with just max-width
 * and left page.tpl's original Tailwind px-4/sm:px-6/lg:px-8 classes in
 * place, which padded the CONTENT inward on top of that max-width instead
 * of narrowing the box itself — at desktop (lg:px-8, 32px/side) that shrank
 * the visible content area to 1696px, narrower than .wrap's true 1760px,
 * and offset breadcrumbs/content ~32px further in than the header's logo.
 * Fixed with its own .page-wrap class using the same width/margin formula
 * as .wrap, with the Tailwind padding classes removed from page.tpl itself.
 */
.page-wrap {
  width: min(var(--scootive-max), calc(100% - 64px));
  margin-left: auto;
  margin-right: auto;
  /* Prototype gives every content page its own bottom breathing room via a
     page-specific wrapper class (.catalog{padding:0 0 90px}, .contact-page
     {padding:54px 0 100px}, .brands-directory{padding:40px 0 90px}, etc.) -
     this shared wrapper has no top/bottom padding of its own by design (see
     the block comment above, and the breadcrumb-position fix elsewhere this
     project), so every page except cart/checkout (which already carry their
     own real 100px bottom padding) rendered completely flush against the
     footer/newsletter section below with zero gap. Added one common value
     here instead of duplicating a page-specific class on every page. */
  padding-bottom: 90px;
}

@media (max-width: 1100px) {
  .page-wrap {
    width: calc(100% - 28px);
  }
}

/* Product info accordion (Description / Product Details) — ported from the
   prototype's .product-info/.info-item/.info-trigger/.info-content pattern
   + accordion.js's open/close toggle (mirrored in initProductInfoAccordion()
   in theme.js). The prototype's own umbrella heading ("INFORMACJE O
   PRODUKCIE") has no real translation anywhere and was dropped — each
   section's own real, verified label ("Opis" / "Szczegóły produktu") is
   still the visible accordion trigger text either way. */
.product-info {
  margin-top: 48px;
  margin-left: 98px;
}

.info-item {
  border-top: 1px solid var(--scootive-line);
}

.info-item:last-child {
  border-bottom: 1px solid var(--scootive-line);
}

.info-trigger {
  width: 100%;
  min-height: 58px;
  padding: 0;
  border: 0;
  background: transparent;
  display: flex;
  justify-content: space-between;
  align-items: center;
  text-align: left;
  cursor: pointer;
  font-size: 12px;
  font-weight: 900;
  color: var(--scootive-ink);
  text-transform: uppercase;
  letter-spacing: .02em;
}

.info-plus {
  width: 24px;
  text-align: center;
  font-size: 20px;
  font-weight: 400;
  color: var(--scootive-ink);
  transition: transform .15s;
}

.info-content {
  display: none;
  padding: 0 0 34px;
}

.info-item.open .info-content {
  display: block;
}

.info-item.open .info-plus {
  transform: rotate(45deg);
}

.info-description {
  max-width: 760px;
  font-size: 14px;
  line-height: 1.8;
  color: #3e3e39;
}

.info-description p {
  margin: 0 0 18px;
}

.info-description > p:first-child {
  font-size: 16px;
  line-height: 1.7;
  color: var(--scootive-ink);
  font-weight: 700;
}

.info-description > p:last-child {
  margin-bottom: 0;
}

.info-description ul,
.info-description ol {
  margin: 0 0 18px;
  padding-left: 22px;
}

.info-description ul {
  list-style: disc;
}

.info-description ol {
  list-style: decimal;
}

.info-description li {
  margin: 0 0 8px;
}

.info-description li p {
  margin: 0;
}

.info-specgrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 58px;
}

.specrow {
  display: grid;
  grid-template-columns: 1fr 1fr;
  padding: 14px 0;
  border-bottom: 1px solid var(--scootive-line);
  font-size: 11px;
  color: var(--scootive-ink);
}

.specrow span:first-child {
  color: var(--scootive-gray-700);
}

.specrow-link {
  color: inherit;
  text-decoration: none;
  font-weight: inherit;
}

.specrow-link:hover {
  text-decoration: underline;
}

@media (max-width: 1100px) {
  .product-info {
    margin-left: 0;
    margin-top: 42px;
  }

  .info-specgrid {
    grid-template-columns: 1fr;
  }
}

/* Related products ("Zobacz również") — same .section/.section-head/.products
   pattern as homepage sections, but the prototype gives this specific
   section a tighter/asymmetric padding than the default .section. */
.reco {
  padding: 54px 0 78px;
}

/* .reco's own .wrap (ported from the prototype's flat <main> layout, where
   .reco has no width-constrained ancestor) now sits inside page.tpl's
   .page-wrap, which already applies the full .wrap width formula to this
   section's containing block at every breakpoint. Re-applying that formula
   a second time here subtracts an extra gutter, making this section ~64px
   narrower than the header/breadcrumb .wrap. Just fill the already-correct
   .page-wrap box. */
.reco .wrap {
  width: 100%;
  margin: 0;
}

/* wetwocomments ("Opinie" reviews block) - complete redesign. This is an
   in-house module (own templates + front.js, safe to edit directly) that
   originally shipped 100% raw Tailwind markup; that markup has now been
   replaced entirely with plain wwc-* classes (see product-comments-section.tpl,
   product-list-reviews.tpl, front.js) so this is real, owned CSS rather than
   a sweep fighting Tailwind utilities. Matches this theme's established
   conventions: Arial Black uppercase headings, hairline dividers (.info-item/
   .specrow), sharp corners, no shadows, ink/gray palette, .btn button shape. */
/* .wwc-section now lives inside the "Reviews" accordion's own .info-content
   (product.tpl), which already provides the heading (the accordion trigger)
   and bottom spacing - no extra margin/heading needed here. */

.wwc-alert {
  border: 1px solid var(--scootive-line);
  padding: 12px 16px;
  margin-bottom: 20px;
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: .02em;
}

.wwc-alert-success {
  border-color: var(--scootive-green);
}

.wwc-alert-error {
  border-color: #c33333;
  color: #c33333;
}

.wwc-layout {
  display: grid;
  gap: 32px;
  grid-template-columns: 280px minmax(0, 1fr);
}

@media (max-width: 1100px) {
  .wwc-layout {
    grid-template-columns: 1fr;
  }
}

.wwc-summary-top {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.wwc-avg {
  font-family: "Arial Black", Arial, sans-serif;
  font-size: 34px;
  font-weight: 950;
  line-height: 1;
  color: var(--scootive-ink);
}

.wwc-avg-max {
  font-size: 11px;
  font-weight: 700;
  color: var(--scootive-gray-600);
  text-transform: uppercase;
  letter-spacing: .04em;
}

.wwc-stars {
  color: var(--scootive-ink);
  letter-spacing: .08em;
}

.wwc-star-empty {
  color: var(--scootive-gray-400);
}

.wwc-stars-lg {
  font-size: 16px;
  margin-top: 6px;
}

.wwc-count {
  font-size: 11px;
  color: var(--scootive-gray-600);
  margin: 6px 0 0;
}

.wwc-btn {
  display: inline-flex;
  height: 44px;
  align-items: center;
  justify-content: center;
  padding: 0 20px;
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  border: 1px solid var(--scootive-ink);
  background: var(--scootive-ink);
  color: #fff;
  cursor: pointer;
}

.wwc-btn:hover {
  background: #1d1d1d;
  border-color: #1d1d1d;
}

.wwc-btn:disabled {
  opacity: .5;
  cursor: not-allowed;
}

.wwc-btn-block {
  width: 100%;
  margin-top: 16px;
}

.wwc-bars {
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.wwc-bar-row {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) 24px;
  align-items: center;
  gap: 10px;
  font-size: 11px;
  color: var(--scootive-gray-700);
}

.wwc-bar-track {
  height: 4px;
  background: var(--scootive-gray-100);
}

.wwc-bar-fill {
  display: block;
  height: 100%;
  background: var(--scootive-ink);
}

.wwc-criteria {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--scootive-line);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.wwc-criteria-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 11px;
}

.wwc-criteria-name {
  font-weight: 900;
  color: var(--scootive-ink);
}

.wwc-criteria-right {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.wwc-criteria-value {
  color: var(--scootive-gray-600);
}

.wwc-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
}

.wwc-filters-group {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.wwc-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 11px;
  font-weight: 900;
  color: var(--scootive-ink);
  text-transform: uppercase;
  letter-spacing: .02em;
}

.wwc-field-full {
  grid-column: 1 / -1;
}

/* Sortuj/Ocena/Język: ported from the prototype's category-page .sort-
   control exactly (label + native select + custom chevron combined in one
   bordered box, appearance:none hiding the native arrow) instead of a
   label-above-select stack, which read as oversized next to this page's
   compact controls no matter how much the select itself was shrunk. */
.wwc-sort-control {
  position: relative;
  height: 32px;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
}

.wwc-sort-label {
  height: 100%;
  display: flex;
  align-items: center;
  padding: 0 8px;
  border-right: 1px solid var(--scootive-line);
  font-size: 9px;
  font-weight: 900;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
  white-space: nowrap;
}

.wwc-sort-select {
  width: 100%;
  height: 30px !important;
  border: 0 !important;
  background: transparent !important;
  appearance: none;
  -webkit-appearance: none;
  padding: 0 22px 0 8px !important;
  font-family: inherit;
  font-size: 10px !important;
  font-weight: 900 !important;
  color: var(--scootive-ink);
  cursor: pointer;
}

.wwc-sort-select:focus {
  outline: 2px solid #111;
  outline-offset: 2px;
}

.wwc-sort-chevron {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-56%);
  font-size: 13px;
  pointer-events: none;
  color: var(--scootive-gray-600);
}

.wwc-input {
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  font-family: inherit;
  color: var(--scootive-ink);
  border-radius: 0;
  height: 40px;
  padding: 0 12px;
  font-size: 12px;
}

.wwc-textarea {
  height: auto;
  padding: 10px 12px;
  resize: vertical;
}

/* Found live, 2026-10-03: the review/report modal's own fields (.wwc-modal,
   not .modal) were never covered by the ".modal .form-control:focus" WCAG
   2.4.7 fix added 2026-10-02 - they got no visible focus outline at all. */
.wwc-input:focus,
.wwc-textarea:focus {
  outline: 2px solid var(--scootive-ink);
  outline-offset: 2px;
}

.wwc-check {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  font-weight: 700;
  color: var(--scootive-ink);
}

.wwc-check input {
  width: 16px;
  height: 16px;
  accent-color: var(--scootive-ink);
}

.wwc-empty {
  border: 1px dashed var(--scootive-line);
  padding: 32px 20px;
  text-align: center;
  font-size: 12px;
  color: var(--scootive-gray-600);
}

.wwc-list {
  display: flex;
  flex-direction: column;
}

.wwc-comment {
  border-top: 1px solid var(--scootive-line);
  padding: 20px 0;
}

.wwc-list .wwc-comment:last-child {
  border-bottom: 1px solid var(--scootive-line);
}

.wwc-comment-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.wwc-comment-author {
  font-size: 12px;
  font-weight: 950;
  color: var(--scootive-ink);
}

.wwc-comment-badges {
  margin-top: 6px;
}

.wwc-badge {
  display: inline-block;
  border: 1px solid var(--scootive-gray-600);
  padding: 3px 8px;
  font-size: 9px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--scootive-gray-700);
}

.wwc-comment-meta {
  flex-shrink: 0;
  text-align: right;
}

.wwc-comment-meta .wwc-stars {
  font-size: 14px;
}

.wwc-comment-date {
  margin-top: 4px;
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--scootive-gray-600);
}

.wwc-comment-title {
  margin: 12px 0 0;
  font-size: 14px;
  font-weight: 950;
  color: var(--scootive-ink);
}

.wwc-comment-body {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.7;
  color: var(--scootive-gray-700);
}

.wwc-comment-criteria {
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.wwc-comment-criteria-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 11px;
  color: var(--scootive-gray-700);
}

.wwc-comment-foot {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--scootive-line);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.wwc-votes {
  display: flex;
  gap: 8px;
}

.wwc-vote-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  font-size: 11px;
  font-weight: 700;
  color: var(--scootive-ink);
  cursor: pointer;
}

.wwc-vote-btn:hover {
  border-color: var(--scootive-ink);
}

.wwc-report-btn {
  border: 0;
  background: none;
  padding: 0;
  font-size: 11px;
  font-weight: 700;
  color: var(--scootive-gray-600);
  text-decoration: underline;
  cursor: pointer;
}

.wwc-report-btn:hover {
  color: #c33333;
}

.wwc-loadmore-wrap {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}

.wwc-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 20px;
}

.wwc-page-info {
  font-size: 11px;
  font-weight: 900;
  color: var(--scootive-ink);
}

.wwc-btn-outline {
  display: inline-flex;
  height: 44px;
  align-items: center;
  justify-content: center;
  padding: 0 20px;
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  color: var(--scootive-ink);
  cursor: pointer;
}

.wwc-btn-outline:hover {
  border-color: var(--scootive-ink);
}

.wwc-btn-outline:disabled {
  opacity: .5;
  cursor: not-allowed;
}

.wwc-btn-sm {
  height: 36px;
  padding: 0 14px;
}

.wwc-teaser {
  margin-top: 8px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  font-weight: 700;
  color: var(--scootive-ink);
  text-decoration: none;
}

.wwc-teaser:hover {
  text-decoration: underline;
}

.wwc-teaser-count {
  color: var(--scootive-gray-600);
}

/* Modals */
html.wwc-modal-open {
  overflow: hidden;
}

.wwc-modal {
  position: fixed;
  inset: 0;
  z-index: 9999;
}

.wwc-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(10, 10, 10, .5);
}

.wwc-modal-center {
  position: relative;
  min-height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.wwc-modal-panel {
  width: 100%;
  max-width: 640px;
  background: #fff;
  border: 1px solid var(--scootive-line);
  max-height: calc(100vh - 40px);
  overflow-y: auto;
}

.wwc-modal-panel-sm {
  max-width: 480px;
}

.wwc-modal-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  border-bottom: 1px solid var(--scootive-line);
  padding: 20px 24px;
}

.wwc-modal-eyebrow {
  font-size: 9px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--scootive-gray-600);
  margin: 0;
}

.wwc-modal-title {
  margin: 6px 0 0;
  font-size: 16px;
  font-weight: 950;
  color: var(--scootive-ink);
}

.wwc-modal-close {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  font-size: 16px;
  line-height: 1;
  color: var(--scootive-ink);
  cursor: pointer;
}

.wwc-modal-close:hover {
  border-color: var(--scootive-ink);
}

.wwc-modal-body {
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.wwc-criteria-input {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  border: 1px solid var(--scootive-line);
}

.wwc-star-input {
  display: flex;
  align-items: center;
  gap: 4px;
}

.wwc-star-btn {
  border: 0;
  background: none;
  padding: 0;
  font-size: 20px;
  line-height: 1;
  color: var(--scootive-gray-600);
  cursor: pointer;
}

.wwc-star-btn.wwc-star-btn-active {
  color: var(--scootive-ink);
}

.wwc-form-grid {
  display: grid;
  gap: 14px;
}

@media (min-width: 640px) {
  .wwc-form-grid {
    grid-template-columns: 1fr 1fr;
  }
}

.wwc-form-message {
  font-size: 11px;
  font-weight: 700;
}

.wwc-form-message-error {
  color: #c33333;
}

.wwc-form-message-success {
  color: var(--scootive-green);
}

.wwc-modal-foot {
  display: flex;
  flex-direction: column;
  gap: 16px;
  border-top: 1px solid var(--scootive-line);
  padding: 20px 24px;
}

@media (min-width: 640px) {
  .wwc-modal-foot {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

.wwc-modal-foot-end {
  justify-content: flex-end;
}

.wwc-modal-note {
  font-size: 11px;
  color: var(--scootive-gray-600);
  margin: 0;
}

.wwc-modal-actions {
  display: flex;
  gap: 12px;
}

/* PDP section wrappers (gallery, and the buybox/description/specs column)
   are each wrapped in a leftover Tailwind "card" recipe (rounded-[2rem],
   border-slate-100, bg-white, shadow-card) from the pre-cutover design -
   present at every viewport (not just mobile), just easy to miss on desktop
   since white-on-#f5f5f1 is subtle. Flatten to match the rest of the page's
   flat, borderless sections. Excludes .zoom - the gallery's small zoom
   button also happens to carry rounded-[...]+shadow-card, but it needs to
   keep its own deliberately-sized 1px border (see .gallery .stage .zoom),
   not have it zeroed by this broader section-wrapper sweep. */
.js-product [class*="rounded-["][class*="shadow-card"]:not(.zoom) {
  border-radius: 0 !important;
  border-width: 0 !important;
  box-shadow: none !important;
  border-color: var(--scootive-line) !important;
  background: transparent !important;
}

/* ===== Footer — real cutover, matches src/partials/footer.html + footer.css exactly ===== */
.footer {
  background: #fff;
  padding: 60px 0 26px;
}
.footer-grid {
  /* 4 columns -> 3: the old logo column and the old "Kontakt" column were
     merged into one (see footer.tpl's own comment for why). */
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 40px;
}
.footer .logo {
  margin-bottom: 20px;
}
.footer-contact-link {
  display: inline-block;
  margin-top: 14px;
  font-size: 11px;
  font-weight: 900;
  text-decoration: underline;
  color: var(--scootive-ink);
}
/* Was ".footer h4" - the footer link-block title is now a real <h2> (see
   themes/ever/modules/ps_linklist/views/templates/hook/linkblock.tpl),
   since <footer> is its own landmark and h4 skipped straight past h2/h3
   on most page types (confirmed: home h1->h4, category/cart h1->h2->h4,
   found via a site-wide accessibility audit, 2026-10-02).
   Was ".footer h2" (any descendant) until found live, 2026-10-03: the
   Assistant widget's overlay (#asstOverlay, its own h2#asstTitle) is ALSO
   mounted inside .footer-grid (displayFooter renders both linklist AND any
   other module's hidden modal markup on the same hook), so the bare
   descendant selector matched it too and only looked fine by accident of
   stylesheet load order (assistant.css loads after this file and wins the
   tie on equal specificity). Scoped to the exact linkblock.tpl shape - a
   direct-child h2 of a direct-child div of .footer-grid - which the
   Assistant's much deeper-nested h2 structurally can't match. */
.footer-grid > div > h2 {
  font-size: 10px;
}
.footer-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.footer-list li {
  font-size: 12px;
  color: #666;
  margin: 8px 0;
}
.footer-list a {
  display: block;
  color: inherit;
  font-size: inherit;
}
.footer-list .nested {
  margin: 6px 0 0 14px;
}

/* Sitemap page (cms/sitemap.tpl) - no prototype mockup exists for this
   page, so it reuses .cat-head (contact.tpl's own plain-page header) for
   the H1 and the footer's own .footer-list link style for each group,
   just laid out as its own responsive grid instead of the footer's fixed
   3-column one. */
.sitemap-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 40px;
  padding: 10px 0 90px;
}
.sitemap-group h2 {
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0 0 16px;
}
@media (max-width: 1100px) {
  .sitemap-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 32px 20px;
  }
}
@media (max-width: 700px) {
  .sitemap-grid {
    grid-template-columns: 1fr;
  }
}

.copyright {
  border-top: 1px solid var(--scootive-line);
  margin-top: 38px;
  padding-top: 18px;
  font-size: 10px;
  color: var(--scootive-gray-700);
  display: flex;
  justify-content: space-between;
}

/* Opening hours: a compact grouped-range line ("mode=footer", e.g.
   "Poniedziałek–Niedziela 11:00–19:00") as the last item of the Kontakt
   list — inherits .footer-list li's font-size/color, see front-hours.css
   for the dot + inline-flex layout. */

@media (max-width: 1100px) {
  .footer {
    padding: 44px 0 26px;
  }
  .footer-grid {
    grid-template-columns: 1fr 1fr;
    gap: 32px 20px;
  }
  .footer-grid > div:first-child {
    grid-column: 1 / -1;
  }
  .copyright {
    flex-direction: column;
    gap: 6px;
    align-items: flex-start;
  }
}

/* ============ Cart page (checkout/cart.tpl, checkout/cart-empty.tpl,
   checkout/_partials/cart-voucher.tpl) — full port of the prototype's
   cart.html/cart.css, plus the shared classes it pulls in from
   cart-drawer.css (.remove/.summary-row/.shipping-progress/.progress -
   this cart page is the first one in the cutover to reuse those, so
   they're defined here for the first time, not duplicated from an
   existing page) and buttons.css (.btn-black/.qty). The prototype's own
   PayU-installments trigger/modal and the header's mini-cart drawer are
   deliberately NOT part of this pass - see project memory. */
.btn-black {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 52px;
  border: 1px solid var(--scootive-ink);
  background: var(--scootive-ink);
  color: #fff;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  padding: 0 22px;
  text-decoration: none;
  cursor: pointer;
}
.btn-black:hover {
  background: #1d1d1d;
  border-color: #1d1d1d;
}

.cart-page {
  padding: 54px 0 100px;
}
.cart-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-end;
  gap: 16px 20px;
  margin-bottom: 34px;
}
.cart-head h1 {
  font-size: 62px;
  margin: 8px 0 0;
}
.cart-head .countline {
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
}

.cart-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) 440px;
  gap: 64px;
  align-items: start;
}

.cart-list {
  border-top: 1px solid var(--scootive-line);
}
.cart-row {
  display: grid;
  grid-template-columns: 130px minmax(0, 1fr) 130px 120px 34px;
  gap: 20px;
  align-items: center;
  padding: 24px 0;
  border-bottom: 1px solid var(--scootive-line);
}
.cart-img {
  width: 130px;
  height: 130px;
  /* Literal #ecece7, not var(--scootive-gray-100) (#f3f3ef) - matches the
     prototype's own cart.css value exactly, and the product card's
     .prodimg background (also a literal #ecece7, see part 16) - these
     are two different steps on the gray scale, easy to conflate. */
  background: #ecece7;
  display: grid;
  place-items: center;
}
.cart-img img {
  width: 88%;
  height: 88%;
  object-fit: contain;
  mix-blend-mode: multiply;
}
.cart-info {
  min-width: 0;
}
.cart-info .brand {
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
  font-weight: 900;
}
.cart-info h3 {
  font-size: 18px;
  font-weight: 900;
  margin: 7px 0 7px;
  overflow-wrap: break-word;
  word-break: break-word;
}
.cart-info h3 a {
  color: inherit;
  text-decoration: none;
}
.cart-info h3 a:hover {
  text-decoration: underline;
}
.cart-info .variant {
  font-size: 11px;
  color: var(--scootive-gray-700);
}
.cart-line-customization {
  font-size: 11px;
  color: var(--scootive-gray-700);
  font-style: italic;
  margin-top: 4px;
}

.cart-row .qty,
.drawer-item .qty {
  height: 42px;
  border: 1px solid var(--scootive-gray-600);
  display: grid;
  grid-template-columns: 36px 1fr 36px;
  background: #fff;
}
.cart-row .qty a,
.drawer-item .qty a {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--scootive-ink);
  text-decoration: none;
  font-size: 16px;
  cursor: pointer;
}
.cart-row .qty span,
.drawer-item .qty span {
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 900;
  color: var(--scootive-ink);
}

.cart-price {
  text-align: right;
}
.cart-price b {
  display: block;
  font-size: 15px;
  font-weight: 950;
  color: var(--scootive-ink);
}
.cart-price .unit {
  display: block;
  margin-top: 4px;
  font-size: 10px;
  color: var(--scootive-gray-700);
}

.remove {
  border: 0;
  background: transparent;
  font-size: 18px;
  color: var(--scootive-gray-700);
  cursor: pointer;
  text-decoration: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
.remove:hover {
  color: var(--scootive-ink);
}

.shipping-progress {
  margin: 28px 0 0;
}
.progress-copy {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  /* Whole line (label AND value) is the same gray-700 in the prototype -
     no separate darker treatment for the <b> value, unlike similar-looking
     .result-count on the category toolbar (a different component). */
  color: var(--scootive-gray-700);
  margin-bottom: 7px;
}
.progress {
  height: 5px;
  /* Literal #e5e5df, matching the prototype's own .progress track color -
     yet another distinct step on the gray scale from #ecece7/#f3f3ef. */
  background: #e5e5df;
  overflow: hidden;
}
.progress span {
  display: block;
  height: 100%;
  background: var(--scootive-green);
}

.continue {
  display: inline-block;
  margin-top: 24px;
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--scootive-ink);
  border-bottom: 1px solid var(--scootive-ink);
  text-decoration: none;
}

.cart-summary {
  position: sticky;
  top: 98px;
  background: #fff;
  border: 1px solid var(--scootive-line);
  padding: 28px;
}
.cart-summary h2 {
  font-size: 28px;
  margin: 0 0 24px;
}
.summary-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  font-size: 12px;
  margin: 8px 0;
}
.summary-row b {
  font-weight: 900;
}
.summary-row.total {
  border-top: 1px solid var(--scootive-line);
  padding-top: 18px;
  margin-top: 18px;
  font-size: 18px;
}
.summary-row.total span {
  font-weight: 950;
}

.promo {
  border-top: 1px solid var(--scootive-line);
  padding-top: 18px;
  margin-top: 18px;
}
.promo-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 7px;
}
.promo-form input {
  height: 42px;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  padding: 0 12px;
  /* !important: same app.css 16px-on-focus override as .field input above
     and .sort-select (part 28) - found while checking this same class of
     bug spread further while building checkout. */
  font-size: 12px !important;
  text-transform: uppercase;
}
.promo-form button {
  height: 42px;
  border: 1px solid var(--scootive-ink);
  background: #fff;
  color: var(--scootive-ink);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  padding: 0 13px;
  cursor: pointer;
}
.promo-form button:hover {
  background: var(--scootive-ink);
  color: #fff;
}

/* Applied-voucher chip, the promo-code disclosure toggle, and the
   available-offers list have no direct prototype equivalent (its .promo
   mockup only ever shows the plain input form) - these follow the
   session's established "plain row/divider, not a bordered card"
   convention for anything without a prototype reference (see e.g. the
   product-page reassurance rows). */
.voucher-applied {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--scootive-line);
}
.voucher-applied .code {
  display: inline-block;
  background: var(--scootive-ink);
  color: #fff;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 5px 9px;
}
.voucher-applied .reduction {
  margin-left: 8px;
  font-size: 11px;
  font-weight: 900;
  color: var(--scootive-ink);
}
.voucher-applied .name {
  margin-top: 6px;
  font-size: 12px;
  font-weight: 700;
  color: var(--scootive-ink);
}
.voucher-applied .desc {
  margin-top: 2px;
  font-size: 11px;
  color: var(--scootive-gray-700);
}
.voucher-applied .remove-voucher {
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
  text-decoration: underline;
  cursor: pointer;
}
.voucher-applied .remove-voucher:hover {
  color: var(--scootive-ink);
}

.voucher-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 0;
}
.voucher-head b {
  font-size: 11px;
  font-weight: 900;
  color: var(--scootive-ink);
}
/* Direct-child combinator only - a qualifier span nested INSIDE the <b>
   (e.g. "(optional)" right after "Create an account") must stay inline on
   the same line as the bold text, not become its own block line like the
   subtitle span below it. A plain ".voucher-head span" caught both. */
.voucher-head > div > span {
  display: block;
  margin-top: 2px;
  font-size: 10px;
  color: var(--scootive-gray-700);
}
.voucher-toggle {
  width: 100%;
  cursor: pointer;
  list-style: none;
}
.voucher-toggle::-webkit-details-marker {
  display: none;
}
.voucher-toggle .chev {
  flex-shrink: 0;
  font-size: 13px;
  color: var(--scootive-gray-700);
  transition: transform 0.15s;
}
.voucher-details[open] .voucher-toggle .chev {
  transform: rotate(180deg);
}
.voucher-details-body {
  padding: 0 0 14px;
}

.voucher-offers-wrap {
  /* .voucher-head no longer carries its own border-top (removed - it was
     doubling up with .promo's own top divider whenever the promo-code
     toggle was the first thing inside .promo). This is the one place that
     genuinely still needs a divider of its own, since it sits AFTER the
     promo-code toggle/applied-voucher-list, not at the very top. */
  border-top: 1px solid var(--scootive-line);
}
.voucher-offers {
  padding-bottom: 4px;
}
.voucher-offer {
  padding: 10px 0;
  border-top: 1px solid var(--scootive-line);
}
.voucher-offer .code {
  display: inline-block;
  background: var(--scootive-ink);
  color: #fff;
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.04em;
  padding: 4px 8px;
  margin-right: 8px;
}
.voucher-offer .desc {
  margin-top: 4px;
  font-size: 11px;
  color: var(--scootive-gray-700);
}

.voucher-error {
  margin-top: 8px;
  font-size: 11px;
  color: #b3261e;
}

.checkout-btn {
  width: 100%;
  margin-top: 20px;
}

/* Empty cart (checkout/cart-empty.tpl) - port of the prototype's
   #cartEmpty/.empty-state block. */
.empty-state {
  text-align: center;
  padding: 90px 20px;
  max-width: 480px;
  margin: 0 auto;
}
.empty-state-icon {
  width: 72px;
  height: 72px;
  margin: 0 auto 24px;
  display: grid;
  place-items: center;
  background: var(--scootive-gray-100);
  border-radius: 999px;
}
.empty-state-icon svg {
  width: 30px;
  height: 30px;
  stroke: var(--scootive-gray-600);
  stroke-width: 1.5;
  fill: none;
}
.empty-state h2 {
  font-size: 28px;
  margin: 0 0 12px;
}
.empty-state p {
  font-size: 13px;
  color: var(--scootive-gray-700);
  line-height: 1.6;
  margin: 0 0 28px;
}
.empty-state .btn-black {
  display: inline-flex;
}

@media (max-width: 1100px) {
  .cart-head h1 {
    font-size: 44px;
  }
  .cart-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .cart-row {
    grid-template-columns: 90px minmax(0, 1fr) auto;
    gap: 12px;
  }
  .cart-img {
    width: 90px;
    height: 90px;
  }
  .cart-row .qty {
    grid-column: 2;
    width: 100%;
    max-width: 120px;
  }
  .cart-price {
    grid-column: 3;
    grid-row: 1 / span 2;
    align-self: center;
  }
  .remove {
    grid-column: 3;
    grid-row: 1;
    justify-self: end;
    align-self: start;
  }
  .cart-summary {
    position: static;
  }
}

/* ============ Checkout page (checkout/checkout.tpl + _partials/) ============
   Full port of the prototype's checkout.html/checkout.css/forms.css. Unlike
   cart, this is a REAL PrestaShop 9 multi-step server-rendered flow (not a
   pure client-side accordion simulation like the prototype) - each step's
   .-current/.-reachable/.-complete state and all step-switching/AJAX
   behavior is computed server-side and driven by core's own always-loaded
   themes/core.js bundle (registered by FrontController::initHeader() at
   priority 0 for every front page, independent of this theme's own stub
   front.js) - only markup/classes are restyled here, no new JS written.
   .field/.title-choice/.checkrow-consent (this section) are shared with
   _partials/form-fields.tpl, which is ALSO the field renderer for every
   customer-account form (login/register/address/profile) - restyling it
   here improves those pages too as a side effect, not a redo of them. */

.checkout-page {
  padding: 54px 0 100px;
}
.checkout-head {
  margin-bottom: 34px;
}
.checkout-head h1 {
  font-size: 62px;
  margin: 8px 0 0;
}
.checkout-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) 440px;
  gap: 64px;
  align-items: start;
}
.checkout-grid > div {
  min-width: 0;
}

/* Steps accordion - styled directly on PrestaShop's own real classes
   (.checkout-step/.-current/.-reachable/.-complete/.step-title/.step-edit/
   .content) rather than inventing new ones, since those exact classes are
   what core's JS (js-current-step, step-edit) and the step logic itself
   key off - renaming them would risk breaking real step-switching. */
.steps {
  border-top: 1px solid var(--scootive-line);
}
.checkout-step {
  border-bottom: 1px solid var(--scootive-line);
}
.checkout-step .step-title {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 26px 0;
  margin: 0;
}
.checkout-step.-reachable:not(.-current) .step-title {
  cursor: pointer;
}
.step-title-main {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 16px;
}
.step-num {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--scootive-gray-100);
  color: var(--scootive-ink);
  display: grid;
  place-items: center;
  font-size: 13px;
  font-weight: 900;
  flex-shrink: 0;
}
.checkout-step.-current .step-num,
.checkout-step.-complete .step-num {
  background: var(--scootive-ink);
  color: #fff;
}
.step-label {
  font-size: 20px;
  font-weight: 800;
  color: var(--scootive-gray-700);
}
.checkout-step.-current .step-label,
.checkout-step.-complete .step-label {
  color: var(--scootive-ink);
}
.step-edit {
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
  text-decoration: underline;
}
.step-edit:hover {
  color: var(--scootive-ink);
}
.checkout-step .content {
  display: none;
  padding: 0 0 34px 50px;
}
.checkout-step.-current .content {
  display: block;
}
.checkout-step.-unreachable .step-title {
  padding: 22px 0;
}
.checkout-step.-unreachable .step-num,
.checkout-step.-unreachable .step-label {
  background: var(--scootive-gray-100);
  color: var(--scootive-gray-700);
}

@media (max-width: 1100px) {
  .checkout-head h1 {
    font-size: 44px;
  }
  .checkout-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .checkout-step .content {
    padding-left: 0;
  }
}

/* Shared radio/payment-card list - used by both the delivery-method step
   and the payment-method step in the prototype, and here also reused for
   the saved-address selector (a real feature the prototype doesn't have,
   since its static mockup never shows a returning customer's saved
   addresses - extended from, not dropped in favor of, the option-card
   language). */
.option-list {
  display: grid;
  gap: 10px;
  margin-bottom: 22px;
}
.option-card {
  display: grid;
  grid-template-columns: 20px 1fr auto;
  gap: 14px;
  align-items: center;
  border: 1px solid var(--scootive-gray-600);
  padding: 16px 18px;
  background: #fff;
  cursor: pointer;
}
.option-card.selected {
  border-color: var(--scootive-ink);
}
.option-card input {
  width: 18px;
  height: 18px;
}
.option-card strong {
  display: block;
  font-size: 13px;
  font-weight: 900;
  color: var(--scootive-ink);
}
.option-card > label > div > div,
.option-card .option-copy {
  font-size: 11px;
  color: var(--scootive-gray-700);
  margin-top: 3px;
  white-space: nowrap;
}
.option-price {
  font-weight: 900;
  font-size: 13px;
  white-space: nowrap;
  color: var(--scootive-ink);
}
.option-logo {
  width: 60px;
  height: 60px;
  flex-shrink: 0;
  background: #fff;
  display: grid;
  place-items: center;
  padding: 6px;
}
.option-logo img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.address-option {
  border: 1px solid var(--scootive-gray-600);
  padding: 18px 20px;
  background: #fff;
}
.address-option.selected {
  border-color: var(--scootive-ink);
}
.address-option .alias {
  display: block;
  font-size: 13px;
  font-weight: 900;
  color: var(--scootive-ink);
}
.address-option .formatted {
  display: block;
  margin-top: 8px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--scootive-gray-700);
}
.address-option-actions {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--scootive-line);
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
.address-option-actions a {
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
  text-decoration: underline;
}
.address-option-actions a:hover {
  color: var(--scootive-ink);
}
.address-option-actions a.delete-address:hover {
  color: #b3261e;
}

/* Field renderer (_partials/form-fields.tpl) - shared with EVERY form on
   the site (checkout steps, customer account, login/register). */
.field {
  margin-bottom: 18px;
}
.field label {
  display: block;
  font-size: 10px;
  font-weight: 900;
  margin-bottom: 8px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--scootive-ink);
}
.field label .req {
  color: #c33;
}
.field input,
.field select,
.field textarea {
  width: 100%;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  padding: 0 14px;
  /* !important: same sitewide app.css `input,select,textarea{font-size:
     16px!important}` (iOS zoom-prevention) fight as .sort-select - see
     part 28. */
  font-size: 13px !important;
  font-family: inherit;
  color: var(--scootive-ink);
}
.field input,
.field select {
  height: 46px;
}
.field textarea {
  padding: 12px 14px;
  height: 140px;
  resize: vertical;
}
.field.has-error input,
.field.has-error select,
.field.has-error textarea {
  border-color: #b3261e;
}
.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.field-row-3 {
  grid-template-columns: 1fr 1fr 1fr;
}
.field-row-3 select {
  width: 100%;
}
.field-hint {
  font-size: 10px;
  color: var(--scootive-gray-700);
  margin-top: 6px;
}
/* Register form (checkout's own customer-form.tpl override) - pairs known
   field names (firstname/lastname) side by side on desktop, matching the
   prototype's .field-row, the same "half-width by name, let grid auto-flow
   seat them" technique the account area's own address-form.tpl already
   uses (untouched, not this cutover's work) for postcode/city. */
.field-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 16px;
}
.field-full {
  grid-column: 1 / -1;
}
@media (max-width: 1100px) {
  .field-grid {
    grid-template-columns: 1fr;
  }
}
.field-errors {
  margin-top: 6px;
  font-size: 11px;
  color: #b3261e;
}
.field-password {
  position: relative;
}
.field-password input {
  padding-right: 70px;
}
.field-password-toggle {
  position: absolute;
  right: 4px;
  top: 4px;
  bottom: 4px;
  border: 0;
  background: transparent;
  padding: 0 12px;
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
  cursor: pointer;
}
.field-password-toggle:hover {
  color: var(--scootive-ink);
}

.title-choice {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 22px;
}
.title-btn {
  height: 44px;
  padding: 0 20px;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  font-size: 11px;
  font-weight: 800;
  display: flex !important;
  align-items: center;
  gap: 9px;
  cursor: pointer;
}
.title-btn input {
  width: 14px;
  height: 14px;
}
.title-btn.selected {
  border-color: var(--scootive-ink);
}

/* This label sits inside the SAME .field wrapper form-fields.tpl gives
   every field type (not just text inputs) - .field label{font-size:10px;
   font-weight:900;color:var(--scootive-ink)} (form-fields.tpl's real
   <label>) has higher specificity (.field label = 0,1,1) than .checkrow-
   consent alone (0,1,0), so it silently won on font-size/weight/color here
   despite never being intended to touch checkboxes - real bug, affected
   EVERY consent checkbox (all rendered bold 10px black instead of the
   intended lighter 11px gray), not just the ones with a second line below.
   !important pins this one back regardless of the ancestor's specificity. */
.checkrow-consent {
  display: flex !important;
  gap: 10px;
  align-items: flex-start;
  font-size: 11px !important;
  font-weight: 700 !important;
  color: var(--scootive-gray-700) !important;
  line-height: 1.5;
  margin: 22px 0;
}
.checkrow-consent input {
  /* Vertically centers the box against the label's OWN first line (11px
     text at line-height:1.5 ≈ a 16.5px line box), not against the whole
     flex row - so it sits centered next to a short one-line label, centered
     next to a wrapped paragraph's first line, and next to the bold "main"
     line specifically when a second, smaller <em> line follows below it,
     matching every checkbox on this page uniformly (general rule on the
     shared input, not a per-checkbox override). */
  margin-top: 1px;
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}
.checkrow-consent .req {
  color: #c33;
}
/* Real links inside consent text (psgdpr's "Regulamin", the core-rendered
   terms-of-service link in conditions_to_approve) - bold+underline so they
   read as clickable, not indistinguishable from the surrounding plain
   text (the core-rendered one had no link styling at all by default). */
.checkrow-consent a {
  font-weight: 700;
  text-decoration: underline;
  color: inherit;
}
/* Secondary explanatory line (psgdpr's newsletter-unsubscribe note, the
   core customer_privacy disclaimer) - real <em> tags already in the
   source HTML, just never given a distinct lighter treatment from the
   main consent line above. */
.checkrow-consent em {
  display: block;
  margin-top: 4px;
  font-style: normal;
  font-size: 10px;
  font-weight: 400;
  color: var(--scootive-gray-700);
}

/* Guest/login mode toggle (personal-information.tpl's real
   .js-checkout-auth-tab buttons) and the register-form's optional
   password <details> (same collapsible pattern as the cart page's
   voucher-code toggle, see .voucher-toggle). */
.mode-toggle {
  display: flex;
  gap: 10px;
  margin-bottom: 26px;
}
/* core.js (themes/core.js, shared/unmodifiable, registered on every front
   page) runs its OWN tab-switching logic on these same buttons and adds ITS
   OWN assumed Tailwind utility classes alongside ours on every real click -
   border-slate-200/bg-white/text-slate-600 when inactive, border-brand-500/
   bg-brand-500/text-white when active (real classes, confirmed live via
   button.className - NOT a browser focus ring, which is what the green
   border was wrongly attributed to earlier). !important beats those
   regardless of load order.
   Styled off [aria-selected], NOT the .active class the template renders
   server-side once: core.js's click handler updates aria-selected (and its
   own Tailwind classes) on every switch but never touches a class literally
   named "active" - so keying off .active would freeze the visible
   selection at whatever the very first page load happened to render,
   showing the WRONG tab as "selected" after a real click (confirmed live:
   clicking "Zaloguj się" correctly flips aria-selected/the visible
   tab-pane, but .active stayed on the original button). */
.mode-btn {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  height: 46px;
  padding: 0 22px;
  border: 1px solid var(--scootive-ink) !important;
  background: #fff !important;
  color: var(--scootive-ink) !important;
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: pointer;
}
.mode-btn[aria-selected='true'] {
  background: var(--scootive-ink) !important;
  border-color: var(--scootive-ink) !important;
  color: #fff !important;
}
/* Explicit, branded focus ring - without this the browser/OS falls back to
   its own default focus indicator, which we don't otherwise control. */
.mode-btn:focus-visible {
  outline: 2px solid var(--scootive-ink);
  outline-offset: 2px;
}

@media (max-width: 1100px) {
  .field-row {
    grid-template-columns: 1fr;
  }
  .field-row-3 {
    grid-template-columns: 1fr;
  }
}

/* checkout/_partials/cart-summary*.tpl - the checkout sidebar's order
   summary, sharing .summary-row/.summary-row.total/.promo/.voucher-* with
   the cart page (see part 27/28) rather than redefining them. Adds a real
   feature the prototype doesn't have (collapsible per-product breakdown,
   .csp-*) - kept per the session's "don't cap real data to the mockup's
   placeholder scope" rule rather than dropped to match the simpler mockup. */
/* Explicit per-block dividers rather than a generic ">* + *" sibling rule -
   .cart-summary-top turned out to NOT always be empty after all (the real
   PayU installments module hooks displayCheckoutSummaryTop with its own
   mini-widget - a genuine, real feature, not something to hide), so it
   needs its own divider treatment below rather than being written off. */
.cart-summary-top:empty {
  display: none;
}
.cart-summary-top:not(:empty) {
  padding-bottom: 20px;
}
.cart-summary-top:not(:empty) + .cart-summary-products {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--scootive-line);
}
/* PayU's own module template ships a plain <hr class="payu-separator-reset">
   + empty <p></p> - the "-reset" in that class name is the module's own
   convention signalling themes are expected to hide it and provide their
   own spacing instead (which the rules above now do), rather than leave
   its unstyled native browser-default hr line sitting next to ours. */
.payu-separator-reset,
.cart-summary-top > p:empty {
  display: none;
}
/* Styled to match the prototype's .payu-trigger (solid black bar, green
   "RATY" tag, green amount, trailing arrow) even though the actual text
   content ("Rata już od: X zł") is generated by PayU's own external SDK,
   not our markup - a ::before/::after supply the tag/arrow decoration,
   and the widget's own inline styles ("color: rgb(29,175,236)", PayU's
   brand blue) are overridden with !important since inline beats any
   non-!important CSS regardless of specificity. */
.payu-installment-panel {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--scootive-ink);
  padding: 16px 18px;
  font-size: 11px;
  font-weight: 800;
  cursor: pointer;
}
.payu-installment-panel::before {
  content: "RATY";
  flex-shrink: 0;
  background: var(--scootive-green);
  color: var(--scootive-ink);
  font-size: 8px;
  font-weight: 950;
  letter-spacing: 0.08em;
  padding: 5px 8px;
}
.payu-installment-panel::after {
  content: "\2192";
  flex-shrink: 0;
  font-size: 14px;
  color: var(--scootive-green);
}
.payu-installment-panel a,
.payu-installment-panel [class*="payu-mini-installments-widget"] {
  color: #fff !important;
  font-weight: 800 !important;
  text-decoration: none !important;
  cursor: pointer !important;
}
.payu-installment-panel .payu-mini-installments-widget-amount {
  color: var(--scootive-green) !important;
  font-weight: 950 !important;
}
.cart-summary-subtotals-container,
.cart-summary-totals,
.checkout-summary-body .promo {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--scootive-line);
}
/* .summary-row.total (shared with the cart page, where it's a bare sibling
   row with no wrapping divider of its own) ALSO carries its own border-top
   - redundant here specifically when "Razem" is the only/first thing in
   .cart-summary-totals (the normal tax-inclusive-prices case), since the
   container above already drew the one divider needed. Cancelled only for
   :first-child so the tax-exclusive branch (where a plain subtotal row
   precedes "Razem" inside the SAME container) still gets its own
   separation from that row. */
.cart-summary-totals > .summary-row.total:first-child {
  border-top: 0;
  margin-top: 0;
  padding-top: 0;
}

.csp-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.csp-label {
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
  margin: 0;
}
.csp-value {
  margin: 4px 0 0;
  font-size: 12px;
  font-weight: 900;
  color: var(--scootive-ink);
}
.csp-toggle {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  padding: 8px 12px;
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--scootive-ink);
  cursor: pointer;
}
.csp-toggle:hover {
  border-color: var(--scootive-ink);
}
.csp-toggle svg {
  width: 12px;
  height: 12px;
  transition: transform 0.15s;
}
.csp-toggle[aria-expanded="true"] svg {
  transform: rotate(180deg);
}

.csp-list {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.csp-line {
  display: flex;
  align-items: center;
  gap: 12px;
}
.csp-line-img {
  width: 56px;
  height: 56px;
  flex-shrink: 0;
  background: #ecece7;
  display: grid;
  place-items: center;
}
.csp-line-img picture {
  display: block;
  width: 82%;
  height: 82%;
}
.csp-line-img img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
}
.csp-line-info {
  min-width: 0;
  flex: 1;
}
.csp-line-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.csp-line-name {
  margin: 0;
  font-size: 12px;
  font-weight: 900;
  color: var(--scootive-ink);
}
.csp-line-name a {
  color: inherit;
  text-decoration: none;
}
.csp-line-name a:hover {
  text-decoration: underline;
}
.csp-line-price {
  flex-shrink: 0;
  margin: 0;
  font-size: 12px;
  font-weight: 900;
  color: var(--scootive-ink);
  white-space: nowrap;
}
.csp-line-qty,
.csp-line-attrs {
  margin: 4px 0 0;
  font-size: 11px;
  color: var(--scootive-gray-700);
}
.csp-line-customization {
  margin: 4px 0 0;
  font-size: 11px;
  color: var(--scootive-gray-700);
  font-style: italic;
}
.csp-line-attr-key {
  color: var(--scootive-ink);
  font-weight: 700;
}
.csp-line-unit:empty {
  display: none;
}

.cart-summary-tax-note {
  margin: 8px 0 0;
  font-size: 10px;
  color: var(--scootive-gray-700);
}

/* Addresses step (checkout/_partials/steps/addresses.tpl + address-form.tpl
   + address-selector-block.tpl) - plain info/error notices and a small
   sub-heading style for "Shipping details"/"Billing details" (no direct
   prototype reference for these two - its own demo has no saved-address
   selector or split invoice/delivery flow, so this follows the same
   plain-box convention as everywhere else in this cutover with no
   prototype source to copy). */
.checkout-notice {
  border: 1px solid var(--scootive-line);
  background: var(--scootive-gray-50);
  padding: 16px 18px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--scootive-gray-700);
}
.checkout-notice a {
  color: var(--scootive-ink);
  font-weight: 700;
}
.checkout-notice.is-error {
  border-color: #f0b8b8;
  background: #fdf3f3;
  color: #a3261e;
}
/* Success variant (password-infos.tpl's "request sent" message) - paired
   with .is-error above using the same real state-success tokens the
   order-status pills already use, not a new color. */
.checkout-notice.is-success {
  border-color: #cdead0;
  background: var(--scootive-state-success-bg);
  color: var(--scootive-state-success);
}
/* Plain informational box (order-return.tpl) - same visual recipe as
   .checkout-notice but under the account section's own naming, and with
   a .account-notice-warning modifier (order-return.tpl's "Reminder" box)
   reusing the real order-status warning tokens instead of an invented
   amber. */
.account-notice {
  border: 1px solid var(--scootive-line);
  background: var(--scootive-gray-50);
  padding: 16px 18px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--scootive-gray-700);
}
.account-notice p {
  margin: 0 0 8px;
}
.account-notice p:last-child {
  margin-bottom: 0;
}
.account-notice-warning {
  border-color: #f3dfb3;
  background: var(--scootive-state-warning-bg);
  color: var(--scootive-state-warning);
}
.checkout-subhead {
  margin: 28px 0 16px;
}
.checkout-subhead:first-child {
  margin-top: 0;
}
.checkout-subhead h3 {
  margin: 4px 0 0;
  font-size: 20px;
  font-weight: 900;
  letter-spacing: -0.01em;
  color: var(--scootive-ink);
}
.checkout-link-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 20px;
  margin-top: 16px;
}
.checkout-link-row a {
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--scootive-ink);
  text-decoration: underline;
}
.checkout-link-row a:hover {
  color: var(--scootive-gray-700);
}
.btn-outline-checkout {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 46px;
  padding: 0 20px;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  color: var(--scootive-ink);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
}
.btn-outline-checkout:hover {
  border-color: var(--scootive-ink);
}
.step-form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 28px;
}

/* Delivery/shipping step (shipping.tpl) - carrier list reuses .option-list/
   .option-card/.option-logo/.option-price (same component as the payment
   step's method cards). extraContent (e.g. an InPost locker picker) is a
   real sibling the core JS shows/hides based on selection, kept outside
   the <label> itself. */
.carrier-extra-content {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--scootive-line);
}
.order-options {
  margin-top: 22px;
}
.order-options .field {
  margin-bottom: 18px;
}
.order-options .checkrow-consent {
  margin: 0 0 18px;
}

/* Payment step (payment.tpl) - method cards reuse .option-list/.option-card/
   .option-logo/.option-price exactly like the prototype's own payment-step
   demo (label>input[radio]+span+span.option-price). .step-edit is also a
   real <button> here (module's own JS-disabled "Choose" fallback and the
   final-check "Edit" buttons in order-final-summary.tpl below) as well as
   an <a> (checkout-step.tpl's step-title edit link) - reset to plain text
   either way. */
.step-edit {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
}
.payment-option-additional {
  margin-top: 14px;
  padding: 16px 18px;
  border: 1px solid var(--scootive-line);
  background: var(--scootive-gray-50);
  font-size: 12px;
  line-height: 1.7;
  color: var(--scootive-gray-700);
}
.payment-option-additional strong {
  color: var(--scootive-ink);
}
.payment-option-form {
  margin-top: 14px;
}
.btn-black[disabled],
.btn-black.disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.btn-black[disabled]:hover,
.btn-black.disabled:hover {
  background: var(--scootive-ink);
  border-color: var(--scootive-ink);
}
.payment-confirm-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 16px;
}
.payment-confirm-actions .checkout-notice {
  align-self: stretch;
}

/* Final check (order-final-summary.tpl) - a read-only recap of addresses/
   shipping method/order total shown at the bottom of the payment step,
   right before "Place order". No direct prototype reference (its own demo
   uses a much smaller #orderReview box, see project memory) - built from
   the same component vocabulary as the rest of checkout instead: .address-
   option for the two read-only address boxes (same look, just without
   .selected/radio since nothing is chosen here), a plain non-interactive
   variant of .option-card for the shipping method line. */
.checkout-review {
  margin-top: 8px;
}
.review-block {
  margin-top: 32px;
}
.review-block:first-of-type {
  margin-top: 0;
}
.review-block-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}
.review-block-title {
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--scootive-ink);
}
.review-address-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.review-address-grid .address-option .alias {
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
}
.review-carrier {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  border: 1px solid var(--scootive-gray-600);
  padding: 16px 18px;
}
.review-carrier strong {
  display: block;
  font-size: 13px;
  font-weight: 900;
  color: var(--scootive-ink);
}
.review-carrier .option-copy {
  font-size: 11px;
  color: var(--scootive-gray-700);
  margin-top: 3px;
}
@media (max-width: 1100px) {
  .review-address-grid {
    grid-template-columns: 1fr;
  }
}

/* Order line items table (order-confirmation-table.tpl) - shared between
   this "Final check" recap and the real post-purchase order-confirmation
   page (checkout/order-confirmation.tpl), which is still in the OLDER/
   different rounded design language (see project memory) - restyled here
   anyway rather than left raw, since on THIS page it sits directly beneath
   the now-restyled payment cards and a half-styled page would look broken,
   not just "a different page in an older style". Reuses .summary-row/
   .summary-row.total for the subtotals/total block underneath (identical
   markup/logic to the cart page and checkout sidebar). */
.review-head {
  display: none;
}
.review-line {
  padding: 20px 0;
  border-bottom: 1px solid var(--scootive-line);
}
.review-line:first-child {
  padding-top: 0;
}
.review-line:last-child {
  border-bottom: 0;
}
.review-grid {
  display: grid;
  gap: 10px;
}
.review-main {
  display: flex;
  gap: 14px;
  min-width: 0;
}
.review-img {
  width: 72px;
  height: 72px;
  flex-shrink: 0;
  background: #ecece7;
  display: grid;
  place-items: center;
}
.review-img picture {
  display: block;
  width: 85%;
  height: 85%;
}
.review-img img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
}
.review-info {
  min-width: 0;
}
.review-info h3 {
  margin: 0;
  font-size: 13px;
  font-weight: 900;
  color: var(--scootive-ink);
}
.review-info h3 a {
  color: inherit;
  text-decoration: none;
}
.review-info h3 a:hover {
  text-decoration: underline;
}
.review-info .variant {
  margin-top: 4px;
  font-size: 11px;
  color: var(--scootive-gray-700);
}
.review-customization {
  margin-top: 10px;
  padding: 10px 12px;
  border: 1px solid var(--scootive-line);
  background: var(--scootive-gray-50);
}
.review-customization-label {
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
  margin-bottom: 6px;
}
.review-customization-field {
  display: flex;
  gap: 8px;
  font-size: 11px;
  color: var(--scootive-gray-700);
  margin-top: 4px;
}
.review-customization-field strong {
  flex-shrink: 0;
  color: var(--scootive-ink);
  font-weight: 700;
}
.review-unit-price {
  margin-top: 6px;
  font-size: 10px;
  color: var(--scootive-gray-700);
}
.review-cols {
  display: flex;
  gap: 16px;
}
.review-col {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  font-weight: 700;
  color: var(--scootive-ink);
}
.review-col.total {
  justify-content: flex-end;
  font-weight: 900;
}
.review-col-label {
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
}
.review-tax-note {
  margin-top: 8px;
  font-size: 10px;
  color: var(--scootive-gray-700);
}
@media (min-width: 901px) {
  .review-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 110px 70px 120px;
    gap: 16px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--scootive-ink);
    margin-bottom: 6px;
  }
  .review-head span {
    font-size: 9px;
    font-weight: 900;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--scootive-gray-700);
  }
  .review-head span:nth-child(2),
  .review-head span:nth-child(3) {
    text-align: center;
  }
  .review-head span:nth-child(4) {
    text-align: right;
  }
  .review-grid {
    grid-template-columns: minmax(0, 1fr) 110px 70px 120px;
    align-items: center;
    gap: 16px;
  }
  .review-cols {
    display: contents;
  }
  .review-col {
    display: block;
    text-align: center;
  }
  .review-col.total {
    text-align: right;
  }
  .review-col-label {
    display: none;
  }
}

/* Header mini-cart drawer (_partials/drawers/cart-drawer.tpl). Its own
   .opacity-0/.opacity-100/.translate-x-full/.translate-x-0/.pointer-events-*
   toggle classes are added/removed directly by theme.js's initCartDrawer() -
   scoped to .cart-overlay/.cart-drawer here rather than left as bare Tailwind
   utilities, since this bundle's compiled CSS doesn't actually contain rules
   for those specific utility names (checked: absent from app.css too), so
   the open/close previously just snapped via the `hidden` attribute alone
   with no slide/fade. */
.cart-overlay {
  position: fixed;
  inset: 0;
  /* Matches the .mobile-nav-overlay/.mobile-nav drawer pair's own 350/351
     scale (same tier: a full-screen slide-in drawer above the sticky
     .mainnav header, which is z-index:100) rather than an arbitrary low
     value - 60/61 first tried here rendered BEHIND the sticky header. */
  z-index: 355;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: flex-end;
  transition: opacity 0.2s;
}
.cart-overlay.opacity-0 {
  opacity: 0;
}
.cart-overlay.opacity-100 {
  opacity: 1;
}
.cart-drawer {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 356;
  width: min(520px, 100%);
  height: 100vh;
  background: #fff;
  border-left: 1px solid var(--scootive-line);
  display: flex;
  flex-direction: column;
  transition: transform 0.24s;
}
.cart-drawer.translate-x-full {
  transform: translateX(100%);
}
.cart-drawer.translate-x-0 {
  transform: translateX(0);
}
/* JS-compat shim, same reasoning/pattern as #espeProductModal's own
   pointer-events-none/-auto rules below: during the ~320ms close
   transition the `hidden` attribute is deliberately deferred, so
   pointer-events is the only thing stopping clicks from landing on the
   fading-out overlay/drawer. Was silently relying on Tailwind's bare
   utility class for this - never had its own real definition. */
.cart-overlay.pointer-events-none,
.cart-drawer.pointer-events-none {
  pointer-events: none;
}
.cart-overlay.pointer-events-auto,
.cart-drawer.pointer-events-auto {
  pointer-events: auto;
}
.drawer-head {
  height: 84px;
  padding: 0 26px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: #fff;
  border-bottom: 1px solid var(--scootive-line);
  flex-shrink: 0;
}
.drawer-head h2 {
  font-size: 26px;
  margin: 0;
}
.drawer-head small {
  display: block;
  color: var(--scootive-gray-700);
  font-size: 10px;
  margin-top: 6px;
  text-transform: uppercase;
}
.drawer-close {
  width: 38px;
  height: 38px;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  font-size: 22px;
  cursor: pointer;
  flex-shrink: 0;
}
.drawer-body {
  padding: 22px 26px;
  overflow: auto;
  flex: 1;
}
.drawer-empty {
  font-size: 13px;
  color: var(--scootive-gray-700);
  text-align: center;
  padding: 40px 0;
}
.drawer-item {
  display: grid;
  grid-template-columns: 90px 1fr 28px;
  gap: 16px;
  padding: 16px 0;
  border-bottom: 1px solid var(--scootive-line);
}
.drawer-item:first-child {
  padding-top: 0;
}
.drawer-image {
  width: 90px;
  height: 90px;
  background: #ecece7;
  display: grid;
  place-items: center;
}
.drawer-image img {
  width: 86%;
  height: 86%;
  object-fit: contain;
  mix-blend-mode: multiply;
}
.drawer-item .brand {
  font-size: 9px;
  letter-spacing: 0.11em;
  color: var(--scootive-gray-700);
  font-weight: 900;
  text-transform: uppercase;
}
.drawer-item h3 {
  font-size: 14px;
  font-weight: 900;
  margin: 6px 0 5px;
}
.drawer-item h3 a {
  color: inherit;
  text-decoration: none;
}
.drawer-item h3 a:hover {
  text-decoration: underline;
}
.drawer-item .variant {
  font-size: 10px;
  color: var(--scootive-gray-700);
}
.drawer-item .line-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 14px;
}
.drawer-item .price {
  font-size: 13px;
  font-weight: 900;
}
.drawer-foot {
  background: #fff;
  border-top: 1px solid var(--scootive-line);
  padding: 22px 26px;
  flex-shrink: 0;
}
.drawer-actions {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
  margin-top: 18px;
}
.drawer-actions .btn-black {
  width: 100%;
}
.drawer-secondary {
  text-align: center;
  font-size: 10px;
  font-weight: 900;
  padding-top: 4px;
  color: var(--scootive-ink);
  text-decoration: none;
  text-transform: uppercase;
}
.drawer-secondary:hover {
  text-decoration: underline;
}

/* Order confirmation page (checkout/order-confirmation.tpl) - the real
   product/subtotal table below reuses the "Final check" step's own
   .review-* component untouched (see the comment above .review-head); this
   block only covers the page's own header/sidebar/actions shell. */
.confirmation-page {
  padding: 70px 0 24px;
}
.confirmation-body {
  padding-bottom: 100px;
}
.confirmation-head {
  max-width: 640px;
  margin: 0 auto 44px;
  text-align: center;
}
.confirmation-icon {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--scootive-green);
  color: #111;
  display: grid;
  place-items: center;
  margin: 0 auto 22px;
}
.confirmation-head .eyebrow {
  color: var(--scootive-gray-700);
}
.confirmation-head h1 {
  font-size: 40px;
  margin: 10px 0 14px;
}
.confirmation-head p {
  font-size: 14px;
  color: var(--scootive-gray-700);
  line-height: 1.6;
}
.confirmation-head p a {
  font-weight: 900;
  text-decoration: underline;
  color: inherit;
}
.confirmation-hook {
  max-width: 640px;
  margin: 0 auto;
}
.confirmation-actions {
  display: flex;
  justify-content: center;
  gap: 12px;
  margin-top: 40px;
}
.btn-outline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 52px;
  border: 1px solid var(--scootive-gray-600);
  background: transparent;
  color: var(--scootive-ink);
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  padding: 0 22px;
  text-decoration: none;
}
.btn-outline:hover {
  border-color: var(--scootive-ink);
}
@media (max-width: 1100px) {
  .confirmation-head h1 {
    font-size: 30px;
  }
  .confirmation-actions {
    flex-direction: column;
  }
}

/* Guest -> customer upsell (customer/_partials/account-transformation-form.tpl),
   shown on the order-confirmation page for guest checkouts. */
.account-benefits {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 24px;
}
.account-benefit {
  border: 1px solid var(--scootive-line);
  padding: 14px;
  font-size: 11px;
  font-weight: 700;
  color: var(--scootive-gray-700);
  text-align: center;
}
@media (max-width: 1100px) {
  .account-benefits {
    grid-template-columns: 1fr;
  }
  /* The shipping-method row can carry a long real carrier delay sentence
     (e.g. "Kurier JWP Przewidywana dostawa: Poniedziałek (21 września)
     (przy szybkiej płatności)") - right-aligned in a narrow value column it
     reads cramped, so this one row stacks label above value on narrow
     screens instead of the plain label:price side-by-side every other
     .summary-row uses (those always hold a short price, never long prose). */
  .summary-row-shipping {
    flex-direction: column;
    align-items: flex-start !important;
    gap: 4px;
  }
  .summary-row-shipping b {
    text-align: left !important;
  }
}


/* Contact page (templates/contact.tpl). The prototype's mockup hardcoded a
   department directory + NIP/REGON/bank details that don't match this
   shop's real configured contact info (confirmed via a DB read) - per
   explicit instruction, this page shows only the real contacts configured
   in Admin > Customer Service > Contacts (no message-sending form), the
   real ps_contactinfo module, the real wetwoshipping opening-hours widget,
   and a map on the real configured shop address. No fabricated legal/
   banking details.
   Structural note: breadcrumb sits directly in page_content_container (same
   nesting depth as the real category page's own .cat-head), not wrapped in
   its own extra .wrap/.contact-page div - an earlier version double-wrapped
   this, which is why the breadcrumb sat at a different height here than on
   other pages. */
.contact-split {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: 40px;
  align-items: stretch;
  margin-bottom: 40px;
}
.contact-list {
  border-top: 1px solid var(--scootive-line);
}
.contact-row {
  display: grid;
  grid-template-columns: minmax(140px, 180px) 1fr;
  gap: 20px;
  padding: 26px 0;
  border-bottom: 1px solid var(--scootive-line);
  align-items: baseline;
}
.contact-label {
  font-size: 12px;
  font-weight: 900;
  letter-spacing: 0.02em;
  color: var(--scootive-ink);
}
.contact-body h3 {
  font-size: 14px;
  font-weight: 500;
  color: var(--scootive-gray-700);
  margin: 0 0 10px;
  line-height: 1.4;
}
.contact-links {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}
.contact-links a {
  font-size: 13px;
  font-weight: 900;
  text-decoration: underline;
  color: var(--scootive-ink);
}
.contact-phone-group {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
}
.contact-ext {
  font-size: 12px;
  font-weight: 400;
  color: var(--scootive-gray-700);
}
.contact-store-dark {
  background: var(--scootive-ink);
  color: #fff;
  padding: 44px;
  position: relative;
  overflow: hidden;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
}
.contact-store-dark .eyebrow {
  margin-bottom: 14px;
}
.contact-store-dark h2 {
  font-size: 32px;
  margin: 8px 0 26px;
  color: #fff;
}
.store-facts {
  display: flex;
  flex-direction: column;
  gap: 22px;
  margin-bottom: 28px;
}
.store-facts b {
  display: block;
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.05em;
  color: var(--scootive-green);
  margin-bottom: 8px;
}
.store-facts span {
  display: block;
  font-size: 14px;
  color: #ddd;
  line-height: 1.6;
}
/* Dark-mode override for wetwoshipping's own hours widget (front-hours.css
   ships light-only colors) so its real weekly table + upcoming exceptions
   fit inside this dark section instead of a separate light sidebar card. */
.contact-store-dark .wetwo-hours--full {
  margin-top: 0;
}
.contact-store-dark .wetwo-hours__row th,
.contact-store-dark .wetwo-hours__row td {
  color: #ddd;
  border-bottom-color: rgba(255, 255, 255, 0.12);
}
.contact-store-dark .wetwo-hours__row th {
  color: #9a9a9a;
}
.contact-store-dark .wetwo-hours__row--today th,
.contact-store-dark .wetwo-hours__row--today td {
  color: #fff;
}
.contact-store-dark .wetwo-hours__exceptions {
  border-top-color: rgba(255, 255, 255, 0.12);
}
.contact-store-dark .wetwo-hours__exceptions-title,
.contact-store-dark .wetwo-hours__note {
  color: #9a9a9a;
}
.store-map {
  flex: 1;
  min-height: 180px;
  border: 1px solid #2a2a2a;
}
.store-map iframe {
  width: 100%;
  height: 100%;
  min-height: 180px;
  border: 0;
  display: block;
}

/* Real store-info block - modules/ps_contactinfo's OWN "rich" template
   variant (ps_contactinfo-rich.tpl), used automatically by the module
   itself for displayContactLeftColumn/RightColumn (confirmed by reading
   renderWidget()'s own hook-name switch - NOT the plain ps_contactinfo.tpl
   footer variant its default .block-contact classes would suggest). Core
   markup, unmodified - themed directly on its own real classes.
   Its <i class="material-icons"> ligature icons are hidden rather than
   restyled: this theme never loads the Material Icons webfont (same root
   cause as the blockwishlist heart-icon fix earlier this project), so
   they'd otherwise render as a visible fallback glyph/box. */
.contact-rich h4 {
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--scootive-ink);
  margin: 0 0 16px;
}
.contact-rich .block {
  display: flex;
  padding: 12px 0;
}
.contact-rich .icon {
  display: none;
}
.contact-rich hr {
  border: 0;
  border-top: 1px solid var(--scootive-line);
  margin: 0;
}
.contact-rich .data {
  font-size: 13px;
  color: var(--scootive-gray-700);
  line-height: 1.7;
}
.contact-rich .data a {
  color: var(--scootive-ink);
  font-weight: 700;
}

/* Real contact form (modules/contactform/views/templates/widget/contactform.tpl),
   core markup, unmodified - themed directly on its own real classes. */
.login-form header h1 {
  font-size: 22px;
  margin: 0 0 8px;
}
.login-form header p {
  font-size: 13px;
  color: var(--scootive-gray-700);
  line-height: 1.6;
  margin: 0 0 24px;
}
.login-form .form-fields {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.login-form .form-fields label {
  display: block;
}
.login-form .form-fields label span {
  display: block;
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--scootive-ink);
  margin-bottom: 8px;
}
.login-form .form-fields input,
.login-form .form-fields select,
.login-form .form-fields textarea {
  width: 100%;
  height: 46px;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  padding: 0 14px;
  font-size: 13px;
  font-family: inherit;
  color: var(--scootive-ink);
}
.login-form .form-fields textarea {
  height: auto;
  padding: 12px 14px;
  resize: vertical;
}
.login-form .form-fields input[type='file'] {
  border: 0;
  height: auto;
  padding: 0;
}
.login-form .form-footer {
  margin-top: 22px;
}
.login-form .form-footer button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 52px;
  border: 1px solid var(--scootive-ink);
  background: var(--scootive-ink);
  color: #fff;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  padding: 0 26px;
  cursor: pointer;
}
.login-form .form-footer button:hover {
  background: #fff;
  color: var(--scootive-ink);
}
.login-form .notification {
  padding: 14px 18px;
  margin-bottom: 20px;
  font-size: 13px;
  border: 1px solid var(--scootive-line);
}
.login-form .notification-error {
  border-color: #f0b8b8;
  background: #fdf3f3;
  color: #a3261e;
}
.login-form .notification-success {
  border-color: #cfe8b0;
  background: #f3fbe9;
  color: #3d6b1e;
}
.login-form .notification ul {
  margin: 0;
  padding-left: 18px;
}

@media (max-width: 1100px) {
  .contact-split {
    grid-template-columns: 1fr;
    gap: 0;
    margin-bottom: 32px;
  }
  .contact-row {
    grid-template-columns: 1fr;
    gap: 6px;
    padding: 20px 0;
  }
  .contact-store-dark {
    padding: 32px;
    margin-top: 32px;
  }
  .store-map {
    min-height: 220px;
  }
  .store-map iframe {
    min-height: 220px;
  }
}

/* Manufacturers/brands listing (templates/catalog/manufacturers.tpl +
   _partials/miniatures/brand.tpl) - REAL prototype reference at
   src/pages/marki.html + assets/css/marki.css (missed on the first pass -
   searched for "brand"/"manufacturer" in the prototype tree, but the file
   is named in Polish). Ported close to 1:1: sticky A-Z jump nav, a
   "featured" section, and a letter-grouped directory - all real-data
   driven, not the prototype's own hardcoded demo array:
   - featured = manufacturers with a real, non-empty admin-written
     description (an honest "someone actually curated this" signal - this
     store currently has exactly 3: Apex/Graphic Corner/Studio Design),
     not a fabricated flag.
   - directory cards drop the prototype's per-brand "tag" (category label)
     and logo image entirely, per explicit request - name + product count
     only.
   - letter-jump grouping is computed server-side per real brand name
     (Smarty {foreach}, not the prototype's own client-side marki.js) so it
     works with no JS and matches this project's established preference for
     real server-rendered content. */
.brands-head {
  padding: 36px 0 40px;
}
.brands-head h1 {
  font-size: 76px;
  margin: 8px 0 16px;
}
.brands-intro {
  font-size: 14px;
  line-height: 1.65;
  color: var(--scootive-gray-700);
  max-width: 560px;
}

.az-jump-wrap {
  position: sticky;
  top: 74px;
  z-index: 90;
  background: rgba(245, 245, 241, 0.97);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--scootive-line);
  border-bottom: 1px solid var(--scootive-line);
  margin: 0 calc(50% - 50vw);
  padding: 0 calc(50vw - 50%);
}
.az-jump {
  display: flex;
  gap: 2px;
  padding: 14px 0;
  overflow-x: auto;
}
.az-jump a,
.az-jump span {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 900;
}
.az-jump a {
  color: var(--scootive-ink);
  cursor: pointer;
  text-decoration: none;
}
.az-jump a:hover {
  background: var(--scootive-ink);
  color: #fff;
}
.az-jump span {
  color: var(--scootive-gray-600);
}

.brands-featured {
  padding: 54px 0 20px;
}
.brands-featured-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
.brand-feature {
  display: block;
  border: 1px solid var(--scootive-line);
  background: #fff;
  padding: 32px 28px;
  position: relative;
  overflow: hidden;
  transition: 0.2s;
  text-decoration: none;
}
.brand-feature-name {
  font-family: "Arial Black", Arial, sans-serif;
  font-size: 34px;
  letter-spacing: -0.03em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--scootive-ink);
}
.brand-feature p {
  font-size: 12px;
  line-height: 1.6;
  color: var(--scootive-gray-700);
  margin: 14px 0 26px;
  max-width: 340px;
  transition: 0.2s;
}
.brand-feature-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.06em;
}
.brand-feature-meta span:first-child {
  color: var(--scootive-gray-600);
  transition: 0.2s;
}
.brand-feature-link {
  position: relative;
  color: var(--scootive-ink);
}
.brand-feature-link:after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -4px;
  width: 0;
  height: 2px;
  background: var(--scootive-green);
  transition: 0.2s;
}
.brand-feature:hover {
  background: var(--scootive-ink);
  border-color: var(--scootive-ink);
}
.brand-feature:hover .brand-feature-name,
.brand-feature:hover p,
.brand-feature:hover .brand-feature-meta span:first-child,
.brand-feature:hover .brand-feature-link {
  color: #fff;
}
.brand-feature:hover .brand-feature-link:after {
  width: 100%;
}

.brands-directory {
  padding: 40px 0 90px;
}
.brand-letter-group {
  display: grid;
  grid-template-columns: 70px 1fr;
  gap: 24px;
  align-items: start;
  border-top: 1px solid var(--scootive-line);
  padding: 30px 0;
  scroll-margin-top: 140px;
}
.brand-letter-group:first-child {
  border-top: 0;
}
.brand-letter {
  font-family: "Arial Black", Arial, sans-serif;
  font-size: 44px;
  line-height: 1;
  color: var(--scootive-ink);
  margin: 0;
}
.brands-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}
.brand-card {
  position: relative;
  display: block;
  border: 1px solid var(--scootive-line);
  background: #fff;
  padding: 18px 34px 18px 20px;
  transition: 0.15s;
  text-decoration: none;
}
.brand-card-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
}
.brand-card-name {
  font-size: 14px;
  font-weight: 900;
  letter-spacing: -0.01em;
  color: var(--scootive-ink);
}
.brand-card-count {
  font-size: 10px;
  font-weight: 900;
  color: var(--scootive-gray-600);
}
.brand-card-arrow {
  position: absolute;
  right: 16px;
  bottom: 16px;
  font-size: 13px;
  opacity: 0;
  transform: translateX(-4px);
  transition: 0.15s;
  color: var(--scootive-green);
}
.brand-card:hover {
  background: var(--scootive-ink);
  border-color: var(--scootive-ink);
}
.brand-card:hover .brand-card-name,
.brand-card:hover .brand-card-count {
  color: #fff;
}
.brand-card:hover .brand-card-arrow {
  opacity: 1;
  transform: translateX(0);
}

@media (max-width: 1100px) {
  .az-jump-wrap {
    top: 137px;
  }
  .brand-letter-group {
    scroll-margin-top: 200px;
  }
  .brands-head {
    padding: 34px 0 26px;
  }
  .brands-head h1 {
    font-size: 46px;
  }
  .brands-featured-grid {
    grid-template-columns: 1fr;
  }
  .brands-featured {
    padding: 38px 0 10px;
  }
  .brand-letter-group {
    grid-template-columns: 1fr;
    gap: 10px;
    padding: 22px 0;
  }
  .brand-letter {
    font-size: 26px;
  }
  .brands-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.catalog-empty {
  border: 1px solid var(--scootive-line);
  padding: 32px;
}
.catalog-empty h4 {
  font-size: 14px;
  font-weight: 900;
  margin: 0 0 8px;
}
.catalog-empty p {
  font-size: 13px;
  color: var(--scootive-gray-700);
  line-height: 1.6;
  margin: 0;
}

/* 404 page (templates/errors/404.tpl) - a standalone document with no
   header/footer, matching the real prototype (src/pages/404.html +
   error-404.css) exactly: full-bleed dark page, side-by-side text+mascot
   on desktop, stacked (mascot above text) on mobile. The scaffold's own
   {l} strings here were ALREADY real, correctly-translated copy (verified
   in the compiled catalogue) - only the visual shell (raw Tailwind,
   green/white instead of the real near-black/white theme) needed work.
   body.page-404 needs its own !important to beat the sitewide
   `body{background:var(--scootive-bg)!important}` rule (added earlier
   this project for every other page) - confirmed live this was silently
   overriding the intended dark background before this fix. */
body.page-404 {
  background: #0b0b0b !important;
  color: #fff;
}
.error-404 {
  min-height: 100vh;
  display: flex;
  align-items: center;
  padding: 60px 0;
}
.error-grid {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 70px;
}
.error-copy {
  flex: 1;
  max-width: 640px;
}
.error-visual {
  flex-shrink: 0;
  width: 320px;
}
.error-visual img {
  width: 100%;
  height: auto;
  display: block;
  filter: drop-shadow(0 30px 40px rgba(0, 0, 0, 0.53));
}
.error-badge {
  display: inline-flex;
  align-items: center;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.08);
  padding: 9px 16px;
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.8);
}
.error-copy h1 {
  font-size: 76px;
  margin: 20px 0 22px;
  color: #fff;
}
.error-copy p {
  font-size: 14px;
  line-height: 1.7;
  color: #aaa;
  max-width: 480px;
}
.error-actions {
  display: flex;
  gap: 12px;
  margin-top: 32px;
}
.error-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 52px;
  padding: 0 26px;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
}
.error-btn-green {
  border: 1px solid var(--scootive-green);
  background: var(--scootive-green);
  color: #111;
}
.error-btn-green:hover {
  background: transparent;
  color: var(--scootive-green);
}
.error-btn-outline {
  border: 1px solid rgba(255, 255, 255, 0.35);
  background: transparent;
  color: #fff;
}
.error-btn-outline:hover {
  background: rgba(255, 255, 255, 0.08);
}

@media (max-width: 1100px) {
  .error-404 {
    padding: 48px 0;
  }
  .error-grid {
    flex-direction: column-reverse;
    gap: 34px;
    text-align: center;
  }
  .error-copy {
    max-width: none;
  }
  .error-copy p {
    margin: 0 auto;
  }
  .error-visual {
    width: 220px;
  }
  .error-copy h1 {
    font-size: 44px;
  }
  .error-actions {
    justify-content: center;
    flex-wrap: wrap;
  }
}

.contact-note {
  font-size: 12px;
  color: var(--scootive-gray-700);
  line-height: 1.6;
  margin: 12px 0 0;
}

/* "___ Only" homepage brand section (src/pages/home.html's own .only,
   home.css) - dark, edge-to-edge, real products of one admin-picked
   manufacturer via the wetwoonly module. Reuses the SAME real product
   card (.card/.prodimg/.card-body/.brand/.wish/.swatch/.weight/
   .variant-line/.omnibus-note, catalog/_partials/miniatures/product.tpl)
   as every other product grid on the site, just re-skinned dark here -
   card own background/border removed in favor of thin dividers between
   them, matching the prototype exactly. */
.only {
  background: #101010;
  color: #fff;
  padding: 90px 0;
}
.only-top {
  display: flex;
  justify-content: space-between;
  align-items: end;
  margin-bottom: 34px;
}
.only h2 {
  font-size: 56px;
  margin: 0;
}
/* Same link treatment as .section-head a (ps_newproducts' "All new
   products ->") so the "___ Only" section's manufacturer link matches
   every other homepage section's link style exactly. */
.only-link {
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  border-bottom: 1px solid;
  text-decoration: none;
  color: inherit;
  white-space: nowrap;
}
/* Grid `gap` (not per-card padding) owns the spacing between cards, so
   every column gets an EQUAL width - the prototype's own version of this
   (padding: 0 18px 18px + border-right, with :first-child/:last-child
   only forgiving the outer edge) gave middle cards padding on BOTH sides
   while edge cards only had it on one, so middle cards rendered visibly
   smaller than the edges (measured: ~403px vs ~421px at 1920px wide).
   The divider line is drawn with a pseudo-element sitting in the middle
   of the gap instead of a border, so it never affects any card's width. */
.only .products {
  gap: 0 36px;
}
.only .card {
  background: #101010;
  padding: 0 0 18px;
  position: relative;
}
.only .card:not(:last-child)::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  right: -18px;
  width: 1px;
  background: #232323;
}
.only .prodimg {
  background: #101010;
  border: 0;
}
.only .prodimg img {
  mix-blend-mode: normal;
}
.only .card-body {
  padding-top: 15px;
}
.only .brand {
  color: #9c9c9c;
}
.only .wish {
  color: #fff;
}
.only .swatch {
  box-shadow: inset 0 0 0 2px #101010;
}
.only .weight {
  color: #969696;
}
.only .variant-line {
  color: #c1c1c1;
}
.only .variant-line .vlabel {
  color: #969696;
}
.only .omnibus-note {
  color: #969696;
}
.only .name {
  color: #fff;
}
.only .price {
  color: #fff;
}
.only .sale-old,
.only .old {
  color: #969696;
}
.only .price.out-label {
  color: #969696;
}
@media (max-width: 1100px) {
  /* Not in the prototype's own mobile CSS (checked - it only had the 3
     rules below) - .only-top staying a side-by-side flex row down to
     narrow widths squeezed the heading into a column too narrow for its
     own text, wrapping it illegibly ("SCOOTIVE® ONLY" broke mid-word). */
  .only-top {
    flex-direction: column;
    align-items: flex-start;
    gap: 20px;
  }
  .only h2 {
    font-size: 38px;
  }
  .only .products {
    gap: 22px;
  }
  .only .card {
    padding: 0;
  }
  .only .card::after {
    display: none;
  }
}

/* Real homepage-only newsletter section (src/pages/home.html's own
   .newsletter/.signup, home.css) - replaces the old sitewide Tailwind-
   scaffold placeholder (hardcoded Polish text, shown on every page except
   cart/checkout/order) per explicit request ("Option A"): dropped entirely
   from every other page, rebuilt here as homepage-only, using the real
   ps_emailsubscription module (restyled, not replaced - see the theme's
   own ps_emailsubscription.tpl override) instead of a fake demo form.
   ps_socialfollow/blockreassurance intentionally excluded from this spot
   (isolated via {hook mod='ps_emailsubscription'}) - socialfollow currently
   has no configured links (renders an empty list) and blockreassurance
   already appears on 5 other hooks sitewide, so nothing is lost. */
.newsletter {
  background: #080808;
  color: #fff;
  padding: 94px 0;
}
.newsletter .wrap {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 70px;
  align-items: center;
}
.newsletter h2 {
  font-size: 72px;
  margin: 8px 0;
}
.newsletter p {
  color: #aaa;
  line-height: 1.6;
}
.signup {
  display: flex;
  border-bottom: 1px solid #555;
}
.signup input {
  flex: 1;
  background: transparent;
  border: 0;
  color: #fff;
  font-size: 20px;
  padding: 18px 0;
}
.signup input::placeholder {
  color: #777;
}
.signup input:focus {
  outline: 2px solid #fff;
  outline-offset: 2px;
}
.signup button {
  width: 90px;
  border: 0;
  background: var(--scootive-green);
  /* Was inheriting white from .newsletter's own color:#fff - against
     Scootive's lime-green accent that measured 1.59:1 contrast (effectively
     invisible), and still fails against AveBmx's blue accent (2.23:1).
     --scootive-ink passes WCAG AA on both (12.42:1 / 8.89:1, computed) and
     every other accent color this bright/light button-background pattern
     would realistically use - found via a site-wide accessibility audit,
     2026-10-02. */
  color: var(--scootive-ink);
  font-size: 20px;
  cursor: pointer;
}
.newsletter-msg {
  color: var(--scootive-green);
  font-size: 14px;
  font-weight: 800;
  padding: 18px 0;
  border-bottom: 1px solid #555;
}
.newsletter-msg-error {
  color: #f5a3a3;
}
.newsletter-conditions {
  font-size: 12px;
  color: #aaa;
  margin-top: 10px;
}
@media (max-width: 1100px) {
  .newsletter {
    padding: 56px 0;
  }
  .newsletter .wrap {
    grid-template-columns: minmax(0, 1fr);
  }
  .newsletter h2 {
    font-size: 38px;
  }
}

/* Login/register pages (src/pages/login.html, login.css/forms.css) - split-
   screen auth shell shared by customer/authentication.tpl and customer/
   registration.tpl. The prototype's single JS-toggled page became two real
   pages (see those templates' own comments); .mode-toggle/.mode-btn are the
   SAME components checkout's guest/register tabs already use (kept
   consistent, not reinvented) - here they're real <a> links between the two
   pages, so core.js's own .js-checkout-auth-tab click handling (which only
   targets its own class) never gets involved. */
.auth-page {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.auth-close {
  position: fixed;
  top: 24px;
  right: 24px;
  width: 40px;
  height: 40px;
  border: 1px solid var(--scootive-line);
  background: #fff;
  display: grid;
  place-items: center;
  font-size: 22px;
  color: var(--scootive-ink);
  z-index: 10;
}
.auth-close:hover {
  border-color: var(--scootive-ink);
}
.auth-visual {
  position: sticky;
  top: 0;
  height: 100vh;
  color: #fff;
  display: flex;
  flex-direction: column;
  gap: 32px;
  padding: 48px;
  overflow: hidden;
}
/* Real registration has more fields than the prototype's mockup (birthdate,
   2 consent checkboxes), so .auth-form-side is often taller than the
   viewport and the page scrolls - sticky (was a plain grid child) keeps
   this panel and the "Wróć do strony głównej" link pinned in view the
   whole time, matching the ORIGINAL raw scaffold's lg:fixed behavior that
   this rebuild had dropped.
   Not justify-content:space-between (the prototype's own value) - that
   prototype is ONE page whose visual/marketing copy never actually changes
   (only the form pane toggles), so it never had to handle two different
   copy heights. Splitting login/register into two real pages gave each its
   own real heading/paragraph (different lengths), and space-between
   redistributes leftover space by how much content there IS - caught live:
   the logo-to-copy gap visibly differed between the two pages.
   margin-top/bottom: auto on the copy block instead centers IT in
   whatever's left between the logo (top) and the back-link (bottom) -
   both of which now stay put at a fixed position regardless of copy
   length, per explicit request. */
.auth-visual-copy {
  margin-top: auto;
  margin-bottom: auto;
}
.auth-visual-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    linear-gradient(180deg, rgba(0, 0, 0, 0.8) 0, rgba(0, 0, 0, 0.4) 45%, rgba(0, 0, 0, 0.65) 100%),
    url('../img/auth-visual.png') center/cover no-repeat;
  filter: saturate(0.85) contrast(1.05);
}
.auth-logo,
.auth-visual-copy,
.auth-back {
  position: relative;
  z-index: 1;
}
.auth-logo img {
  height: 22px;
  width: auto;
  display: block;
  filter: invert(1);
}
.auth-visual-copy {
  max-width: 440px;
}
.auth-pill {
  display: inline-block;
  border: 1px solid rgba(255, 255, 255, 0.3);
  padding: 6px 12px;
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: 18px;
}
.auth-visual h1 {
  font-size: 52px;
  margin: 0 0 18px;
}
.auth-visual-copy p {
  font-size: 13px;
  line-height: 1.65;
  color: #d4d4d4;
  max-width: 380px;
}
.auth-chips {
  display: grid;
  gap: 10px;
  margin-top: 28px;
}
.auth-chip {
  border: 1px solid rgba(255, 255, 255, 0.2);
  padding: 14px 16px;
}
.auth-chip b {
  display: block;
  font-size: 12px;
  font-weight: 900;
  color: var(--scootive-green);
}
.auth-chip span {
  display: block;
  font-size: 11px;
  color: #ccc;
  margin-top: 4px;
}
.auth-back {
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.04em;
  color: #fff;
}
.auth-form-side {
  background: var(--scootive-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px;
}
.auth-card {
  width: 100%;
  max-width: 440px;
  background: #fff;
  border: 1px solid var(--scootive-line);
  padding: 44px;
}
.auth-card h2 {
  font-size: 26px;
  margin: 14px 0 8px;
}
.auth-card .sub {
  font-size: 12px;
  color: var(--scootive-gray-700);
  margin-bottom: 26px;
}
/* Real registration has 2 real consent checkboxes stacked (regulamin/
   polityka prywatności + newsletter) that the prototype's own mockup never
   had, making the card taller than the sticky visual panel/viewport - per
   explicit request, tightened just their OWN spacing (not the shared
   .field rhythm, which stays at the prototype's real 18px value) to help
   the page need less scrolling. */
.auth-card .checkrow-consent {
  margin: 14px 0;
}
.auth-forgot {
  display: block;
  font-size: 11px;
  font-weight: 800;
  text-decoration: underline;
  margin: -6px 0 22px;
  color: var(--scootive-ink);
}
/* Generic form-error list (_partials/form-errors.tpl's real .help-block/
   .alert-danger classes) - same color values as .login-form's own
   .notification-error (contactform page) for visual consistency, kept as a
   separate rule rather than reusing that class since the markup shape
   differs entirely (.form-fields there vs .field here). */
.help-block ul {
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.help-block .alert-danger {
  border: 1px solid #f0b8b8;
  background: #fdf3f3;
  color: #a3261e;
  font-size: 12px;
  padding: 12px 14px;
}
@media (max-width: 1100px) {
  .auth-page {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto;
  }
  .auth-visual {
    /* NOT position:static - a real bug caught live: .auth-visual-bg is
       position:absolute;inset:0, and static removes the positioning
       context it needs, so the background photo escaped to the nearest
       OTHER positioned ancestor and rendered full-viewport-tall instead of
       confined to this 340px panel, bleeding into the form card below it. */
    position: relative;
    /* height, not min-height - a real bug caught live: login/register have
       their own distinct real copy (different heading/paragraph lengths,
       kept per explicit request), so a content-driven min-height made this
       whole panel a different size on each page, with the back-link
       landing at a different Y position and a different-looking gap
       before the form card below. A fixed height (tall enough for
       register's own longer 3-line heading, the taller of the two) keeps
       the photo and every page's own back-link at one consistent size/
       position regardless of which page's copy is showing; .auth-visual-
       copy's margin-top/bottom:auto (set globally, not mobile-specific)
       centers each page's own (shorter or taller) copy within it. */
    height: 430px;
    padding: 32px 24px;
    gap: 20px;
  }
  .auth-visual h1 {
    font-size: 36px;
  }
  .auth-chips {
    display: none;
  }
  .auth-form-side {
    padding: 32px 20px 60px;
  }
  .auth-card {
    padding: 30px 24px;
  }
  .auth-close {
    top: 16px;
    right: 16px;
    width: 36px;
    height: 36px;
    font-size: 20px;
  }
  /* Real logo is a wide wordmark (naturalWidth 800x158, not the prototype's
     compact square-ish SVG mark) - at the prototype's fixed height:22px it
     renders ~330px wide, wide enough to collide with .auth-close at narrow
     widths (caught live at 375px). Capped by width instead, height auto. */
  .auth-logo img {
    height: auto;
    max-width: 130px;
  }
}

/* Account area (src/pages/account.html, account.css) - the prototype
   toggles 8 panes via JS on one page; real PrestaShop spreads these across
   separate controllers that already share customer/page.tpl, so the
   persistent .account-head/.account-layout/.account-nav shell lives there
   once and every page below (my-account/history/order-follow/discount/
   addresses/identity) picks it up. This block covers the whole area's CSS
   (including pieces not wired into a template yet in this same pass) so
   later pages reuse it directly instead of re-deriving it. */
.account-head {
  /* Matches .cat-head's own real padding (Marki/category pages etc.) - the
   * prototype's account.css only ever sets margin-bottom (34px) since its
   * own .account-page{padding:40px 0 100px} already provides the top
   * breathing room; this theme's shared page.tpl has no such per-page
   * padding (removed sitewide for the breadcrumb-position fix earlier this
   * project), so .account-head needs its own top padding to match every
   * other page's header position, same as .cat-head. */
  padding: 36px 0 0;
  margin-bottom: 34px;
}
.account-head h1 {
  font-size: 56px;
  margin: 8px 0 0;
}
.account-layout {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 56px;
  align-items: start;
  margin-bottom: 90px;
}
.account-nav {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--scootive-line);
  background: #fff;
  position: sticky;
  top: 98px;
}
.account-nav-item {
  width: 100%;
  text-align: left;
  padding: 16px 20px;
  border: 0;
  border-bottom: 1px solid var(--scootive-line);
  background: transparent;
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--scootive-gray-700);
  cursor: pointer;
}
.account-nav-item:last-child {
  border-bottom: 0;
}
.account-nav-item:hover {
  background: var(--scootive-gray-100);
}
.account-nav-item.active {
  background: var(--scootive-ink);
  color: #fff;
}
.account-nav-logout {
  color: var(--scootive-state-danger);
}
.account-nav-logout:hover {
  background: var(--scootive-state-danger-bg);
}
.account-content {
  min-width: 0;
}
.account-pane-head {
  margin-bottom: 22px;
}
.account-pane-head h2 {
  font-size: 13px;
  font-weight: 900;
  letter-spacing: 0.06em;
  color: var(--scootive-gray-700);
  text-transform: uppercase;
}
.orders-list {
  border-top: 1px solid var(--scootive-line);
  list-style: none;
  margin: 0;
  padding: 0;
}
.order-row {
  display: grid;
  grid-template-columns: auto 1fr auto auto auto;
  gap: 20px;
  align-items: center;
  padding: 20px 0;
  border-bottom: 1px solid var(--scootive-line);
  font-size: 12px;
}
.order-row .num {
  font-weight: 900;
}
.order-row .date {
  color: var(--scootive-gray-700);
}
.order-status {
  display: inline-block;
  padding: 5px 10px;
  font-size: 9px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.order-status-warning {
  background: var(--scootive-state-warning-bg);
  color: var(--scootive-state-warning);
}
.order-status-info {
  background: var(--scootive-state-info-bg);
  color: var(--scootive-gray-800);
}
.order-status-success {
  background: var(--scootive-state-success-bg);
  color: var(--scootive-state-success);
}
.order-status-danger {
  background: var(--scootive-state-danger-bg);
  color: var(--scootive-state-danger);
}
.order-row .total {
  font-weight: 900;
  text-align: right;
  white-space: nowrap;
}
.order-row a {
  font-size: 10px;
  font-weight: 900;
  text-decoration: underline;
  white-space: nowrap;
}
.order-row-actions {
  display: flex;
  justify-content: flex-end;
  gap: 14px;
}
.account-divider {
  margin: 34px 0 22px;
  padding-top: 22px;
  border-top: 1px solid var(--scootive-line);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.06em;
  color: var(--scootive-gray-700);
  text-transform: uppercase;
}
.account-hint {
  font-size: 12px;
  color: var(--scootive-gray-700);
  margin: 0 0 16px;
}
.detail-row {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--scootive-gray-700);
  padding: 9px 0;
  border-bottom: 1px solid var(--scootive-line);
}
.account-welcome {
  font-size: 13px;
  color: var(--scootive-gray-700);
  margin: 0 0 26px;
}
.summary-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}
.summary-card {
  display: block;
  text-align: left;
  border: 1px solid var(--scootive-line);
  background: #fff;
  padding: 20px;
  cursor: pointer;
}
.summary-card:hover {
  border-color: var(--scootive-ink);
}
.summary-card-label {
  display: block;
  font-size: 9px;
  font-weight: 900;
  letter-spacing: 0.05em;
  color: var(--scootive-gray-700);
  margin-bottom: 10px;
  text-transform: uppercase;
}
.summary-card p {
  font-size: 12px;
  color: var(--scootive-gray-700);
  line-height: 1.5;
  margin: 0 0 12px;
}
.summary-card-link {
  font-size: 10px;
  font-weight: 900;
  text-decoration: underline;
}
.coupon-list {
  display: grid;
  gap: 12px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.coupon-card {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  border: 1px solid var(--scootive-line);
  background: #fff;
  padding: 18px 22px;
}
.coupon-code {
  display: inline-block;
  background: var(--scootive-ink);
  color: var(--scootive-green);
  font-family: 'Arial Black', Arial, sans-serif;
  font-size: 13px;
  padding: 6px 10px;
  margin-bottom: 8px;
  letter-spacing: 0.02em;
}
.coupon-value {
  display: inline-block;
  font-size: 13px;
  font-weight: 900;
  color: var(--scootive-ink);
  margin: 0 0 8px 10px;
}
.coupon-card span {
  display: block;
  font-size: 11px;
  color: var(--scootive-gray-600);
}
.coupon-expiry {
  font-size: 10px;
  color: var(--scootive-gray-700);
  white-space: nowrap;
}
.address-list {
  display: grid;
  gap: 14px;
}
.address-list-2col {
  grid-template-columns: 1fr 1fr;
}
.address-card {
  position: relative;
  border: 1px solid var(--scootive-line);
  background: #fff;
  padding: 22px;
  font-size: 12px;
  line-height: 1.6;
}
.address-card b {
  display: block;
  font-size: 13px;
  margin-bottom: 8px;
}
.address-badge {
  position: absolute;
  top: 22px;
  right: 22px;
  background: var(--scootive-green);
  color: var(--scootive-ink);
  font-size: 8px;
  font-weight: 900;
  letter-spacing: 0.05em;
  padding: 5px 8px;
}
.address-actions {
  display: flex;
  gap: 16px;
  margin-top: 14px;
}
.address-actions a {
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  text-decoration: underline;
}
.address-add {
  width: 100%;
  text-align: center;
  border: 1px dashed var(--scootive-gray-400);
  background: transparent;
  color: var(--scootive-gray-700);
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  padding: 22px;
  cursor: pointer;
}
.address-add:hover {
  border-color: var(--scootive-ink);
  color: var(--scootive-ink);
}
@media (max-width: 1100px) {
  .account-head h1 {
    font-size: 38px;
  }
  .account-layout {
    grid-template-columns: 1fr;
    gap: 24px;
    margin-bottom: 60px;
  }
  .address-list-2col {
    grid-template-columns: 1fr;
  }
  .account-nav {
    position: static;
    flex-direction: row;
    overflow-x: auto;
  }
  .account-nav-item {
    white-space: nowrap;
    border-bottom: 0;
    border-right: 1px solid var(--scootive-line);
  }
  .account-nav-item:last-child {
    border-right: 0;
  }
  .order-row {
    grid-template-columns: 1fr auto;
    grid-template-areas: 'num status' 'date total' 'action action';
  }
  .order-row .num {
    grid-area: num;
  }
  .order-row .order-status {
    grid-area: status;
    justify-self: end;
  }
  .order-row .date {
    grid-area: date;
  }
  .order-row .total {
    grid-area: total;
  }
  .order-row-actions {
    grid-area: action;
    justify-content: flex-start;
  }
  .summary-grid {
    grid-template-columns: 1fr 1fr;
  }
  .coupon-card {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }
}

/* Header account dropdown (ps_customersignin.tpl, logged-in state) -
   restyled to the site's real flat design language (solid ink border, no
   shadow/rounding - same convention as the category page's own
   .quick-filter-dropdown) instead of the old rounded/shadowed Tailwind
   card. Pure CSS hover/focus-within, same as the original (no JS).
   Real bug caught live: "disappears 95% of the time" trying to hover down
   into it - the exact same dead-zone bug the mega-menu hit earlier this
   project. .account-menu has no explicit height of its own (only the
   40px icon-btn contributes to it, since the dropdown is
   position:absolute and doesn't), so the visual gap between the button
   and the panel (top:calc(100% + 8px)) was OUTSIDE .account-menu's own
   hoverable box - moving the mouse straight down through it lost :hover
   before ever reaching the panel. Fixed with the standard invisible-
   bridge technique: .account-dropdown itself now starts flush (top:100%,
   no gap) and stays a plain hover target with NO visual styling of its
   own; the real visible card is a nested .account-dropdown-panel offset
   by padding-top instead of a parent gap, so the "gap" is now padding
   INSIDE the hoverable element, not empty space outside it. */
.account-menu {
  position: relative;
}
.account-dropdown {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 30;
  width: 300px;
  padding-top: 10px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.15s;
}
.account-menu:hover .account-dropdown,
.account-menu:focus-within .account-dropdown {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
.account-dropdown-panel {
  background: #fff;
  border: 1px solid var(--scootive-ink);
  padding: 18px;
}
.account-dropdown-user {
  padding-bottom: 16px;
  margin-bottom: 10px;
  border-bottom: 1px solid var(--scootive-line);
}
.account-dropdown-user .eyebrow {
  color: var(--scootive-gray-700);
  margin-bottom: 6px;
}
.account-dropdown-user b {
  display: block;
  font-size: 14px;
}
.account-dropdown-link {
  display: block;
  margin: 0 -10px;
  padding: 10px;
  font-size: 12px;
  font-weight: 700;
  color: var(--scootive-ink);
}
.account-dropdown-link:hover {
  background: var(--scootive-gray-100);
}
.account-dropdown-logout {
  /* NOT padding-top:18px (was mismatched against the base link's own 10px
     bottom padding) - a real bug caught live: the extra top padding made
     the hover highlight box taller above the text than below it, so
     "Logout" sat visibly off-center within its own hover state and read
     as crowding the divider. The divider now gets its breathing room from
     margin-top (transparent, outside the hover box) instead of asymmetric
     padding inside it - padding stays the same symmetric 10px as every
     other link. */
  margin-top: 8px;
  border-top: 1px solid var(--scootive-line);
  color: var(--scootive-state-danger);
}
.account-dropdown-logout:hover {
  background: var(--scootive-state-danger-bg);
}

/* Order detail (customer/order-detail.tpl + its _partials) - no direct
   prototype page exists for this view (the prototype's own account.html
   demo links "SZCZEGÓŁY" to order-confirmation.html, the checkout
   thank-you page, as a rough stand-in, not a real order-detail design), so
   this reuses the account section's own established primitives
   (.detail-row, .address-card, .order-status, .account-divider, .field,
   .btn-black) instead of inventing an unrelated visual language. */
.detail-row b {
  color: var(--scootive-ink);
  font-weight: 900;
}
.order-detail-note {
  font-size: 12px;
  color: var(--scootive-gray-700);
  line-height: 1.6;
  padding: 12px 0;
  border-bottom: 1px solid var(--scootive-line);
}
.order-detail-note a {
  font-weight: 900;
  text-decoration: underline;
  color: var(--scootive-ink);
}
.order-timeline-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  font-size: 12px;
  color: var(--scootive-gray-700);
  padding: 10px 0;
  border-bottom: 1px solid var(--scootive-line);
}
/* Product table - real desktop <table>/mobile <ul> split (not a CSS grid
   reflow like .order-row) because the return-request variant needs a
   checkbox + qty <select> INSIDE each mobile row too, and core's own JS
   injects those into fixed placeholder ids that must exist in both the
   desktop and mobile markup at once (see order-detail-return.tpl) -
   collapsing to one shared markup block per row isn't possible here. */
.order-products-table {
  display: none;
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
.order-products-table th {
  text-align: left;
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--scootive-gray-700);
  padding: 0 12px 10px;
  border-bottom: 1px solid var(--scootive-ink);
}
.order-products-table th.align-right,
.order-products-table td.align-right {
  text-align: right;
}
.order-products-table td {
  padding: 16px 12px;
  border-bottom: 1px solid var(--scootive-line);
  vertical-align: top;
}
.order-products-table tfoot td {
  font-weight: 900;
  border-bottom: 0;
}
.order-products-table tfoot tr:first-child td {
  padding-top: 16px;
}
.op-name {
  font-weight: 900;
  color: var(--scootive-ink);
}
.op-meta {
  margin-top: 4px;
  font-size: 11px;
  color: var(--scootive-gray-700);
}
.op-warning {
  color: var(--scootive-state-warning);
}
.order-products-mobile {
  list-style: none;
  margin: 0;
  padding: 0;
}
.order-product-card {
  border: 1px solid var(--scootive-line);
  padding: 18px;
  margin-bottom: 12px;
  font-size: 12px;
}
.order-product-card .op-head {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.order-product-card .op-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 14px;
}
.order-product-card .op-grid > div {
  border: 1px solid var(--scootive-line);
  padding: 8px 10px;
}
.order-product-card .op-grid b {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--scootive-ink);
}
.order-qty-select {
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  padding: 0 8px;
  height: 34px;
  font-size: 12px !important;
  font-weight: 700;
}
.order-return-check {
  width: 16px;
  height: 16px;
  accent-color: var(--scootive-ink);
}
@media (min-width: 901px) {
  .order-products-table {
    display: table;
  }
  .order-products-mobile,
  .order-mobile-only {
    display: none;
  }
}
.order-return-panel {
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid var(--scootive-line);
}
.message-card {
  border: 1px solid var(--scootive-line);
  padding: 16px 18px;
  margin-bottom: 10px;
  font-size: 12px;
  line-height: 1.6;
}
.message-card b {
  display: block;
  color: var(--scootive-ink);
}
.message-card .msg-date {
  color: var(--scootive-gray-700);
  font-size: 11px;
  margin-bottom: 8px;
}

/* .module/.notify (product.css) - the generic bordered product-page module
   card, ported here for the ps_emailalerts "notify me when back in stock"
   widget (its own theme override was still the raw Tailwind scaffold -
   rounded green pill button - never actually restyled). Only the base
   .module/.module-title/.module p/.module button + .notify input pieces
   are ported (not .module.greenish, .module.dark, .cut-service, .addon, .check), since
   those belong to other product-page modules not touched here. The
   prototype's own .notify{display:none} is NOT ported - there it's a
   demo-only toggle for one static HTML page; on the real site this hook
   only renders at all when the product is genuinely out of stock, so it
   should always be visible when present. */
.module {
  border: 1px solid var(--scootive-line);
  background: #fff;
  margin: 15px 0;
  padding: 18px;
}
.module-title {
  font-size: 13px;
  font-weight: 900;
}
.module p {
  font-size: 11px;
  line-height: 1.5;
  color: var(--scootive-gray-700);
  margin: 8px 0 0;
}
.module button {
  margin-top: 14px;
  border: 0;
  background: var(--scootive-ink);
  color: #fff;
  padding: 11px 14px;
  font-size: 9px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: pointer;
}
.module button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.notify input {
  width: 100%;
  height: 44px;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  padding: 0 12px;
  margin: 12px 0;
  font-size: 13px !important;
}

/* My account > My alerts (ps_emailalerts's own mailalerts-account.tpl) -
   real prototype .notify-list/.notify-row (account.css). */
.notify-list {
  border-top: 1px solid var(--scootive-line);
  list-style: none;
  margin: 0;
  padding: 0;
}
.notify-row {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 16px;
  align-items: center;
  padding: 16px 0;
  border-bottom: 1px solid var(--scootive-line);
}
.notify-row img {
  width: 56px;
  height: 56px;
  object-fit: contain;
  mix-blend-mode: multiply;
  background: var(--scootive-gray-100);
}
.notify-row b {
  display: block;
  font-size: 12px;
}
.notify-row span {
  display: block;
  font-size: 10px;
  color: var(--scootive-gray-700);
  margin-top: 3px;
}
.notify-cancel {
  border: 1px solid var(--scootive-ink);
  background: transparent;
  height: 36px;
  padding: 0 14px;
  font-size: 9px;
  font-weight: 900;
  cursor: pointer;
  white-space: nowrap;
}
.notify-cancel:hover {
  background: var(--scootive-ink);
  color: #fff;
}

/* blockwishlist's own "My wishlists" / single-list / add-to-wishlist-modal
   views (customer/page.tpl's .wishlist-container, .wishlist-products-
   container, and the .wishlist-add-to popup opened from any product card's
   heart icon) are rendered entirely by compiled Vue apps
   (public/wishlistcontainer.bundle.js, productslist.bundle.js,
   addtowishlist.bundle.js), not our Smarty templates - their DOM
   structure/behavior can't be changed from here, only recolored to feel
   consistent with the rest of the site instead of building a full 1:1
   replacement of the prototype's own tabs/grid (a much bigger, separate
   project). Every class below was confirmed by reading the compiled
   bundles directly (not guessed). !important throughout since load order
   relative to the module's own wishlist.css isn't guaranteed (same class
   of risk fought earlier against the Tailwind CDN cascade).
   Also fixes a real, recurring bug found in THREE separate places now:
   its buttons use <i class="material-icons"> ligatures - that font was
   never loaded anywhere on this front theme (same root cause as the admin
   "EXPAND_" bug and ps_emailalerts' old "delete" button) - hidden here
   rather than left showing literal "add_circle_outline"/"share"/"delete"/
   "shopping_cart"/"arrow_drop_down" text with no icon. */
.wishlist-add-to .material-icons,
.wishlist-container .material-icons,
.wishlist-products-container .material-icons,
.wishlist-list-item-right .material-icons {
  font-size: 0 !important;
}
.wishlist-container-header,
.wishlist-list-item-title,
.wishlist-products-container-header,
.wishlist-products-count,
.wishlist-product-title {
  font-family: inherit !important;
  color: var(--scootive-ink) !important;
}
.wishlist-add-to-new,
.wishlist-share,
.wishlist-list-item-actions {
  font-family: inherit !important;
  font-size: 10px !important;
  font-weight: 900 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.04em !important;
  color: var(--scootive-ink) !important;
}
.wishlist-list-item-default,
.wishlist-list {
  border-color: var(--scootive-line) !important;
}
.wishlist-list-item:hover .wishlist-list-item-title {
  color: var(--scootive-ink) !important;
}
.wishlist-toast {
  border-radius: 0 !important;
  border-color: var(--scootive-ink) !important;
  font-family: inherit !important;
}
.wishlist-product {
  border: 1px solid var(--scootive-line) !important;
  border-radius: 0 !important;
  padding: 16px !important;
  font-family: inherit !important;
}
.wishlist-product-price,
.wishlist-product-price-promo {
  font-family: inherit !important;
  font-weight: 900 !important;
  color: var(--scootive-ink) !important;
}
.wishlist-product-combinations-text {
  font-family: inherit !important;
  font-size: 11px !important;
  color: var(--scootive-gray-700) !important;
}
.wishlist-product-addtocart {
  font-family: inherit !important;
  background: var(--scootive-ink) !important;
  color: #fff !important;
  text-transform: uppercase !important;
  font-weight: 900 !important;
  font-size: 10px !important;
  letter-spacing: 0.04em !important;
  border-radius: 0 !important;
  border: 0 !important;
}

/* Confirmed live (authenticated session) rather than guessed: the "..."
   options button per wishlist row (rename/delete/share trigger) had
   collapsed to an unusable ~4px sliver, because its only content - a
   broken <i class="material-icons">more_vert</i> ligature - was hidden by
   the earlier font-size:0 rule with nothing put in its place; the button
   itself was still in the DOM, just invisible/unclickable. Fixed with an
   explicit size plus a real drawn "⋮" via ::after, same pattern already
   used elsewhere in this theme for the product-card wishlist-heart icon
   (explicit size + a real icon instead of the missing font glyph). */
.wishlist-list-item-actions {
  position: relative !important;
  width: 28px !important;
  height: 28px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
}
.wishlist-list-item-actions::after {
  content: "\22EE";
  font-size: 20px !important;
  line-height: 1 !important;
  color: var(--scootive-ink) !important;
  font-family: inherit !important;
}

/* Sort dropdown on the single-wishlist products page - also confirmed
   live: [data-toggle="dropdown"] never gets wired up (no Bootstrap JS on
   this front theme) and .dropdown-menu has no default display:none in
   the module's own CSS, so all 4 sort options rendered permanently
   inline as plain stacked text instead of a collapsed menu. Fixed with
   the same CSS-only hover-reveal technique already used for the header
   account dropdown (no JS required either way). */
/* Restyled to match .cat-head exactly (real category-page header
   convention, confirmed by reading category.tpl/scootive-theme.css
   directly): big uppercase Arial Black display h1, count dropped onto
   its own line below since .wishlist-products-count is a <span> NESTED
   INSIDE the <h1> in the module's own real DOM (confirmed live) - it
   can't be reordered into a sibling position via CSS alone. A real
   breadcrumb still can't be added here (products-list.tpl never includes
   _partials/breadcrumb.tpl at all, unlike category.tpl) without a
   template change - see that file's own comment for the fix. */
.wishlist-products-container-header {
  /* Per explicit follow-up request: back to one row like the module's own
     stock layout, title left / sort right - just with the real .cat-head
     typography now applied to the title instead of the plain 32px style. */
  display: flex !important;
  align-items: flex-end !important;
  flex-wrap: wrap !important;
  justify-content: space-between !important;
  gap: 16px !important;
  padding: 36px 0 38px !important;
  margin-bottom: 0 !important;
}
.wishlist-products-container-header h1 {
  font-family: "Arial Black", Arial, sans-serif !important;
  font-weight: 950 !important;
  font-size: 76px !important;
  letter-spacing: -0.055em !important;
  line-height: 0.9 !important;
  text-transform: uppercase !important;
  color: var(--scootive-ink) !important;
  margin: 8px 0 0 !important;
}
.wishlist-products-count {
  /* Per explicit request: stays inline next to the name (its real markup
     is "(N)", already parenthesized) instead of dropping to its own line. */
  display: inline !important;
  font-family: inherit !important;
  font-size: 32px !important;
  font-weight: 400 !important;
  text-transform: none !important;
  letter-spacing: normal !important;
  color: var(--scootive-gray-700) !important;
  margin-left: 14px !important;
  vertical-align: middle !important;
}
@media (max-width: 1100px) {
  .wishlist-products-container-header h1 {
    font-size: 46px !important;
  }
}
.sort-by-row {
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  margin: 0 !important;
  font-family: inherit !important;
}
.sort-by {
  font-size: 11px !important;
  font-weight: 900 !important;
  text-transform: uppercase !important;
  color: var(--scootive-gray-700) !important;
}
.products-sort-order {
  position: relative !important;
}
.select-title {
  font-family: inherit !important;
  font-size: 11px !important;
  font-weight: 900 !important;
  text-transform: uppercase !important;
  color: var(--scootive-ink) !important;
  border: 1px solid var(--scootive-line) !important;
  padding: 8px 32px 8px 12px !important;
  position: relative !important;
  background: #fff !important;
}
.select-title::after {
  content: "\25BE";
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 12px;
  color: var(--scootive-ink);
}
.products-sort-order .dropdown-menu {
  /* Same hover dead-zone bug as the header account dropdown / mega-menu
     earlier in this project: margin-top left a real 4px gap between the
     button and the menu that belongs to neither element's hoverable box,
     so moving the mouse down into the menu lost :hover before arriving.
     Flush against the button (no gap) instead, rather than reaching for
     the full invisible-bridge markup change for 4px. */
  display: none !important;
  position: absolute !important;
  top: 100% !important;
  right: 0 !important;
  left: auto !important;
  z-index: 20 !important;
  background: #fff !important;
  border: 1px solid var(--scootive-ink) !important;
  padding: 6px 0 !important;
  min-width: 180px !important;
  margin-top: 0 !important;
}
.products-sort-order:hover .dropdown-menu,
.products-sort-order:focus-within .dropdown-menu {
  display: block !important;
}
.select-list {
  display: block !important;
  padding: 8px 14px !important;
  font-size: 11px !important;
  font-weight: 700 !important;
  color: var(--scootive-ink) !important;
  font-family: inherit !important;
}
.select-list:hover {
  background: var(--scootive-gray-100) !important;
}

/* Two more icon-only buttons found live on the wishlists list page, same
   "broken ligature = invisible button" issue: the default list's row has
   a persistent share button (its ONLY child), and every non-default row
   has a persistent delete button as its LAST child (separate from, and
   in addition to, the "..." rename/share popup - confirmed live by
   reading the actual rendered DOM, not guessed). Both get real text
   labels instead of a redrawn icon, matching the sitewide convention
   already used for real address-card actions (EDYTUJ/USUŃ). */
.wishlist-list-item-default .wishlist-list-item-right > button {
  font-size: 0 !important;
  position: relative !important;
  min-width: 70px !important;
  height: 24px !important;
}
.wishlist-list-item-default .wishlist-list-item-right > button::after {
  content: "Udostępnij";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  font-size: 10px !important;
  font-weight: 900 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.04em;
  color: var(--scootive-ink) !important;
  font-family: inherit !important;
  white-space: nowrap;
}
.wishlist-list-item:not(.wishlist-list-item-default) .wishlist-list-item-right > button:last-child {
  font-size: 0 !important;
  position: relative !important;
  min-width: 50px !important;
  height: 24px !important;
}
.wishlist-list-item:not(.wishlist-list-item-default) .wishlist-list-item-right > button:last-child::after {
  content: "Usuń";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  font-size: 10px !important;
  font-weight: 900 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.04em;
  color: var(--scootive-state-danger) !important;
  font-family: inherit !important;
  white-space: nowrap;
}
.wishlist-list-item-right .dropdown-menu {
  /* Confirmed live: this had no position set at all (module's own CSS
     sets "right:1.25rem" but that has zero effect without position also
     being set), so it rendered INLINE in normal document flow instead of
     floating over the row - pushing "USUŃ" down/around and misaligning
     everything whenever the menu opened. .wishlist-list-item-right itself
     is already position:relative (confirmed live), so anchoring here. */
  position: absolute !important;
  top: 100% !important;
  right: 0 !important;
  left: auto !important;
  margin-top: 4px !important;
  z-index: 20 !important;
  background: #fff !important;
  border: 1px solid var(--scootive-ink) !important;
  box-shadow: none !important;
  padding: 4px 0 !important;
  border-radius: 0 !important;
}
.wishlist-list-item-right .dropdown-menu button {
  font-family: inherit !important;
  font-size: 10px !important;
  font-weight: 900 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.04em !important;
  color: var(--scootive-ink) !important;
  padding: 10px 16px !important;
  text-align: left !important;
  white-space: nowrap !important;
}
.wishlist-list-item-right .dropdown-menu button:hover {
  background: var(--scootive-gray-100) !important;
}

/* Remove-from-wishlist circle button on each product card within a single
   list's product view (productslist.bundle.js reuses the class
   .wishlist-button-add here for a "delete" action, confirmed live - a
   different DOM context from the real heart/add-to-wishlist button
   elsewhere, which already has its own .wish .wishlist-button-add SVG
   replacement). 40x40 circle confirmed live; centered "×" replacement.
   Real bug found on a second look: position:relative (below) cancelled
   the module's OWN stock position:absolute;top:.625rem;right:.625rem,
   which is what overlays this circle on the product photo's corner in
   the first place (.wishlist-product, its real positioned ancestor, is
   untouched by this theme) - relative dropped it into normal document
   flow instead, after the full-width "Dodaj do koszyka" button, reading
   as a disconnected floating circle. Restored the real absolute overlay
   instead of fighting it. */
.wishlist-products-item .wishlist-button-add,
.wishlist-product .wishlist-button-add {
  position: absolute !important;
  top: 0.625rem !important;
  right: 0.625rem !important;
  /* Per explicit request: square + bordered, matching this site's own
     flat design language, instead of the module's stock circle/shadow. */
  border-radius: 0 !important;
  border: 1px solid var(--scootive-ink) !important;
  box-shadow: none !important;
  background: #fff !important;
}
.wishlist-products-item .wishlist-button-add::after,
.wishlist-product .wishlist-button-add::after {
  content: "\00d7";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px !important;
  font-weight: 700 !important;
  color: var(--scootive-ink) !important;
  font-family: inherit !important;
}

/* "Add to wishlist" modal (opened from any product card/detail page's
   heart icon) had no visible way to close it - confirmed live: its real
   .btn-close element (Bootstrap 5's close button) was present but
   collapsed to 0x0, since Bootstrap 5's own CSS - which normally draws
   the "×" via a background-image SVG on this exact class - isn't loaded
   on this front theme. Same real "×" glyph convention already used for
   .auth-close (login/register pages), sized for this modal's own header
   instead of that page-level fixed position. */
.wishlist-modal .btn-close {
  width: 32px !important;
  height: 32px !important;
  min-width: 32px !important;
  border: 0 !important;
  background: transparent !important;
  position: relative !important;
  flex-shrink: 0;
  cursor: pointer;
}
.wishlist-modal .btn-close::before {
  content: "\00d7";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  color: var(--scootive-ink);
  font-family: inherit;
  line-height: 1;
}

/* The "choose a list" row inside the add-to-wishlist modal highlighted
   itself on hover with a light cyan (~rgb(236,248,251) over
   #2fb5d2-tinted text) - confirmed by reading addtowishlist.bundle.js
   directly: that's the module's own out-of-the-box default accent color,
   not anything from this theme's palette, so it read as random/off-brand.
   Swapped for the same real tokens used for every other hover state in
   this project (e.g. .account-dropdown-link:hover). */
.wishlist-chooselist .wishlist-list-item:hover {
  background: var(--scootive-gray-100) !important;
  cursor: pointer;
}
.wishlist-chooselist .wishlist-list-item:hover .wishlist-list-item-title {
  color: var(--scootive-ink) !important;
}

/* Product photos in the single-wishlist products view - confirmed by
   reading productslist.bundle.js directly: its own @media(max-width:768px)
   rule resets position/transform to "inherit" on both the image box and
   the <img> itself (killing the desktop version's working center-crop),
   without ever setting object-fit/max-width/height as a replacement - the
   real, full-size product photo (e.g. PrestaShop's own ~800x800 "large"
   image) then renders at its natural size pinned to the box's top-left
   corner and gets hard-cropped by the box's own overflow:hidden to a
   random, zoomed-in top-left sliver. Ported the site's own real product-
   card image convention (.prodimg) instead: gray box, contain-fit,
   multiply blend so white product-shot backgrounds melt into it. Applied
   both outside AND inside the same breakpoint the bundle uses, since
   which of two same-specificity, injected-at-runtime <style> tags wins
   depends on DOM order, not just specificity - duplicating inside the
   query removes that ambiguity instead of hoping the outer rule wins. */
.wishlist-product-image {
  width: 100% !important;
  height: auto !important;
  aspect-ratio: 1 !important;
  background: #ecece7 !important;
  display: grid !important;
  place-items: center !important;
  overflow: hidden !important;
  position: relative !important;
  margin-right: 0 !important;
}
.wishlist-product-image img {
  position: static !important;
  top: auto !important;
  left: auto !important;
  width: 88% !important;
  height: 88% !important;
  max-width: 88% !important;
  max-height: 88% !important;
  object-fit: contain !important;
  mix-blend-mode: multiply !important;
  transform: none !important;
  transition: transform 0.28s ease !important;
}
.wishlist-product-link:hover .wishlist-product-image img {
  transform: scale(1.04) !important;
}
@media screen and (max-width: 768px) {
  .wishlist-product-image {
    width: 100% !important;
    height: auto !important;
    aspect-ratio: 1 !important;
    background: #ecece7 !important;
    margin-right: 0 !important;
  }
  .wishlist-product-image img {
    position: static !important;
    top: auto !important;
    left: auto !important;
    transform: none !important;
    width: 88% !important;
    height: 88% !important;
    max-width: 88% !important;
    max-height: 88% !important;
    object-fit: contain !important;
  }
}

/* "Ilość : 0" on every product card, confirmed by reading the module's
   own source end to end (button.bundle.js/WishListProductSearchProvider.php/
   WishList.php): this is NOT stock and never was - it's
   wishlist_product.quantity, the "how many did the customer want" value
   captured only when a product is added to a wishlist FROM the product
   page's own quantity selector. Adding from a category grid, the
   homepage, or anywhere else without that input present always writes a
   hardcoded 0 (confirmed in button.bundle.js), so it reads as an
   incorrect/confusing "out of stock" signal on products that are
   available. Not a CSS bug to begin with - hiding it rather than
   fabricating a display for genuinely meaningless stored data. Confirmed
   live: the quantity is always the LAST <span> inside
   .wishlist-product-combinations-text when the product has attributes; a
   product with none renders the same span as a lone child of
   .wishlist-product-combinations instead (no wrapping <p> at all). */
.wishlist-product-combinations-text > span:last-child,
.wishlist-product-combinations > span:only-child {
  display: none !important;
}

/* Real, separate icon-only element found live while checking the above:
   an "edit/customize" link (pencil icon, class-less <a>, ligature text
   "create") sits next to the combinations line - same missing-Material-
   Icons-font issue as everywhere else, hidden entirely rather than
   redrawn since it duplicates the product-name link right above it (both
   go to the exact same product URL). */
.wishlist-product-combinations > a {
  display: none !important;
}
/* Broader, more robust catch-all for the same "create" pencil icon in
   case a product without any attributes puts it in a different spot in
   the DOM (couldn't verify that specific variant live - no attribute-less
   product was in the test list) - any icon-only anchor anywhere inside a
   wishlist product card, whatever its exact path, gets the same
   treatment rather than only the one confirmed position above. */
.wishlist-product a:has(> i.material-icons:only-child),
.wishlist-products-item a:has(> i.material-icons:only-child) {
  display: none !important;
}

/* ===== Ship-timer topbar (_partials/ui/ship-timer.tpl) — matches the
   prototype's own .utility bar 1:1 (src/partials/header.html + header.css:
   a plain 30px black bar, two space-between items, no live countdown, no
   accent color - just uppercase 9px text). Real dynamic values (cutoff
   time, next-ship date, free-shipping threshold, return window) are
   plugged into this exact layout instead of the prototype's static copy. */
.ship-timer {
  background: var(--scootive-ink);
  color: #fff;
  min-height: 30px;
}
.ship-timer-grid {
  min-height: 30px;
  padding: 6px 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 2px 12px;
  font-size: 9px;
  /* Prototype's own .utility has no explicit font-weight (inherits normal),
     but real-browser testing showed normal-weight 9px white-on-black text
     rendering visibly blurrier/harder to read than the prototype's own
     screenshot - small light text on a dark background needs more weight
     to stay crisp. 700 (this bar's own previous weight) confirmed better
     than 400 in a direct side-by-side check. */
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
}
.ship-timer-item {
  white-space: nowrap;
}
@media (max-width: 1100px) {
  .ship-timer-grid {
    justify-content: center;
    text-align: center;
  }
  .ship-timer-item {
    white-space: normal;
  }
}

/* ===== Homepage — builder teaser, Scootive World, social sections
   (src/pages/home.html's own .builder-grid/.community/.social + home.css)
   — ported verbatim, .section/.section-head/.products/.btn.green already
   exist above and are reused as-is; --line/--gray-700/--green/--green2 in
   the prototype's home.css map to this theme's own --scootive-* tokens. */
.builder-grid {
  min-height: 390px;
  margin-top: 56px;
  margin-bottom: 56px;
  display: grid;
  grid-template-columns: .84fr 1.16fr;
  background: #e8e8e2;
}
.builder-copy {
  padding: 30px 56px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.builder-copy h2 {
  font-size: 36px;
  margin: 6px 0 10px;
}
.builder-copy h2 span {
  color: var(--scootive-green2);
}
.builder-copy p {
  line-height: 1.55;
  color: var(--scootive-gray-700);
  max-width: 440px;
  margin-bottom: 26px;
}
.builder-photo {
  background: linear-gradient(90deg, #0002, #0000), url("../img/builder-flatlay.jpg") center/cover no-repeat;
}

.community {
  display: grid;
  grid-template-columns: 1.3fr .7fr;
  gap: 18px;
}
.community-main,
.tile {
  position: relative;
  overflow: hidden;
  color: #fff;
  background: #151515;
}
.community-main {
  min-height: 560px;
  padding: 45px;
  background: linear-gradient(90deg, #000d, #0003), url('https://cdn2.scootive.pl/gfx/template/scootive-camp.jpg') center/cover;
}
.community-main h3 {
  font-size: 67px;
  margin: 12px 0;
}
.side {
  display: grid;
  gap: 18px;
}
.tile {
  min-height: 270px;
  padding: 30px;
}
.tile.light {
  background: #e7e7e1;
  color: #111;
}
.tile h3 {
  font-size: 34px;
  margin: 10px 0;
}
.community-bottom {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin-top: 18px;
}
.link-bottom {
  position: absolute;
  bottom: 24px;
  left: 30px;
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  color: inherit;
  text-decoration: none;
}
/* Prototype's own rule here is a bare, unscoped ".tile:nth-child(2)" -
   since :nth-child counts siblings within each tile's OWN parent, that
   also matches "Praca w Scootive" (2nd child of .community-bottom),
   silently overriding its intended flat .tile.light look with this same
   skatepark photo (higher source order, equal specificity). Scoped to
   .side here so it only reaches the one tile it's actually meant for
   (Avepark, 2nd child of .side) - not a deliberate prototype effect worth
   reproducing. */
.side .tile:nth-child(2) {
  background:
    linear-gradient(180deg, rgba(0,0,0,.55) 0%, rgba(0,0,0,.18) 32%, rgba(0,0,0,.72) 100%),
    url('https://cdn2.scootive.pl/gfx/template/skatepark-avepark_new.jpg') center/cover no-repeat;
  color: #fff;
}
.community-bottom .tile:first-child {
  background:
    linear-gradient(180deg, rgba(0,0,0,.58) 0%, rgba(0,0,0,.2) 32%, rgba(0,0,0,.78) 100%),
    url('https://i.ytimg.com/vi/TsFHhejY2ik/hqdefault.jpg') center/cover no-repeat;
}

.social {
  background: #eaeae5;
}
.social-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 10px;
}
.social-post {
  aspect-ratio: 1 / 1.12;
  position: relative;
  background: #222;
  overflow: hidden;
  color: #fff;
}
.social-post img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(.8);
}
.platform {
  position: absolute;
  right: 10px;
  top: 10px;
  background: #111;
  color: #fff;
  font-size: 9px;
  font-weight: 900;
  padding: 5px 7px;
}

@media (max-width: 1100px) {
  .builder-grid {
    grid-template-columns: minmax(0, 1fr);
    margin-top: 32px;
  }
  .builder-copy {
    padding: 36px;
  }
  .builder-copy h2 {
    font-size: 28px;
  }
  .builder-photo {
    min-height: 165px;
  }
  .community,
  .community-bottom {
    grid-template-columns: 1fr;
  }
  .community-main {
    padding: 30px;
    min-height: 400px;
  }
  .community-main h3 {
    font-size: 38px;
  }
  .tile h3 {
    font-size: 28px;
  }
  .social-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* ===== scootivearticles module - homepage teaser (.eta-wide), homepage
   "Porady techniczne" grid (.advice), category listing guide card
   (.guide-card), blog listing (.blog-*) and single article (.post-*) -
   ported from the prototype's home.css/category.css/blog.css/article.css,
   --line / --gray / --green mapped to this theme's --scootive-* tokens.
   .section/.section-head/.products/.info-item family/.cat-tag(new) already
   exist or are reused as-is. */
.eta-wide {
  min-height: 520px;
  display: grid;
  grid-template-columns: .84fr 1.16fr;
  background: #e8e8e2;
}
.eta-copy {
  padding: 72px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.eta-copy h2 {
  font-size: 64px;
  margin: 10px 0 20px;
}
.eta-copy p {
  color: var(--scootive-gray-700);
  line-height: 1.55;
  max-width: 460px;
  margin-bottom: 20px;
}
.eta-photo {
  min-height: 520px;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.advice {
  display: grid;
  grid-template-columns: 1.25fr 1fr 1fr;
  gap: 18px;
}
.article {
  display: block;
  background: #fff;
  border: 1px solid var(--scootive-line);
  text-decoration: none;
  color: inherit;
}
.article-img {
  height: 230px;
  background-size: cover;
  background-position: center;
  background-color: var(--scootive-gray-100);
}
.article-featured .article-img {
  height: 280px;
}
.article-body {
  padding: 24px;
}
.article-body h3 {
  font-size: 28px;
  margin: 8px 0;
}
.article-featured .article-body h3 {
  font-size: 38px;
}
.article-body p {
  font-size: 13px;
  line-height: 1.55;
  color: var(--scootive-gray-700);
}

.cat-tag {
  display: inline-block;
  background: var(--scootive-green);
  color: var(--scootive-ink);
  font-size: 9px;
  font-weight: 900;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 6px 10px;
}

.guide-card {
  grid-column: span 2;
  background: #111;
  color: #fff;
  min-height: 450px;
  padding: 36px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  position: relative;
  overflow: hidden;
  text-decoration: none;
}
.guide-card:before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, #000d, #0003), var(--guide-card-bg) center/cover;
  opacity: .62;
}
.guide-card > * {
  position: relative;
}
.guide-card .eyebrow {
  color: #fff;
}
.guide-card h2 {
  font-size: 48px;
  margin: 10px 0 14px;
  color: #fff;
}
.guide-card p {
  font-size: 12px;
  color: #ddd;
  max-width: 390px;
  line-height: 1.6;
}
.guide-link {
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  margin-top: 18px;
  display: inline-block;
}

.blog-head {
  padding: 54px 0 30px;
  max-width: 760px;
}
.blog-head h1 {
  font-size: 76px;
  margin: 8px 0 16px;
}
.blog-intro {
  font-size: 14px;
  line-height: 1.65;
  color: var(--scootive-gray-700);
}

.blog-filters-wrap {
  position: sticky;
  top: 0;
  z-index: 30;
  background: rgba(245, 245, 241, .97);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--scootive-line);
  border-bottom: 1px solid var(--scootive-line);
  margin: 0 calc(50% - 50vw);
  width: 100vw;
}
.blog-filters {
  display: flex;
  gap: 8px;
  padding: 14px 0;
  overflow-x: auto;
  width: min(var(--scootive-max), calc(100% - 64px));
  margin: 0 auto;
}
.blog-filter {
  height: 38px;
  padding: 0 16px;
  border: 1px solid var(--scootive-gray-400);
  background: #fff;
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  text-decoration: none;
  color: inherit;
  white-space: nowrap;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
}
.blog-filter:hover {
  border-color: var(--scootive-ink);
}
.blog-filter.active {
  background: var(--scootive-ink);
  color: #fff;
  border-color: var(--scootive-ink);
}

.blog-featured {
  padding: 40px 0 10px;
}
.featured-card {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  border: 1px solid var(--scootive-line);
  background: #fff;
  min-height: 420px;
  text-decoration: none;
  color: inherit;
}
.featured-img {
  background: var(--scootive-gray-100);
  overflow: hidden;
}
.featured-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.featured-body {
  padding: 40px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.featured-body .cat-tag {
  margin-bottom: 14px;
  width: fit-content;
}
.featured-body h2 {
  font-size: 38px;
  margin: 0 0 14px;
  line-height: 1;
}
.featured-body p {
  font-size: 13px;
  line-height: 1.6;
  color: var(--scootive-gray-700);
  max-width: 420px;
  margin-bottom: 22px;
}
.featured-meta {
  font-size: 9px;
  font-weight: 900;
  color: var(--scootive-gray-600);
  letter-spacing: .04em;
}

.blog-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 26px;
  padding: 40px 0 90px;
}
.blog-card {
  display: block;
  background: #fff;
  border: 1px solid var(--scootive-line);
  text-decoration: none;
  color: inherit;
}
.blog-card-img {
  aspect-ratio: 16 / 10;
  background: var(--scootive-gray-100);
  overflow: hidden;
}
.blog-card-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .3s ease;
}
.blog-card:hover .blog-card-img img {
  transform: scale(1.05);
}
.blog-card-body {
  padding: 22px;
}
.blog-card .cat-tag {
  font-size: 8px;
  padding: 5px 8px;
}
.blog-card h3 {
  font-size: 18px;
  margin: 12px 0 8px;
  line-height: 1.2;
}
.blog-card p {
  font-size: 12px;
  line-height: 1.55;
  color: var(--scootive-gray-600);
  margin: 0 0 14px;
}
.blog-card-meta {
  font-size: 9px;
  font-weight: 900;
  color: var(--scootive-gray-700);
  letter-spacing: .03em;
}

.post-head {
  max-width: 1070px;
  margin: 28px auto 0;
}
.post-head .cat-tag {
  margin-bottom: 18px;
}
.post-head h1 {
  font-size: 56px;
  margin: 0 0 26px;
  line-height: .98;
}
.post-author {
  display: flex;
  align-items: center;
  gap: 12px;
}
.post-author b {
  display: block;
  font-size: 12px;
}
.post-author span {
  display: block;
  font-size: 10px;
  color: var(--scootive-gray-600);
  margin-top: 2px;
}
.post-hero {
  margin: 36px 0;
  aspect-ratio: 2.2 / 1;
  background: var(--scootive-gray-100);
  overflow: hidden;
}
.post-hero img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.post-layout {
  max-width: 1070px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 760px) 240px;
  gap: 70px;
  align-items: start;
}
.post-faq-jump {
  display: block;
  border: 1px solid var(--scootive-ink);
  padding: 16px 18px;
  text-align: center;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .02em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--scootive-ink);
}
.post-faq-jump:hover {
  background: var(--scootive-ink);
  color: #fff;
}
.post-body {
  font-size: 15px;
  line-height: 1.85;
  color: var(--scootive-gray-800);
}
.post-body p {
  margin: 0 0 22px;
}
.post-body > p:first-child {
  font-size: 17px;
  line-height: 1.7;
  font-weight: 700;
  color: var(--scootive-ink);
}
.post-body ul,
.post-body ol {
  margin: 0 0 22px;
  padding-left: 22px;
}
.post-body ul {
  list-style: disc;
}
.post-body ol {
  list-style: decimal;
}
.post-body li {
  margin: 0 0 8px;
}
.post-body li p {
  margin: 0;
}
.post-body table {
  width: 100%;
  border-collapse: collapse;
  margin: 8px 0 32px;
  font-size: 13px;
}
.post-body table th,
.post-body table td {
  border: 1px solid var(--scootive-line);
  padding: 10px 12px;
  text-align: left;
}
.post-faq {
  margin: 54px auto 0;
  max-width: 1070px;
  scroll-margin-top: 160px;
}
.info-title {
  padding: 44px 0 26px;
  font-family: "Arial Black", Arial, sans-serif;
  font-size: 30px;
  letter-spacing: -.045em;
  line-height: 1;
  text-transform: uppercase;
}
@media (max-width: 1100px) {
  .info-title {
    padding-top: 34px;
    font-size: 27px;
  }
}
/* Prototype's own .post-related (src/assets/css/article.css) - sits
   BEFORE .post-more in the markup, so it keeps the prototype's smaller
   20px bottom padding (unlike .post-more below, which is the last section
   on the page and needs more room before the footer). Product cards reuse
   the site's own real .products grid + catalog/_partials/miniatures/
   product.tpl - no new card markup. */
.post-related {
  padding: 70px 0 20px;
  border-top: 1px solid var(--scootive-line);
  margin-top: 64px;
}
.post-more {
  padding: 70px 0 90px;
  border-top: 1px solid var(--scootive-line);
  margin-top: 64px;
}

@media (max-width: 1100px) {
  .eta-wide {
    grid-template-columns: minmax(0, 1fr);
  }
  .eta-copy {
    padding: 36px;
  }
  .eta-copy h2 {
    font-size: 40px;
  }
  .eta-photo {
    min-height: 220px;
  }
  .advice {
    grid-template-columns: 1fr;
  }
  .guide-card {
    grid-column: 1 / -1;
    min-height: 340px;
  }
  .guide-card h2 {
    font-size: 38px;
  }
  .blog-filters-wrap {
    top: 0;
  }
  .blog-head h1 {
    font-size: 44px;
  }
  .featured-card {
    grid-template-columns: 1fr;
    min-height: 0;
  }
  .featured-img {
    aspect-ratio: 16 / 10;
  }
  .featured-body {
    padding: 26px;
  }
  .blog-grid {
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    padding: 30px 0 60px;
  }
  .post-head h1 {
    font-size: 36px;
  }
  .post-hero {
    aspect-ratio: 16 / 10;
    margin: 26px 0;
  }
  .post-layout {
    grid-template-columns: 1fr;
    gap: 24px;
  }
  .post-faq-jump {
    order: -1;
    max-width: none;
    margin-bottom: 4px;
  }
}

/* ============================================================================
 * Batch-2 Tailwind CDN removal - new real CSS for catalog/product templates.
 * ========================================================================= */

/* catalog/_partials/product-variants.tpl - `.sr-only` was previously
   supplied by the Tailwind CDN. Visually hides the real <input
   type="radio"> for each color/size choice while keeping it screen-reader-
   and keyboard-accessible (the visible pill is the sibling .color-dot/
   .size span) - real accessibility behavior, not decorative. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

/* catalog/_partials/product-specs.tpl */
.nowrap {
  white-space: nowrap;
}
/* The combfeat module injects extra .specrow-shaped rows directly into this
   empty placeholder at runtime - display:contents keeps them acting as
   direct grid items of the parent .info-specgrid grid instead of being
   boxed inside this div (was Tailwind's class="contents"). */
[data-combfeat-features] {
  display: contents;
}

/* catalog/_partials/product-pack-items.tpl - ported from the prototype's
   own #bundleBlock (src/pages/product.html, assets/css/product.css lines
   1411-1449, class names kept verbatim). */
.bundle-list {
  display: grid;
  gap: 10px;
}
.bundle-item {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 14px;
  align-items: center;
  border: 1px solid var(--scootive-line);
  padding: 10px 14px;
  background: #fff;
}
.bundle-item img {
  width: 56px;
  height: 56px;
  object-fit: contain;
  mix-blend-mode: multiply;
  background: var(--scootive-gray-100);
}
.bundle-item strong {
  display: block;
  font-size: 12px;
  line-height: 1.35;
}
.bundle-item span {
  display: block;
  font-size: 10px;
  color: var(--scootive-gray-600);
  margin-top: 3px;
}
.qty-label {
  font-size: 11px;
  font-weight: 900;
  color: var(--scootive-gray-700);
  white-space: nowrap;
}

/* catalog/_partials/product-cover-thumbnails.tpl - the zoom button's icon
   relied on Tailwind's h-5 w-5 (20px); nothing else in .gallery/.stage sets
   an explicit icon size. */
.gallery .stage .zoom svg {
  width: 16px;
  height: 16px;
}

/* catalog/suppliers.tpl + miniatures/supplier.tpl - flat card matching this
   theme's own established card aesthetic (thin border, no shadow/rounding
   - same recipe as .card/.address-card/.summary-card), keeping the
   original card's image + "View products" button (a deliberate, narrower
   conversion than adopting manufacturers.tpl's brand.tpl look, which has
   neither - see suppliers.tpl's own comment). */
.supplier-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  border: 1px solid var(--scootive-line);
  background: #fff;
}
.supplier-card-image {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16 / 9;
  padding: 24px;
  border-bottom: 1px solid var(--scootive-line);
  background: var(--scootive-gray-50);
}
.supplier-card-image img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.supplier-card-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 20px;
}
.supplier-card-body h2 {
  font-size: 16px;
  font-weight: 900;
  flex: 1;
}
.supplier-card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--scootive-line);
  font-size: 12px;
  color: var(--scootive-gray-700);
}
.supplier-card-footer .btn-black {
  padding: 8px 14px;
  font-size: 10px;
}

/* catalog/_partials/product-images-modal.tpl - full real conversion of the
 * "Gallery lightbox modal" component, replacing the old #espeProductModal
 * Tailwind-class-override hack (already deleted from this file). Ported
 * from the prototype's own #lightbox (src/pages/product.html, assets/css/
 * product.css lines ~1452-1490), adapted for two differences that are
 * real, already-working behavior this pass did not change (editing
 * theme.js was out of scope for this .tpl-only conversion pass):
 *   1. theme.js's initEspeProductModal() shows/hides the modal by toggling
 *      the literal class names "opacity-0"/"pointer-events-none"/
 *      "opacity-100"/"pointer-events-auto" (not a simple .open class), and
 *      "overflow-hidden" on <body> for scroll-lock. Kept as-is, given real
 *      (non-Tailwind-CDN) definitions below instead of being renamed.
 *   2. theme.js also renders every thumbnail <button>/<img> itself, into
 *      two always-populated containers (desktop 2-col grid, mobile
 *      horizontal strip) using hardcoded utility-class strings for each
 *      generated thumb (including "border-brand-500" for the selected
 *      one). [data-espe-product-modal-thumb] is a real DOM attribute
 *      (not a class) used below as the real styling hook instead, so the
 *      real box shape doesn't depend on theme.js's own class names at all
 *      except for the unavoidable ".border-brand-500" selected-state hook.
 * A follow-up theme.js edit to emit real class names (removing both shims)
 * is a reasonable future cleanup but out of scope here. */
#espeProductModal.lightbox {
  position: fixed;
  inset: 0;
  z-index: 120;
  background: #fff;
  display: flex;
  flex-direction: column;
  transition: opacity .3s;
}
#espeProductModal.lightbox[hidden] {
  display: none !important;
}
/* JS-compat shim (see header comment, point 1) */
#espeProductModal.opacity-0 { opacity: 0; }
#espeProductModal.opacity-100 { opacity: 1; }
#espeProductModal.pointer-events-none { pointer-events: none; }
#espeProductModal.pointer-events-auto { pointer-events: auto; }
body.overflow-hidden { overflow: hidden; }

.lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: #fff;
}
.lightbox-inner {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}
.lightbox-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding: 28px 32px 0;
  flex-shrink: 0;
}
.lightbox-heading {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.lightbox-heading .eyebrow {
  color: var(--scootive-gray-700);
}
.lightbox-heading h3.display {
  font-size: 22px;
  margin: 0;
}
.lightbox-close {
  width: 40px;
  height: 40px;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  color: var(--scootive-ink);
  display: grid;
  place-items: center;
  cursor: pointer;
  flex-shrink: 0;
}
.lightbox-close:hover {
  border-color: #111;
}
.lightbox-close svg {
  width: 18px;
  height: 18px;
}
.lightbox-body {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 28px;
  padding: 24px 32px 32px;
  overflow-y: auto;
}
.lightbox-stagewrap {
  position: relative;
  min-width: 0;
  min-height: 0;
  display: grid;
  place-items: center;
  background: var(--scootive-gray-100);
}
.lightbox-stage {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
}
.lightbox-stage img {
  max-width: 82%;
  max-height: 78vh;
  object-fit: contain;
  mix-blend-mode: multiply;
  border-radius: 0;
}
.lightbox-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  border: 1px solid var(--scootive-gray-600);
  background: #fff;
  color: var(--scootive-ink);
  display: grid;
  place-items: center;
  cursor: pointer;
  z-index: 1;
}
.lightbox-arrow:hover {
  border-color: #111;
}
.lightbox-arrow svg {
  width: 18px;
  height: 18px;
}
.lightbox-prev { left: 16px; }
.lightbox-next { right: 16px; }

/* Desktop sidebar thumb rail - hidden below 1024px (this component's own
   pre-existing breakpoint, carried over from the old Tailwind lg: hack;
   the rest of the theme uses 1100px, but changing this component's own
   breakpoint wasn't part of this pass). */
.lightbox-side {
  display: none;
  min-height: 0;
  flex-direction: column;
}
.lightbox-side-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 9px;
  font-weight: 900;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--scootive-gray-600);
  margin-bottom: 12px;
}
.lightbox-thumbs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  overflow-y: auto;
  padding: 0;
}

/* Mobile thumb strip - own always-rendered container, shown only below
   1024px (see header comment, point 2). */
.lightbox-mobile-panel {
  border-top: 1px solid var(--scootive-line);
  padding: 16px 18px 22px;
  flex-shrink: 0;
}
.lightbox-mobile-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 9px;
  font-weight: 900;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--scootive-gray-600);
  margin-bottom: 12px;
}
.lightbox-thumbs--mobile {
  display: flex;
  grid-template-columns: none;
  gap: 8px;
  overflow-x: auto;
  overflow-y: visible;
}

/* JS-rendered thumb buttons/images (see header comment, point 2) - real
   box shape via the [data-espe-product-modal-thumb] attribute, independent
   of whatever class names theme.js still hardcodes onto each generated
   button. JS-compat shim: ".border-brand-500" below is theme.js's own
   selected-state class name, kept as-is. */
#espeProductModal [data-espe-product-modal-thumb] {
  aspect-ratio: 1;
  border: 1px solid var(--scootive-gray-600);
  background: var(--scootive-gray-100);
  display: grid;
  place-items: center;
  padding: 6px;
  cursor: pointer;
  border-radius: 0;
}
.lightbox-thumbs--mobile [data-espe-product-modal-thumb] {
  flex: 0 0 64px;
  width: 64px;
}
#espeProductModal [data-espe-product-modal-thumb].border-brand-500 {
  border: 2px solid #111;
  box-shadow: none;
}
#espeProductModal [data-espe-product-modal-thumb] img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
  border-radius: 0;
}

@media (min-width: 1024px) {
  .lightbox-body {
    grid-template-columns: 1fr 280px;
  }
  .lightbox-side {
    display: flex;
  }
  .lightbox-mobile-panel {
    display: none;
  }
}
@media (max-width: 1023px) {
  .lightbox-head {
    padding: 20px 18px 0;
  }
  .lightbox-heading h3.display {
    font-size: 17px;
  }
  .lightbox-body {
    padding: 16px 18px;
    gap: 0;
  }
  .lightbox-stage img {
    max-height: 44vh;
  }
  .lightbox-arrow {
    width: 36px;
    height: 36px;
  }
  .lightbox-prev { left: 8px; }
  .lightbox-next { right: 8px; }
}

/* ==================================================================
   ps_brandlist/views/templates/_partials/brand_text.tpl
   ==================================================================
   Infinite-scrolling brand-logo marquee. No 1:1 prototype exists for this
   (src/pages/home.html's own ".brands"/".brandrow" section is a static
   plain-text row of brand names, not a logo carousel), so this is a new
   component in the site's flat, sharp-corner language. Confirmed via DB
   (hook_module) that this template renders both on displayHome (wide) and
   displayRightColumn (narrow sidebar) - the horizontal-scroll strip clips
   cleanly to either container width, so one component serves both. The
   Smarty structure repeats the brand list 4x ({for $i=1 to 4}) with groups
   2-4 marked aria-hidden/tabindex="-1" - a standard seamless-marquee
   technique - so the CSS below animates the whole track exactly one
   group-width (-25%) and loops forever. No JS drives this. */
.brand-marquee {
  position: relative;
  overflow: hidden;
  padding: 22px 0;
}

/* Wider, softer edge fade (was a flat 80px cutoff) - a longer gradient
   distance reads as a gentler vignette instead of a hard curtain,
   especially now the logos themselves are smaller/lighter. */
.brand-marquee__fade {
  pointer-events: none;
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 1;
  width: 120px;
}

.brand-marquee__fade--left {
  left: 0;
  /* Was a hardcoded #fff - this strip actually sits on the page's own
     --scootive-bg (#f5f5f1, confirmed live via computed style), not white,
     so a flat white fade cut a visible seam against the real background. */
  background: linear-gradient(to right, var(--scootive-bg), color-mix(in srgb, var(--scootive-bg) 60%, transparent) 55%, transparent);
}

.brand-marquee__fade--right {
  right: 0;
  background: linear-gradient(to left, var(--scootive-bg), color-mix(in srgb, var(--scootive-bg) 60%, transparent) 55%, transparent);
}

.brand-marquee__track {
  display: flex;
  width: max-content;
  /* Was 32s - nudged up to keep the same real px/s scroll speed now that
     logos are smaller but gaps are wider (roughly the same group width
     overall), rather than the strip suddenly feeling like it sped up. */
  animation: brand-marquee-scroll 38s linear infinite;
}

/* Pause the scroll on hover so a curious visitor can actually read a logo
   instead of it sliding past - hovering any single logo already stops the
   whole track (not just that item), which reads as more predictable than
   only pausing under the cursor's exact logo. */
.brand-marquee:hover .brand-marquee__track {
  animation-play-state: paused;
}

.brand-marquee__group {
  display: flex;
  align-items: center;
  gap: 72px;
  padding: 0 36px;
  margin: 0;
  list-style: none;
}

.brand-marquee__item {
  flex-shrink: 0;
  margin: 0;
  list-style: none;
}

.brand-marquee__link {
  display: flex;
  align-items: center;
  justify-content: center;
}

.brand-marquee__logo {
  height: 56px;
  width: auto;
  object-fit: contain;
  /* Brand logos come in from many different sources/exports at full
     saturation - a light grayscale-until-hover treatment reads as more
     "lekkie" (lightweight) than a busy row of full-color marks, matching
     the flat, quiet rest of the footer area instead of competing with it. */
  filter: grayscale(1) opacity(0.55);
  transition: filter 0.2s ease;
}
.brand-marquee__link:hover .brand-marquee__logo {
  filter: grayscale(0) opacity(1);
}

@keyframes brand-marquee-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-25%); }
}

@media (max-width: 700px) {
  .brand-marquee { padding: 16px 0; }
  .brand-marquee__logo { height: 40px; }
  .brand-marquee__group { gap: 48px; padding: 0 24px; }
  .brand-marquee__fade { width: 56px; }
}

/* ==================================================================
   blockreassurance module - blockreassurance.tpl, displayBlock.tpl,
   displayBlockProduct.tpl
   ==================================================================
   All three render the same "icon + title + description" reassurance /
   trust-badge row, from two data sources (blockreassurance.tpl's own
   $elements from the Psreassurance repository, vs. displayBlock(Product)
   .tpl's $blocks). Unified into one shared component so all placements
   look identical. blockreassurance.tpl (id="block-reassurance") is
   rendered live via the generic Module::renderWidget() path on the
   displayProductAdditionalInfo hook (confirmed via hook_module - it has no
   own hookDisplayProductAdditionalInfo() method, so core falls back to
   templateFile). displayBlock.tpl / displayBlockProduct.tpl keep class=
   "blockreassurance_product" on their root <div> - NOT a Tailwind class:
   blockreassurance's own views/dist/front.js does
   `$(".blockreassurance_product img.svg, .blockreassurance img.svg")`
   literally by this class name. The "svg"/"invisible" classes on the <img>
   are also functional: front.js fetches the icon's own URL, injects a real
   inlined <svg> via jQuery .replaceWith(), and only then removes
   "invisible" from the clone - scoped below with the exact selector shape
   front.js itself uses, never a generic sitewide utility. .reassurance-icon
   is a plain class (not img.reassurance-icon) because front.js's
   replaceWith() clones the original <img>'s class list onto the injected
   inline <svg> - it must size correctly whichever element it ends up on. */
.reassurance-list {
  display: flex;
  flex-direction: column;
  list-style: none;
  margin: 0;
  padding: 0;
}

.reassurance-item {
  border-top: 1px solid var(--scootive-line);
}

.reassurance-item:last-child {
  border-bottom: 1px solid var(--scootive-line);
}

.reassurance-row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  padding: 14px 0;
}

.reassurance-icon-slot {
  flex-shrink: 0;
}

.reassurance-icon {
  display: block;
  width: 20px;
  height: 20px;
  padding: 8px;
  box-sizing: content-box;
  background: var(--scootive-gray-100);
  object-fit: contain;
  flex-shrink: 0;
}

/* Scoped exactly like blockreassurance's own front.js selector (see
   comment above) - not a generic ".invisible" utility. */
.blockreassurance_product img.svg.invisible,
.blockreassurance img.svg.invisible {
  visibility: hidden;
}

.reassurance-copy {
  min-width: 0;
}

.reassurance-title {
  display: block;
  margin: 0;
  font-size: 12px;
  font-weight: 900;
  line-height: 1.3;
  color: var(--scootive-ink);
}

.reassurance-text {
  display: block;
  margin: 2px 0 0;
  font-size: 11px;
  line-height: 1.4;
  color: var(--scootive-gray-600);
}

.reassurance-text:empty {
  display: none;
}

/* Only displayBlock.tpl's "above/below header" placement had its own
   horizontal breathing room in the original markup - displayBlockProduct
   .tpl and blockreassurance.tpl already sit inside an already-padded
   parent slot. Preserved that one difference via this modifier class. */
.reassurance-block--padded {
  padding: 24px;
}

/* ==================================================================
   ps_searchbar/ps_searchbar.tpl
   ==================================================================
   Header search-suggestion dropdown - NOT the search input itself, only
   the results dropdown panel below it. No live-typeahead JS exists yet
   (ps_searchbar.js is an empty stub, deferred deliberately per project
   plan). This conversion only gives the server-rendered dropdown markup
   its real, flat classes and a working hidden-by-default state, ready for
   that future JS to toggle .is-open. */
#_desktop_search {
  width: 100%;
}

.search-widgets {
  position: relative;
  width: 100%;
}

.search-widgets__dropdown {
  display: none;
  position: absolute;
  left: 0;
  top: 100%;
  /* .mega (glowne mega-menu nawigacji) ma z-index:120 i geometrycznie
     pokrywa dokladnie ten sam obszar headera (position:absolute na cala
     szerokosc, zaczyna sie tuz pod rzedem nawigacji) - jesli z jakiegokolwiek
     powodu stanie sie aktywne (np. mysz musnela kategorie tuz przed
     kliknieciem w wyniki wyszukiwania), wygrywalo nad tym dropdownem mimo
     ze wizualnie niewidoczne (znaleziono live przez Inspect w Firefoksie:
     klik w "pierwszy wynik" trafial w div.mega-links zupelnie innej
     kategorii). Wyzszy z-index niz .mega gwarantuje, ze ten dropdown zawsze
     wygrywa hit-testing, niezaleznie od stanu mega-menu. */
  z-index: 130;
  margin-top: 8px;
  width: 100%;
  border: 1px solid var(--scootive-line);
  background: #fff;
  overflow: hidden;
}

.search-widgets__dropdown.is-open {
  display: block;
}

.search-widgets__results {
  list-style: none;
  margin: 0;
  padding: 0;
}

.search-widgets__results li + li {
  border-top: 1px solid var(--scootive-line);
}

/* Live-suggestion content inside .search-widgets__results, added once
   ps_searchbar.js (theme override) was finally built - see that file's own
   header comment for the 3 data sources (core search, wetwosearch module,
   localStorage). Sharp corners / --scootive-* tokens / uppercase micro-labels,
   matching every other card-ish component on the site (.asst-card, .brand-card). */
.search-widgets__section-label {
  padding: 10px 14px 6px;
  font-size: 9px;
  font-weight: 900;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--scootive-gray-600);
}
.search-widgets__result {
  cursor: pointer;
}
.search-widgets__result a {
  display: flex;
  align-items: center;
  width: 100%;
  gap: 10px;
  padding: 9px 14px;
  color: var(--scootive-ink);
  text-decoration: none;
  pointer-events: none;
}
.search-widgets__result:hover {
  background: var(--scootive-gray-50);
}

.search-widgets__result--category .swr-cat-name {
  flex: 1;
  font-size: 12px;
}
.search-widgets__result--category .swr-cat-count {
  font-size: 10px;
  color: var(--scootive-gray-600);
}

.search-widgets__result--recent {
  display: flex;
  align-items: center;
}
.search-widgets__result--recent a {
  flex: 1;
  width: auto;
}
.search-widgets__result--recent span {
  font-size: 12px;
}
.search-widgets__result--recent .swr-remove {
  flex: none;
  width: 36px;
  height: 36px;
  border: 0;
  background: none;
  color: var(--scootive-gray-600);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  pointer-events: auto;
}
.search-widgets__result--recent .swr-remove:hover {
  color: var(--scootive-ink);
}

.search-widgets__result--article .swr-article-title {
  font-size: 12px;
}

.search-widgets__result--product .swr-thumb {
  width: 40px;
  height: 40px;
  object-fit: contain;
  background: #ecece7;
  mix-blend-mode: multiply;
  flex: none;
}
.search-widgets__result--product .swr-thumb--empty {
  background: #ecece7;
}
.search-widgets__result--product .swr-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.search-widgets__result--product .swr-brand {
  font-size: 9px;
  font-weight: 900;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--scootive-gray-700);
}
.search-widgets__result--product .swr-name {
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.search-widgets__result--product .swr-price {
  font-size: 12px;
  font-weight: 900;
  white-space: nowrap;
}

.search-widgets__seeall a {
  display: flex;
  justify-content: center;
  padding: 14px;
  font-size: 10px;
  font-weight: 900;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--scootive-ink);
  background: var(--scootive-gray-50);
}
.search-widgets__seeall a:hover {
  background: var(--scootive-gray-100);
}
.search-widgets__empty {
  padding: 14px;
  font-size: 12px;
  color: var(--scootive-gray-600);
}

/* ==================================================================
   ps_linklist/views/templates/hook/linkblock.tpl
   (displayNav1 branch only - the displayFooter branch was already real)
   ==================================================================
   1:1 prototype match (src/partials/header.html): bare <a> tags, no
   wrapper div. .subnav .wrap already supplies display:flex/gap/align-items
   for this spot. whitespace-nowrap had no existing equivalent (.subnav has
   a fixed 36px height) - added below. Hover treatment: underline-on-hover,
   matching the pattern already used for .block-categories__title a and
   .footer-contact-link. */
.subnav .wrap a {
  white-space: nowrap;
}

.subnav .wrap a:hover {
  text-decoration: underline;
}

/* ==================================================================
   orbitvuviewer module - "360°" badges restyled to match the theme's own
   flat, sharp-corner .badge component instead of the module's own rounded-
   pill defaults. Both badges are generated by inline <style>/JS the module
   injects itself (orbitvuviewer.php renderListingBadgeScript() and the
   product-page gallery script) - overridden here via a theme stylesheet
   rather than editing the vendored module, same convention as every other
   third-party-module restyle in this project. !important is needed because
   the module's own rules are also injected inline per-page and cascade
   order between the two is not guaranteed.

   Listing-card badge (.ovv-list-badge): the module tries to reuse this
   theme's own top-right flag stack via Tailwind utility classes
   (.absolute.right-5.top-5.z-20.flex.flex-col.items-end). That combination
   IS still genuinely styled on some card templates (e.g. the homepage
   "new products" widget - real Tailwind output survives there), but NOT on
   others (the plain catalog listing grid), where it has zero effect and
   the badge fell into normal document flow below the color swatches
   instead of sitting on the image. First attempt forced position:absolute
   directly on the badge itself, which "fixed" the listing grid but broke
   the homepage widget (the badge got yanked out of the working flex stack
   there and mispositioned instead). Correct fix: supply the missing
   utility behavior on the STACK CONTAINER only, so the module's own
   flex-stack script logic behaves identically whether or not this theme
   happens to still style that exact Tailwind class combination elsewhere -
   the badge itself only gets restyled (color/shape/type), never
   repositioned. top/right set to 10px (not Tailwind's 1.25rem/20px) to
   land exactly on the theme's own .badge/.badge--new offset, so "NOWY"
   and "360°" sit as a matched pair. */
.absolute.right-5.top-5.z-20.flex.flex-col.items-end {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 20;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}

.ovv-list-badge {
  background: #161614 !important;
  border-radius: 0 !important;
  padding: 6px 8px !important;
  font-size: 8px !important;
  font-weight: 900 !important;
  letter-spacing: .02em;
  text-transform: uppercase;
}

/* Product-page gallery thumbnail rail badge (.ovv-thumb-360-badge) - same
   sharp-corner treatment, kept in place (bottom-left of the thumbnail
   square) since that spot doesn't collide with anything. */
.ovv-thumb-360-badge {
  border-radius: 0 !important;
}
