:root {
  /* --------------------------------------------------------------------
     Marketing palette: the structural language of ripplefzco.com (warm
     off-white canvas, deep near-black panels, big display type, generous
     rhythm) carrying OUR brand accent -- Console gold #F5A501 from
     tokens.css -- wherever the reference uses its red. That substitution
     is the whole point: the layout language is borrowed, the identity
     stays Ayn Al Fahad.
     -------------------------------------------------------------------- */

  /* Warm neutrals (reference) */
  --lp-canvas:     #FBFAF8;
  --lp-sand:       #F0EBE1;
  --lp-sand-deep:  #EEEAE4;
  --lp-line:       #E7E4DF;
  --lp-line-soft:  #F1EDE7;

  /* Ink ramp (reference) */
  --lp-ink:        #14110F;
  --lp-ink-soft:   #46403A;
  --lp-muted:      #6E6A66;
  --lp-faint:      #9A958F;

  /* Dark panels (reference) — used for alternating bands and the footer */
  --lp-panel:      #241F1A;
  --lp-panel-2:    #1E1A17;
  --lp-deepest:    #000000;
  --lp-on-dark:        #F4F1EC;
  --lp-on-dark-muted:  #B7B0A7;
  --lp-on-dark-faint:  #8A847B;
  --lp-line-on-dark:   #332D27;

  /* OUR accent — system Console gold, not the reference red */
  --lp-accent:      #F5A501;
  --lp-accent-hover:#DB9300;
  --lp-accent-ink:  #8A5D00;   /* gold text on light surfaces */
  --lp-accent-soft: #FCEFCF;
  --lp-accent-ring: rgba(245, 165, 1, .5);
  --lp-on-accent:   #1C1917;   /* ink reads on gold, never white */

  --lp-radius:    12px;
  --lp-radius-lg: 20px;

  /* Warm shadows only — never pure black, matching DESIGN.md's rule */
  --lp-shadow-sm: 0 1px 2px rgba(32, 24, 18, .06), 0 2px 8px rgba(32, 24, 18, .04);
  --lp-shadow-md: 0 8px 24px rgba(32, 24, 18, .09);
  --lp-shadow-lg: 0 24px 60px rgba(32, 24, 18, .16);
  --lp-shadow-gold: 0 2px 14px rgba(245, 165, 1, .32);

  --lp-shell:  1240px;
  --lp-gutter: 24px;

  --lp-ease:      cubic-bezier(.22, .61, .36, 1);
  --lp-ease-out:  cubic-bezier(.16, 1, .3, 1);
  --lp-fast:      .18s;
  --lp-base:      .34s;
  --lp-slow:      .7s;

  /* Sora for display (the reference's own face), Inter for body copy */
  --lp-display: 'Sora', 'Inter', system-ui, sans-serif;
  --lp-font:    'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --lp-font-ar: 'Noto Kufi Arabic', 'Inter', system-ui, sans-serif;
}

[dir="rtl"] { --lp-font: var(--lp-font-ar); --lp-display: var(--lp-font-ar); }

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

.lp-body {
  margin: 0;
  font-family: var(--lp-font);
  color: var(--lp-ink-soft);
  background: var(--lp-canvas);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.lp-body img { max-width: 100%; display: block; }

.lp-shell {
  width: 100%;
  max-width: var(--lp-shell);
  margin-inline: auto;
  padding-inline: var(--lp-gutter);
}

/* ---------- Motion primitives -------------------------------------------
   Two classes cover almost every entrance on the page. `lp-reveal` is armed
   by IntersectionObserver in landing.js; `lp-rise` fires immediately (used
   inside the hero, which is above the fold). Both honour reduced-motion.    */

.lp-reveal {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition:
    opacity var(--lp-slow) var(--lp-ease-out) var(--lp-delay, 0ms),
    transform var(--lp-slow) var(--lp-ease-out) var(--lp-delay, 0ms);
  will-change: opacity, transform;
}
.lp-reveal.is-visible { opacity: 1; transform: none; }

@keyframes lp-rise-in {
  from { opacity: 0; transform: translate3d(0, 22px, 0); }
  to   { opacity: 1; transform: none; }
}
.lp-rise {
  opacity: 0;
  animation: lp-rise-in .85s var(--lp-ease-out) forwards;
  animation-delay: var(--lp-delay, 0ms);
}

@media (prefers-reduced-motion: reduce) {
  .lp-reveal, .lp-rise { opacity: 1 !important; transform: none !important; animation: none !important; transition: none !important; }
  * { scroll-behavior: auto !important; }
}

/* ---------- Buttons & links ---------------------------------------------- */

.lp-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 22px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--lp-fast) var(--lp-ease),
              box-shadow var(--lp-base) var(--lp-ease),
              background-color var(--lp-fast) var(--lp-ease);
}
.lp-btn--lg { padding: 16px 30px; font-size: 15px; }
.lp-btn--primary { background: var(--lp-ink); color: #fff; }
.lp-btn--primary:hover { background: #000; transform: translateY(-2px); box-shadow: var(--lp-shadow-md); }
.lp-btn--accent { background: var(--lp-accent); color: var(--lp-on-accent); }
.lp-btn--accent:hover { background: var(--lp-accent-hover); transform: translateY(-2px); box-shadow: var(--lp-shadow-gold); }
.lp-btn--light { background: #fff; color: var(--lp-ink); }
.lp-btn--light:hover { transform: translateY(-2px); box-shadow: var(--lp-shadow-lg); }
.lp-btn:active { transform: translateY(0); }

.lp-btn__arrow { transition: transform var(--lp-base) var(--lp-ease); }
.lp-btn:hover .lp-btn__arrow { transform: translateX(4px); }
[dir="rtl"] .lp-btn__arrow { transform: scaleX(-1); }
[dir="rtl"] .lp-btn:hover .lp-btn__arrow { transform: scaleX(-1) translateX(4px); }

.lp-link {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--lp-ink); font-weight: 600; font-size: 14px; text-decoration: none;
  transition: gap var(--lp-base) var(--lp-ease), color var(--lp-fast) var(--lp-ease);
}
.lp-link:hover { color: var(--lp-accent-ink); gap: 10px; }
[dir="rtl"] .lp-link svg { transform: scaleX(-1); }

/* ---------- Header -------------------------------------------------------- */

.lp-header {
  position: static; z-index: 60;
  background: color-mix(in srgb, var(--lp-header-bg, var(--lp-canvas)) 82%, transparent);
  color: var(--lp-header-fg, var(--lp-ink));
  backdrop-filter: saturate(1.6) blur(14px);
  border-block-end: 1px solid transparent;
  transition: border-color var(--lp-base) var(--lp-ease), box-shadow var(--lp-base) var(--lp-ease);
}
.lp-header.is-stuck { border-block-end-color: var(--lp-line); box-shadow: var(--lp-shadow-sm); }
.lp-header__inner { display: flex; align-items: center; gap: 28px; height: 72px; }
.lp-header__brand { display: flex; align-items: center; }
.lp-header.is-sticky { position: sticky; inset-block-start: 0; }
.lp-header__logo { height: var(--lp-logo-h, 30px); width: auto; }
.lp-header__nav { display: flex; align-items: center; gap: 26px; margin-inline-start: 12px; }
.lp-header__link {
  position: relative; color: color-mix(in srgb, var(--lp-header-fg, var(--lp-ink)) 72%, transparent); font-size: 14px; font-weight: 500; text-decoration: none;
  transition: color var(--lp-fast) var(--lp-ease);
}
.lp-header__link::after {
  content: ''; position: absolute; inset-block-end: -6px; inset-inline-start: 0;
  width: 100%; height: 2px; background: var(--lp-accent);
  transform: scaleX(0); transform-origin: inline-start;
  transition: transform var(--lp-base) var(--lp-ease-out);
}
.lp-header__link:hover { color: var(--lp-header-fg, var(--lp-ink)); }
.lp-header__link:hover::after { transform: scaleX(1); }
.lp-header__actions { display: flex; align-items: center; gap: 12px; margin-inline-start: auto; }

.lp-lang { position: relative; }
.lp-lang__btn {
  display: inline-flex; align-items: center; gap: 5px;
  background: none; border: 1px solid var(--lp-line); border-radius: 999px;
  padding: 8px 12px; font: inherit; font-size: 13px; font-weight: 600;
  color: var(--lp-ink-soft); cursor: pointer;
  transition: border-color var(--lp-fast) var(--lp-ease), color var(--lp-fast) var(--lp-ease);
}
.lp-lang__btn:hover { border-color: var(--lp-ink); color: var(--lp-ink); }
.lp-lang__menu {
  position: absolute; inset-block-start: calc(100% + 8px); inset-inline-end: 0;
  min-width: 150px; margin: 0; padding: 6px; list-style: none;
  background: #fff; border: 1px solid var(--lp-line); border-radius: 12px;
  box-shadow: var(--lp-shadow-md); z-index: 10;
}
.lp-lang__item {
  display: block; padding: 9px 12px; border-radius: 8px;
  font-size: 14px; color: var(--lp-ink-soft); text-decoration: none;
}
.lp-lang__item:hover { background: var(--lp-sand); color: var(--lp-ink); }
.lp-lang__item.is-active { color: var(--lp-accent-ink); font-weight: 600; }

.lp-header__burger { display: none; flex-direction: column; gap: 5px; background: none; border: 0; padding: 8px; cursor: pointer; }
.lp-header__burger span { display: block; width: 20px; height: 2px; background: var(--lp-header-fg, var(--lp-ink)); border-radius: 2px; }

/* ---------- Section furniture -------------------------------------------- */

/* The home page's list of sections (landing/index + the builder preview). A
   flex column, because in a flex container neighbouring margins do not
   collapse: a section's margin bottom and the next one's margin top are both
   applied in full, rather than the larger silently swallowing the smaller. */
.lp-blocks { display: flex; flex-direction: column; }
/* flow-root keeps a child's margin inside its section, so a section's own
   spacing settings are the only thing deciding the gap around it. */
.lp-widget { display: flow-root; }
.lp-widget + .lp-widget { margin-block-start: clamp(48px, 7vw, 96px); }
.lp-widget--banner + .lp-widget { margin-block-start: clamp(40px, 5vw, 72px); }
.lp-widget--spacer + .lp-widget, .lp-widget--countdown + .lp-widget { margin-block-start: 0; }
/* A banner is full-bleed art, so it sits flush against whatever precedes it
   rather than floating in a strip of canvas. Without this a hero reads as
   "attached to the top of the page" only while it happens to be the FIRST
   section -- put a stories row above it and it inherits the default rhythm.
   An explicit Margin top on the section still wins (see the end of the file). */
.lp-widget + .lp-widget--banner { margin-block-start: 0; }

.lp-section__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; margin-block-end: 28px;
}
.lp-section__tools { display: flex; align-items: center; gap: 16px; flex-shrink: 0; }
.lp-section__title {
  margin: 0;
  font-family: var(--lp-display);
  font-size: clamp(26px, 3.4vw, 42px); font-weight: 700; letter-spacing: -.028em;
  color: var(--lp-ink); line-height: 1.1;
}
.lp-section__subtitle { margin: 8px 0 0; font-size: 15px; color: var(--lp-muted); max-width: 62ch; }

/* ---------- Banner -------------------------------------------------------- */

.lp-banner { position: relative; overflow: hidden; background: var(--lp-panel); display: flex; }
/* Heights track the ratios the upload slots ask for, so a correctly sized
   image fills the frame with nothing cropped away:
     desktop 1920x800 (12:5) · tablet 1024x720 (64:45) · mobile 720x900 (4:5)
   `cover` then has nothing to trim. If an admin supplies an odd size it still
   fills rather than letterboxing — the ratio is the contract, stated on the
   field itself. */
.lp-banner--small  { min-height: 340px; }
.lp-banner--medium { min-height: 480px; }
.lp-banner--large  { aspect-ratio: 12 / 5; min-height: 420px; }
.lp-banner--full   { min-height: calc(100vh - 72px); }
/* Admin-entered height (px or vh), with its own mobile value. min-height, like
   the presets, so a tall headline still grows the banner rather than being
   clipped; the text padding shrinks with it so a short banner stays short. */
.lp-banner--custom { min-height: var(--lp-banner-h, 480px); }
.lp-banner--custom .lp-banner__content { padding-block: clamp(24px, 5vw, 88px); }

/* Boxed: inside the page shell, rounded, with a little air above it. */
.lp-banner-shell { padding-block-start: clamp(12px, 2vw, 24px); }
.lp-banner--boxed { border-radius: var(--lp-radius-lg); isolation: isolate; }

@media (max-width: 1024px) {
  .lp-banner--large { aspect-ratio: 64 / 45; }
}
@media (max-width: 640px) {
  .lp-banner--large  { aspect-ratio: 4 / 5; }
  .lp-banner--small,
  .lp-banner--medium { aspect-ratio: 4 / 5; min-height: 0; }
  .lp-banner--custom { min-height: var(--lp-banner-h-m, var(--lp-banner-h, 420px)); }
  .lp-banner--boxed { border-radius: var(--lp-radius); }
}

.lp-banner__track { position: relative; flex: 1 1 auto; display: flex; }
.lp-banner__slide {
  position: absolute; inset: 0;
  display: flex; align-items: center; width: 100%;
  opacity: 0; visibility: hidden;
  transition: opacity 1s var(--lp-ease-out), visibility 1s;
}
.lp-banner__slide.is-active { position: relative; opacity: 1; visibility: visible; flex: 1 1 auto; }

.lp-banner__media {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
  /* Slow drift keeps a static hero from feeling dead without distracting. */
  animation: lp-kenburns 18s var(--lp-ease) forwards;
}
@keyframes lp-kenburns { from { transform: scale(1.06); } to { transform: scale(1); } }

/* Overlay colour and strength are both per slide. Every stop is a MULTIPLE of
   the chosen strength rather than an offset from it, so setting the opacity to
   0 leaves the background completely untouched -- which is what an admin who
   picked a flat brand colour expects. */
.lp-banner__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(
    to top,
    rgba(var(--lp-banner-overlay-rgb, 10,8,6), calc(var(--lp-banner-overlay, .45) * 1.6)) 0%,
    rgba(var(--lp-banner-overlay-rgb, 10,8,6), var(--lp-banner-overlay, .45)) 55%,
    rgba(var(--lp-banner-overlay-rgb, 10,8,6), calc(var(--lp-banner-overlay, .45) * .5)) 100%);
}
.lp-banner__media--color { position: absolute; inset: 0; display: block; }
.lp-banner__slide > video.lp-banner__media { object-fit: cover; }

/* Text block: the admin places it on both axes, sets its own colour and
   scales it, all per slide -- one deck often mixes a photo, a video and a
   flat colour, and each needs different treatment to stay readable. */
