/* =========================================================
   Engines & Spare Parts — Landing
   Scoped port of html/assets/css/style.css: every selector sits under
   .esp-landing (the <main> wrapper) so the theme header/footer are untouched.
   Regenerate from the static build with scope-css.js, then re-append the
   "Theme neutralisers" block at the end of this file.

   1. Reset
   2. Tokens
   3. Base typography
   4. Layout utilities
   5. Components
   6. Sections (design order)
   7. Theme neutralisers (Bootstrap 4 + custom.css collisions)
   ========================================================= */

/* ---------- 1. Reset ---------- */
.esp-landing *,
.esp-landing *::before,
.esp-landing *::after { box-sizing: border-box; }



.esp-landing h1,
.esp-landing h2,
.esp-landing h3,
.esp-landing h4,
.esp-landing p,
.esp-landing ul,
.esp-landing figure { margin: 0; }

.esp-landing ul { padding: 0; list-style: none; }

.esp-landing img,
.esp-landing picture,
.esp-landing svg { display: block; max-width: 100%; }

.esp-landing img { height: auto; }

.esp-landing a { color: inherit; text-decoration: none; }

.esp-landing button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

/* ---------- 2. Tokens ---------- */
.esp-landing {
  /* brand */
  --c-red: #d11515;
  --c-red-dark: #ad1010;
  --c-navy: #150a5d;

  /* neutrals — sampled from the comp, refine per section */
  --c-ink: #14142b;
  --c-body: #5c5c6e;
  --c-muted: #7a7a88;
  --c-line: #e3e3ea;
  --c-bg: #ffffff;
  --c-bg-alt: #f7f8fa;
  --c-media-bg: #f5f3f6;      /* behind product photos (object-fit: contain) */

  /* comp text navy — headings on light sections, trust strip, badge label */
  --c-navy-text: #043673;

  /* type */
  --font: "Jost", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-ui: "Roboto", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* layout */
  --container: calc(1360 * var(--px));
  --gutter: calc(16 * var(--px));
  --header-h: 144px;
  --header-h-mobile: 64px;

  /* shape */
  --radius: 0;

  /* scale unit — every length is written calc(N * var(--px)), N = the comp's
     px value. 1px below 1200 (tablet/mobile layouts are unchanged). */
  --px: 1px;
}

/* From 1200 the page scales with the viewport against the 1920 comp:
   1920 -> 1px, floor 0.8 (reached at 1536) so text stays readable on laptops,
   cap 1.3 (reached at 2496) for big screens. Scoped to .esp-landing — the
   theme header/footer are not scaled. Values of 1-2px (hairlines, borders),
   media queries and rules inside max-width queries stay in px. Font sizes are
   max(calc(N * var(--px)), 12px) so text never drops below 12px (sizes under
   12 keep their own value) while still growing on big screens. */
@media (min-width: 1200px) {
  .esp-landing { --px: clamp(0.8px, calc(100vw / 1920), 1.3px); }
}

/* ---------- 3. Base typography ---------- */
.esp-landing {
  font-family: var(--font);
  font-size: max(calc(16 * var(--px)), 12px);
  line-height: 1.6;
  color: var(--c-body);
  background: var(--c-bg);
  -webkit-font-smoothing: antialiased;
}

.esp-landing h1,
.esp-landing h2,
.esp-landing h3 {
  color: var(--c-ink);
  font-weight: 600;
  line-height: 1.18;
  letter-spacing: -0.01em;
}

/* ---------- 4. Layout utilities ---------- */
/* The container IS the comp's 1360 content box — the gutter is subtracted from
   the viewport rather than added inside, so DevTools reports 1360, not 1440.
   1920 -> 1360 (280 each side, as the comp)   393 -> 361 (16 each side) */
.esp-landing .container {
  width: min(100% - var(--gutter) * 2, var(--container));
  margin-inline: auto;
}

@media (min-width: 1024px) {
  .esp-landing { --gutter: calc(40 * var(--px)); }
}

.esp-landing .skip-link {
  position: absolute;
  left: calc(-9999 * var(--px));
  top: 0;
  z-index: 100;
  padding: calc(12 * var(--px)) calc(20 * var(--px));
  background: var(--c-ink);
  color: #fff;
}
.esp-landing .skip-link:focus { left: 0; }

.esp-landing a:focus-visible,
.esp-landing button:focus-visible {
  outline: 2px solid var(--c-red);
  outline-offset: calc(3 * var(--px));
}

.esp-landing .u-desktop-break { display: none; }
@media (min-width: 1200px) { .esp-landing .u-desktop-break { display: inline; } }

/* ---------- 5. Components ---------- */
/* comp: gap 10, radius 0, borders drawn INSIDE via inset shadow so the box
   stays exactly the comp's width (primary 222, outline 227) */
.esp-landing .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: calc(10 * var(--px));
  padding: calc(12 * var(--px)) calc(25 * var(--px));
  border: 0;
  border-radius: var(--radius);
  font-size: max(calc(16 * var(--px)), 12px);
  font-weight: 500;
  line-height: 1.5;
  text-align: center;
  transition: background-color .2s ease, color .2s ease, box-shadow .2s ease;
}

.esp-landing .btn--primary {
  background: var(--c-red);
  color: #fff;
}

/* comp: no fill at all, 1px solid #FFFFFF stroke */
.esp-landing .btn--ghost {
  background: transparent;
  box-shadow: inset 0 0 0 1px #fff;
  color: #fff;
}

/* Hover comes from the live theme:
     .main-btn:hover { background: rgb(4,54,115); color: #fff; }   <- red goes NAVY
   and, only below 768, an override that keeps it red on touch:
     @media (max-width: 767.98px) .btn.main-btn:hover { background:#D11515 !important }  */
/* Hover effects apply only to a real mouse — `(hover: hover) and (pointer: fine)`
   — everywhere in this file, so a tap on phones / tablets never leaves a sticky
   hover state (user request, 24 Sep 2026). */
@media (hover: hover) and (pointer: fine) {
  .esp-landing .btn--primary:hover {
    background: var(--c-navy-text);
    color: #fff;
  }

  /* No live counterpart for the outline button (it is new in this comp), so it
     follows the primary's navy hover to stay in-system. */
  .esp-landing .btn--ghost:hover {
    background: var(--c-navy-text);
    box-shadow: inset 0 0 0 1px var(--c-navy-text);
    color: #fff;
  }
}

@media (hover: hover) and (pointer: fine) and (max-width: 767.98px) {
  .esp-landing .btn--primary:hover { background: var(--c-red); }
  .esp-landing .btn--ghost:hover {
    background: transparent;
    box-shadow: inset 0 0 0 1px #fff;
  }
}

.esp-landing .btn__icon {
  flex: 0 0 auto;
  width: calc(17 * var(--px));
  height: calc(17 * var(--px));
}

/* comp: 56px tall, padding 32/16, labels Roboto 14/21 w600, ls 1px, uppercase */
.esp-landing .btn--lg {
  min-height: calc(56 * var(--px));
  padding: calc(16 * var(--px)) calc(32 * var(--px));
  font-family: var(--font-ui);
  font-size: max(calc(14 * var(--px)), 12px);
  font-weight: 600;
  line-height: calc(21 * var(--px));
  letter-spacing: 1px;
  text-transform: uppercase;
}

.esp-landing .icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: calc(40 * var(--px));
  height: calc(40 * var(--px));
  color: var(--c-ink);
}
@media (hover: hover) and (pointer: fine) {
  .esp-landing .icon-btn:hover { color: var(--c-red); }
}

/* ---------- 6. Sections ---------- */

/* ---- Hero ---- */
.esp-landing .hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: calc(560 * var(--px));
  overflow: hidden;
  background: #0b2a4a;
  isolation: isolate;
}

.esp-landing .hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}

.esp-landing .hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
}

/* Banner scrim (::after gradient overlay) removed on request — it darkened
   the banner image against the design. */

.esp-landing .hero__inner {
  padding-block: calc(48 * var(--px)) calc(56 * var(--px));
  color: #fff;
}

.esp-landing .hero__eyebrow {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: calc(14 * var(--px));
  margin-bottom: calc(20 * var(--px));
}

/* comp: Roboto 14/21 w600, ls 1px, navy on white */
.esp-landing .hero__badge {
  display: inline-block;
  padding: calc(7 * var(--px)) calc(14 * var(--px));
  background: #fff;
  color: var(--c-navy-text);
  font-family: var(--font-ui);
  font-size: max(calc(14 * var(--px)), 12px);
  font-weight: 600;
  line-height: calc(21 * var(--px));
  letter-spacing: 1px;
  text-transform: uppercase;
}

/* keeps the rule glued to its label when the eyebrow wraps on mobile */
.esp-landing .hero__where {
  display: inline-flex;
  align-items: center;
  gap: calc(14 * var(--px));
}

.esp-landing .hero__rule {
  flex: 0 0 auto;
  width: calc(34 * var(--px));
  height: 1px;
  background: rgba(255, 255, 255, .7);
}

/* comp: Jost 12/20 w500, ls 2px */
.esp-landing .hero__place {
  font-size: max(calc(12 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(20 * var(--px));
  letter-spacing: 2px;
  text-transform: uppercase;
  color: #fff;
}

/* comp: Jost 64/68 w600, ls -1px, box 665 wide */
.esp-landing .hero__title {
  max-width: calc(665 * var(--px));
  color: #fff;
  font-size: clamp(2rem, 3.34vw, 4rem);
  font-weight: 600;
  line-height: 1.0625;
  letter-spacing: -1px;
}

/* comp: Jost 18/24 w400, box 538 wide */
.esp-landing .hero__text {
  max-width: calc(538 * var(--px));
  margin-top: calc(18 * var(--px));
  color: #fff;
  font-size: max(calc(18 * var(--px)), 12px);
  line-height: calc(24 * var(--px));
}

/* comp: container gap 12, padding-top 34 */
.esp-landing .hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: calc(12 * var(--px));
  margin-top: calc(34 * var(--px));
}

/* The comp's outline button sits its arrow tight against the label (box is
   227 = 64 padding + 144 label + 17 icon + 2), unlike the red button's 10px.
   Reproduced as drawn — say the word and it becomes 10px like the other. */
.esp-landing .hero__actions .btn--ghost { gap: 2px; }

/* comp mobile 12:124 (393 x 762): content bottom-aligned, 60 below the buttons */
@media (max-width: 767.98px) {
  .esp-landing .hero { min-height: 762px; }
  .esp-landing .hero__inner { padding-block: 40px 60px; }

  /* comp 12:124: scrim over the photo so the white copy reads — clear at the
     top, 35% black behind the text and buttons. Mobile only: the desktop
     overlay stays removed (user request, 25 Sep). Sits between the photo
     (z -2) and the copy. */
  .esp-landing .hero::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(193.31deg, rgba(0, 0, 0, 0) 41.19%, rgba(0, 0, 0, .35) 73.54%);
    pointer-events: none;
  }

  /* comp: badge on its own line, 14 above the rule + place row */
  .esp-landing .hero__eyebrow {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    margin-bottom: 22px;
  }

  /* comp: Roboto 16/21 w600, padding 11/5 */
  .esp-landing .hero__badge { padding: 5px 11px; font-size: 16px; }

  /* comp: 30 x 2 rule at 60% white, 9 from the label */
  .esp-landing .hero__where { gap: 9px; }
  .esp-landing .hero__rule { width: 30px; height: 2px; background: rgba(255, 255, 255, .6); }

  /* comp: Jost 14/20 w500, ls 2px */
  .esp-landing .hero__place { font-size: 14px; }

  /* comp: Jost 28/36 w600, ls -1px */
  .esp-landing .hero__title { max-width: none; font-size: 28px; line-height: 36px; }

  /* comp: Jost 16/24, 20 below the title */
  .esp-landing .hero__text { margin-top: 20px; font-size: 16px; line-height: 24px; }

  /* comp: full-width 52px buttons, 12 apart */
  .esp-landing .hero__actions { flex-direction: column; gap: 12px; }
  .esp-landing .hero__actions .btn { width: 100%; min-height: 52px; padding-block: 0; }
}