.lp-banner__slide { --lp-banner-scale: 1; }
.lp-banner__slide--y-top    { align-items: flex-start; }
.lp-banner__slide--y-middle { align-items: center; }
.lp-banner__slide--y-bottom { align-items: flex-end; }

.lp-banner__content {
  position: relative; padding-block: 88px;
  color: var(--lp-banner-text, #fff);
  max-width: 720px;
  font-size: calc(1em * var(--lp-banner-scale));
}
/* Alignment of the text INSIDE the block. Where the block itself sits is the
   --x-* classes below; both setting margins is what made them fight. */
.lp-banner__content--start  { text-align: start; }
.lp-banner__content--center { text-align: center; }
.lp-banner__content--end    { text-align: end; }

/* Both sides must be named. .lp-shell already sets `margin-inline: auto`, so
   overriding only ONE side leaves the other one auto and the block stays
   centred -- which is exactly why "start" rendered in the middle. */
.lp-banner__slide--x-start  .lp-banner__content { margin-inline: 0 auto; }
.lp-banner__slide--x-center .lp-banner__content { margin-inline: auto; }
.lp-banner__slide--x-end    .lp-banner__content { margin-inline: auto 0; }

/* Copy inherits the slide's colour and scale rather than hardcoding white. */
.lp-banner__eyebrow,
.lp-banner__headline,
.lp-banner__body { color: inherit; }
/* Each line multiplies the slide's overall scale by its own. Both default to
   1, so a slide saved before the per-line controls existed renders unchanged.
   The clamp() stays inside the calc so the headline keeps scaling with the
   viewport -- the admin's percentage tunes that curve, it does not replace it. */
.lp-banner__eyebrow {
  margin: 0 0 14px; font-weight: 600;
  font-size: calc(12px * var(--lp-banner-scale) * var(--lp-banner-eyebrow-scale, 1));
  letter-spacing: .16em; text-transform: uppercase; opacity: .82;
}
.lp-banner__headline {
  margin: 0; font-family: var(--lp-display);
  font-size: calc(clamp(34px, 5.8vw, 72px) * var(--lp-banner-scale) * var(--lp-banner-headline-scale, 1));
  font-weight: 700;
  line-height: 1.02; letter-spacing: -.035em; color: #fff;
}
.lp-banner__body {
  margin: 18px 0 30px;
  font-size: calc(clamp(15px, 1.5vw, 18px) * var(--lp-banner-scale) * var(--lp-banner-body-scale, 1));
  line-height: 1.6; opacity: .88; max-width: 54ch;
}
.lp-banner__content--center .lp-banner__body { margin-inline: auto; }

.lp-banner__nav {
  position: absolute; inset-block-start: 50%; translate: 0 -50%;
  display: grid; place-items: center; width: 46px; height: 46px;
  background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.28);
  color: #fff; border-radius: 50%; cursor: pointer; z-index: 3;
  backdrop-filter: blur(6px);
  transition: background-color var(--lp-fast) var(--lp-ease), transform var(--lp-fast) var(--lp-ease);
}
.lp-banner__nav:hover { background: rgba(255,255,255,.28); transform: translateY(-50%) scale(1.06); }
.lp-banner__nav--prev { inset-inline-start: 20px; }
.lp-banner__nav--next { inset-inline-end: 20px; }
[dir="rtl"] .lp-banner__nav svg { transform: scaleX(-1); }

.lp-banner__dots {
  position: absolute; inset-block-end: 26px; inset-inline: 0;
  display: flex; justify-content: center; gap: 8px; z-index: 3;
}
.lp-banner__dot {
  width: 26px; height: 3px; border: 0; border-radius: 2px; padding: 0;
  background: rgba(255,255,255,.4); cursor: pointer;
  transition: background-color var(--lp-base) var(--lp-ease), width var(--lp-base) var(--lp-ease);
}
.lp-banner__dot.is-active { background: #fff; width: 42px; }

/* ---------- Stories ------------------------------------------------------- */

/* --lp-story-size is the circle diameter (StoriesWidget: small / medium / large
   / custom px); the column around each circle is 8px wider. */
.lp-stories { --lp-story-size: 84px; }
.lp-stories .lp-section__head { margin-block-end: 20px; }
.lp-stories__row {
  display: flex; gap: 22px; margin: 0; padding: 4px 0 8px; list-style: none;
  overflow-x: auto; scrollbar-width: none;
}
.lp-stories__row::-webkit-scrollbar { display: none; }
/* Centre / end use auto margins rather than justify-content: when the row
   overflows, auto margins collapse to zero, so the first story stays
   reachable by scrolling -- justify-content would push it off-screen. */
.lp-stories--center .lp-stories__item:first-child,
.lp-stories--end .lp-stories__item:first-child { margin-inline-start: auto; }
.lp-stories--center .lp-stories__item:last-child { margin-inline-end: auto; }
.lp-stories--center .lp-stories__head { justify-content: center; align-items: center; text-align: center; }
.lp-stories--end .lp-stories__head { justify-content: flex-end; align-items: flex-end; text-align: end; }
.lp-stories__btn { background: none; border: 0; padding: 0; cursor: pointer; text-align: center; width: calc(var(--lp-story-size) + 8px); }
.lp-stories__ring {
  display: grid; place-items: center; width: var(--lp-story-size); height: var(--lp-story-size); border-radius: 50%;
  padding: 3px; margin-inline: auto;
  background: conic-gradient(from 210deg, var(--lp-story-ring, #F5A501), #FFD37A, var(--lp-story-ring, #F5A501));
  transition: transform var(--lp-base) var(--lp-ease-out);
}
.lp-stories__btn:hover .lp-stories__ring { transform: scale(1.07) rotate(4deg); }
.lp-stories__btn:active .lp-stories__ring { transform: scale(.97); }
.lp-stories__avatar {
  display: block; width: 100%; height: 100%; border-radius: 50%;
  overflow: hidden; border: 3px solid var(--lp-canvas); background: var(--lp-sand);
}
.lp-stories__avatar img { width: 100%; height: 100%; object-fit: cover; }
.lp-stories__label {
  display: block; margin-block-start: 9px; font-size: 12.5px; font-weight: 500; color: var(--lp-ink-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Full-screen story viewer */
.lp-story-viewer {
  position: fixed; inset: 0; z-index: 200;
  background: #0B0908; display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity var(--lp-base) var(--lp-ease);
}
.lp-story-viewer.is-open { opacity: 1; }
.lp-story-viewer__stage { position: relative; width: min(440px, 100%); height: 100%; max-height: 100vh; }
.lp-story-viewer__img { width: 100%; height: 100%; object-fit: cover; }
.lp-story-viewer__bars { position: absolute; inset-block-start: 12px; inset-inline: 12px; display: flex; gap: 4px; z-index: 3; }
.lp-story-viewer__bar { flex: 1; height: 3px; background: rgba(255,255,255,.3); border-radius: 2px; overflow: hidden; }
.lp-story-viewer__fill { display: block; height: 100%; width: 0; background: #fff; }
.lp-story-viewer__caption {
  position: absolute; inset-block-end: 0; inset-inline: 0; padding: 60px 22px 30px; color: #fff;
  background: linear-gradient(to top, rgba(0,0,0,.78), transparent);
}
.lp-story-viewer__caption h3 { margin: 0 0 6px; font-size: 20px; font-weight: 700; }
.lp-story-viewer__caption p { margin: 0; font-size: 14px; color: rgba(255,255,255,.82); }
.lp-story-viewer__close {
  position: absolute; inset-block-start: 22px; inset-inline-end: 16px; z-index: 4;
  width: 38px; height: 38px; display: grid; place-items: center;
  background: rgba(255,255,255,.16); border: 0; border-radius: 50%; color: #fff; cursor: pointer;
}
.lp-story-viewer__zone { position: absolute; inset-block: 0; width: 33%; z-index: 2; background: none; border: 0; cursor: pointer; }
.lp-story-viewer__zone--prev { inset-inline-start: 0; }
.lp-story-viewer__zone--next { inset-inline-end: 0; }

/* ---------- Product / generic carousel ------------------------------------ */

/* Clipped sideways only, where the browser can: a product card's hover lift and
   glow reach above and below the track, and overflow:hidden would shave them
   off. Nothing here adds or removes vertical space, so the widget's height is
   exactly its content and the section spacing around it stays exact. */
.lp-carousel { position: relative; overflow: hidden; }
@supports (overflow-x: clip) {
  .lp-carousel { overflow: visible; overflow-x: clip; }
}
.lp-carousel__track {
  display: flex; gap: 20px;
  /* Explicit, not inherited: .lp-card carries height:100%, and a definite
     cross-size makes a flex item opt out of the default stretch -- which is
     what let a card with prices sit taller than the locked card beside it. */
  align-items: stretch;
  transition: transform .62s var(--lp-ease-out);
  touch-action: pan-y;
}
.lp-carousel__track > * {
  flex: 0 0 calc((100% - (var(--lp-per-view, 4) - 1) * 20px) / var(--lp-per-view, 4));
  min-width: 0;
}
/* Several rows per slide: the track becomes a grid of --lp-rows rows that fills
   column by column, one column per card-per-view. landing.js still moves it by
   one column width at a time, so arrows and swipe behave as with one row. */
.lp-carousel--rows .lp-carousel__track {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: repeat(var(--lp-rows, 1), auto);
  grid-auto-columns: calc((100% - (var(--lp-per-view, 4) - 1) * 20px) / var(--lp-per-view, 4));
  gap: 20px;
}
/* Compact carousels (small tiles) size every column from --lp-per-view at all
   widths. The two extra classes outrank the narrow-screen overrides below,
   which switch product cards to two-up / one-and-a-peek. */
.lp-carousel.lp-carousel--compact .lp-carousel__track > * {
  flex-basis: calc((100% - (var(--lp-per-view, 4) - 1) * 20px) / var(--lp-per-view, 4));
}
.lp-carousel.lp-carousel--compact.lp-carousel--rows .lp-carousel__track {
  grid-auto-columns: calc((100% - (var(--lp-per-view, 4) - 1) * 20px) / var(--lp-per-view, 4));
}
.lp-carousel__nav { display: flex; gap: 8px; }
.lp-carousel__btn {
  display: grid; place-items: center; width: 40px; height: 40px;
  background: var(--lp-canvas); border: 1px solid var(--lp-line); border-radius: 50%;
  color: var(--lp-ink); cursor: pointer;
  transition: border-color var(--lp-fast) var(--lp-ease), transform var(--lp-fast) var(--lp-ease),
              box-shadow var(--lp-fast) var(--lp-ease), opacity var(--lp-fast) var(--lp-ease);
}
.lp-carousel__btn:hover { border-color: var(--lp-ink); transform: translateY(-2px); box-shadow: var(--lp-shadow-sm); }
.lp-carousel__btn[disabled] { opacity: .32; pointer-events: none; }
[dir="rtl"] .lp-carousel__btn svg { transform: scaleX(-1); }

/* ---------- Product card -------------------------------------------------- */

/* A surfaced column, and the column is about uniformity rather than taste.
   Cards sit in a flex carousel and a stretch grid, so they already share a
   height; the body grows and the Order button is pinned to the bottom, which
   puts every button in a row on the same line whatever the text above does.

   The border is layered backgrounds -- the card colour on the padding box and
   a conic gradient on the border box -- so it can carry a moving highlight
   without an extra element.

   At rest the card already wears its "active" look: a gold edge with two
   brighter gold arcs, a soft gold halo, and the gold Order button. The edge
   is translucent gold, so it reads on a white page and on a dark band alike.

   Hover (or keyboard focus) adds motion on top of that:
     - the card lifts, and its halo deepens into a warm glow;
     - the edge turns solid gold and two pale lights orbit it (@property makes
       the angle animatable; without it the lights simply stand still);
     - a gold spotlight follows the pointer across the card (--lp-mx/--lp-my,
       set by landing.js; the colour is registered so it fades in);
     - a sheen sweeps once across the image, which zooms slightly;
     - the Order button glows, and fills with ink when it is itself hovered.
   Reduced motion keeps every colour and drops the movement.

   Colours: the Product slider widget can set --lp-card-accent (the edge, and
   every glow and light derived from it), --lp-buy-bg and --lp-buy-fg (the
   Order button) on its root. Cards outside it -- /products, the related strip
   -- fall back to the site gold. The card reads them into its own
   --lp-card-tint / --lp-buy-base / --lp-buy-ink, never setting the inherited
   names itself, so the widget's values reach it. */
@property --lp-card-angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}
@property --lp-card-spot {
  syntax: '<color>';
  inherits: false;
  initial-value: rgba(245, 165, 1, 0);
}
@keyframes lp-card-orbit { to { --lp-card-angle: 360deg; } }

.lp-card {
  --lp-card-bg: #fff;
  --lp-card-tint: var(--lp-card-accent, var(--lp-accent));
  --lp-card-line: color-mix(in srgb, var(--lp-card-tint) 50%, transparent);
  --lp-card-glow: var(--lp-card-tint);
  --lp-card-spot: color-mix(in srgb, var(--lp-card-tint) 0%, transparent);
  position: relative;
  display: flex; flex-direction: column; height: 100%;
  padding: 10px;
  border: 1.5px solid transparent;
  border-radius: 18px;
  background:
    radial-gradient(260px circle at var(--lp-mx, 50%) var(--lp-my, 0%), var(--lp-card-spot), transparent 70%) padding-box,
    linear-gradient(var(--lp-card-bg), var(--lp-card-bg)) padding-box,
    conic-gradient(from var(--lp-card-angle),
      var(--lp-card-line) 0deg,
      var(--lp-card-glow) 45deg,
      var(--lp-card-line) 95deg,
      var(--lp-card-line) 180deg,
      var(--lp-card-glow) 225deg,
      var(--lp-card-line) 275deg) border-box;
  box-shadow:
    0 14px 30px -20px rgba(32, 24, 18, .26),
    0 0 0 3px color-mix(in srgb, var(--lp-card-tint) 7%, transparent);
  /* opacity/transform belong to .lp-reveal's entrance and are restated here
     so this declaration does not cancel them; the lift uses `translate`,
     which composes with the reveal's transform instead of fighting it. */
  transition:
    opacity var(--lp-slow) var(--lp-ease-out) var(--lp-delay, 0ms),
    transform var(--lp-slow) var(--lp-ease-out) var(--lp-delay, 0ms),
    translate var(--lp-base) var(--lp-ease-out),
    box-shadow var(--lp-base) var(--lp-ease),
    --lp-card-spot var(--lp-base) var(--lp-ease);
}
.lp-card:hover,
.lp-card:focus-within {
  --lp-card-line: var(--lp-card-tint);
  /* A pale version of the tint: light travelling round the edge. */
  --lp-card-glow: color-mix(in srgb, var(--lp-card-tint) 25%, #fff);
  --lp-card-spot: color-mix(in srgb, var(--lp-card-tint) 14%, transparent);
  translate: 0 -6px;
  box-shadow:
    0 30px 50px -24px rgba(32, 24, 18, .4),
    0 14px 34px -16px color-mix(in srgb, var(--lp-card-tint) 50%, transparent),
    0 0 0 4px color-mix(in srgb, var(--lp-card-tint) 12%, transparent);
  animation: lp-card-orbit 3s linear infinite;
}

/* The sheen: parked off the image's leading side, and swept across on hover.
   Only the hover state carries the transition, so leaving snaps it back
   unseen and the next hover sweeps again. Under the badges and the panel. */
.lp-card__media::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, .5) 48%, transparent 66%);
  transform: translateX(-120%);
}
.lp-card:hover .lp-card__media::after {
  transform: translateX(120%);
  transition: transform .9s var(--lp-ease-out);
}

@media (prefers-reduced-motion: reduce) {
  .lp-card:hover,
  .lp-card:focus-within { animation: none; translate: none; }
  .lp-card:hover .lp-card__media::after { transform: translateX(-120%); transition: none; }
}

.lp-card__media {
  position: relative; aspect-ratio: 1 / 1; overflow: hidden;
  border-radius: 12px; background: var(--lp-sand);
}
.lp-card__media-link { display: block; width: 100%; height: 100%; }
.lp-card__media-link:focus-visible { outline: 2px solid var(--lp-accent); outline-offset: -2px; border-radius: 12px; }
.lp-card__media img {
  width: 100%; height: 100%; object-fit: cover;
  /* opacity: the short fade when a colour swatch swaps the image (landing.js). */
  transition: transform .75s var(--lp-ease-out), opacity .15s ease;
}
.lp-card:hover .lp-card__media img { transform: scale(1.07); }
@media (prefers-reduced-motion: reduce) {
  .lp-card:hover .lp-card__media img { transform: none; }
}
.lp-card__media .lp-badge { z-index: 2; pointer-events: none; }
.lp-card__placeholder { display: block; width: 100%; height: 100%; background: var(--lp-line-soft); }

.lp-card__lockmark {
  position: absolute; z-index: 2; inset-block-start: 10px; inset-inline-end: 10px;
  display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%;
  background: rgba(255, 255, 255, .92); color: var(--lp-accent-ink);
  box-shadow: var(--lp-shadow-sm); pointer-events: none;
}

/* Brand + title only. Everything below the title moved out of this anchor:
   the variant chooser is made of buttons, and a button inside a link cannot be
   clicked -- the link swallows the press. */
.lp-card__body {
  display: flex; flex-direction: column; flex: 0 0 auto;
  padding: 14px 4px 6px; color: inherit; text-decoration: none;
}
/* The unlinked half: variants, prices, rule. Grows so the action row below it
   is pushed to the bottom of every card in the row.
   All three of its children are optional, and the card omits this wrapper
   entirely when none of them render -- a locked brand's page, or a guest's --
   rather than leaving a padded box holding nothing. A :empty selector could
   not do that job: Blade leaves whitespace text nodes behind a false @if, so
   the element is never truly empty. */
.lp-card__foot {
  display: flex; flex-direction: column; flex: 1 1 auto;
  padding-inline: 4px; padding-block-end: 12px;
}
/* Always rendered and reserving its line: a card with no brand keeps the row
   the others spend on one, so the titles below still start on the same line. */
.lp-card__brand {
  margin: 0 0 4px; font-size: 11px; font-weight: 700; letter-spacing: .1em;
  line-height: 1.3; min-height: 1.3em;
  text-transform: uppercase; color: var(--lp-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Clamped to two lines AND reserving two: the clamp alone stopped a long name
   from pushing the card taller, but a short one still made it shorter. */
.lp-card__title {
  margin: 0 0 8px; font-size: 14.5px; font-weight: 600; line-height: 1.4; color: var(--lp-ink);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  min-height: calc(1.4em * 2);
  transition: color var(--lp-fast) var(--lp-ease);
}
.lp-card__body:hover .lp-card__title { color: var(--lp-accent-ink); }
/* The price line swaps between an amount, a "login to buy" chip and the
   locked note, each a different size — so it reserves the tallest. */
.lp-card__price { min-height: 22px; display: flex; align-items: center; }
/* Quantity discount rule. Shown whether or not a price is, because it is a
   quantity and a percentage rather than a figure this viewer would pay. */
.lp-card__rule {
  display: flex; align-items: center; gap: 5px;
  margin: 6px 0 0; font-size: 12px; font-weight: 600; color: var(--lp-accent-ink);
}
.lp-card__rule svg { flex: none; }
.lp-card__amount { font-size: 15px; font-weight: 700; color: var(--lp-ink); }

/* ---- Card price pair (retail + the reseller's own) -----------------------
   The same two lines the portal card has always carried. The block RESERVES
   its height whether or not this viewer gets prices: a guest's card and a
   reseller's card sit side by side in the same grid on the same page, and
   without the reservation the buy buttons would land on different lines. */
/*
 * The block only exists when it has something in it, so there is nothing to
 * reserve for a guest or a locked card -- see the card partial.
 *
 * The 44px belongs to the PAIR alone: retail over the reseller's own price. It
 * keeps a product that has only one of the two the same height as one that has
 * both, which is a real difference between two cards that both show prices. A
 * single "sign in to see prices" note takes its natural line and no more.
 */
.lp-card__prices { display: flex; flex-direction: column; justify-content: center; gap: 2px; }
.lp-card__prices--pair { min-height: 44px; }
/* In flight while a newly picked variant is being priced. Dimmed rather than
   blanked: the previous figure stays readable, so the card does not flash
   empty between two prices. */
.lp-card__prices.is-lp-repricing { opacity: .45; }
/*
 * One row: the label, then the figures on the far edge -- the struck-through
 * one (only while there is a reduction) right before the one that applies.
 *
 * The figures are one unbreakable group: a number is never split from its
 * currency, and the struck figure never parts from the new one. When a narrow
 * card has no room for all of it, the LABEL gives way first -- flex-basis 0
 * lets it wrap onto a second line of its own words while the figures keep
 * their place on the row. Only if even the label's longest word will not fit
 * beside them does the group drop to the next row, still on the far edge.
 */
.lp-price-line {
  display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 8px;
  margin: 0; font-size: 12px; line-height: 1.5;
}
.lp-price-line__label { flex: 1 1 0; color: var(--lp-muted); font-weight: 500; }
.lp-price-line__value {
  flex: none; margin-inline-start: auto;
  display: inline-flex; align-items: baseline; gap: 5px;
  font-weight: 700; color: var(--lp-ink); white-space: nowrap;
}
/* Just the number: the new figure beside it already carries the currency. */
.lp-price-line__was {
  font-weight: 500; font-size: 10.5px;
  color: var(--lp-muted); text-decoration: line-through;
}
/* The reseller's own price is the one they act on, so it carries the weight. */
.lp-price-line--own .lp-price-line__value { font-size: 14px; color: var(--lp-accent-ink); }

/* ---- Rows that must exist even when empty -------------------------------
   Each of these is optional content. Reserving the row is what keeps a card
   with a discount rule exactly as tall as one without, which is the whole
   reason the buy buttons line up across a row. */
/* Present only when the product actually has a rule. */
.lp-card__ruleslot { min-height: 18px; }

/* ---- Card action row ----------------------------------------------------
   Last child of the card and pushed to the bottom by .lp-card__body's
   flex-grow, so it is the line every card in a grid row ends on. */
.lp-card__actions { display: flex; align-items: stretch; gap: 6px; margin-block-start: auto; }
.lp-card__actions .lp-card__buy { flex: 1 1 auto; margin-block-start: 0; }
/* The row can hold an <a> (Order), a <button> (Notify me) or a <span>
   (Out of stock). A button does not inherit the page font, so say it once for
   all three rather than styling each element type separately. */
.lp-card__actions .lp-card__buy { font-family: inherit; }
button.lp-card__buy { cursor: pointer; }

/* ---- Variant chooser, on the face of the card ---------------------------
   Compact on purpose. It sits above the price because picking a variant
   re-prices the card, and it is capped so a product with eight colours is
   exactly as tall as one with two -- which is what keeps the buy buttons of a
   whole grid row on one line. One row per option group, scrolled sideways
   rather than wrapped onto a second line. */
/* Rendered only when the product has options to choose, so the height here is
   the row's real height rather than a reservation. One option row is 19px of
   swatch plus the 3px of breathing room the scroll box needs above and below. */
.lp-card__variants {
  display: flex; flex-direction: column; gap: 4px;
  min-height: 25px; margin-block-end: 8px;
}
/*
 * Sideways scroll instead of wrapping, so eight colours occupy exactly the
 * same height as two.
 *
 * padding-block is load-bearing, not cosmetic: `overflow-x: auto` establishes
 * a clipping box on BOTH axes, and the active swatch's selection ring is an
 * outer box-shadow. Without room above and below, that ring was being sliced
 * flat top and bottom -- the squared-off look on the selected colour.
 */
.lp-opt--inline .lp-opt__values {
  flex-wrap: nowrap; overflow-x: auto; gap: 6px;
  padding-block: 3px; padding-inline: 1px;
  scrollbar-width: none;
}
.lp-opt--inline .lp-opt__values::-webkit-scrollbar { display: none; }
.lp-opt--inline .lp-swatch { width: 19px; height: 19px; border-width: 2px; }
/* The ring is drawn tighter than the panel's, so it stays inside the 3px the
   scroll box can show. */
.lp-opt--inline .lp-swatch.is-active { box-shadow: 0 0 0 2px var(--lp-ink); }
.lp-opt--inline .lp-optchip { padding: 3px 8px; font-size: 11px; }

/* ---- Action row variants ------------------------------------------------
   Notify me is the SAME button as Order -- same fill, same size -- because on
   an out-of-stock card it IS the action, not a secondary offer beside one. It
   therefore needs no styling of its own; only the two states below differ. */
.lp-card__buy--notify.is-lp-subscribed {
  background: var(--lp-canvas); color: var(--lp-ink);
  box-shadow: inset 0 0 0 1.5px var(--lp-accent);
}
.lp-card__buy--notify.is-lp-subscribed::before { display: none; }
.lp-card__buy--notify[disabled] { opacity: .6; cursor: default; }
/* Bell at rest, struck-through bell once subscribed -- the portal button's
   bi-bell / bi-bell-slash pair. */
.lp-card__buy--notify .lp-notify-ico--off,
.lp-card__buy--notify.is-lp-subscribed .lp-notify-ico--on { display: none; }
.lp-card__buy--notify.is-lp-subscribed .lp-notify-ico--off { display: block; }

/* A live card carries both Order and Notify me and shows one (landing-card.js,
   syncLive). .lp-card__buy sets `display`, which beats the UA's [hidden] rule,
   so this is what actually hides the other one. */
.lp-card__buy[hidden] { display: none; }

/* Nothing to click: no access to the product (a locked card). The button
   states the fact instead of inviting a press. A guest never gets this one --
   their card always offers Order. */
.lp-card__buy--oos {
  background: var(--lp-line-soft); color: var(--lp-muted);
  cursor: default; box-shadow: none;
}
.lp-card__buy--oos::before { display: none; }
.lp-card:hover .lp-card__buy--oos { box-shadow: none; }
.lp-card:hover .lp-card__buy--oos svg { transform: none; }

/* The Notify me popups (landing/partials/notify-modal.blade.php). The shell is
   the unlock modal's (.lp-unlock); these are the pieces it did not have. */
.lp-notify__input {
  display: block; width: 100%; margin: 0 0 14px; padding: 11px 14px;
  border: 1px solid var(--lp-line); border-radius: var(--lp-radius);
  background: #fff; color: var(--lp-ink);
  font: inherit; font-size: 15px;
}
.lp-notify__input:focus { outline: 2px solid var(--lp-accent); outline-offset: 1px; border-color: transparent; }
.lp-notify__error { margin-block-start: -4px; }
.lp-notify__icon--danger { background: #FDECEC; color: #B42318; }
.lp-notify__danger,
.lp-notify__danger:hover { background: #B42318; border-color: #B42318; color: #fff; }


/* ---- Quantity discount tooltip --------------------------------------------
   The portal card's qty-discount-tooltip: hovering (or focusing) the rule line
   lists every tier it summarises. Opens ABOVE the line, over the prices,
   because below it are the buy button and the card's edge -- which a slider
   track would clip. Pure CSS, so a guest's card gets it too. */
.lp-card__ruleslot { position: relative; }
.lp-card__rule[tabindex] { cursor: help; }
.lp-card__rule[tabindex]:focus-visible { outline: 2px solid var(--lp-accent); outline-offset: 2px; border-radius: 4px; }
.lp-card__rule-info { opacity: .65; }
.lp-rule-tip {
  position: absolute; z-index: 6;
  inset-inline: 0; inset-block-end: calc(100% + 8px);
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--lp-ink); color: #fff;
  box-shadow: var(--lp-shadow-md);
  font-size: 11.5px; line-height: 1.4;
  opacity: 0; visibility: hidden; transform: translateY(4px);
  pointer-events: none;
  transition: opacity var(--lp-fast) var(--lp-ease), transform var(--lp-fast) var(--lp-ease),
              visibility 0s linear var(--lp-fast);
}
/* The little pointer down to the line. */
.lp-rule-tip::after {
  content: ''; position: absolute; inset-block-start: 100%; inset-inline-start: 14px;
  border: 6px solid transparent; border-block-start-color: var(--lp-ink);
}
.lp-card__ruleslot:hover .lp-rule-tip,
.lp-card__ruleslot:focus-within .lp-rule-tip {
  opacity: 1; visibility: visible; transform: none; transition-delay: 0s;
}
.lp-rule-tip__head {
  margin: 0 0 6px;
  font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: rgba(255, 255, 255, .65);
}
.lp-rule-tip__rows { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; }
.lp-rule-tip__row { display: flex; justify-content: space-between; gap: 10px; }
.lp-rule-tip__off { font-weight: 700; color: var(--lp-accent); white-space: nowrap; }
@media (prefers-reduced-motion: reduce) {
  .lp-rule-tip { transition: none; transform: none; }
}



.lp-card__cta {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; font-weight: 600; color: var(--lp-muted);
}
.lp-badge {
  position: absolute; inset-block-start: 10px; inset-inline-start: 10px;
  padding: 5px 10px; border-radius: 999px; font-size: 11px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase;
}
.lp-badge--sale { background: var(--lp-accent); color: var(--lp-on-accent); }
.lp-products__note { margin-block-start: 26px; font-size: 14px; color: var(--lp-muted); }

/* Products as a static grid. The widget is the size container, so the column
   count steps down with the space the widget has -- a narrow section column
   included -- not with the window. */
.lp-products { container-type: inline-size; }
.lp-pgrid { display: grid; gap: 20px; align-items: stretch; grid-template-columns: repeat(var(--lp-pgrid-cols, 4), minmax(0, 1fr)); }

/*
 * Equal-height cards, in every container that holds a row of them.
 *
 * .lp-card carries `height: 100%`, and per the flexbox spec a DEFINITE cross
 * size makes an item opt out of `align-items: stretch` -- so in the slider each
 * card sized itself to its own content and a card with prices sat taller than
 * the locked card beside it. Handing the height back to `auto` lets stretch do
 * its job; in the grids it changes nothing, because a stretched grid item
 * already fills its row.
 */
.lp-carousel__track > .lp-card,
.lp-pgrid > .lp-card,
.lp-grid--products > .lp-card { height: auto; align-self: stretch; }
.lp-pgrid--cols-1 { --lp-pgrid-cols: 1; }
.lp-pgrid--cols-2 { --lp-pgrid-cols: 2; }
.lp-pgrid--cols-3 { --lp-pgrid-cols: 3; }
.lp-pgrid--cols-4 { --lp-pgrid-cols: 4; }
.lp-pgrid--cols-5 { --lp-pgrid-cols: 5; }
.lp-pgrid--cols-6 { --lp-pgrid-cols: 6; }
@container (max-width: 980px) {
  .lp-pgrid--cols-4, .lp-pgrid--cols-5, .lp-pgrid--cols-6 { --lp-pgrid-cols: 3; }
}
@container (max-width: 700px) {
  .lp-pgrid--cols-3, .lp-pgrid--cols-4, .lp-pgrid--cols-5, .lp-pgrid--cols-6 { --lp-pgrid-cols: 2; }
  .lp-pgrid { gap: 12px; }
}

/* ---------- Brands -------------------------------------------------------- */

/* The marquee itself now lives in assets/css/components/marquee.css, which
   the landing shell links just before this sheet -- the reseller dashboard
   loads the same file, so there is one strip, not two. Only the brand
   widget's own monochrome treatment stays here. */
.lp-brands.is-mono .lp-marquee__item img,
.lp-brands.is-mono .lp-brands__tile img { filter: grayscale(1); opacity: .62; transition: filter var(--lp-base) var(--lp-ease), opacity var(--lp-base) var(--lp-ease), transform var(--lp-base) var(--lp-ease); }
.lp-brands.is-mono .lp-marquee__item:hover img,
.lp-brands.is-mono .lp-brands__tile:hover img { filter: grayscale(0); opacity: 1; }

.lp-brands__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 190px));
  justify-content: center;
  gap: 14px; margin: 0; padding: 0; list-style: none;
}

/* Fixed columns (the widget's columns x rows). The widget is the size
   container, so the column count steps down with the space the widget has --
   a narrow section column included -- not with the window. */
.lp-brands { container-type: inline-size; }
.lp-brands__grid--cols { grid-template-columns: repeat(var(--lp-brand-cols, 6), minmax(0, 1fr)); justify-content: stretch; }
.lp-brands__grid--cols-1 { --lp-brand-cols: 1; }
.lp-brands__grid--cols-2 { --lp-brand-cols: 2; }
.lp-brands__grid--cols-3 { --lp-brand-cols: 3; }
.lp-brands__grid--cols-4 { --lp-brand-cols: 4; }
.lp-brands__grid--cols-5 { --lp-brand-cols: 5; }
.lp-brands__grid--cols-6 { --lp-brand-cols: 6; }
.lp-brands__grid--cols-7 { --lp-brand-cols: 7; }
.lp-brands__grid--cols-8 { --lp-brand-cols: 8; }
@container (max-width: 980px) {
  .lp-brands__grid--cols-5, .lp-brands__grid--cols-6,
  .lp-brands__grid--cols-7, .lp-brands__grid--cols-8 { --lp-brand-cols: 4; }
}
@container (max-width: 700px) {
  .lp-brands__grid--cols-4, .lp-brands__grid--cols-5, .lp-brands__grid--cols-6,
  .lp-brands__grid--cols-7, .lp-brands__grid--cols-8 { --lp-brand-cols: 3; }
}
@container (max-width: 440px) {
  .lp-brands__grid--cols-3, .lp-brands__grid--cols-4, .lp-brands__grid--cols-5,
  .lp-brands__grid--cols-6, .lp-brands__grid--cols-7, .lp-brands__grid--cols-8 { --lp-brand-cols: 2; }
}
.lp-brands__tile {
  display: grid; place-items: center; height: 104px; padding: 18px;
  background: var(--lp-canvas); border: 1px solid var(--lp-line); border-radius: var(--lp-radius);
  transition: border-color var(--lp-base) var(--lp-ease), transform var(--lp-base) var(--lp-ease),
              box-shadow var(--lp-base) var(--lp-ease);
}
.lp-brands__tile:hover { border-color: transparent; transform: translateY(-4px); box-shadow: var(--lp-shadow-md); }
.lp-brands__tile img { max-height: 100%; width: auto; object-fit: contain; }

/* ---------- Categories ---------------------------------------------------- */

.lp-categories__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 190px));
  justify-content: center;
  gap: 18px; margin: 0; padding: 0; list-style: none;
}
/* Carousel mode uses the shared .lp-carousel (see Product / generic carousel);
   the track is a <ul>, so it drops the list styling. */