@media (min-width: 1200px) {
  /* comp: banner frame is 1920 x 825, content box 590 wide, 89px inset top and bottom */
  .esp-landing .hero { min-height: calc(825 * var(--px)); align-items: center; }
  .esp-landing .hero__inner { padding-block: calc(89 * var(--px)); }
  /* line breaks come from .u-desktop-break so the three lines match the comp */
  .esp-landing .hero__title { font-size: max(calc(64 * var(--px)), 12px); }
}

/* ---- Trust strip (sits directly under the banner; comp: 1920 x 109) ---- */
.esp-landing .trust {
  background: #eff3f8;          /* comp fill */
}

.esp-landing .trust__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: calc(24 * var(--px)) calc(32 * var(--px));
  padding-block: calc(32 * var(--px));          /* comp: 32 + 45 + 32 = 109 */
}

.esp-landing .trust__item {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--px));
  min-height: calc(45 * var(--px));
  color: var(--c-navy-text);
  font-size: max(calc(20 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(20 * var(--px));
}

.esp-landing .trust__item img {
  flex: 0 0 auto;
  width: calc(45 * var(--px));
  height: calc(45 * var(--px));
}

/* Four across only fits the 1360 desktop row; below that the flex wrap left a
   ragged 3 + 1, so switch to an even 2 x 2 for the whole tablet/mobile range. */
@media (max-width: 1023.98px) {
  .esp-landing .trust__list {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px 16px;
    padding-block: 28px;
  }
}

@media (max-width: 767.98px) {
  .esp-landing .trust__item { font-size: 16px; gap: 10px; }
  .esp-landing .trust__item img { width: 36px; height: 36px; }
}

/* ---- Shared section furniture ---- */

/* comp: Jost 16/20 w500, ls 2px, #707070 */
.esp-landing .eyebrow {
  color: #707070;
  font-size: max(calc(16 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(20 * var(--px));
  letter-spacing: 2px;
}

/* red rule to the left of an eyebrow + heading pair (comp: 5px bar, 50px gutter) */
.esp-landing .about__head {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: calc(8 * var(--px));
}

.esp-landing .about__head::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(-55 * var(--px));
  width: calc(5 * var(--px));
  background: var(--c-red);
}

/* ---- About ---- */
.esp-landing .about {
  background: #fff;
  padding-block: calc(100 * var(--px));
}

/* comp: 1360 = 617 copy + 61 gap + 682 media */
.esp-landing .about__grid {
  display: grid;
  grid-template-columns: 617fr 682fr;
  gap: calc(61 * var(--px));
  align-items: start;
}

.esp-landing .about__copy { padding-left: calc(55 * var(--px)); }

/* comp: Jost 46/55 w500, black */
.esp-landing .about__title {
  color: #000;
  font-size: max(calc(46 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(55 * var(--px));
  letter-spacing: 0;
}

/* comp: Jost 16/24 w300, #4E5A66 */
.esp-landing .about__text {
  margin-top: calc(24 * var(--px));
  max-width: calc(545 * var(--px));
  color: #4e5a66;
  font-size: max(calc(16 * var(--px)), 12px);
  font-weight: 300;
  line-height: calc(24 * var(--px));
}

.esp-landing .about__text strong {
  color: #10152f;
  font-weight: 500;
}

.esp-landing .about__offer { padding-top: calc(50 * var(--px)); }

/* comp: Jost 16/19 w500, ls 3px, navy */
.esp-landing .about__offer-title {
  color: var(--c-navy-text);
  font-size: max(calc(16 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(19 * var(--px));
  letter-spacing: calc(3 * var(--px));
}

/* comp: 9x2 red dash, 16px from the label */
.esp-landing .dash-list {
  display: flex;
  flex-direction: column;
  gap: calc(8 * var(--px));
  padding-top: calc(12 * var(--px));
}

.esp-landing .dash-list li {
  display: flex;
  align-items: flex-start;
  gap: calc(16 * var(--px));
  color: #4e5a66;
  font-size: max(calc(16 * var(--px)), 12px);
  line-height: calc(24 * var(--px));
}

.esp-landing .dash-list li::before {
  content: "";
  flex: 0 0 auto;
  width: calc(9 * var(--px));
  height: 2px;
  margin-top: calc(11 * var(--px));
  background: var(--c-red);
}

/* comp 30:103: a 682 x 488 frame with the photo ZOOMED inside it, not just
   fitted — image box 122.77% x 113.93%, offset -11.22% / -11.48%. That crops
   the hills off the top (sea only above the bow rail) and trims the winches
   at the bottom. The frame clips; object-fit keeps the photo's own ratio if
   the frame's proportions drift at other widths. */
.esp-landing .about__media {
  position: relative;
  overflow: hidden;
  height: calc(488 * var(--px));
}

.esp-landing .about__media img {
  position: absolute;
  top: -11.48%;
  left: -11.22%;
  width: 122.77%;
  max-width: none;
  height: 113.93%;
  object-fit: cover;
}

/* ---- Stats row (comp: 4 cards, 20px gap, 111 tall, #EFF3F8) ---- */
.esp-landing .stats {
  display: grid;
  grid-template-columns: 288fr 288fr 437fr 288fr;
  gap: calc(20 * var(--px));
  margin-top: calc(60 * var(--px));
}

/* comp: 24 pad + 32 value + (6 gap + 6 label inset) + 20 label + 24 pad = 111 */
.esp-landing .stats__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(12 * var(--px));
  padding: calc(24 * var(--px)) calc(16 * var(--px));
  background: #eff3f8;
  text-align: center;
}

/* comp: Jost 28/32 w500, navy */
.esp-landing .stats__value {
  color: var(--c-navy-text);
  font-size: max(calc(28 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(32 * var(--px));
}

/* comp: Jost 16/20 w400, ls 2px, #707070, capitalised */
.esp-landing .stats__label {
  color: #707070;
  font-size: max(calc(16 * var(--px)), 12px);
  line-height: calc(20 * var(--px));
  letter-spacing: 2px;
  text-transform: capitalize;
}

/* ---- Brands ---- */
.esp-landing .brands {
  background: #eff3f8;
  padding-block: calc(100 * var(--px));
}

.esp-landing .brands__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(60 * var(--px));
  padding-left: calc(55 * var(--px));
}

/* comp: Jost 46/46 w500, black */
.esp-landing .brands__title {
  color: #000;
  font-size: max(calc(46 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(46 * var(--px));
  letter-spacing: 0;
}

/* comp: Jost 16/24 w600, navy, with the red rule + round arrow */
.esp-landing .view-more {
  display: inline-flex;
  align-items: center;
  gap: calc(8 * var(--px));
  flex: 0 0 auto;
  color: var(--c-navy-text);
  font-size: max(calc(16 * var(--px)), 12px);
  font-weight: 600;
  line-height: calc(24 * var(--px));
  text-transform: uppercase;
}

.esp-landing .view-more__line { width: calc(55 * var(--px)); height: calc(16 * var(--px)); }

/* Live behaviour: the ring is a background image that swaps to the red variant
   on hover (theme rule `.view-more-btn:hover::after { background-image:
   read-more-round-red.svg }`). Grey ring #D1D1D1 -> red #FF0000, both at .65 alpha. */
.esp-landing .view-more__round {
  flex: 0 0 auto;
  width: calc(57 * var(--px));
  height: calc(57 * var(--px));
  margin-left: calc(-34 * var(--px));
  background: url("../icons/read-more-round.svg") center / contain no-repeat;
}

/* On hover the whole control goes red: label -> #D11515, ring -> red variant.
   (red-arrow.svg is already #FF0000, so the shaft needs no state change.) */
@media (hover: hover) and (pointer: fine) {
  .esp-landing .view-more:hover { color: var(--c-red); }

  .esp-landing .view-more:hover .view-more__round {
    background-image: url("../icons/read-more-round-red.svg");
  }
}

/* The live site made the label red at rest below 768; the mobile comp (12:40)
   keeps it navy like desktop, so no mobile colour override. */

/* comp: 4 x 325 tiles, 20px gap, white on the pale ground */
.esp-landing .brands__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: calc(20 * var(--px));
  margin-top: calc(60 * var(--px));
}

.esp-landing .brands__tile {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  /* 20 -> a 285 x 142.5 logo box at 1920. The logo files are 570x285 (2x) with
     each logo at its Figma ink size (node 30:135), widest Tohatsu 257. */
  padding: calc(20 * var(--px));
  background: #fff;
}

.esp-landing .brands__tile img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

@media (max-width: 1023.98px) {
  .esp-landing .about { padding-block: 64px; }
  .esp-landing .about__grid { grid-template-columns: 1fr; gap: 32px; }
  .esp-landing .about__title { font-size: 34px; line-height: 42px; }
  .esp-landing .about__media { height: auto; aspect-ratio: 682 / 488; }
  /* comp's mobile grid is an even 2x2 — no card spans two columns */
  .esp-landing .stats { grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 40px; }

  /* Tablet follows the mobile composition: VIEW MORE drops below the grid.
     `display: contents` lifts the heading and the link into the section's
     flex column so `order` can place them; 3 tiles across at this width. */
  .esp-landing .brands { padding-block: 64px; }

  .esp-landing .brands .container {
    display: flex;
    flex-direction: column;
    gap: 32px;
  }

  .esp-landing .brands__head { display: contents; }

  .esp-landing .brands .about__head { order: 1; }

  .esp-landing .brands__grid {
    order: 2;
    margin-top: 0;
    grid-template-columns: repeat(3, 1fr);
  }

  .esp-landing .brands .view-more {
    order: 3;
    align-self: center;
  }

  .esp-landing .brands__title { font-size: 34px; line-height: 42px; }
}

/* ---- About: the mobile comp (12:925) is a different composition, not
   just a stacked desktop. Section padding 40/16, 25px between blocks, the
   heading is indented past its red bar while the paragraph is full-bleed,
   and "What we offer" is a plain list (no panel). ---- */
@media (max-width: 767.98px) {
  .esp-landing .about { padding-block: 40px; }

  .esp-landing .about__grid { gap: 25px; }

  .esp-landing .about__copy {
    display: flex;
    flex-direction: column;
    gap: 25px;
    padding-left: 0;
  }

  /* comp: 25px gap between the heading block and the paragraph */
  .esp-landing .about__intro {
    display: flex;
    flex-direction: column;
    gap: 25px;
  }

  /* only the heading clears the bar (5 bar + 20 inset, every mobile section);
     the paragraph starts at the edge */
  .esp-landing .about__head { padding-left: 25px; }
  .esp-landing .about__head::before { left: 0; }

  .esp-landing .eyebrow {
    font-size: 12px;
    line-height: 16px;
    letter-spacing: 2px;
  }

  .esp-landing .about__title { font-size: 20px; line-height: 24px; }

  /* comp: Jost 16/24 w400 (desktop is w300) */
  .esp-landing .about__text {
    max-width: none;
    margin-top: 0;
    font-size: 16px;
    font-weight: 400;
    line-height: 24px;
  }

  /* comp: plain list, 10px under its title */
  .esp-landing .about__offer {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 0;
  }

  /* comp: Jost 16/16 w500, ls 2px, navy */
  .esp-landing .about__offer-title {
    font-size: 16px;
    line-height: 16px;
    letter-spacing: 2px;
  }

  .esp-landing .dash-list li { font-size: 16px; line-height: 24px; }

  /* comp 12:955: 361 x 269 frame, photo 126.93% x 113.12%, offset -13.66% / -13.18% */
  .esp-landing .about__media { height: 269px; aspect-ratio: auto; }

  .esp-landing .about__media img {
    top: -13.18%;
    left: -13.66%;
    width: 126.93%;
    height: 113.12%;
  }

  /* comp: photo and stats share one block, 12px apart. Figma's GRID gives
     every row the tallest row's height (cards 114 tall). margin-top is set
     here because .stats is a sibling of .about__grid, so the grid's own gap
     does not reach it. */
  .esp-landing .stats {
    gap: 12px;
    margin-top: 12px;
    grid-auto-rows: 1fr;
  }

  .esp-landing .stats__item { justify-content: center; min-height: 114px; padding: 24px 12px; gap: 6px; }
  .esp-landing .stats__value { font-size: 18px; line-height: 24px; }
  /* comp: Jost 12/16, ls 1px, #707070 */
  .esp-landing .stats__label { font-size: 12px; line-height: 16px; letter-spacing: 1px; }

  /* ---- Brands: the mobile comp (12:147) reorders the block ----
     Section is #EFF3F8 with 40px padding and a 25px gap between three
     siblings: heading, grid, VIEW MORE. The link moves BELOW the grid, and
     the tiles are 174 x 132 landscape rather than the desktop's squares. */
  .esp-landing .brands { padding-block: 40px; }

  .esp-landing .brands .container {
    display: flex;
    flex-direction: column;
    gap: 25px;
  }

  /* lift the heading and the link out so they can be ordered independently */
  .esp-landing .brands__head { display: contents; }

  .esp-landing .brands .about__head { order: 1; }
  .esp-landing .brands__grid { order: 2; margin-top: 0; }
  .esp-landing .brands .view-more { order: 3; }

  .esp-landing .brands__title { font-size: 20px; line-height: 24px; }

  /* comp: 2 columns, 12px gaps, tiles 174.5 x 132 (4 rows in 565) */
  .esp-landing .brands__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
  }

  .esp-landing .brands__tile {
    aspect-ratio: 174.5 / 132;
    padding: 20px;
  }

  /* comp: VIEW MORE is identical in EVERY mobile section (brands 12:173,
     outboard 12:914, inboard 12:358, parts 12:497) — a centred 178x48
     block with a 14/21 label, a 47x14 rule and a 49px ring that overlaps
     the rule's last 27px. */
  .esp-landing .view-more {
    align-self: center;
    font-size: 14px;
    line-height: 21px;
  }

  .esp-landing .view-more__line { width: 47px; height: 14px; }

  .esp-landing .view-more__round {
    width: 49px;
    height: 49px;
    margin-left: -35px;
  }

  /* The mobile comp swaps two pairs of tiles versus desktop
     (Tohatsu/Honda and Yanmar/Volvo). Reproduced as drawn — it looks like
     visual balancing for the logo widths rather than anything meaningful,
     so say the word and these four rules go. */
  .esp-landing .brands__tile:nth-child(1) { order: 1; }
  .esp-landing .brands__tile:nth-child(2) { order: 2; }
  .esp-landing .brands__tile:nth-child(3) { order: 4; }   /* Honda after Tohatsu */
  .esp-landing .brands__tile:nth-child(4) { order: 3; }
  .esp-landing .brands__tile:nth-child(5) { order: 6; }   /* Volvo after Yanmar */
  .esp-landing .brands__tile:nth-child(6) { order: 5; }
  .esp-landing .brands__tile:nth-child(7) { order: 7; }
  .esp-landing .brands__tile:nth-child(8) { order: 8; }
}

/* ---- Product sections (Find your outboard / inboard) ---- */
.esp-landing .products {
  background: #f8f8f8;            /* comp section fill */
  padding-block: calc(100 * var(--px));
}

.esp-landing .section-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(60 * var(--px));
  padding-left: calc(55 * var(--px));
}

/* comp: Jost 46/46 w500, black */
.esp-landing .section-title {
  color: #000;
  font-size: max(calc(46 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(46 * var(--px));
  letter-spacing: 0;
}

/* ---- Filter row (comp: 1360 x 46, list 1071 + selects 269, gap 20) ---- */
.esp-landing .filters {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(20 * var(--px));
  margin-top: calc(60 * var(--px));      /* comp: filter block is 48 row + 60 padding-top */
}

/* Brand/category list is a plain ul/li — the active item carries .active.
   No tab panels: selecting one re-requests the cards.
   The comp keeps it on ONE line at every size (`layoutWrap: NO_WRAP`); on the
   1360 desktop row the 9 part categories total exactly 1360, and anywhere
   narrower the row scrolls sideways with a styled bar. */
.esp-landing .brand-filter {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  overflow-x: auto;
  padding-bottom: calc(8 * var(--px));
  -webkit-overflow-scrolling: touch;
}

.esp-landing .brand-filter button { white-space: nowrap; }

.esp-landing .brand-filter::-webkit-scrollbar { height: calc(6 * var(--px)); }

.esp-landing .brand-filter::-webkit-scrollbar-track {
  background: #e2e8ee;
  border-radius: 2px;
}

.esp-landing .brand-filter::-webkit-scrollbar-thumb {
  background: var(--c-navy-text);
  border-radius: 2px;
}

.esp-landing .brand-filter::-webkit-scrollbar-thumb:hover { background: var(--c-red); }

@supports not selector(::-webkit-scrollbar) {
  .esp-landing .brand-filter {
    scrollbar-width: thin;
    scrollbar-color: var(--c-navy-text) #e2e8ee;
  }
}

/* Below 1024 (touch layouts) the row just swipes — no visible bar and no 8px
   gutter under the tabs (user request, 28 Sep 2026; the comp shows none).
   1024+ keeps the bar so mouse users can still reach the last categories. */
@media (max-width: 1023.98px) {
  .esp-landing .brand-filter {
    padding-bottom: 0;
    scrollbar-width: none;
  }

  .esp-landing .brand-filter::-webkit-scrollbar { display: none; }
}

/* Bottom border only: transparent side borders mitred into the 2px active
   underline and gave its ends a slanted / rounded look (not in Figma).
   Padding takes back the 1px the top and side borders used, so every chip
   keeps its size. */
.esp-landing .brand-filter button {
  padding: calc(12 * var(--px)) calc(16 * var(--px)) calc(11 * var(--px));
  border: 0;
  border-bottom: 1px solid transparent;
  border-radius: 0;
  color: #5a6572;
  font-size: max(calc(16 * var(--px)), 12px);
  font-weight: 400;
  line-height: calc(24 * var(--px));
  /* Jost is a variable font, so the 400 -> 500 weight change eases in with
     the colour and underline instead of snapping (the width no longer
     changes — see the ::after reserve below). */
  transition: color .3s ease, border-color .3s ease, font-weight .3s ease;
}

@media (hover: hover) and (pointer: fine) {
  .esp-landing .brand-filter button:hover { color: var(--c-navy-text); }
}

/* comp: individualStrokeWeights {top:0,right:0,bottom:2,left:0} — the active
   item is a 2px RED UNDERLINE, not a box. */
.esp-landing .brand-filter .active button {
  border-bottom-color: var(--c-red);
  border-bottom-width: 2px;
  color: var(--c-navy-text);
  font-weight: 500;
}

/* No jump on select: the active tab is w500, which is wider than w400, so the
   tab grew and pushed the rest of the row along. Each button carries an
   invisible, zero-height w500 copy of its label (data-label, products.php),
   so it is always as wide as its bold self. visibility:hidden keeps the copy
   out of screen readers. */
.esp-landing .brand-filter button {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
}

.esp-landing .brand-filter button::after {
  content: attr(data-label);
  height: 0;
  overflow: hidden;
  visibility: hidden;
  font-weight: 500;
  pointer-events: none;
  user-select: none;
}

@media (prefers-reduced-motion: reduce) {
  .esp-landing .brand-filter button { transition: none; }
}

.esp-landing .filters__selects {
  display: flex;
  gap: calc(10 * var(--px));
  flex: 0 0 auto;
}

/* ---- Cards (comp: Article 435 x 567, 27 gap) ---- */
.esp-landing .products__viewport { margin-top: calc(30 * var(--px)); }

.esp-landing .card {
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid #e2e8ee;
}

/* comp: the image node itself is 433x264 (its 12px padding no longer applies
   — the badge sits flush). The media block must NOT add height of its own. */
.esp-landing .card__media {
  position: relative;
}

/* The whole product shows (contain), never cropped; the box behind it is
   #F5F3F6 (user request, 30 Sep 2026 — was object-fit: cover). */
.esp-landing .card__media img {
  width: 100%;
  height: calc(264 * var(--px));
  object-fit: contain;
}

/* comp: #043673 chip, Jost 12/20 w500 ls 1px, padding 11/5; flush to the
   photo's top-left corner (user: the 12px inset did not match the design) */
.esp-landing .card__power {
  position: absolute;
  top: 0;
  left: 0;
  padding: calc(5 * var(--px)) calc(11 * var(--px));
  background: var(--c-navy-text);
  color: #fff;
  font-size: max(calc(12 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(20 * var(--px));
  letter-spacing: 1px;
}

.esp-landing .card__body {
  display: flex;
  flex-direction: column;
  gap: calc(10 * var(--px));
  padding: calc(18 * var(--px));
}

/* comp: Jost 12/19 w500 ls 1px, brand red */
.esp-landing .card__brand {
  color: var(--c-red);
  font-size: max(calc(12 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(19 * var(--px));
  letter-spacing: 1px;
}

/* comp: Jost 19/22 w500 */
.esp-landing .card__title {
  color: #10152f;
  font-size: max(calc(19 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(22 * var(--px));
  letter-spacing: 0;
}

.esp-landing .card__chips {
  display: flex;
  flex-wrap: wrap;
  gap: calc(6 * var(--px));
}

/* comp: 1px #CFDAE6, padding 9/3, Jost 12/18 w400 ls .66, textCase UPPER */
.esp-landing .card__chips li {
  padding: calc(3 * var(--px)) calc(9 * var(--px));
  text-transform: uppercase;
  border: 1px solid #cfdae6;
  color: #5a6572;
  font-size: max(calc(12 * var(--px)), 12px);
  line-height: calc(18 * var(--px));
  letter-spacing: .66px;
}

/* Spec rows — loop as many as the data provides.
   comp puts a rule under every row EXCEPT the last. */
.esp-landing .card__specs { margin-top: 2px; }

.esp-landing .card__specs li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: calc(10 * var(--px));
  padding: calc(7 * var(--px)) 0;
  border-bottom: 1px solid #e2e8ee;
}

.esp-landing .card__specs li:last-child { border-bottom: 0; }

.esp-landing .card__spec-label {
  color: #5a6572;
  font-size: max(calc(14 * var(--px)), 12px);
  line-height: calc(20 * var(--px));
}

.esp-landing .card__spec-value {
  color: #10152f;
  font-size: max(calc(14 * var(--px)), 12px);
  line-height: calc(20 * var(--px));
  text-align: right;
}

/* comp: 47 tall, padding 12, gap 8 */
.esp-landing .btn--sm {
  min-height: calc(47 * var(--px));
  padding: calc(12 * var(--px));
  gap: calc(8 * var(--px));
  font-family: var(--font-ui);
  font-size: max(calc(14 * var(--px)), 12px);
  font-weight: 600;
  line-height: calc(21 * var(--px));
  letter-spacing: 1px;
  text-transform: uppercase;
}

.esp-landing .card__cta {
  width: 100%;
  margin-top: calc(8 * var(--px));
}

/* ---- Shimmer skeleton (mirrors the card's own geometry) ---- */
.esp-landing .sk {
  display: block;
  border-radius: 2px;
  background: linear-gradient(90deg, #e8ecf1 25%, #f4f6f9 37%, #e8ecf1 63%);
  background-size: 400% 100%;
  animation: sk-shimmer 1.3s ease-in-out infinite;
}

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

.esp-landing .card--skeleton .card__media { height: calc(264 * var(--px)); }

.esp-landing .card--skeleton .card__media.sk { border-radius: 0; }

.esp-landing .sk-line { height: calc(14 * var(--px)); }
.esp-landing .sk-line--lg { height: calc(20 * var(--px)); }
.esp-landing .sk-chip { width: calc(76 * var(--px)); height: calc(24 * var(--px)); }
.esp-landing .sk-btn { height: calc(47 * var(--px)); margin-top: calc(8 * var(--px)); }

.esp-landing .card--skeleton .card__specs li { border-bottom: 1px solid #e2e8ee; }
.esp-landing .card--skeleton .card__specs li:last-child { border-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
  .esp-landing .sk { animation: none; }
}

/* ---- Owl overrides so the carousel matches the comp ---- */
.esp-landing .product-carousel .owl-stage { display: flex; }
.esp-landing .product-carousel .owl-item { display: flex; }
.esp-landing .product-carousel .owl-item > .card { width: 100%; }

/* comp: a single 53x53 white circle sitting on the container's right edge,
   positioned from the top of the card row as the comp draws it (icon top 205
   on the 567 engine card, `440:2440`). The SPARE PARTS slider is the one
   exception — it is vertically centred, see `.parts` below. Owl renders prev +
   next; the prev is hidden while disabled, which is the state the comp shows. */
.esp-landing .products__viewport {
  position: relative;
  --nav-top: calc(205 * var(--px));
}

.esp-landing .product-carousel .owl-nav { margin: 0; }

.esp-landing .product-carousel .owl-nav button.owl-prev,
.esp-landing .product-carousel .owl-nav button.owl-next {
  position: absolute;
  top: var(--nav-top);
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(53 * var(--px));
  height: calc(53 * var(--px));
  margin: 0;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 2px calc(10 * var(--px)) rgba(16, 21, 47, .12);
  color: var(--c-navy-text);
  transition: background-color .2s ease, color .2s ease;
}

.esp-landing .product-carousel .owl-nav button.owl-prev { left: calc(-26 * var(--px)); }
.esp-landing .product-carousel .owl-nav button.owl-next { right: calc(-26 * var(--px)); }

.esp-landing .product-carousel .owl-nav button svg { width: calc(8 * var(--px)); height: calc(15 * var(--px)); }

@media (hover: hover) and (pointer: fine) {
  .esp-landing .product-carousel .owl-nav button:hover {
    background: var(--c-navy-text);
    color: #fff;
  }
}

/* Spare parts slider only: centre the arrow on the card (user's call).
   The engine sliders keep the comp's 205px top offset. */
.esp-landing .parts .product-carousel .owl-nav button.owl-prev,
.esp-landing .parts .product-carousel .owl-nav button.owl-next {
  top: 50%;
  transform: translateY(-50%);
}

/* comp shows no back arrow at the first slide */
.esp-landing .product-carousel .owl-nav button.disabled { display: none; }

.esp-landing .product-carousel .owl-dots {
  display: flex;
  justify-content: center;
  gap: calc(8 * var(--px));
  margin-top: calc(20 * var(--px));
}

.esp-landing .product-carousel .owl-dots button.owl-dot span {
  display: block;
  width: calc(8 * var(--px));
  height: calc(8 * var(--px));
  border-radius: 50%;
  background: #cfdae6;
}

.esp-landing .product-carousel .owl-dots button.owl-dot.active span { background: var(--c-red); }

/* ---- Select2 skinned to the comp's dropdown ---- */
.esp-landing .select2-container--default .select2-selection--single {
  height: calc(46 * var(--px)) !important;
  background: #fff !important;
  border: 1px solid #cfdae6 !important;
  border-radius: 0 !important;
}

/* comp 30:192 (All power): padding 12/20, Jost 16/20 #10152F, then a 10px
   gap and a 20px icon box -> the label clears 20 + 20 + 10 = 50 on the right */
.esp-landing .select2-container--default .select2-selection--single .select2-selection__rendered {
  padding: calc(12 * var(--px)) calc(50 * var(--px)) calc(12 * var(--px)) calc(20 * var(--px)) !important;
  color: #10152f !important;
  font-size: max(calc(16 * var(--px)), 12px) !important;
  line-height: calc(20 * var(--px)) !important;
}

/* the 20px icon box sits inside the 20 padding */
.esp-landing .select2-container--default .select2-selection--single .select2-selection__arrow {
  height: calc(44 * var(--px)) !important;
  right: calc(20 * var(--px)) !important;
}

/* comp 30:197 (All types): the second dropdown is padded 16, not 20.
   nth-of-type counts the Select2 spans only (the <select>s are skipped). */
.esp-landing .filters__selects .select2-container:nth-of-type(2) .select2-selection__rendered {
  padding-right: calc(46 * var(--px)) !important;
  padding-left: calc(16 * var(--px)) !important;
}

.esp-landing .filters__selects .select2-container:nth-of-type(2) .select2-selection__arrow {
  right: calc(16 * var(--px)) !important;
}

.esp-landing .select2-container--default .select2-results__option--highlighted[aria-selected] {
  background: var(--c-navy-text) !important;
}

.esp-landing .select2-dropdown {
  border-color: #cfdae6 !important;
  border-radius: 0 !important;
}

@media (max-width: 1023.98px) {
  /* Comp mobile order (440:3283 / 440:3470 / 440:3655):
     heading -> filters -> cards -> VIEW MORE -> (parts only) notice.
     `display: contents` on .section-row lifts the heading and the link into
     the section's flex column so the link can drop to the bottom. */
  .esp-landing .products { padding-block: 64px; }

  .esp-landing .products .container {
    display: flex;
    flex-direction: column;
    gap: 25px;
  }

  .esp-landing .section-row { display: contents; }

  .esp-landing .products .about__head { order: 1; }
  .esp-landing .filters { order: 2; margin-top: 0; }
  .esp-landing .products__viewport { order: 3; margin-top: 0; }
  .esp-landing .products .view-more { order: 4; align-self: center; }
  .esp-landing .notice { order: 5; margin-top: 0; }

  .esp-landing .section-title { font-size: 34px; line-height: 42px; }
  .esp-landing .filters { flex-direction: column; align-items: stretch; }

  /* comp (440:3306): the two dropdowns share one row — 180 + 10 + 172 in a
     361 container. Let them shrink rather than wrap, or they stack on
     narrow devices (2 x 160 + 10 already exceeds a 360 viewport). */
  .esp-landing .filters__selects { flex-wrap: nowrap; }

  .esp-landing .filters__selects .select2-container {
    flex: 1 1 0 !important;
    min-width: 0 !important;
  }

  /* The arrows overhang the container by 26px, which only fits once the
     gutter grows to 40 at 1024. Below that, sit them inside the edge so the
     page never gains a horizontal scrollbar. */
  .esp-landing .product-carousel .owl-nav button.owl-prev { left: 0; }
  .esp-landing .product-carousel .owl-nav button.owl-next { right: 0; }
}

@media (max-width: 767.98px) {
  /* comp: every mobile section is padded 40 top and bottom (440:3283 etc.),
     and the sections butt straight together with no gap between them. */
  .esp-landing .products { padding-block: 40px; }

  /* comp (12:738 / 12:184 / 12:369): 25 between every block in all three
     sections, and the two filter rows inside .filters use the same rhythm */
  .esp-landing .filters { gap: 25px; }

  /* comp: engine chips are Jost 14/24 (46 tall); the parts chips stay 16/24 */
  .esp-landing .brand-filter button { font-size: 14px; }
  .esp-landing .parts .brand-filter button { font-size: 16px; }

  /* comp: two equal dropdowns, 44 tall, Jost 14/20 */
  .esp-landing .filters__selects { gap: 10px; }
  .esp-landing .select2-container--default .select2-selection--single { height: 44px !important; }

  /* padding and arrow insets are the desktop 20 / 16 (1px scale here) */
  .esp-landing .select2-container--default .select2-selection--single .select2-selection__rendered {
    font-size: 14px !important;
    line-height: 20px !important;
  }

  .esp-landing .select2-container--default .select2-selection--single .select2-selection__arrow { height: 42px !important; }

  /* comp: add-to-enquiry button 46 tall */
  .esp-landing .btn--sm { min-height: 46px; }

  /* Arrows stay visible on mobile so the next card is discoverable; they are
     pulled inside the edge by the <1024 rule above (at right:-26px they hung
     10px past a 393 viewport and gave the page a horizontal scrollbar). */
  .esp-landing .product-carousel .owl-nav button.owl-prev,
.esp-landing .product-carousel .owl-nav button.owl-next {
    width: 44px;
    height: 44px;
  }

  /* mobile engine cards are a different height from the comp's desktop ones,
     so place the arrow proportionally; parts stays centred via its own rule */
  .esp-landing .products__viewport { --nav-top: 32%; }


  .esp-landing .section-row { padding-left: 24px; }

  /* comp mobile headings are Jost 20/24 with a 12/16 ls2 eyebrow — the same
     in every section (440:3284, 440:3471, 440:3656, 440:3250) */
  .esp-landing .section-title { font-size: 20px; line-height: 24px; }

  /* the wider desktop tracking does not apply on mobile */
  .esp-landing .eyebrow--wide { line-height: 16px; letter-spacing: 2px; }
}

.esp-landing .u-sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Empty state: occupies exactly the height a row of cards did, so the section
   never collapses or jumps between a loaded and an empty brand.
   --card-h is written by main.js from a real rendered card. */
.esp-landing .js-product-grid.is-empty { display: block; }

.esp-landing .products__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(8 * var(--px));
  min-height: var(--card-h, calc(593 * var(--px)));
  padding: calc(32 * var(--px)) calc(24 * var(--px));
  background: #fff;
  border: 1px solid #e2e8ee;
  text-align: center;
}

.esp-landing .products__empty-title {
  color: #10152f;
  font-size: max(calc(19 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(22 * var(--px));
}

.esp-landing .products__empty-text {
  max-width: 46ch;
  color: #5a6572;
  font-size: max(calc(16 * var(--px)), 12px);
  line-height: calc(24 * var(--px));
}

/* Select2 sizes itself from the (unstyled) native select, which truncates the
   label. Let it size to content instead — comp: All power 137, All types 122. */
.esp-landing .filters__selects .select2-container {
  width: auto !important;
  min-width: calc(122 * var(--px)) !important;
}

/* Owl ships `.owl-carousel .owl-item img { width:100% }`, which outranks
   .btn__icon and stretches the 17px arrow to the full button width.
   Re-assert the icon size at higher specificity. */
.esp-landing .product-carousel .owl-item img.btn__icon {
  width: calc(17 * var(--px));
  height: calc(17 * var(--px));
}

/* the card photo does want full width, but keep the comp's fixed height */
.esp-landing .product-carousel .owl-item .card__media img {
  width: 100%;
  height: calc(264 * var(--px));
  object-fit: contain;
}

/* skeleton matches a real card's height too, so the shimmer does not jump */
.esp-landing .card--skeleton { min-height: var(--card-h, calc(593 * var(--px))); }

/* ---- Find your inboard ----
   Same component as the outboard section; the comp differs only in the
   section fill (white, not #F8F8F8) and a slightly wider eyebrow tracking. */
.esp-landing .products--inboard { background: #fff; }

/* comp: inboard eyebrow is Jost 16/19 ls 3px (outboard is 16/20 ls 2px) */
.esp-landing .eyebrow--wide {
  line-height: calc(19 * var(--px));
  letter-spacing: calc(3 * var(--px));
}

/* ---- Find a part (spare parts) ----
   Same section shell and carousel as the engine sections; the card has no
   photo (comp: Article 435 x 254) and there is a notice bar underneath. */
.esp-landing .parts { background: #f8f8f8; }

.esp-landing .card--part { min-height: calc(254 * var(--px)); }

/* comp: 433 x 66, padding 18, gap 14 */
.esp-landing .part__head {
  display: flex;
  align-items: center;
  gap: calc(14 * var(--px));
  padding: calc(18 * var(--px)) calc(18 * var(--px)) 0;
}

/* comp: 48x48 #EFF3F8 tile holding a 24x24 navy icon */
.esp-landing .part__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: calc(48 * var(--px));
  height: calc(48 * var(--px));
  background: #eff3f8;
}

.esp-landing .part__icon img { width: calc(24 * var(--px)); height: calc(24 * var(--px)); }

/* comp: Jost 12/19 w500 ls 1px, brand red */
.esp-landing .part__cat {
  color: var(--c-red);
  font-size: max(calc(12 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(19 * var(--px));
  letter-spacing: 1px;
}

/* comp: 433 x 186, padding 18, top 14, gap 10 */
.esp-landing .part__body {
  display: flex;
  flex-direction: column;
  gap: calc(10 * var(--px));
  padding: calc(14 * var(--px)) calc(18 * var(--px)) calc(18 * var(--px));
}

/* comp: Jost 18/22 w500 */
.esp-landing .part__title {
  color: #10152f;
  font-size: max(calc(18 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(22 * var(--px));
  letter-spacing: 0;
}

/* comp: Jost 14/20 w400 */
.esp-landing .part__text {
  color: #5a6572;
  font-size: max(calc(14 * var(--px)), 12px);
  line-height: calc(20 * var(--px));
}

.esp-landing .card--part .card__cta { margin-top: calc(10 * var(--px)); }

/* Buttons line up across a row. Cards in a row are already equal height, so
   the body fills the card and one block absorbs the spare space: the part
   description (comp 12:409 is `flex-grow`) and, on engine cards, the spec
   list. A two-line description or title then no longer pushes one card's
   button lower than its neighbour's. */
.esp-landing .card__body,
.esp-landing .part__body { flex: 1 1 auto; }

.esp-landing .part__text,
.esp-landing .card__specs { flex-grow: 1; }

/* ---- Notice bar (comp: 1360 x 152) ----
   Outer 1px #E2E8EE on top/right/bottom, inner 5px navy left accent. */
.esp-landing .notice {
  display: flex;
  align-items: center;
  gap: calc(16 * var(--px));
  margin-top: calc(50 * var(--px));
  padding: calc(40 * var(--px));
  background: #fff;
  border: 1px solid #e2e8ee;
  border-left: calc(5 * var(--px)) solid var(--c-navy-text);
}

/* comp 30:669: icon + copy sit in an `items-start` row, so the icon lines up
   with the TOP of the title, not the middle of the block (only the button is
   centred on the bar). Mobile re-centres it on the title row below 1024. */
.esp-landing .notice__icon { flex: 0 0 auto; align-self: flex-start; width: calc(45 * var(--px)); height: calc(45 * var(--px)); }

.esp-landing .notice__copy { flex: 1 1 auto; }

/* comp: Jost 20/25 w500 */
.esp-landing .notice__title {
  color: #10152f;
  font-size: max(calc(20 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(25 * var(--px));
}

/* comp: Jost 14/20 w400, box 589 wide */
.esp-landing .notice__text {
  max-width: calc(589 * var(--px));
  margin-top: calc(6 * var(--px));
  color: #5a6572;
  font-size: max(calc(14 * var(--px)), 12px);
  line-height: calc(20 * var(--px));
}

/* comp: 182 x 47, #043673, padding 24/13 */
.esp-landing .btn--navy {
  background: var(--c-navy-text);
  color: #fff;
}
@media (hover: hover) and (pointer: fine) {
  .esp-landing .btn--navy:hover { background: var(--c-red); }
}

.esp-landing .notice__cta {
  flex: 0 0 auto;
  padding-inline: calc(24 * var(--px));
}

/* part-card skeleton bits */
.esp-landing .sk-part-icon { width: calc(48 * var(--px)); height: calc(48 * var(--px)); }

@media (max-width: 1023.98px) {
  /* margin-top would stack on top of the section container's gap (giving 72
     instead of the comp's 40) — the flex gap already handles the spacing */
  /* comp mobile notice (12:508): 20px padding, the icon sits on the TITLE
     row 24 from it, the paragraph runs full width 18 beneath (12 gap + 6
     margin), then the button 16 below that.
     `display: contents` promotes the title and text to grid items. */
  .esp-landing .notice {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0 24px;
    padding: 20px;
    margin-top: 0;
  }

  .esp-landing .notice__copy { display: contents; }

  /* The icon file is the desktop comp's 45 x 45 box with the clipboard glyph
     (~23 x 32) centred in it — ~11px of empty space each side (inset 24.17%).
     The mobile comp (12:512) places the bare glyph flush with the 20px padding
     and 24 from the title. The icon keeps its full 45px size (user, 28 Sep):
     the column gap drops to 13 (13 + 11 built-in = 24) and only the left side
     is pulled back 11. max-width: none, or the reset's max-width: 100% would
     squeeze the image into its narrowed grid column. */
  .esp-landing .notice { column-gap: 13px; }

  .esp-landing .notice__icon {
    grid-area: 1 / 1;
    align-self: center;
    max-width: none;
    margin-left: -11px;
  }
  .esp-landing .notice__title { grid-area: 1 / 2; font-size: 16px; line-height: 20px; }

  .esp-landing .notice__text {
    grid-area: 2 / 1 / 3 / -1;
    margin-top: 18px;
    font-size: 14px;
    line-height: 24px;
  }

  .esp-landing .notice__cta { grid-area: 3 / 1 / 4 / -1; width: 100%; margin-top: 16px; }
}

/* ---- Native scroll strip (all three product sections, below 1024) ----
   Outboard and inboard joined the parts section here on 28 Sep 2026 (user's
   call): the mobile comp has no arrow, so the bar is the "more cards" cue in
   every section.
   Owl transforms a stage, so it can never show a real scrollbar. Sections
   flagged `data-mobile-scroll` drop the carousel here and scroll natively,
   which gives a genuine bar at the bottom and removes the arrows that were
   overlapping the card text on narrow screens. The bar stays (user's call,
   28 Sep 2026): the comp has no dots, and the bar is the "more cards" cue. */
/* Peek layout (user request, 28 Sep 2026): cards are narrower than the row so
   the edge of the next one shows — the standard "there is more" cue, with no
   extra UI. The strip bleeds to the screen edges (negative gutter margin +
   the same padding back), so the first card still lines up with the heading
   and the peeking card runs off the screen edge instead of being cut at the
   page margin. scroll-padding keeps snapped cards on that same 16px line. */
.esp-landing .js-product-grid.is-scroller {
  display: flex;
  gap: calc(20 * var(--px));
  overflow-x: auto;
  margin-inline: calc(-1 * var(--gutter));
  padding: 0 var(--gutter) calc(12 * var(--px));
  scroll-padding-inline: var(--gutter);
  overscroll-behavior-x: contain;          /* a hard swipe never flips browser history */
  -webkit-overflow-scrolling: touch;
}

/* `proximity`, not `mandatory`: a swipe settles a card on the gutter line,
   but dragging the scrollbar thumb is never yanked back to a snap point. */
@media (prefers-reduced-motion: no-preference) {
  .esp-landing .js-product-grid.is-scroller { scroll-snap-type: x proximity; }
}

/* tablet: just under two across, so a sliver of the third card shows */
.esp-landing .js-product-grid.is-scroller > .card {
  flex: 0 0 46%;
  scroll-snap-align: start;
}

.esp-landing .js-product-grid.is-scroller::-webkit-scrollbar { height: calc(6 * var(--px)); }

/* a 6px bar is hard to grab with a mouse — give pointer devices a bigger target */
@media (pointer: fine) {
  .esp-landing .js-product-grid.is-scroller { padding-bottom: calc(14 * var(--px)); }
  .esp-landing .js-product-grid.is-scroller::-webkit-scrollbar { height: calc(10 * var(--px)); }
}

.esp-landing .js-product-grid.is-scroller::-webkit-scrollbar-track {
  background: #e2e8ee;
  border-radius: 2px;
}

.esp-landing .js-product-grid.is-scroller::-webkit-scrollbar-thumb {
  background: var(--c-navy-text);
  border-radius: 2px;
}

.esp-landing .js-product-grid.is-scroller::-webkit-scrollbar-thumb:hover { background: var(--c-red); }

@supports not selector(::-webkit-scrollbar) {
  .esp-landing .js-product-grid.is-scroller {
    scrollbar-width: thin;
    scrollbar-color: var(--c-navy-text) #e2e8ee;
  }
}

/* mobile: one card at 85% of the row (≈307 of 361 on a 393 phone), so about
   40px of the next card shows before the screen edge */
@media (max-width: 767.98px) {
  .esp-landing .js-product-grid.is-scroller > .card { flex: 0 0 85%; }
}

/* ---- Mobile card photo ----
   Must come AFTER the Owl override above: that rule has the same specificity,
   so an earlier media-query block loses on source order alone.
   comp mobile card (12:774) is 360 wide with a 218-tall photo. The peek cards
   are narrower (85%), but the photo keeps the comp's 218 HEIGHT (user,
   28 Sep 2026) — a ratio made it only ~186 tall. */
@media (max-width: 767.98px) {
  .esp-landing .card__media img,
.esp-landing .product-carousel .owl-item .card__media img { height: 218px; }

  .esp-landing .card--skeleton .card__media { height: 218px; }
}

/* =========================================================
   VISIT OR ENQUIRE  (comp 440:2793 — 1920 x 985, fill #043673)
   Markup mirrors Contact Form 7's output, so the same rules style both the
   static page and the CF7 version. Anything CF7 generates is handled here
   too (`.wpcf7-form-control-wrap`, `.wpcf7-not-valid-tip`, response output).
   ========================================================= */
.esp-landing .enquiry {
  background: var(--c-navy-text);
  padding-block: calc(100 * var(--px));
}

/* comp: 1360 = 500 intro + 60 gap + 800 panel */
.esp-landing .enquiry__grid {
  display: grid;
  grid-template-columns: 500fr 800fr;
  gap: calc(60 * var(--px));
  align-items: start;
}

.esp-landing .enquiry__intro { padding-left: calc(55 * var(--px)); }

.esp-landing .enquiry .about__head::before { background: var(--c-red); }

/* comp: eyebrow #DFD6D6, heading 46/55 white */
.esp-landing .enquiry .eyebrow { color: #dfd6d6; }

.esp-landing .enquiry__title {
  color: #fff;
  font-size: max(calc(46 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(55 * var(--px));
  letter-spacing: 0;
  width: 100%;
  max-width: calc(400 * var(--px));
}

/* comp: Jost 16/26, box 445 */
.esp-landing .enquiry__text {
  max-width: calc(445 * var(--px));
  margin-top: calc(24 * var(--px));
  color: #fff;
  font-size: max(calc(16 * var(--px)), 12px);
  line-height: calc(26 * var(--px));
}

/* ---- Info card (comp: 445 x 325, #013A80, 32 padding, 30 gap) ---- */
.esp-landing .info-card {
  max-width: calc(445 * var(--px));
  margin-top: calc(45 * var(--px));
  padding: calc(32 * var(--px));
  background: #013a80;
}

.esp-landing .info-card__row {
  display: flex;
  gap: calc(24 * var(--px));
}

.esp-landing .info-card__row + .info-card__row { margin-top: calc(30 * var(--px)); }

/* comp: key column is 120 wide, Jost 20/24 #F8F8F8 */
.esp-landing .info-card__key {
  flex: 0 0 calc(120 * var(--px));
  padding-top: calc(3 * var(--px));
  color: #f8f8f8;
  font-size: max(calc(20 * var(--px)), 12px);
  line-height: calc(24 * var(--px));
}

/* comp: value Jost 16/30 (single lines 16/24), white */
.esp-landing .info-card__val {
  margin: 0;
  color: #fff;
  font-size: max(calc(16 * var(--px)), 12px);
  line-height: calc(30 * var(--px));
}

.esp-landing .info-card__val a { text-decoration: none; }
@media (hover: hover) and (pointer: fine) {
  .esp-landing .info-card__val a:hover { text-decoration: underline; }
}

/* ---- Ghost links (comp: 445 x 48, 1px white, label 13/20 w600 ls1) ---- */
.esp-landing .enquiry__links {
  display: flex;
  flex-direction: column;
  gap: calc(30 * var(--px));
  max-width: calc(445 * var(--px));
  margin-top: calc(40 * var(--px));
}

/* comp 440:2828: individualStrokeWeights {bottom:1} and no side padding —
   these are underlined rows, not outlined buttons */
.esp-landing .ghost-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(9 * var(--px));
  padding: calc(14 * var(--px)) 0;
  border-bottom: 1px solid #fff;
  color: #fff;
  font-family: var(--font-ui);
  font-size: max(calc(13 * var(--px)), 12px);
  font-weight: 600;
  line-height: calc(20 * var(--px));
  letter-spacing: 1px;
  text-transform: uppercase;
  transition: background-color .2s ease;
}

/* no fill on hover — only the submit button changes colour in this section */
@media (hover: hover) and (pointer: fine) {
  .esp-landing .ghost-link:hover .ghost-link__arrow { transform: translateX(calc(4 * var(--px))); }
}
.esp-landing .ghost-link__arrow { transition: transform .2s ease; }

.esp-landing .ghost-link__main {
  display: inline-flex;
  align-items: center;
  gap: calc(9 * var(--px));
}

.esp-landing .ghost-link img { width: calc(17 * var(--px)); height: calc(17 * var(--px)); flex: 0 0 auto; }

/* ---- Form panel (comp: 800 x 785, #013A80, 34 padding) ---- */
.esp-landing .enquiry__panel {
  padding: calc(34 * var(--px));
  background: #013a80;
}

/* comp: Jost 26/32 w500 */
.esp-landing .enquiry__form-title {
  color: #fff;
  font-size: max(calc(26 * var(--px)), 12px);
  font-weight: 500;
  line-height: calc(32 * var(--px));
  letter-spacing: 0;
}

.esp-landing .enquiry-form {
  display: flex;
  flex-direction: column;
  gap: calc(30 * var(--px));
  padding-top: calc(20 * var(--px));
}

/* comp: two equal columns, 30px gutter */
.esp-landing .field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: calc(30 * var(--px));
}

.esp-landing .field {
  display: flex;
  flex-direction: column;
  gap: calc(6 * var(--px));
  min-width: 0;
}

/* comp: Jost 12/16 #F8F8F8 */
.esp-landing .field__label {
  color: #f8f8f8;
  font-size: max(calc(12 * var(--px)), 12px);
  line-height: calc(16 * var(--px));
}

/* comp 30:756: the required asterisk is #FF4545 */
.esp-landing .field__req { color: #ff4545; }

/* CF7 wraps every control in this span; make it a block so it does not
   collapse the field layout. */
.esp-landing .wpcf7-form-control-wrap {
  display: block;
  position: relative;
}

/* comp: 49 tall, 14 padding, transparent fill, 1px white stroke at 20% alpha
   (440:2856 strokes = #FFFFFF a=0.20) — solid white reads far too bright */
.esp-landing .field__input {
  width: 100%;
  min-height: calc(49 * var(--px));
  padding: calc(14 * var(--px));
  background: transparent;
  border: 1px solid rgba(255, 255, 255, .2);
  border-radius: 0;
  color: #fff;
  font-family: var(--font);
  font-size: max(calc(14 * var(--px)), 12px);
  line-height: calc(20 * var(--px));
  transition: border-color .2s ease, box-shadow .2s ease;
}

/* comp 30:758: placeholder #CFDAE6 at 54% */
.esp-landing .field__input::placeholder { color: rgba(207, 218, 230, .54); opacity: 1; }

/* A placeholder longer than its input (the serial-number field on phones)
   shows what fits and ends in "…" instead of being cut mid-word. Applies to
   single-line inputs; typed text scrolls as normal while focused. */
.esp-landing input.field__input,
.esp-landing input.field__input::placeholder {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

@media (hover: hover) and (pointer: fine) {
  .esp-landing .field__input:hover { border-color: rgba(255, 255, 255, .4); }
}

.esp-landing .field__input:focus {
  outline: none;
  border-color: #fff;
  box-shadow: inset 0 0 0 1px #fff;
}

/* comp: textarea 126 tall, placeholder 14/24 */
/* display:block — as an inline-block the textarea left a text-baseline gap
   (~5px) under itself inside CF7's wrapper span */
.esp-landing .field__input--area {
  display: block;
  height: calc(126 * var(--px));
  min-height: calc(126 * var(--px));
  line-height: calc(24 * var(--px));
  resize: vertical;
}

/* comp: 60px above the button — 30 of it is the form's own gap */
.esp-landing .enquiry-form__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: calc(16 * var(--px));
  padding-top: calc(20 * var(--px));
}

/* The site-wide red -> navy hover would make this button disappear against
   the navy panel, so this one button darkens its red instead. */
@media (hover: hover) and (pointer: fine) {
  .esp-landing .enquiry-form__submit:hover { background: var(--c-red-dark); }
}

.esp-landing .enquiry-form__submit {
  min-height: calc(52 * var(--px));
  padding: calc(16 * var(--px)) calc(32 * var(--px));
  gap: calc(10 * var(--px));
  font-family: var(--font);             /* comp 30:801: Jost SemiBold 13/20 */
  font-size: max(calc(13 * var(--px)), 12px);
  font-weight: 600;
  line-height: calc(20 * var(--px));
  letter-spacing: 1px;
  text-transform: uppercase;
}

/* ---- Select2, scoped to this panel so the filter selects keep their skin ---- */
.esp-landing .enquiry .select2-container--default .select2-selection--single {
  height: calc(50 * var(--px)) !important;
  background: transparent !important;
  border: 1px solid rgba(255, 255, 255, .2) !important;
  border-radius: 0 !important;
}

/* right padding clears the 20px arrow box (14 + 20 + 14) */
.esp-landing .enquiry .select2-container--default .select2-selection--single .select2-selection__rendered {
  padding: calc(14 * var(--px)) calc(48 * var(--px)) calc(14 * var(--px)) calc(14 * var(--px)) !important;
  color: #fff !important;
  font-size: max(calc(14 * var(--px)), 12px) !important;
  line-height: calc(20 * var(--px)) !important;
}

.esp-landing .enquiry .select2-container--default .select2-selection--single .select2-selection__arrow {
  height: calc(48 * var(--px)) !important;
  right: calc(14 * var(--px)) !important;   /* comp: 20px icon box inside the 14 padding */
}

/* comp 30:780: until something is picked, "Engine" is a Select2 placeholder
   (engines-landing.js adds the empty option) in the input placeholder colour;
   a chosen option — "Engine" included — is white. */
.esp-landing .enquiry .select2-container--default .select2-selection--single .select2-selection__placeholder {
  color: rgba(207, 218, 230, .54) !important;   /* beats Select2 #999 and any theme !important */
}

/* ---- Dropdown arrow (comp: 10 x 6 chevron, 1.5 stroke) ----
   Replaces Select2's CSS triangle: #10152F on the white filter selects,
   white on the enquiry panel; flips while open. */
.esp-landing .select2-container--default .select2-selection--single .select2-selection__arrow {
  width: calc(20 * var(--px)) !important;
  background: url("../icons/chevron-down.svg") center / calc(10 * var(--px)) calc(6 * var(--px)) no-repeat;
  transition: transform .4s ease-in-out;   /* slower flip (user request, 28 Sep 2026) */
}

.esp-landing .enquiry .select2-container--default .select2-selection--single .select2-selection__arrow {
  background-image: url("../icons/chevron-down-white.svg");
}

.esp-landing .select2-container--default .select2-selection--single .select2-selection__arrow b { display: none !important; }

.esp-landing .select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow {
  transform: rotate(180deg);
}

/* ---- CF7 runtime output ---- */
.esp-landing .wpcf7-not-valid-tip {
  display: block;
  margin-top: calc(6 * var(--px));
  color: #ffc9c9;
  font-size: max(calc(12 * var(--px)), 12px);
  line-height: calc(16 * var(--px));
}

.esp-landing .field__input.wpcf7-not-valid { border-color: #ffc9c9; }

.esp-landing .wpcf7-response-output:empty { display: none; }

.esp-landing .wpcf7-response-output {
  display: block;
  flex: 1 1 100%;
  margin: 0;
  color: #fff;
  font-size: max(calc(14 * var(--px)), 12px);
  line-height: calc(20 * var(--px));
}

.esp-landing .wpcf7 form.invalid .wpcf7-response-output,
.esp-landing .wpcf7 form.sent .wpcf7-response-output { padding: calc(12 * var(--px)) calc(16 * var(--px)); }

.esp-landing .wpcf7 form.sent .wpcf7-response-output { background: rgba(255, 255, 255, .14); }
.esp-landing .wpcf7 form.invalid .wpcf7-response-output { background: rgba(209, 21, 21, .35); }

.esp-landing .wpcf7-spinner { margin: 0 0 0 calc(12 * var(--px)); }

@media (max-width: 1023.98px) {
  .esp-landing .enquiry { padding-block: 64px; }
  .esp-landing .enquiry__grid { grid-template-columns: 1fr; gap: 32px; }
  .esp-landing .enquiry__title { font-size: 34px; line-height: 42px; }
  .esp-landing .enquiry__panel { padding: 24px; }
  .esp-landing .enquiry-form__footer { padding-top: 12px; }
}

/* comp mobile 12:629: intro block, then the form panel 40 below it */
@media (max-width: 767.98px) {
  .esp-landing .enquiry { padding-block: 40px; }
  .esp-landing .enquiry__grid { gap: 40px; }
  .esp-landing .enquiry__intro { padding-left: 35px; }

  /* comp: eyebrow white 12/16 ls 2, title 20/24 */
  .esp-landing .enquiry .eyebrow { color: #fff; }
  .esp-landing .enquiry__title { font-size: 20px; line-height: 24px; }

  /* comp: Jost 16/24 #F7F7F7, 30 under the heading */
  .esp-landing .enquiry__text { margin-top: 30px; color: #f7f7f7; font-size: 16px; line-height: 24px; }

  /* comp: 24 padding, faint border, rows keep the 120px label column, 30 apart */
  .esp-landing .info-card {
    margin-top: 25px;
    padding: 24px;
    border: 1px solid rgba(196, 212, 230, .18);
  }

  .esp-landing .info-card__row + .info-card__row { margin-top: 30px; }
  .esp-landing .info-card__key { flex: 0 0 120px; font-size: 16px; line-height: 24px; }
  .esp-landing .info-card__val { flex: 1 1 auto; min-width: 0; font-size: 14px; line-height: 30px; overflow-wrap: anywhere; }

  /* comp: 25 between the rows, label Jost 12/20 w600 ls 1 */
  .esp-landing .enquiry__links { gap: 25px; margin-top: 25px; }
  .esp-landing .ghost-link { font-family: var(--font); font-size: 12px; }

  /* comp: panel has the same faint border; title Jost 20/32 */
  .esp-landing .enquiry__panel { border: 1px solid rgba(196, 212, 230, .18); }
  .esp-landing .enquiry__form-title { font-size: 20px; line-height: 32px; }

  /* comp: one column, 16 between fields */
  .esp-landing .field-row { grid-template-columns: 1fr; gap: 16px; }
  .esp-landing .enquiry-form { gap: 16px; }

  /* comp: label Jost 14/16 #F8F8F8 */
  .esp-landing .field__label { font-size: 14px; line-height: 16px; }

  /* comp: padding 12/14 */
  .esp-landing .field__input { min-height: 46px; padding: 12px 14px; }

  /* comp: textarea 111 tall, 14 padding */
  .esp-landing .field__input--area { height: 111px; min-height: 111px; padding: 14px; }

  .esp-landing .enquiry .select2-container--default .select2-selection--single { height: 46px !important; }
  .esp-landing .enquiry .select2-container--default .select2-selection--single .select2-selection__rendered {
    padding: 12px 48px 12px 14px !important;
  }
  .esp-landing .enquiry .select2-container--default .select2-selection--single .select2-selection__arrow { height: 44px !important; }

  /* comp 12:732: submit sits 20 below the message box at its natural width,
     Jost 13/20 — the form's 16px field gap already gives 16 of it */
  .esp-landing .enquiry-form__footer { padding-top: 4px; }
  .esp-landing .enquiry-form__submit { font-family: var(--font); }
}

/* ---------- 7. Theme neutralisers ----------
   The theme ships Bootstrap 4 (.container, .btn, .card) and global Select2 rules
   in custom.css (with !important). Reset the properties the landing rules above
   do not declare, so none of them leak into the landing sections. */
.esp-landing .container {
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.esp-landing .btn {
  vertical-align: middle;
  white-space: normal;
  user-select: auto;
}

.esp-landing .btn:focus { outline: 0; }

.esp-landing .card {
  min-width: 0;
  border-radius: var(--radius);
  background-clip: border-box;
}

/* custom.css: .select2-container { height:40px!important; margin-top:7px!important }
   and a system font stack + #666 on the rendered label. */
.esp-landing .select2-container {
  height: auto !important;
  margin-top: 0 !important;
}

.esp-landing .select2-container--default .select2-selection--single .select2-selection__rendered {
  height: auto !important;
  font-family: var(--font) !important;
}

/* ---------- 8. WordPress adaptations ----------
   Changes the static build did not need because its content was fixed. */

/* Stats are an open-ended ACF repeater. The static grid hard-coded 4 columns
   (288fr 288fr 437fr 288fr), so a 5th card would have wrapped into those same
   tracks. Desktop uses flex instead: the same 288 : 437 proportions via
   flex-grow (4 cards, one wide, lay out exactly as the comp), a 220px floor so
   6+ cards wrap onto a new row. Tablet/mobile keep the comp's even 2-column grid. */
@media (min-width: 1024px) {
  .esp-landing .stats {
    display: flex;
    flex-wrap: wrap;
  }

  .esp-landing .stats__item {
    flex: 288 1 0;
    min-width: calc(220 * var(--px));
  }

  .esp-landing .stats__item--wide { flex-grow: 437; }
}

/* Brand logos are an open-ended repeater shown in the editor's order. The
   static build swapped two tile pairs on mobile with nth-child(1..8) `order`
   rules; with any count, tiles 9+ would get order 0 and jump to the front.
   Reset them so every screen shows the admin order. */
@media (max-width: 767.98px) {
  .esp-landing .brands__grid .brands__tile:nth-child(n) { order: 0; }
}

/* ---- Scroll reveal (engines-landing.js) ----
   Matches the theme's `.em-animate` / `boom` used on the other pages: rise
   2rem and fade in over 400ms. Only elements the script tagged (below the fold,
   JS running, motion allowed) are hidden. `backwards` fill holds the start
   frame during the stagger delay and then hands the element back to its own
   styles, so no transform lingers after the reveal. */
.esp-landing.has-reveal .esp-reveal:not(.is-revealed) { opacity: 0; }

.esp-landing .esp-reveal.is-revealed {
  animation: esp-reveal 400ms ease-out backwards;
}

@keyframes esp-reveal {
  from {
    opacity: 0;
    transform: translateY(2rem);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .esp-landing.has-reveal .esp-reveal:not(.is-revealed) { opacity: 1; }
  .esp-landing .esp-reveal.is-revealed { animation: none; }
}

@media print {
  .esp-landing.has-reveal .esp-reveal:not(.is-revealed) { opacity: 1; }
}

/* Optional per-logo link: fill the tile so the logo stays centred and fitted. */
.esp-landing .brands__tile > a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

/* Product grids: no layout jump before Owl starts.
   The server renders the cards WITHOUT the `owl-carousel` class (the theme's
   carousel.css hides .owl-carousel until .owl-loaded, which made the row
   collapse and then pop in). Until JS builds the carousel, lay the cards out
   at the exact size Owl will give them: 3 across >=1000 (27px gap), 2 across
   600-999, 1 across below 600 (20px gap) — the same steps as owlOptions. */
.esp-landing .js-product-grid:not(.owl-loaded):not(.is-scroller):not(.is-empty) {
  display: flex;
  gap: calc(27 * var(--px));
  overflow: hidden;
}

.esp-landing .js-product-grid:not(.owl-loaded):not(.is-scroller):not(.is-empty) > .card {
  flex: 0 0 calc((100% - calc(54 * var(--px))) / 3);
}

/* Below 1024 every product row becomes the peek scroll strip, so the pre-JS
   row uses the strip's own geometry (bleed, 46% / 85% cards, 20 gap) and
   nothing shifts when engines-landing.js adds .is-scroller. */
@media (max-width: 1023.98px) {
  .esp-landing .js-product-grid:not(.owl-loaded):not(.is-scroller):not(.is-empty) {
    gap: 20px;
    margin-inline: calc(-1 * var(--gutter));
    padding: 0 var(--gutter) 12px;
  }

  .esp-landing .js-product-grid:not(.owl-loaded):not(.is-scroller):not(.is-empty) > .card { flex-basis: 46%; }
}

@media (max-width: 767.98px) {
  .esp-landing .js-product-grid:not(.owl-loaded):not(.is-scroller):not(.is-empty) > .card { flex-basis: 85%; }
}

/* Photo shimmer: the media box shimmers until its image has loaded
   (engines-landing.js adds .is-loaded), so slow images never leave a blank hole. */
.esp-landing .card:not(.card--skeleton) .card__media {
  background: linear-gradient(90deg, #e8ecf1 25%, #f4f6f9 37%, #e8ecf1 63%);
  background-size: 400% 100%;
  animation: sk-shimmer 1.3s ease-in-out infinite;
}

/* loaded: the shimmer gives way to the flat photo ground */
.esp-landing .card:not(.card--skeleton) .card__media.is-loaded {
  background: var(--c-media-bg);
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .esp-landing .card:not(.card--skeleton) .card__media { animation: none; }
}

/* Link colours vs the theme. main.min.css has a site-wide
     a:hover, a:focus, a:active { color: #D11515 !important; }
   which turned every landing button label red on hover (invisible on the red
   button, off-design on navy/outline) and kept links red after a click.
   Restore the design's colours for every state, landing only.
   (0,2,1)+ specificity with !important beats the theme's (0,1,1) !important. */
.esp-landing a.btn,
.esp-landing a.btn:hover,
.esp-landing a.btn:focus,
.esp-landing a.btn:active,
.esp-landing a.ghost-link,
.esp-landing a.ghost-link:hover,
.esp-landing a.ghost-link:focus,
.esp-landing a.ghost-link:active,
.esp-landing .info-card__val a:hover,
.esp-landing .info-card__val a:focus,
.esp-landing .info-card__val a:active {
  color: #fff !important;
}

/* VIEW MORE: red on hover (design), but back to its resting colour once the
   pointer leaves — not stuck red while it keeps focus after a click. */
@media (hover: hover) and (pointer: fine) {
  .esp-landing a.view-more:hover { color: var(--c-red) !important; }
}

/* Touch: the theme's `a:hover { color:#D11515 !important }` would still stick
   after a tap, so hold the resting navy. */
@media (hover: none), (pointer: coarse) {
  .esp-landing a.view-more:hover { color: var(--c-navy-text) !important; }
}

.esp-landing a.view-more:focus:not(:hover),
.esp-landing a.view-more:active:not(:hover) {
  color: var(--c-navy-text) !important;
}

/* Enquiry form vs the theme's CF7 rules (custom.css / main.min.css):
     .wpcf7-not-valid-tip { display: none !important }        -> error tips never showed
     .wpcf7 form.sent .wpcf7-response-output { background: transparent !important;
       color: green; margin-top: 30px }                        -> green text, extra gap
   Restore the design's dark-panel states inside the landing enquiry only. */
.esp-landing .enquiry .wpcf7-not-valid-tip { display: block !important; }

.esp-landing .enquiry .wpcf7 form .wpcf7-response-output {
  margin: 0 !important;
  color: #fff !important;
}

.esp-landing .enquiry .wpcf7 form.sent .wpcf7-response-output,
.esp-landing .enquiry .wpcf7 form.success .wpcf7-response-output {
  background: rgba(255, 255, 255, .14) !important;
}

.esp-landing .enquiry .wpcf7 form.invalid .wpcf7-response-output,
.esp-landing .enquiry .wpcf7 form.unaccepted .wpcf7-response-output,
.esp-landing .enquiry .wpcf7 form.spam .wpcf7-response-output,
.esp-landing .enquiry .wpcf7 form.failed .wpcf7-response-output {
  padding: calc(12 * var(--px)) calc(16 * var(--px));
  background: rgba(209, 21, 21, .35) !important;
}

/* The submit is a real <button> (init.php swaps CF7's input); keep the icon
   white-on-red and the label from inheriting CF7 input styles. */
.esp-landing .enquiry .enquiry-form__submit { cursor: pointer; }
.esp-landing .enquiry .enquiry-form__submit:disabled { opacity: .7; cursor: wait; }

/* Typed text stays white. The theme's style.css (_s) has
     input[type="text"]:focus, input[type="email"]:focus, … { color: #111; }
   (0,2,1), which beats .esp-landing .field__input (0,2,0) — text turned
   near-black while typing. :focus here is (0,3,0).
   Browser autofill also paints its own text/background; keep it on-design by
   forcing the text fill and delaying the autofill background indefinitely. */
.esp-landing .field__input:focus { color: #fff; }

.esp-landing .field__input:-webkit-autofill,
.esp-landing .field__input:-webkit-autofill:hover,
.esp-landing .field__input:-webkit-autofill:focus {
  -webkit-text-fill-color: #fff;
  caret-color: #fff;
  transition: background-color 9999s ease-out 0s;
}

/* Info-card labels are <dt>s. The theme (main.min.css and style.css) sets
   dt { font-weight: 700 }, so "Showroom / Hours / Telephone / Email" rendered
   bold; the comp is Jost 20/24 regular (the static page got the browser's
   normal dt weight). */
.esp-landing .info-card__key { font-weight: 400; }

/* ---- Enquiry: custom validation (assets/js/enquiry-validation.js) ----
   The JS owns the client-side errors: CF7's own tips are hidden here (server
   rejections are copied into our slot), and CF7's .wpcf7-not-valid border is
   replaced by the .field.is-invalid state. No error design in the comp — the
   input border keeps #ffc9c9 on the dark panel; the message uses the contact
   page's red tip (below). */
.esp-landing .enquiry .wpcf7-not-valid-tip { display: none !important; }

.esp-landing .enquiry .field__input.wpcf7-not-valid { border-color: rgba(255, 255, 255, .2); }

.esp-landing .enquiry .field.is-invalid .field__input,
.esp-landing .enquiry .field.is-invalid .field__input:hover {
  border-color: #ffc9c9;
}

.esp-landing .enquiry .field.is-invalid .field__input:focus {
  border-color: #ffc9c9;
  box-shadow: inset 0 0 0 1px #ffc9c9;
}

/* Error tip matches the contact page (main.min.css label.error): red box,
   white Jost 13/21, 7px arrow pointing up at the field. Absolute, so a shown
   error does not push the rows below down: .field is its anchor and the tip
   sits 8px under the field (top 7 + margin 1), in the row gap. */
.esp-landing .enquiry .field { position: relative; }

.esp-landing .field__error {
  position: absolute;
  top: calc(100% + calc(7 * var(--px)));
  left: 0;
  align-self: flex-start;
  margin-top: 1px;
  padding: 0 calc(7 * var(--px));
  background: var(--c-red);
  color: #fff;
  font-family: var(--font);
  font-size: max(calc(13 * var(--px)), 12px);
  font-weight: 400;
  line-height: calc(21 * var(--px));
}

/* Mobile stacks the fields with a 20px gap — too tight for the 29px tip, which
   covered the next field's label. Keep it in the flow there (margin 1 + the
   field's 6px gap = the same 7px under the input). */
@media (max-width: 767.98px) {
  .esp-landing .field__error { position: relative; top: auto; left: auto; }
}

.esp-landing .field__error[hidden],
.esp-landing .field__count[hidden] { display: none; }

.esp-landing .field__error::before {
  content: "";
  position: absolute;
  top: -14px;
  left: 7px;
  border: 7px solid transparent;
  border-bottom-color: var(--c-red);
}

.esp-landing .field__count {
  align-self: flex-end;
  color: #cfdae6;
  font-family: var(--font);
  font-size: max(calc(12 * var(--px)), 12px);
  line-height: calc(16 * var(--px));
}

.esp-landing .field__count.is-over { color: #ffc9c9; }

/* Bot trap field (form-antispam.php): off-screen, not display:none, so simple
   bots still see and fill it; aria-hidden + tabindex -1 keep people out. */
.esp-landing .esp-hp {
  position: absolute !important;
  left: calc(-9999 * var(--px)) !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Response bar: only the success message is shown. Invalid / spam / failed
   states are hidden — field errors already show inline under each field. */
.esp-landing .enquiry .wpcf7 form:not(.sent) .wpcf7-response-output {
  display: none !important;
}

/* Success strip (CF7 "mail sent" message, text in form 9653 › Messages).
   Soft white panel on the dark enquiry card, thin border, green check drawn in
   CSS (no icon file). Overrides the earlier sent/success background rule. */
.esp-landing .enquiry .wpcf7 form.sent .wpcf7-response-output,
.esp-landing .enquiry .wpcf7 form.success .wpcf7-response-output {
  position: relative;
  margin-top: calc(8 * var(--px)) !important;
  padding: calc(16 * var(--px)) calc(20 * var(--px)) calc(16 * var(--px)) calc(56 * var(--px));
  background: rgba(255, 255, 255, .08) !important;
  border: 1px solid rgba(255, 255, 255, .22) !important;
  border-left: calc(3 * var(--px)) solid #2eb67d !important;
  border-radius: 0;
  color: #fff !important;
  font-family: var(--font);
  font-size: max(calc(15 * var(--px)), 12px);
  line-height: calc(22 * var(--px));
}

/* green circle */
.esp-landing .enquiry .wpcf7 form.sent .wpcf7-response-output::before,
.esp-landing .enquiry .wpcf7 form.success .wpcf7-response-output::before {
  content: "";
  position: absolute;
  top: 50%;
  left: calc(18 * var(--px));
  width: calc(24 * var(--px));
  height: calc(24 * var(--px));
  margin-top: calc(-12 * var(--px));
  border-radius: 50%;
  background: #2eb67d;
}

/* white tick */
.esp-landing .enquiry .wpcf7 form.sent .wpcf7-response-output::after,
.esp-landing .enquiry .wpcf7 form.success .wpcf7-response-output::after {
  content: "";
  position: absolute;
  top: 50%;
  left: calc(26.5 * var(--px));
  width: calc(6 * var(--px));
  height: calc(11 * var(--px));
  margin-top: calc(-7.5 * var(--px));
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

@media (max-width: 767.98px) {
  .esp-landing .enquiry .wpcf7 form.sent .wpcf7-response-output,
  .esp-landing .enquiry .wpcf7 form.success .wpcf7-response-output {
    padding: 14px 16px 14px 52px;
    font-size: 14px;
    line-height: 20px;
  }
  .esp-landing .enquiry .wpcf7 form.sent .wpcf7-response-output::before,
  .esp-landing .enquiry .wpcf7 form.success .wpcf7-response-output::before { left: 16px; }
  .esp-landing .enquiry .wpcf7 form.sent .wpcf7-response-output::after,
  .esp-landing .enquiry .wpcf7 form.success .wpcf7-response-output::after { left: 24.5px; }
}

/* Success strip auto-hide (enquiry-validation.js): fades after 8 s, then goes. */
.esp-landing .enquiry .wpcf7 form .wpcf7-response-output {
  transition: opacity .4s ease;
}

.esp-landing .enquiry .wpcf7 form .wpcf7-response-output.is-fading { opacity: 0; }

.esp-landing .enquiry .wpcf7 form .wpcf7-response-output.is-dismissed { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  .esp-landing .enquiry .wpcf7 form .wpcf7-response-output { transition: none; }
}

/* Enquiry intro on mobile: the 35px inset stacked with the red-bar heading's own
   inset, pushing the title to 86px and the text / info card / links to 51px —
   an empty strip on the left. Align it like the About section on mobile: heading
   block and content start at the container edge. (768–1023 keeps the 55px inset,
   same as the About intro there.) */
@media (max-width: 767.98px) {
  .esp-landing .enquiry__intro { padding-left: 0; }
}

/* Found in the 393 comparison against the static build (fonts, colours and
   spacing otherwise identical):
   - the theme gives every <label> margin-bottom: 8px -> field labels sat 8px
     lower than the design (6px field gap only);
   - the theme's carousel.css shows Owl's *disabled* dots (display:flex +
     margin-top 20px) -> an empty 20px row under every product carousel;
   - CF7's spinner used to wrap under a full-width submit on mobile; the
     12:629 comp sizes the submit to its label, so the spinner now sits beside
     it in the footer row and needs no pinning. */
.esp-landing .field__label { margin: 0; }

.esp-landing .product-carousel .owl-dots.disabled { display: none; }

/* Enquiry intro below 1024: the desktop column cap (max-width 445px on the text,
   info card and links) left an empty strip on the right once the section is a
   single full-width column. Let them use the full container width. */
@media (max-width: 1023.98px) {
  .esp-landing .enquiry__text,
  .esp-landing .info-card,
  .esp-landing .enquiry__links { max-width: none; }
}

/* About at 1024–1199: two columns (copy + photo) were too cramped — the title
   wrapped to 4 lines beside the photo. Stack it like tablet: copy full width,
   photo below the "What we offer" list at the comp's 682:488 ratio. Desktop
   type sizes stay. Below 1200 the paragraph's desktop 545px cap is dropped so
   the copy uses the full width (tablet had the same empty strip). */
@media (min-width: 1024px) and (max-width: 1199.98px) {
  .esp-landing .about__grid { grid-template-columns: 1fr; gap: 40px; }
  .esp-landing .about__media { height: auto; aspect-ratio: 682 / 488; }
}

@media (max-width: 1199.98px) {
  .esp-landing .about__text { max-width: none; }
}

/* Enquiry at 1024–1199 (user: "too congested"): keep the two columns but
   tighten them — column gap 60 -> 32, no 55px intro inset (the red-bar heading
   keeps its own), tablet title size, and the info card stacks each label above
   its value (as on mobile) so the address is not squeezed into a narrow column. */
@media (min-width: 1024px) and (max-width: 1199.98px) {
  .esp-landing .enquiry__grid { gap: 32px; }
  .esp-landing .enquiry__intro { padding-left: 0; }
  /* the red bar lived in that 55px inset (left:-55px) — use the mobile pattern:
     bar at the column edge, only the heading clears it */
  .esp-landing .enquiry .about__head { padding-left: 35px; }
  .esp-landing .enquiry .about__head::before { left: 0; }
  .esp-landing .enquiry__title { font-size: 34px; line-height: 42px; }
  .esp-landing .info-card { padding: 24px; }
  .esp-landing .info-card__row { flex-direction: column; gap: 4px; }
  .esp-landing .info-card__row + .info-card__row { margin-top: 20px; }
  .esp-landing .info-card__key { flex: none; padding-top: 0; }
  .esp-landing .info-card__val { line-height: 24px; }
}