.lp-categories__track { margin: 0; padding: 0; list-style: none; }
.lp-cat { display: block; text-decoration: none; color: inherit; }
.lp-cat__media {
  display: grid; place-items: center; aspect-ratio: 4 / 3; overflow: hidden;
  background: var(--lp-sand); border-radius: var(--lp-radius-lg);
  transition: transform var(--lp-base) var(--lp-ease-out), box-shadow var(--lp-base) var(--lp-ease);
}
.lp-cat:hover .lp-cat__media { transform: translateY(-5px); box-shadow: var(--lp-shadow-md); }
.lp-cat__media img { width: 62%; height: 62%; object-fit: contain; transition: transform .6s var(--lp-ease-out); }
.lp-cat:hover .lp-cat__media img { transform: scale(1.08); }
.lp-cat__placeholder { width: 100%; height: 100%; background: var(--lp-line-soft); }
.lp-cat__name { display: block; margin-block-start: 12px; text-align: center; font-size: 14px; font-weight: 600; color: var(--lp-ink); }

/* ---------- Ads ----------------------------------------------------------- */

/* --lp-ads-cols / --lp-ads-rows come from the widget's settings, and each
   image's own --lp-ads-ratio from that image's size, as inline custom
   properties (AdsWidget). An image with a size keeps its shape at the top of
   its cell; an "Original" image beside it fills the row's height. */
.lp-ads { display: grid; grid-template-columns: repeat(var(--lp-ads-cols, 2), minmax(0, 1fr)); }
.lp-ads__item.has-ratio { aspect-ratio: var(--lp-ads-ratio); align-self: start; }
.lp-ads__link { display: block; height: 100%; }
.lp-ads--gap-small  { gap: 10px; }
.lp-ads--gap-medium { gap: 18px; }
.lp-ads--gap-large  { gap: 28px; }
.lp-ads.is-rounded .lp-ads__item, .lp-ads.is-rounded img { border-radius: var(--lp-radius-lg); }
.lp-ads__item { overflow: hidden; }
.lp-ads__item img { width: 100%; height: 100%; object-fit: cover; transition: transform .7s var(--lp-ease-out); }
.lp-ads__item:hover img { transform: scale(1.04); }

/* ---------- Countdown ----------------------------------------------------- */

.lp-countdown { background: var(--lp-cd-bg, #1F1B18); color: #fff; }
/* When the SECTION carries its own background, the widget must not paint over
   it, and the band's text colour must win over the widget's hardcoded white. */
.lp-band .lp-countdown { background: transparent; color: inherit; }
.lp-band .lp-countdown__subtext { color: inherit; opacity: .78; }
.lp-band .lp-countdown__unit { background: rgba(127,127,127,.16); }
.lp-band .lp-countdown__lbl { color: inherit; opacity: .65; }
.lp-countdown__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 28px; padding-block: 34px; flex-wrap: wrap;
}
.lp-countdown__headline { margin: 0; font-family: var(--lp-display); font-size: clamp(20px, 2.6vw, 32px); font-weight: 700; letter-spacing: -.025em; }
.lp-countdown__subtext { margin: 6px 0 0; font-size: 14px; color: rgba(255,255,255,.72); }
.lp-countdown__clock { display: flex; gap: 10px; }
.lp-countdown__unit {
  min-width: 68px; padding: 12px 10px; text-align: center;
  background: rgba(255,255,255,.08); border-radius: 12px;
}
.lp-countdown__num {
  display: block; font-size: 26px; font-weight: 800;
  font-variant-numeric: tabular-nums; color: var(--lp-cd-accent, #E2703A);
}
.lp-countdown__lbl { display: block; margin-block-start: 3px; font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: rgba(255,255,255,.6); }

/* ---------- Trust bar ----------------------------------------------------- */

.lp-trust {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 4px; margin: 0; padding: 0; list-style: none;
  border-radius: var(--lp-radius-lg); overflow: hidden;
}
.lp-trust.is-bordered { border: 1px solid var(--lp-line); gap: 0; }
.lp-trust.is-bordered .lp-trust__item + .lp-trust__item { border-inline-start: 1px solid var(--lp-line); }
.lp-trust__item { display: flex; align-items: center; gap: 13px; padding: 22px 20px; }
.lp-trust.is-compact .lp-trust__item { padding: 15px 16px; }
.lp-trust__icon {
  display: grid; place-items: center; flex: 0 0 42px; width: 42px; height: 42px;
  border-radius: 50%; background: var(--lp-accent-soft); color: var(--lp-accent-ink);
  transition: transform var(--lp-base) var(--lp-ease-out), background-color var(--lp-base) var(--lp-ease);
}
.lp-trust__item:hover .lp-trust__icon { transform: scale(1.09) rotate(-6deg); background: var(--lp-accent); color: var(--lp-on-accent); }
.lp-trust__text strong { display: block; font-size: 14px; font-weight: 700; color: var(--lp-ink); }
.lp-trust__text em { display: block; margin-block-start: 2px; font-size: 12.5px; font-style: normal; color: var(--lp-muted); }

/* ---------- Stats --------------------------------------------------------- */

.lp-stats__grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 26px; margin: 26px 0 0; padding: 0; list-style: none; text-align: center;
}
.lp-stats__value {
  display: block; font-family: var(--lp-display);
  font-size: clamp(32px, 4.6vw, 54px); font-weight: 700;
  letter-spacing: -.03em; color: var(--lp-ink); font-variant-numeric: tabular-nums;
}
.lp-stats__label { display: block; margin-block-start: 6px; font-size: 13.5px; color: var(--lp-muted); }

/* ---------- Testimonials -------------------------------------------------- */

.lp-testimonials__viewport { overflow: hidden; }
.lp-testimonials__track { position: relative; min-height: 220px; }
.lp-quote {
  position: absolute; inset: 0; margin: 0;
  display: flex; flex-direction: column; align-items: center; text-align: center;
  opacity: 0; visibility: hidden; transform: translateY(14px);
  transition: opacity .55s var(--lp-ease-out), transform .55s var(--lp-ease-out), visibility .55s;
}
.lp-quote.is-active { position: relative; opacity: 1; visibility: visible; transform: none; }
.lp-quote__stars { display: flex; gap: 3px; color: var(--lp-accent); margin-block-end: 16px; }
.lp-quote__text {
  margin: 0; max-width: 68ch; font-family: var(--lp-display);
  font-size: clamp(18px, 2.2vw, 25px); font-weight: 600; line-height: 1.5;
  letter-spacing: -.015em; color: var(--lp-ink);
}
.lp-quote__author { display: flex; align-items: center; gap: 11px; margin-block-start: 22px; }
.lp-quote__author img { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; }
.lp-quote__author strong { display: block; font-size: 14px; color: var(--lp-ink); }
.lp-quote__author em { display: block; font-style: normal; font-size: 12.5px; color: var(--lp-muted); }
.lp-testimonials__dots { display: flex; justify-content: center; gap: 7px; margin-block-start: 24px; }
.lp-dot {
  width: 7px; height: 7px; padding: 0; border: 0; border-radius: 50%;
  background: var(--lp-line); cursor: pointer;
  transition: background-color var(--lp-base) var(--lp-ease), width var(--lp-base) var(--lp-ease);
}
.lp-dot.is-active { background: var(--lp-ink); width: 20px; border-radius: 4px; }

/* ---------- FAQ ----------------------------------------------------------- */

.lp-faq__list { border-block-start: 1px solid var(--lp-line); }
.lp-faq__item { border-block-end: 1px solid var(--lp-line); }
.lp-faq__heading { margin: 0; }
.lp-faq__q {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  width: 100%; padding: 20px 2px; background: none; border: 0;
  font: inherit; font-size: 16px; font-weight: 600; color: var(--lp-ink);
  text-align: start; cursor: pointer;
}
.lp-faq__chev { flex: 0 0 auto; color: var(--lp-muted); transition: transform var(--lp-base) var(--lp-ease-out); }
.lp-faq__item.is-open .lp-faq__chev { transform: rotate(180deg); }
.lp-faq__a { padding: 0 2px 20px; font-size: 15px; line-height: 1.65; color: var(--lp-ink-soft); max-width: 78ch; }
.lp-faq__a p { margin: 0; }

/* ---------- Video --------------------------------------------------------- */

.lp-video__frame { position: relative; overflow: hidden; border-radius: var(--lp-radius-lg); background: var(--lp-panel); }
.lp-video__frame--16x9 { aspect-ratio: 16 / 9; }
.lp-video__frame--4x3  { aspect-ratio: 4 / 3; }
.lp-video__frame--1x1  { aspect-ratio: 1 / 1; }
.lp-video__frame iframe, .lp-video__frame video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.lp-video__poster { position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; border: 0; background: none; cursor: pointer; }
.lp-video__poster img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--lp-ease-out); }
.lp-video__poster:hover img { transform: scale(1.04); }
.lp-video__play {
  position: absolute; inset-block-start: 50%; inset-inline-start: 50%; translate: -50% -50%;
  display: grid; place-items: center; width: 78px; height: 78px;
  background: rgba(255,255,255,.94); color: var(--lp-ink); border-radius: 50%;
  box-shadow: var(--lp-shadow-lg);
  transition: transform var(--lp-base) var(--lp-ease-out);
}
[dir="rtl"] .lp-video__play svg { transform: scaleX(-1); }
.lp-video__poster:hover .lp-video__play { transform: translate(-50%, -50%) scale(1.08); }

/* ---------- Spacer -------------------------------------------------------- */

.lp-spacer--small  { height: 28px; }
.lp-spacer--medium { height: 56px; }
.lp-spacer--large  { height: 92px; }
.lp-spacer--xlarge { height: 132px; }
.lp-spacer { display: flex; align-items: center; }
.lp-spacer__rule { width: 100%; height: 0; margin: 0; border: 0; border-block-start: 1px solid var(--lp-line); }

/* ---------- Footer -------------------------------------------------------- */

.lp-footer { margin-block-start: clamp(64px, 9vw, 120px); background: var(--lp-footer-bg, var(--lp-deepest)); color: var(--lp-footer-fg, var(--lp-on-dark-muted)); }
.lp-footer__inner { display: flex; justify-content: space-between; gap: 40px; padding-block: 54px 34px; flex-wrap: wrap; }
.lp-footer__tagline { margin: 16px 0 0; font-size: 14px; max-width: 40ch; }

.lp-footer__col a { color: var(--lp-footer-fg, var(--lp-on-dark-muted)); font-size: 14px; text-decoration: none; transition: color var(--lp-fast) var(--lp-ease); }
.lp-footer__col a:hover { color: #fff; }
.lp-footer__legal { padding-block: 20px 34px; border-block-start: 1px solid rgba(255,255,255,.1); font-size: 13px; }

/* ---------- Builder preview affordances ----------------------------------- */

.lp-preview__empty { display: grid; place-items: center; min-height: 60vh; color: var(--lp-muted); font-size: 15px; }
.is-lp-selected { outline: 2px solid var(--lp-accent); outline-offset: -2px; }

/* ---------- Responsive ---------------------------------------------------- */

@media (max-width: 1024px) {
  .lp-categories__list { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 860px) {
  .lp-header__nav { display: none; }
  .lp-header__burger { display: flex; }
  .lp-header__inner { height: 62px; }
  .lp-banner--large, .lp-banner--full { min-height: 480px; }
  .lp-banner__content { padding-block: 62px; }
  .lp-carousel__track > * { flex-basis: calc((100% - 20px) / 2); }
  .lp-carousel--rows .lp-carousel__track { grid-auto-columns: calc((100% - 20px) / 2); }
  .lp-categories__list { grid-template-columns: repeat(2, 1fr); }
  .lp-ads { grid-template-columns: 1fr; }
  .lp-ads--wide { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lp-countdown__inner { justify-content: center; text-align: center; }
  .lp-trust.is-bordered .lp-trust__item + .lp-trust__item { border-inline-start: 0; border-block-start: 1px solid var(--lp-line); }
  .lp-section__head { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 560px) {
  :root { --lp-gutter: 16px; }
  .lp-carousel__track > * { flex-basis: 76%; }
  .lp-carousel--rows .lp-carousel__track { grid-auto-columns: 76%; }
  .lp-ads--wide { grid-template-columns: 1fr; }
  /* Same proportion the fixed sizes used (84px -> 70px). */
  .lp-stories__btn { width: calc(var(--lp-story-size) * .833 + 6px); }
  .lp-stories__ring { width: calc(var(--lp-story-size) * .833); height: calc(var(--lp-story-size) * .833); }
  .lp-banner__headline { font-size: 32px; }
  .lp-footer__inner { flex-direction: column; gap: 28px; }
}

/* =============================================================================
   Dark bands + section numbering.

   The reference alternates warm off-white and near-black full-bleed bands, and
   numbers its sections (01, 02 …). Both are opt-in per widget: the builder sets
   nothing here, but a widget partial can carry `lp-band--dark` / `lp-band--sand`
   and the section head can render an `lp-eyebrow-num`.
   ========================================================================== */

/* A section with any background is full-bleed and owns its own vertical
   padding, so consecutive bands butt together rather than being separated by
   the default inter-widget margin. */
.lp-band { position: relative; isolation: isolate; }
.lp-band + .lp-band, .lp-widget + .lp-band { margin-block-start: 0 !important; }

.lp-band--pad-default { padding-block: clamp(48px, 6vw, 92px); }
.lp-band--pad-small   { padding-block: clamp(24px, 3vw, 44px); }
.lp-band--pad-large   { padding-block: clamp(72px, 9vw, 140px); }
.lp-band--pad-none    { padding-block: 0; }

/* Presets */
.lp-band--sand    { background: var(--lp-sand); }
.lp-band--dark    { background: var(--lp-panel);   color: var(--lp-on-dark); }
.lp-band--deepest { background: var(--lp-deepest); color: var(--lp-on-dark); }

/* Admin-picked colour */
.lp-band--custom { background: var(--lp-band-bg, var(--lp-sand)); }

/* Background image — a real <picture> behind the content, not a CSS
   background-image, so the mobile crop and lazy loading behave identically to
   widget imagery. */
.lp-band--image { background: var(--lp-panel); }
.lp-band__media { position: absolute; inset: 0; z-index: -1; overflow: hidden; }
.lp-band__media picture { display: block; width: 100%; height: 100%; }
.lp-band__img { width: 100%; height: 100%; object-fit: cover; }
.lp-band__scrim {
  position: absolute; inset: 0; display: block;
  background: rgba(10, 8, 7, var(--lp-band-overlay, .45));
}
.lp-band__content { position: relative; }

/* Text colour on a custom colour or photo: the admin declares it, because the
   page cannot infer it from an arbitrary hex or an image. */
.lp-band--on-light { color: var(--lp-on-dark); }
.lp-band--on-dark  { color: var(--lp-ink-soft); }

.lp-band--dark .lp-section__title,
.lp-band--deepest .lp-section__title,
.lp-band--on-light .lp-section__title { color: var(--lp-on-dark); }
.lp-band--dark .lp-section__subtitle,
.lp-band--deepest .lp-section__subtitle,
.lp-band--on-light .lp-section__subtitle { color: var(--lp-on-dark-muted); }
.lp-band--dark .lp-card__title,
.lp-band--deepest .lp-card__title,
.lp-band--on-light .lp-card__title { color: var(--lp-on-dark); }
.lp-band--dark .lp-card__brand,
.lp-band--deepest .lp-card__brand,
.lp-band--on-light .lp-card__brand { color: var(--lp-on-dark-faint); }
/* The gold-on-light ink the rule normally uses disappears on a dark band, so
   it switches to the accent itself, the way the locked chip already does. */
.lp-band--dark .lp-card__rule,
.lp-band--deepest .lp-card__rule,
.lp-band--on-light .lp-card__rule { color: var(--lp-accent); }
.lp-band--dark .lp-card__amount,
.lp-band--deepest .lp-card__amount,
.lp-band--on-light .lp-card__amount { color: var(--lp-on-dark); }
.lp-band--dark .lp-card__cta,
.lp-band--deepest .lp-card__cta,
.lp-band--on-light .lp-card__cta { color: var(--lp-on-dark-muted); }
/* On a dark band the card becomes a dark surface of its own. Its translucent
   edge (see .lp-card) reads on the band as it is. The Order button keeps its
   colours; its DEFAULT hover turns to a white fill with ink text, since ink
   would vanish on the dark card. Hover colours set on the Product slider
   widget still win -- the widget only passes them when they were changed. */
.lp-band--dark .lp-card,
.lp-band--deepest .lp-card,
.lp-band--on-light .lp-card {
  --lp-card-bg: #2A241F;
  box-shadow: none;
}
.lp-band--dark .lp-card__buy,
.lp-band--deepest .lp-card__buy,
.lp-band--on-light .lp-card__buy {
  --lp-buy-fill: var(--lp-buy-hover-bg, #fff);
  --lp-buy-hover-ink: var(--lp-buy-hover-fg, var(--lp-ink));
}
.lp-band--dark .lp-link,
.lp-band--deepest .lp-link,
.lp-band--on-light .lp-link { color: var(--lp-on-dark); }
.lp-band--dark .lp-link:hover,
.lp-band--deepest .lp-link:hover,
.lp-band--on-light .lp-link:hover { color: var(--lp-accent); }
.lp-band--dark .lp-carousel__btn,
.lp-band--deepest .lp-carousel__btn,
.lp-band--on-light .lp-carousel__btn {
  background: transparent; border-color: var(--lp-line-on-dark); color: var(--lp-on-dark);
}
.lp-band--dark .lp-carousel__btn:hover,
.lp-band--deepest .lp-carousel__btn:hover,
.lp-band--on-light .lp-carousel__btn:hover { border-color: var(--lp-accent); color: var(--lp-accent); }
.lp-band--dark .lp-cat__media,
.lp-band--deepest .lp-cat__media,
.lp-band--on-light .lp-cat__media { background: var(--lp-panel-2); }
.lp-band--dark .lp-cat__name,
.lp-band--deepest .lp-cat__name,
.lp-band--on-light .lp-cat__name { color: var(--lp-on-dark); }
.lp-band--dark .lp-brands__tile,
.lp-band--deepest .lp-brands__tile,
.lp-band--on-light .lp-brands__tile { background: var(--lp-panel-2); border-color: var(--lp-line-on-dark); }
.lp-band--dark .lp-faq__list,
.lp-band--deepest .lp-faq__list,
.lp-band--on-light .lp-faq__list { border-block-start-color: var(--lp-line-on-dark); }
.lp-band--dark .lp-faq__item,
.lp-band--deepest .lp-faq__item,
.lp-band--on-light .lp-faq__item { border-block-end-color: var(--lp-line-on-dark); }
.lp-band--dark .lp-faq__q,
.lp-band--deepest .lp-faq__q,
.lp-band--on-light .lp-faq__q { color: var(--lp-on-dark); }
.lp-band--dark .lp-faq__a,
.lp-band--deepest .lp-faq__a,
.lp-band--on-light .lp-faq__a { color: var(--lp-on-dark-muted); }
.lp-band--dark .lp-quote__text,
.lp-band--deepest .lp-quote__text,
.lp-band--on-light .lp-quote__text { color: var(--lp-on-dark); }
.lp-band--dark .lp-quote__author strong,
.lp-band--deepest .lp-quote__author strong,
.lp-band--on-light .lp-quote__author strong { color: var(--lp-on-dark); }
.lp-band--dark .lp-stats__value,
.lp-band--deepest .lp-stats__value,
.lp-band--on-light .lp-stats__value { color: var(--lp-accent); }
.lp-band--dark .lp-stats__label,
.lp-band--deepest .lp-stats__label,
.lp-band--on-light .lp-stats__label { color: var(--lp-on-dark-muted); }
.lp-band--dark .lp-trust,
.lp-band--deepest .lp-trust,
.lp-band--on-light .lp-trust { border-color: var(--lp-line-on-dark); }
.lp-band--dark .lp-trust.is-bordered .lp-trust__item + .lp-trust__item,
.lp-band--deepest .lp-trust.is-bordered .lp-trust__item + .lp-trust__item,
.lp-band--on-light .lp-trust.is-bordered .lp-trust__item + .lp-trust__item { border-inline-start-color: var(--lp-line-on-dark); }
.lp-band--dark .lp-trust__text strong,
.lp-band--deepest .lp-trust__text strong,
.lp-band--on-light .lp-trust__text strong { color: var(--lp-on-dark); }
.lp-band--dark .lp-trust__text em,
.lp-band--deepest .lp-trust__text em,
.lp-band--on-light .lp-trust__text em { color: var(--lp-on-dark-faint); }
.lp-band--dark .lp-trust__icon,
.lp-band--deepest .lp-trust__icon,
.lp-band--on-light .lp-trust__icon { background: var(--lp-panel-2); color: var(--lp-accent); }
.lp-band--dark .lp-dot,
.lp-band--deepest .lp-dot,
.lp-band--on-light .lp-dot { background: var(--lp-line-on-dark); }
.lp-band--dark .lp-dot.is-active,
.lp-band--deepest .lp-dot.is-active,
.lp-band--on-light .lp-dot.is-active { background: var(--lp-accent); }

/* Numbered eyebrow — the reference's "01 / Regional Reach" device. */
.lp-eyebrow-num {
  display: inline-flex; align-items: center; gap: 10px;
  margin: 0 0 14px;
  font-family: var(--lp-display);
  font-size: 12px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  color: var(--lp-muted);
}
.lp-eyebrow-num::before {
  content: attr(data-num);
  color: var(--lp-accent); font-variant-numeric: tabular-nums;
}
.lp-eyebrow-num::after {
  content: ''; width: 36px; height: 1px; background: var(--lp-line);
}
.lp-band--dark .lp-eyebrow-num,
.lp-band--deepest .lp-eyebrow-num,
.lp-band--on-light .lp-eyebrow-num { color: var(--lp-on-dark-faint); }
.lp-band--dark .lp-eyebrow-num::after,
.lp-band--deepest .lp-eyebrow-num::after,
.lp-band--on-light .lp-eyebrow-num::after { background: var(--lp-line-on-dark); }

/* <picture> is an inline wrapper by default; the banner media must still fill
   its slide, and ad/video pictures must behave like the block images they
   replaced. */
.lp-banner__picture { position: absolute; inset: 0; display: block; }
.lp-ads__item picture, .lp-video__poster picture { display: block; width: 100%; height: 100%; }
.lp-ads__item picture img, .lp-video__poster picture img { width: 100%; height: 100%; object-fit: cover; }

/* =============================================================================
   Uniform media tiles (landing.partials.media-tile)

   Fixed aspect boxes so an admin uploading a 400x400 logo and a 2000x600 one
   cannot break the row. Shared by the landing sliders and the /brands and
   /categories pages -- never restyle per instance.
   ========================================================================== */

.lp-tile {
  display: block; position: relative; overflow: hidden;
  border-radius: var(--lp-radius);
  background: var(--lp-sand);
}
.lp-tile__img { position: absolute; inset: 0; width: 100%; height: 100%; }
.lp-tile__empty { position: absolute; inset: 0; background: var(--lp-line-soft); }

/* Both kinds are CONTAINED, never cropped, and never upscaled.

   The real data decides this: category images in this catalogue are 150x150
   line-art icons, not photography, and brand logos range from 400x150 to
   2000x872. `cover` on a 150px icon both crops it and blows it up, which is
   exactly the blur this replaced. `--lp-tile-max` caps the box near the
   smallest real source so nothing is ever scaled past its own resolution. */
.lp-tile {
  max-width: var(--lp-tile-max, 190px);
  margin-inline: auto;
}
.lp-tile__img { object-fit: contain; }

/* Same surface treatment as a brand tile: the sand fill read as a box drawn
   around the icon rather than as a tile. Only the aspect ratio still differs,
   and that is the source data talking -- category icons are square, brand
   logos are wide, and forcing either into the other's box letterboxes it. */
.lp-tile--category {
  aspect-ratio: 1 / 1;          /* icons are square at source */
  background: var(--lp-canvas);
  border: 1px solid var(--lp-line);
}
.lp-tile--category .lp-tile__img {
  padding: 16%;
  transition: transform var(--lp-base) var(--lp-ease-out);
}

.lp-tile--brand {
  aspect-ratio: 3 / 2;          /* logos are wide at source */
  background: var(--lp-canvas);
  border: 1px solid var(--lp-line);
}
.lp-tile--brand .lp-tile__img {
  padding: 14%;
  transition: transform var(--lp-base) var(--lp-ease-out);
}

/* Hover lift belongs to the card, not the tile, so both pages share it. */
.lp-tilecard:hover .lp-tile--category .lp-tile__img { transform: translateY(-3px) scale(1.05); }
.lp-tilecard:hover .lp-tile--brand .lp-tile__img { transform: translateY(-3px) scale(1.04); }
.lp-tilecard:hover .lp-tile--brand,
.lp-tilecard:hover .lp-tile--category { border-color: transparent; box-shadow: var(--lp-shadow-md); }
.lp-tilecard { display: block; color: inherit; text-decoration: none; transition: transform var(--lp-base) var(--lp-ease-out); }
.lp-tilecard:hover { transform: translateY(-4px); }
.lp-tilecard__name {
  display: block; margin-block-start: 12px; text-align: center;
  font-size: 14px; font-weight: 600; color: var(--lp-ink);
}
.lp-band--dark .lp-tilecard__name,
.lp-band--deepest .lp-tilecard__name,
.lp-band--on-light .lp-tilecard__name { color: var(--lp-on-dark); }

/* =============================================================================
   Catalogue pages: /products, /brands, /categories
   ========================================================================== */

.lp-page { padding-block: clamp(32px, 5vw, 64px) clamp(48px, 7vw, 96px); }
.lp-page__head { max-width: 72ch; margin-block-end: clamp(28px, 4vw, 44px); }
.lp-page__title {
  margin: 0; font-family: var(--lp-display);
  font-size: clamp(30px, 4.6vw, 54px); font-weight: 700;
  letter-spacing: -.03em; line-height: 1.06; color: var(--lp-ink);
}
.lp-page__lead { margin: 14px 0 0; font-size: 16px; line-height: 1.6; color: var(--lp-muted); }
.lp-page__count { margin: 0 0 20px; font-size: 13px; color: var(--lp-muted); }

/* Applied-filter chips on /brands and /categories: what the list is narrowed
   to, and the way out of it. Distinct from .lp-chip, which is a checkbox
   filter control -- this one states a filter that is already on. */
.lp-filterchips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 20px; }
.lp-filterchip {
  display: inline-flex; align-items: center; gap: 8px;
  /* Logical, so the clear button stays on the trailing edge in RTL. */
  padding-block: 7px; padding-inline: 14px 8px;
  border: 1px solid var(--lp-line); border-radius: 999px;
  background: var(--lp-surface); color: var(--lp-ink);
  font-size: 13px; font-weight: 600;
}
.lp-filterchip__label { color: var(--lp-muted); font-weight: 500; }
.lp-filterchip__clear {
  display: grid; place-items: center;
  width: 20px; height: 20px; border-radius: 999px;
  background: var(--lp-sand, rgba(0,0,0,.05)); color: var(--lp-muted);
  font-size: 15px; line-height: 1; text-decoration: none;
}
.lp-filterchip__clear:hover { background: var(--lp-accent); color: var(--lp-on-accent); }
/* The brand's unlock request, sitting beside its chip. It reuses the brand
   tile's own unlock styling (.lp-tilecard__unlock) so one request looks the
   same wherever it is made; only the tile's full-width block sizing is undone,
   because here it sits inline next to the chip. */
/* Two classes, deliberately: .lp-tilecard__unlock is defined LATER in this
   sheet, so a single-class selector here would lose to it on source order. */
.lp-tilecard__unlock.lp-filterchip__unlock { width: auto; margin-block-start: 0; padding: 7px 14px; font-size: 13px; }
/* The same request again, this time under a brand's own page heading. Sized to
   a page control rather than to a tile's full-width block. */
.lp-page__action { margin-block-start: 18px; }
.lp-tilecard__unlock.lp-page__unlock { width: auto; margin-block-start: 0; padding: 10px 20px; font-size: 14px; }

/* Product count under a tile, shown only while a cross-filter is applied. */
.lp-tilecard__meta { display: block; margin-top: 2px; font-size: 12px; color: var(--lp-muted); }
.lp-header__link.is-current { color: var(--lp-header-fg, var(--lp-ink)); }
.lp-header__link.is-current::after { transform: scaleX(1); }

/* Filters */
.lp-filters {
  display: flex; flex-direction: column; gap: 16px;
  padding: 20px; margin-block-end: 28px;
  background: var(--lp-sand); border-radius: var(--lp-radius-lg);
}
.lp-filters__row { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end; }
.lp-filters__row--toggles { align-items: center; }
.lp-filters__actions { display: flex; align-items: center; gap: 14px; margin-inline-start: auto; }
.lp-field { display: flex; flex-direction: column; gap: 6px; min-width: 170px; }
.lp-field--grow { flex: 1 1 240px; }
.lp-field__label {
  font-size: 11px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--lp-muted);
}
.lp-field input, .lp-field select {
  width: 100%; padding: 11px 14px; font: inherit; font-size: 14px;
  color: var(--lp-ink); background: var(--lp-canvas);
  border: 1px solid var(--lp-line); border-radius: 999px;
  transition: border-color var(--lp-fast) var(--lp-ease);
}
.lp-field input:focus, .lp-field select:focus { outline: none; border-color: var(--lp-accent); }

.lp-chip { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.lp-chip input { position: absolute; opacity: 0; pointer-events: none; }
.lp-chip span {
  display: inline-block; padding: 8px 16px; border-radius: 999px;
  border: 1px solid var(--lp-line); background: var(--lp-canvas);
  font-size: 13px; font-weight: 600; color: var(--lp-ink-soft);
  transition: background-color var(--lp-fast) var(--lp-ease), border-color var(--lp-fast) var(--lp-ease), color var(--lp-fast) var(--lp-ease);
}
.lp-chip input:checked + span { background: var(--lp-accent); border-color: var(--lp-accent); color: var(--lp-on-accent); }
.lp-chip input:focus-visible + span { outline: 2px solid var(--lp-accent-ring); outline-offset: 2px; }

/* Alphabetical index */
.lp-alpha { display: flex; flex-wrap: wrap; gap: 6px; }
.lp-alpha__item {
  display: grid; place-items: center; min-width: 34px; height: 34px; padding-inline: 8px;
  border-radius: 999px; border: 1px solid transparent;
  font-size: 13px; font-weight: 600; color: var(--lp-muted); text-decoration: none;
  transition: background-color var(--lp-fast) var(--lp-ease), color var(--lp-fast) var(--lp-ease);
}
.lp-alpha__item:hover { background: var(--lp-canvas); color: var(--lp-ink); }
.lp-alpha__item.is-active { background: var(--lp-ink); color: #fff; }

/* Grids */
.lp-grid { display: grid; gap: 22px; margin: 0; padding: 0; list-style: none; }
.lp-grid--products   { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
.lp-grid--brands     { grid-template-columns: repeat(auto-fill, minmax(150px, 190px)); justify-content: center; }
.lp-grid--categories { grid-template-columns: repeat(auto-fill, minmax(150px, 190px)); justify-content: center; }

/* The "Order" button every product card ends in. margin-block-start:auto is
   what pins it to the bottom of the column, so a one-line and a two-line
   product name still put their buttons on one line. */
/* Gold at rest (the card's "active" look) unless the Product slider widget
   sets --lp-buy-bg / --lp-buy-fg. Hovering the card makes it glow; hovering
   the button itself fills it from the leading edge -- ink with white text,
   or the widget's --lp-buy-hover-bg / --lp-buy-hover-fg. The fill is a
   pseudo-element under the label; a dark band swaps the default fill to
   white (see the band rules). */
.lp-card__buy {
  --lp-buy-base: var(--lp-buy-bg, var(--lp-accent));
  --lp-buy-ink: var(--lp-buy-fg, var(--lp-on-accent));
  --lp-buy-fill: var(--lp-buy-hover-bg, var(--lp-ink));
  --lp-buy-hover-ink: var(--lp-buy-hover-fg, #fff);
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin-block-start: auto; padding: 11px 16px;
  border: 1px solid var(--lp-buy-base); border-radius: 999px;
  font-size: 13.5px; font-weight: 600; color: var(--lp-buy-ink);
  text-decoration: none; background: var(--lp-buy-base);
  box-shadow: 0 6px 16px -8px color-mix(in srgb, var(--lp-buy-base) 60%, transparent);
  transition: background-color var(--lp-fast) var(--lp-ease), color var(--lp-fast) var(--lp-ease),
              border-color var(--lp-fast) var(--lp-ease), box-shadow var(--lp-base) var(--lp-ease);
}
.lp-card__buy::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: var(--lp-buy-fill);
  transform: scaleX(0); transform-origin: left center;
  transition: transform var(--lp-base) var(--lp-ease-out);
}
[dir="rtl"] .lp-card__buy::before { transform-origin: right center; }
.lp-card__buy svg { flex: none; transition: transform var(--lp-base) var(--lp-ease-out); }
.lp-card:hover .lp-card__buy { box-shadow: 0 12px 26px -8px color-mix(in srgb, var(--lp-buy-base) 80%, transparent); }
.lp-card:hover .lp-card__buy svg { transform: translateY(-1px); }
.lp-card__buy:hover,
.lp-card__buy:focus-visible {
  border-color: var(--lp-buy-fill); color: var(--lp-buy-hover-ink); outline: none;
}
.lp-card__buy:hover::before,
.lp-card__buy:focus-visible::before { transform: scaleX(1); }
.lp-card .lp-card__buy:hover svg { transform: translateY(-1px) rotate(-8deg); }
@media (prefers-reduced-motion: reduce) {
  .lp-card__buy::before { transition: none; }
}

@media (max-width: 560px) {
  .lp-grid--products { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .lp-grid--products .lp-card { padding: 6px; border-radius: 14px; }
  .lp-grid--products .lp-card__media { border-radius: 10px; }
  .lp-grid--products .lp-card__title { font-size: 13.5px; }
  .lp-grid--products .lp-card__buy { padding: 9px 10px; font-size: 12.5px; }
}

/* Empty state */
.lp-empty {
  padding: clamp(48px, 8vw, 96px) 24px; text-align: center;
  background: var(--lp-sand); border-radius: var(--lp-radius-lg);
}
.lp-empty h2 { margin: 0 0 10px; font-family: var(--lp-display); font-size: 22px; font-weight: 700; color: var(--lp-ink); }
.lp-empty p { margin: 0 0 22px; color: var(--lp-muted); }

/* Pagination — Laravel's Bootstrap paginator, restyled to the marketing set. */
.lp-pagination { margin-block-start: 40px; display: flex; justify-content: center; }
.lp-pagination .pagination { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin: 0; padding: 0; }
.lp-pagination .page-item .page-link {
  display: grid; place-items: center; min-width: 40px; height: 40px; padding-inline: 12px;
  border: 1px solid var(--lp-line); border-radius: 999px; background: var(--lp-canvas);
  font-size: 14px; font-weight: 600; color: var(--lp-ink-soft); text-decoration: none;
}
.lp-pagination .page-item .page-link:hover { border-color: var(--lp-ink); color: var(--lp-ink); }
.lp-pagination .page-item.active .page-link { background: var(--lp-ink); border-color: var(--lp-ink); color: #fff; }
.lp-pagination .page-item.disabled .page-link { opacity: .4; pointer-events: none; }
[dir="rtl"] .lp-pagination .page-item svg { transform: scaleX(-1); }

@media (max-width: 700px) {
  .lp-filters__actions { margin-inline-start: 0; width: 100%; }
  .lp-field { min-width: 100%; }
}

/* ---------- Admin-controlled chrome ---------- */

.lp-header__nav { min-width: 0; }
.lp-btn--outline {
  background: transparent;
  border-color: color-mix(in srgb, var(--lp-header-fg, var(--lp-ink)) 35%, transparent);
  color: var(--lp-header-fg, var(--lp-ink));
}
.lp-btn--outline:hover {
  background: var(--lp-header-fg, var(--lp-ink));
  color: var(--lp-header-bg, var(--lp-canvas));
  transform: translateY(-2px);
}

.lp-footer__logo { height: 33px; width: auto; }
.lp-footer__cols { display: flex; flex-wrap: wrap; gap: 40px; align-content: flex-start; }
.lp-footer__col { display: flex; flex-direction: column; gap: 10px; min-width: 140px; }
.lp-footer__coltitle {
  margin: 0 0 4px; font-family: var(--lp-display);
  font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: #fff;
}
.lp-footer__col a { font-size: 14px; text-decoration: none; transition: color var(--lp-fast) var(--lp-ease); }

.lp-social { display: flex; gap: 10px; margin: 18px 0 0; padding: 0; list-style: none; }
.lp-social a {
  display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.18); color: inherit;
  transition: background-color var(--lp-fast) var(--lp-ease), color var(--lp-fast) var(--lp-ease), transform var(--lp-fast) var(--lp-ease);
}
.lp-social a:hover { background: var(--lp-accent); border-color: var(--lp-accent); color: var(--lp-on-accent); transform: translateY(-2px); }

/* =============================================================================
   Per-section spacing (admin-controlled, BlockSchema::spacing)

   The admin enters pixels; blocks.blade.php emits the value as a custom
   property plus a marker class. A blank field emits neither, so that edge
   keeps the automatic rhythm above.

   These rules are LAST in the file on purpose. `.lp-widget + .lp-widget` and
   `.lp-widget.lp-sp--mt` carry the same specificity, so source order is what
   lets an explicit admin value win over the automatic one.
   ========================================================================== */

/* A section with a background needs inner padding or its content touches the
   band edge; this is the value an explicit padding entry overrides. */
.lp-band { padding-block: clamp(48px, 6vw, 92px); }

/* A value entered in the builder always wins -- 0 included -- over every
   automatic rhythm and every preset band padding above, hence !important on
   all four. */
.lp-widget.lp-sp--mt { margin-block-start: var(--lp-mt) !important; }
.lp-widget.lp-sp--mb { margin-block-end:   var(--lp-mb) !important; }
.lp-widget.lp-sp--pt { padding-block-start: var(--lp-pt) !important; }
.lp-widget.lp-sp--pb { padding-block-end:   var(--lp-pb) !important; }

/* The automatic gap between two sections lives on the LOWER one's margin top.
   Once the upper section has an explicit margin bottom, that value is the
   gap: the lower section drops its automatic top margin. An explicit margin
   top on the lower section still applies, and adds to it. */
.lp-widget.lp-sp--mb + .lp-widget:not(.lp-sp--mt) { margin-block-start: 0 !important; }

/* Widget-internal outer spacing yields to an explicit section padding. */
.lp-widget.lp-sp--pt .lp-banner-shell { padding-block-start: 0; }


/* -----------------------------------------------------------------------------
   Explicit DARK text on a custom background.

   `.lp-band--on-dark` set the root colour, but each descendant (titles, card
   text, quotes, stats) has its own colour rule, so they kept whatever the band
   preset gave them. These put the normal ink ramp back, which is what "dark
   text" has to mean on a light custom colour or photo.
   -------------------------------------------------------------------------- */
.lp-band--on-dark,
.lp-band--on-dark .lp-section__subtitle { color: var(--lp-ink-soft); }
.lp-band--on-dark .lp-section__title,
.lp-band--on-dark .lp-card__title,
.lp-band--on-dark .lp-card__amount,
.lp-band--on-dark .lp-tilecard__name,
.lp-band--on-dark .lp-quote__text,
.lp-band--on-dark .lp-quote__author strong,
.lp-band--on-dark .lp-faq__q,
.lp-band--on-dark .lp-trust__text strong,
.lp-band--on-dark .lp-countdown__headline,
.lp-band--on-dark .lp-stats__value { color: var(--lp-ink); }
.lp-band--on-dark .lp-card__brand,
.lp-band--on-dark .lp-card__cta,
.lp-band--on-dark .lp-stats__label,
.lp-band--on-dark .lp-trust__text em,
.lp-band--on-dark .lp-faq__a,
.lp-band--on-dark .lp-quote__author em { color: var(--lp-muted); }
.lp-band--on-dark .lp-link { color: var(--lp-ink); }
.lp-band--on-dark .lp-carousel__btn { background: var(--lp-canvas); border-color: var(--lp-line); color: var(--lp-ink); }
.lp-band--on-dark .lp-faq__list, .lp-band--on-dark .lp-faq__item { border-color: var(--lp-line); }
.lp-band--on-dark .lp-dot { background: var(--lp-line); }
.lp-band--on-dark .lp-dot.is-active { background: var(--lp-ink); }

/* =============================================================================
   Locked access + the public product page.

   Appended LAST so these rules sit after the card and tile blocks they extend,
   which is what lets `.lp-card__buy--locked` override the plain buy chip's
   colours without raising specificity.
   ========================================================================== */

/* ---------- Locked state ---------- */

/* A locked card keeps its full imagery -- browsing is allowed, buying is not --
   so the signal is the button, not a dimmed tile. */
.lp-card__buy--locked,
.lp-tilecard__unlock {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  width: 100%; margin-block-start: 12px; padding: 10px 14px;
  border: 1px solid var(--lp-accent); border-radius: 999px;
  font: inherit; font-size: 13px; font-weight: 600;
  background: var(--lp-accent-soft); color: var(--lp-accent-ink);
  cursor: pointer;
  transition: background-color var(--lp-fast) var(--lp-ease), color var(--lp-fast) var(--lp-ease);
}
.lp-card__buy--locked:hover,
.lp-tilecard__unlock:hover { background: var(--lp-accent); color: var(--lp-on-accent); }

/* Inside a product card the locked chip is the SAME bottom slot as the plain
   buy chip, so it takes the same auto margin — otherwise a locked card and an
   open one beside it put their buttons on two different lines. A brand tile
   is not a flex column and keeps the fixed 12px above. */
.lp-card .lp-card__buy--locked { margin-block-start: auto; }

/* Already asked. Muted and inert on purpose: the request is with a human now,
   so the chip reports rather than invites. Kept at the same size so a grid of
   cards does not reflow as requests go out. */
.lp-card__buy--locked.is-lp-requested,
.lp-tilecard__unlock.is-lp-requested {
  border-color: var(--lp-line);
  background: var(--lp-sand);
  color: var(--lp-muted);
  cursor: default;
}
.lp-card__buy--locked.is-lp-requested:hover,
.lp-tilecard__unlock.is-lp-requested:hover {
  background: var(--lp-sand);
  color: var(--lp-muted);
}

/* On a dark band the tint has nothing to sit on, so the chip carries its own. */
.lp-band--dark .lp-card__buy--locked,
.lp-band--deepest .lp-card__buy--locked,
.lp-band--dark .lp-tilecard__unlock,
.lp-band--deepest .lp-tilecard__unlock { background: transparent; color: var(--lp-accent); }

/* ---------- Unlock request modal ---------- */

.lp-unlock {
  position: fixed; inset: 0; z-index: 300;
  display: grid; place-items: center; padding: 20px;
  background: rgba(20, 17, 15, .55);
}
/* REQUIRED, not belt-and-braces. The `hidden` attribute only works through the
   UA stylesheet's `[hidden] { display: none }`, and ANY author `display` beats
   the UA sheet -- so the `display: grid` above would otherwise keep this
   overlay on screen permanently, empty, on every page a reseller opens. The
   portal's own overlay carries the same pairing (design-system.css,
   `.bl-overlay[hidden]`); never set `display` on a [hidden] element without it. */
.lp-unlock[hidden] { display: none; }
.lp-unlock__card {
  position: relative; width: min(460px, 100%);
  padding: 30px 26px 24px;
  background: var(--lp-canvas); border-radius: var(--lp-radius-lg);
  box-shadow: var(--lp-shadow-lg);
  max-height: calc(100vh - 40px); overflow-y: auto;
}
.lp-unlock__x {
  position: absolute; inset-block-start: 14px; inset-inline-end: 14px;
  display: grid; place-items: center; width: 32px; height: 32px;
  background: none; border: 0; border-radius: 50%;
  color: var(--lp-muted); cursor: pointer;
}
.lp-unlock__x:hover { background: var(--lp-sand); color: var(--lp-ink); }

.lp-unlock__head { display: flex; gap: 14px; align-items: flex-start; margin-block-end: 18px; }
.lp-unlock__icon {
  flex-shrink: 0; display: grid; place-items: center; width: 42px; height: 42px;
  border-radius: 12px; background: var(--lp-accent-soft); color: var(--lp-accent-ink);
}
.lp-unlock__title {
  margin: 0 0 6px; font-family: var(--lp-display);
  font-size: 19px; font-weight: 700; color: var(--lp-ink); line-height: 1.25;
}
.lp-unlock__title--center { text-align: center; }
.lp-unlock__desc { margin: 0; font-size: 14px; line-height: 1.55; color: var(--lp-ink-soft); }
.lp-unlock__desc--center { text-align: center; margin-block-end: 22px; }

.lp-unlock__note {
  margin: 0 0 18px; padding: 12px 14px;
  background: var(--lp-sand); border-radius: var(--lp-radius);
  font-size: 13px; line-height: 1.5; color: var(--lp-ink-soft);
}
.lp-unlock__error {
  margin: 0 0 14px; padding: 11px 14px;
  background: #FDECEC; border-radius: var(--lp-radius);
  font-size: 13px; color: #8B2020;
}

.lp-unlock__foot { display: flex; justify-content: flex-end; gap: 10px; flex-wrap: wrap; }
.lp-unlock__foot .lp-btn { padding: 11px 20px; font-size: 14px; }
.lp-unlock__block { width: 100%; justify-content: center; }

.lp-unlock__check {
  display: grid; place-items: center; width: 54px; height: 54px; margin: 6px auto 16px;
  border-radius: 50%; background: #E6F4EA; color: #1E7B3C;
}

.lp-btn--ghost {
  background: transparent; border: 1px solid var(--lp-line); color: var(--lp-ink-soft);
}
.lp-btn--ghost:hover { background: var(--lp-sand); color: var(--lp-ink); }

/* ---------- Public product page ----------
   The product card itself is the portal's: this page loads tokens.css +
   design-system.css and reuses the `.pdp-*` classes verbatim, so almost
   nothing is needed here. What IS needed is the handful of places the landing
   shell meets that card. */

/* `.pdp-cta` was written for a <button> in the portal, so it never had to
   cancel link underlining. Here it is also an <a> (sign in / view in portal). */
a.pdp-cta { text-decoration: none; }

/* The guest note under the buy bar, and the related strip, are landing
   furniture sitting inside the portal card's column. */
.lp-pdp__pricenote { margin: 12px 0 0; font-size: 13px; line-height: 1.5; color: var(--lp-muted); }
.lp-pdp__related { margin-block-start: clamp(32px, 5vw, 56px); }
.lp-pdp__related .lp-grid { margin-block-start: 18px; }

/* =============================================================================
   Product card quick-order panel (signed-in resellers only).

   Floats over the lower part of the card image. On devices that can hover it
   appears on hover or keyboard focus; elsewhere the round button in the image
   corner opens it (.is-lp-open, set by landing-card.js). A guest's card has
   neither the panel nor the button, so none of this applies to them.
   ========================================================================== */

.lp-card__panel {
  position: absolute; z-index: 3;
  inset-inline: 8px; inset-block-end: 8px;
  max-height: calc(100% - 16px); overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 10px;
  padding: 12px;
  border-radius: 12px;
  background: rgba(255, 255, 255, .93);
  -webkit-backdrop-filter: blur(12px) saturate(1.4);
  backdrop-filter: blur(12px) saturate(1.4);
  box-shadow: 0 12px 30px -12px rgba(20, 17, 15, .38);
  color: var(--lp-ink);
  opacity: 0; visibility: hidden; transform: translateY(14px);
  transition: opacity var(--lp-base) var(--lp-ease-out),
              transform var(--lp-base) var(--lp-ease-out),
              visibility 0s linear var(--lp-base);
}
.lp-card.is-lp-open .lp-card__panel {
  opacity: 1; visibility: visible; transform: none; transition-delay: 0s;
}
@media (hover: hover) and (pointer: fine) {
  .lp-card.has-lp-panel:hover .lp-card__panel,
  .lp-card.has-lp-panel:focus-within .lp-card__panel {
    opacity: 1; visibility: visible; transform: none; transition-delay: 0s;
  }
}

/* Touch-screen opener. Takes the lock mark's corner on a locked card. */
.lp-card__quick {
  position: absolute; z-index: 4; inset-block-start: 10px; inset-inline-end: 10px;
  display: none; place-items: center; width: 38px; height: 38px; padding: 0;
  border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .94); color: var(--lp-ink);
  box-shadow: var(--lp-shadow-sm); cursor: pointer;
  transition: background-color var(--lp-fast) var(--lp-ease), color var(--lp-fast) var(--lp-ease);
}
.lp-card.is-lp-locked .lp-card__quick { color: var(--lp-accent-ink); }
.lp-card.is-lp-open .lp-card__quick { background: var(--lp-ink); color: #fff; }
.lp-card.is-lp-open .lp-card__quick svg { display: none; }

/* ---- Favourite heart on a card -----------------------------------------
   Top corner, like the portal card's heart. It used to sit in a bottom
   corner, which is exactly where the quick-order panel opens -- the heart
   covered the quantity stepper's minus button. The top-start corner is the
   sale badge's, so it takes the top-end one and steps down below whatever
   else lives there: the padlock on a locked card, the quick-order button on a
   touch screen (see the (hover: none) block below). Outline at rest, filled
   once it is on the list -- the same read as the portal card's own heart. */
.lp-card__fav {
  position: absolute; z-index: 4;
  inset-block-start: 10px; inset-inline-end: 10px;
  display: grid; place-items: center; width: 32px; height: 32px; padding: 0;
  border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .94); color: var(--lp-muted);
  box-shadow: var(--lp-shadow-sm); cursor: pointer;
  transition: color var(--lp-fast) var(--lp-ease), transform var(--lp-fast) var(--lp-ease);
}
.lp-card__fav svg { width: 16px; height: 16px; }
.lp-card__fav:hover { color: #C8432F; transform: scale(1.08); }
.lp-card__fav.is-lp-fav { color: #C8432F; }
.lp-card__fav.is-lp-fav svg { fill: currentColor; }
.lp-card__fav[disabled] { opacity: .6; cursor: default; }
.lp-card__fav:focus-visible { outline: 2px solid var(--lp-accent); outline-offset: 2px; }
/* Below the padlock (30px at 10px) on a locked card. */
.lp-card.is-lp-locked .lp-card__fav { inset-block-start: 46px; }
.lp-card.is-lp-open .lp-card__quick::before { content: "\00D7"; font-size: 24px; line-height: 1; }
@media (hover: none), (pointer: coarse) {
  .lp-card__quick { display: grid; }
  .has-lp-panel .lp-card__lockmark { display: none; }
  /* Below the quick-order button (38px at 10px), which takes the padlock's
     corner here; and out of the way while the panel covers the image. */
  .has-lp-panel .lp-card__fav,
  .has-lp-panel.is-lp-locked .lp-card__fav { inset-block-start: 56px; }
  .lp-card.is-lp-open .lp-card__fav { visibility: hidden; }
  /* Open over the whole image, clear of the close button. */
  .lp-card__panel { inset: 0; max-height: none; border-radius: 12px; padding-block-start: 56px; }
}

/* Options */
.lp-opt { display: flex; flex-direction: column; gap: 6px; }
.lp-opt__label {
  font-size: 10.5px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--lp-muted);
}
.lp-opt__values { display: flex; flex-wrap: wrap; gap: 6px; }

.lp-swatch {
  --lp-swatch: var(--lp-line);
  width: 24px; height: 24px; padding: 0; flex: none;
  border: 2px solid #fff; border-radius: 50%;
  background: var(--lp-swatch);
  box-shadow: 0 0 0 1px var(--lp-line);
  cursor: pointer;
  transition: box-shadow var(--lp-fast) var(--lp-ease), transform var(--lp-fast) var(--lp-ease), opacity var(--lp-fast) var(--lp-ease);
}
.lp-swatch:hover { transform: scale(1.1); }
.lp-swatch.is-active { box-shadow: 0 0 0 2px var(--lp-ink); }

.lp-optchip {
  padding: 5px 10px;
  border: 1px solid var(--lp-line); border-radius: 999px;
  background: #fff; font: inherit; font-size: 12px; font-weight: 600; line-height: 1.2;
  color: var(--lp-ink-soft); cursor: pointer;
  transition: background-color var(--lp-fast) var(--lp-ease), border-color var(--lp-fast) var(--lp-ease),
              color var(--lp-fast) var(--lp-ease), opacity var(--lp-fast) var(--lp-ease);
}
.lp-optchip:hover { border-color: var(--lp-ink); color: var(--lp-ink); }
.lp-optchip.is-active { background: var(--lp-ink); border-color: var(--lp-ink); color: #fff; }

/* No orderable combination with the rest of the selection. Still clickable:
   picking it is how the reseller finds out why. */
.lp-swatch.is-unavailable,
.lp-optchip.is-unavailable { opacity: .38; }
.lp-optchip.is-unavailable { text-decoration: line-through; }
.lp-swatch.is-unavailable.is-active,
.lp-optchip.is-unavailable.is-active { opacity: .7; }

.lp-swatch:focus-visible,
.lp-optchip:focus-visible,
.lp-qty__btn:focus-visible,
.lp-card__add:focus-visible,
.lp-card__unlock:focus-visible,
.lp-card__quick:focus-visible { outline: 2px solid var(--lp-accent); outline-offset: 2px; }

/* Quantity + add */
.lp-card__panel-row { display: flex; align-items: stretch; gap: 8px; }
.lp-qty {
  display: flex; align-items: stretch; flex: none;
  border: 1px solid var(--lp-line); border-radius: 999px;
  background: #fff; overflow: hidden;
}
.lp-qty__btn {
  width: 30px; padding: 0; border: 0; background: none;
  font: inherit; font-size: 16px; font-weight: 600; line-height: 1;
  color: var(--lp-ink); cursor: pointer;
}
.lp-qty__btn:hover:not(:disabled) { background: var(--lp-sand); }
.lp-qty__btn:disabled { color: var(--lp-faint); cursor: default; }
.lp-qty__input {
  width: 40px; min-width: 0; padding: 0; border: 0;
  background: transparent; text-align: center;
  font: inherit; font-size: 13px; font-weight: 700; color: var(--lp-ink);
  -moz-appearance: textfield; appearance: textfield;
}
.lp-qty__input::-webkit-outer-spin-button,
.lp-qty__input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.lp-qty__input:focus { outline: none; background: var(--lp-sand); }

.lp-card__add {
  flex: 1 1 auto; min-width: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 12px;
  border: 0; border-radius: 999px;
  background: var(--lp-accent); color: var(--lp-on-accent);
  font: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer;
  transition: background-color var(--lp-fast) var(--lp-ease), box-shadow var(--lp-base) var(--lp-ease), transform var(--lp-fast) var(--lp-ease);
}
.lp-card__add svg { flex: none; }
.lp-card__add span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lp-card__add:hover:not(:disabled) { background: var(--lp-accent-hover); box-shadow: var(--lp-shadow-gold); }
.lp-card__add:active:not(:disabled) { transform: scale(.98); }
.lp-card__add:disabled { background: var(--lp-line); color: var(--lp-muted); cursor: not-allowed; }
.is-lp-busy .lp-card__add { cursor: progress; }

/* Locked card: a short note and the unlock request. */
.lp-card__panel-note {
  display: flex; align-items: center; gap: 6px; margin: 0;
  font-size: 12.5px; font-weight: 600; color: var(--lp-ink-soft);
}
.lp-card__panel-note svg { flex: none; color: var(--lp-accent-ink); }
.lp-card__unlock {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  width: 100%; padding: 10px 14px;
  border: 1px solid var(--lp-accent); border-radius: 999px;
  background: var(--lp-accent); color: var(--lp-on-accent);
  font: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
  transition: background-color var(--lp-fast) var(--lp-ease), box-shadow var(--lp-base) var(--lp-ease);
}
.lp-card__unlock:hover { background: var(--lp-accent-hover); box-shadow: var(--lp-shadow-gold); }
.lp-card__unlock.is-lp-requested,
.lp-card__unlock.is-lp-requested:hover {
  border-color: var(--lp-line); background: var(--lp-sand); color: var(--lp-muted);
  box-shadow: none; cursor: default;
}

/* Narrow cards: quantity and button stack. */
@media (max-width: 560px) {
  .lp-grid--products .lp-card__panel { padding: 8px; gap: 8px; }
  .lp-grid--products .lp-card__panel-row { flex-wrap: wrap; }
  .lp-grid--products .lp-qty { flex: 1 1 100%; justify-content: space-between; }
  .lp-grid--products .lp-card__add { flex-basis: 100%; }
}
@media (max-width: 560px) and (hover: none), (max-width: 560px) and (pointer: coarse) {
  .lp-grid--products .lp-card__panel { padding-block-start: 52px; }
}

/* ---------- Toast (quick-order result) ---------- */

.lp-toast {
  position: fixed; z-index: 320;
  inset-inline: 0; inset-block-end: 20px; margin-inline: auto;
  width: max-content; max-width: calc(100vw - 32px);
  display: flex; align-items: center; gap: 12px;
  padding-block: 12px; padding-inline: 16px 10px;
  border-radius: 14px;
  background: var(--lp-ink); color: #fff;
  box-shadow: var(--lp-shadow-lg);
  font-size: 14px; font-weight: 500; line-height: 1.4;
  opacity: 0; transform: translateY(12px);
  transition: opacity .25s var(--lp-ease), transform .25s var(--lp-ease-out);
}
/* `display` above would otherwise beat the [hidden] attribute. */
.lp-toast[hidden] { display: none; }
.lp-toast.is-visible { opacity: 1; transform: none; }
.lp-toast::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--lp-accent); }
.lp-toast--success::before { background: #3DD68C; }
.lp-toast--error::before { background: #FF6B6B; }
.lp-toast__text { flex: 1 1 auto; }
.lp-toast__link { flex: none; color: var(--lp-accent); font-weight: 700; text-decoration: none; white-space: nowrap; }
.lp-toast__link:hover { text-decoration: underline; }
.lp-toast__close {
  flex: none; padding: 0 6px; border: 0; background: none;
  color: rgba(255, 255, 255, .6); font-size: 22px; line-height: 1; cursor: pointer;
}
.lp-toast__close:hover { color: #fff; }

/* =============================================================================
   Navbar search (header setting "Show search in header").
   ========================================================================== */

.lp-header__inner { position: relative; }
.lp-search { position: relative; }

.lp-search__toggle {
  display: grid; place-items: center; width: 38px; height: 38px; padding: 0;
  border: 1px solid color-mix(in srgb, var(--lp-header-fg, var(--lp-ink)) 18%, transparent);
  border-radius: 50%; background: none;
  color: var(--lp-header-fg, var(--lp-ink)); cursor: pointer;
  transition: border-color var(--lp-fast) var(--lp-ease), background-color var(--lp-fast) var(--lp-ease);
}
.lp-search__toggle:hover,
.lp-search.is-open .lp-search__toggle { border-color: var(--lp-header-fg, var(--lp-ink)); }
.lp-search__toggle:focus-visible { outline: 2px solid var(--lp-accent); outline-offset: 2px; }

/* ---- Header reseller icons (favourites, cart) ---------------------------
   Same 38px circle as the search toggle beside them, so the action row reads
   as one set rather than three different controls. Rendered for a signed-in
   reseller only. */
.lp-header__icon {
  position: relative;
  display: grid; place-items: center; width: 38px; height: 38px; flex: none;
  border: 1px solid color-mix(in srgb, var(--lp-header-fg, var(--lp-ink)) 18%, transparent);
  border-radius: 50%;
  color: var(--lp-header-fg, var(--lp-ink)); text-decoration: none;
  transition: border-color var(--lp-fast) var(--lp-ease), color var(--lp-fast) var(--lp-ease);
}
.lp-header__icon:hover { border-color: var(--lp-header-fg, var(--lp-ink)); }
.lp-header__icon:focus-visible { outline: 2px solid var(--lp-accent); outline-offset: 2px; }
/* Logical inset so the badge stays on the trailing corner in RTL. */
.lp-header__count {
  position: absolute; inset-block-start: -3px; inset-inline-end: -3px;
  min-width: 17px; height: 17px; padding-inline: 4px;
  display: grid; place-items: center;
  border-radius: 999px; background: var(--lp-accent); color: var(--lp-on-accent);
  font-size: 10px; font-weight: 700; line-height: 1;
}

.lp-search__panel {
  position: absolute; z-index: 20;
  inset-block-start: calc(100% + 10px); inset-inline-end: 0;
  width: min(460px, calc(100vw - 32px));
  background: #fff; color: var(--lp-ink-soft);
  border: 1px solid var(--lp-line); border-radius: 16px;
  box-shadow: var(--lp-shadow-lg);
  overflow: hidden;
  animation: lp-search-in .22s var(--lp-ease-out);
}
/* `display` is not set above, but keep the pairing explicit for safety. */
.lp-search__panel[hidden] { display: none; }
@keyframes lp-search-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

.lp-search__form {
  display: flex; align-items: center; gap: 10px;
  padding-block: 10px; padding-inline: 14px 10px;
  border-block-end: 1px solid var(--lp-line);
}
.lp-search__icon { flex: none; color: var(--lp-muted); }
.lp-search__input {
  flex: 1 1 auto; min-width: 0; padding: 8px 0;
  border: 0; background: none; outline: none;
  font: inherit; font-size: 15px; color: var(--lp-ink);
}
.lp-search__input::-webkit-search-cancel-button { -webkit-appearance: none; }
.lp-search__close {
  flex: none; display: grid; place-items: center; width: 32px; height: 32px; padding: 0;
  border: 0; border-radius: 50%; background: none; color: var(--lp-muted); cursor: pointer;
}
.lp-search__close:hover { background: var(--lp-sand); color: var(--lp-ink); }
.lp-search.is-loading .lp-search__icon { animation: lp-search-pulse .9s var(--lp-ease) infinite alternate; }
@keyframes lp-search-pulse { to { color: var(--lp-accent); } }

.lp-search__results { max-height: min(62vh, 520px); overflow-y: auto; overscroll-behavior: contain; padding: 6px; }
.lp-search__status { margin: 0; padding: 18px 12px; font-size: 13.5px; color: var(--lp-muted); text-align: center; }

.lp-search__group + .lp-search__group { border-block-start: 1px solid var(--lp-line-soft); margin-block-start: 4px; padding-block-start: 4px; }
.lp-search__heading {
  margin: 0; padding: 10px 10px 6px;
  font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--lp-muted);
}
.lp-search__list { margin: 0; padding: 0; list-style: none; }

.lp-search__item {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 10px; border-radius: 10px;
  color: var(--lp-ink); text-decoration: none; outline: none;
  transition: background-color var(--lp-fast) var(--lp-ease);
}
.lp-search__item:hover,
.lp-search__item:focus-visible { background: var(--lp-sand); }

.lp-search__thumb {
  flex: none; display: grid; place-items: center;
  width: 40px; height: 40px; border-radius: 8px; overflow: hidden;
  background: var(--lp-canvas); border: 1px solid var(--lp-line-soft);
}
.lp-search__thumb img { width: 100%; height: 100%; object-fit: cover; }
.lp-search__thumb--brand img { object-fit: contain; padding: 4px; }
.lp-search__noimg { width: 14px; height: 14px; border-radius: 4px; background: var(--lp-line); }

.lp-search__text { display: flex; flex-direction: column; min-width: 0; }
.lp-search__name {
  font-size: 14px; font-weight: 600; line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lp-search__name mark { background: var(--lp-accent-soft); color: var(--lp-accent-ink); border-radius: 3px; padding: 0 1px; }
.lp-search__meta { font-size: 12px; color: var(--lp-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.lp-search__all {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin: 6px 4px 4px; padding: 11px 12px; border-radius: 10px;
  background: var(--lp-ink); color: #fff;
  font-size: 13.5px; font-weight: 600; text-decoration: none; outline: none;
  transition: background-color var(--lp-fast) var(--lp-ease), color var(--lp-fast) var(--lp-ease);
}
.lp-search__all:hover,
.lp-search__all:focus-visible { background: var(--lp-accent); color: var(--lp-on-accent); }
[dir="rtl"] .lp-search__all svg { transform: scaleX(-1); }

/* On a phone the panel spans the header, not the toggle's corner. */
@media (max-width: 860px) {
  .lp-search { position: static; }
  .lp-search__panel {
    inset-block-start: 100%;
    inset-inline: var(--lp-gutter);
    width: auto;
  }
}
@media (prefers-reduced-motion: reduce) {
  .lp-search__panel,
  .lp-search.is-loading .lp-search__icon { animation: none; }
}

/* =============================================================================
   Section widget: several widgets side by side in a 12-column row.

   Each child spans --lp-span columns (SectionWidget). With "equal height"
   (lp-section--stretch) every column is as tall as the tallest one and the
   child widget fills its column. At 860px and below the columns stack, one
   widget per row, at their natural height.
   ========================================================================== */

.lp-section {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--lp-section-gap, 24px);
  align-items: stretch;
}
.lp-section--start  { align-items: start; }
.lp-section--center { align-items: center; }
/* Full width still keeps the page gutter, so product text does not touch the
   screen edge. */
.lp-section--full { padding-inline: var(--lp-gutter); }

.lp-section__cell {
  grid-column: span var(--lp-span, 12);
  min-width: 0;
  display: flex; flex-direction: column;
}
.lp-section__cell > :not(script) { flex: 1 1 auto; min-height: 0; }

/* The section owns the page width and gutter; a child's own shell must not
   add a second one inside the column. */
.lp-section__cell .lp-shell { max-width: none; padding-inline: 0; }
.lp-section__cell .lp-banner__content { padding-inline: clamp(20px, 4vw, 48px); }
.lp-section__cell .lp-banner-shell { padding-block-start: 0; }

/* Equal height: an ad block fills its column while keeping each image's own
   size in proportion.

   - Every image reserves its own height with a spacer (::before, padding as a
     multiple of its width -- --lp-ads-tall, e.g. 2 for 1:2, 0.5 for 2:1). That
     is the height the block asks the section for, so when the ad block is the
     tallest column every image is exactly its chosen size.
   - Rows share any extra height in proportion to those sizes
     (--lp-ads-stretch-rows, e.g. "2fr 0.5fr 0.5fr"), so when a neighbour is
     taller the images grow together and keep their relative sizes; the
     picture covers its box. */
@media (min-width: 861px) {
  .lp-section--stretch .lp-section__cell > .lp-ads {
    grid-template-rows: var(--lp-ads-stretch-rows, repeat(var(--lp-ads-rows, 1), minmax(0, 1fr)));
  }
  .lp-section--stretch .lp-section__cell > .lp-ads .lp-ads__item {
    position: relative; min-height: 0;
    aspect-ratio: auto; align-self: stretch;
  }
  .lp-section--stretch .lp-section__cell > .lp-ads .lp-ads__item::before {
    content: ""; display: block;
    padding-block-start: calc(var(--lp-ads-tall, 1) * 100%);
  }
  .lp-section--stretch .lp-section__cell > .lp-ads .lp-ads__item > a,
  .lp-section--stretch .lp-section__cell > .lp-ads .lp-ads__item > picture {
    position: absolute; inset: 0;
  }
}

@media (max-width: 860px) {
  .lp-section { grid-template-columns: minmax(0, 1fr); }
  .lp-section__cell { grid-column: auto; }
}

/* Builder preview only: a column whose widget has nothing to show yet. */
.lp-section__placeholder {
  display: grid; place-items: center; min-height: 160px; padding: 20px;
  border: 1px dashed var(--lp-line); border-radius: var(--lp-radius);
  background: var(--lp-sand); color: var(--lp-muted);
  font-size: 13px; font-weight: 600; text-align: center;
}
.lp-section__placeholder--empty { grid-column: 1 / -1; }
