/* ═══════════════════════════════════════════════════════════════════════
   LANDING PAGE — public `/` only (app/Views/front/landing.php).

   Loaded via $pageStyles by layouts/front.php, AFTER app.css, so every `.lp-*`
   rule overrides `.mk-*` on plain two-class specificity. This file contains no
   !important (the only sanctioned one is app.css's reduced-motion kill switch)
   and no @layer — wrapping this in a layer would make every `.lp .mk-*`
   override lose to unlayered app.css regardless of specificity.

   Rules that bind here:
   · Tokens only. Every colour, space and size comes from tokens.css, so dark
     mode (html[data-theme='dark']) follows for free. The exceptions are the two
     fixed-dark surfaces — the hero scrim and the navy band — whose text is
     deliberately #fff in BOTH themes, the same exemption .mk-promo-primary has.
   · Mobile-first: base rules are the phone, columns are added at min-width:768px.
   · app.css's ≤768px safety net only knows the hardcoded `.mk-*` grid names, so
     every `.lp-*` grid carries its own guard at the bottom of this file — with
     minmax(0, 1fr), never bare 1fr, which is minmax(auto, 1fr) and lets one long
     unbroken Kazakh word push a track past the viewport.
   · Radii are a hierarchy, not a grab bag: --lp-r-shell (the hero card that
     holds everything) > --lp-r-card (tiles, panels) > --lp-r-control (inputs,
     buttons). Three roles, three values, and nothing picks a fourth — a screen
     where four unrelated corners meet is what cheap looks like.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Page-local sizing ──────────────────────────────────────────────────
   Scoped custom properties rather than bare values, so a size lives in one
   place and the desktop block below only has to restate the ones that change. */
.lp {
  --lp-tile-h:     150px;
  --lp-sec-pad:    var(--space-12);
  --lp-gap:        var(--space-4);
  --lp-pad:        var(--space-6);
  --lp-control:    52px;
  --lp-r-control:  var(--radius-md);   /* 14 — inputs, buttons, badges */
  --lp-r-card:     var(--radius-lg);   /* 20 — tiles, panels */
  --lp-r-shell:    var(--radius-xl);   /* 28 — the hero card itself */
  --lp-shell-gap:  var(--space-3);     /* page margin around the hero card */
}

/* ── Ground rhythm ──────────────────────────────────────────────────────
   Each section is its own full-bleed band. Padding, never margin: margins
   between coloured grounds would tear them apart and leave a white seam.
   In dark mode the polarity flips correctly — background #0B0F1A < surface
   #121828 < surface-muted #1A2133 — so a "muted" band reads as raised, which
   is the dark-UI convention rather than a mistake. */
.lp-sec {
  padding-block: var(--lp-sec-pad);
  background: var(--color-surface);
}
.lp-sec--muted { background: var(--color-surface-muted); }

/* Section heads: drop app.css's permanent 2px underline for a rule that draws
   itself when the section arrives (see Motion). */
.lp .mk-section-title {
  position: relative;
  border-bottom: 0;
  padding-bottom: var(--space-3);
  font-size: var(--text-display-lg);
  font-weight: var(--weight-black);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tighter);
  text-wrap: balance;
  max-width: 20ch;
}
.lp .mk-section-head { align-items: flex-end; margin-bottom: var(--space-6); }

/* ── Hero ───────────────────────────────────────────────────────────────
   Full-bleed той-hall photo under a navy scrim. `isolation: isolate` keeps the
   negative z-indexes of the media and scrim inside this section instead of
   sliding behind the page background. */
/* An inset card, not a full-bleed band: the page ground shows as a margin on all
   four sides, which is what makes the hero read as an object placed on the page
   rather than as the top of the page. overflow:hidden is what clips the photo and
   the scrim to the rounded corners. */
.lp-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin: var(--lp-shell-gap);
  border-radius: var(--lp-r-shell);
  /* Painted before the photo decodes, so the headline is never on bare white. */
  background: var(--color-navy);
}

.lp-hero-media {
  position: absolute;
  inset: 0;
  z-index: -2;
  display: block;
}
.lp-hero-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 46%;
}

/* Scrim. The plain rgba() declaration is the fallback for engines without
   color-mix(); the color-mix() line below wins wherever it is supported.
   Vertical on phones — the 4:5 crop needs the whole frame darkened. */
.lp-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, rgba(0, 0, 60, .58) 0%, rgba(0, 0, 60, .46) 38%, rgba(0, 0, 60, .86) 100%);
  background: linear-gradient(180deg,
      color-mix(in srgb, var(--color-navy) 58%, transparent) 0%,
      color-mix(in srgb, var(--color-navy) 46%, transparent) 38%,
      color-mix(in srgb, var(--color-navy) 86%, transparent) 100%);
}
html[data-theme='dark'] .lp-hero::after {
  background: linear-gradient(180deg, rgba(5, 5, 31, .82) 0%, rgba(5, 5, 31, .70) 38%, rgba(5, 5, 31, .94) 100%);
  background: linear-gradient(180deg,
      color-mix(in srgb, var(--color-navy) 82%, transparent) 0%,
      color-mix(in srgb, var(--color-navy) 70%, transparent) 38%,
      color-mix(in srgb, var(--color-navy) 94%, transparent) 100%);
}
html[data-theme='dark'] .lp-hero-media img { filter: brightness(.82) saturate(.92); }

/* No min-height on phones: the stacked search box adds ~300px on its own, and a
   viewport-height floor on top of that overflows a 640px screen. */
.lp-hero-inner {
  position: relative;
  padding-block: var(--space-16) var(--space-12);
}

.lp-hero-eyebrow {
  margin: 0 0 var(--space-3);
  letter-spacing: var(--tracking-eyebrow);
  color: rgba(255, 255, 255, .70);
}

.lp-hero-title {
  margin: 0 0 var(--space-4);
  max-width: 16ch;
  font-family: var(--font-display);
  font-size: var(--text-display-xl);
  font-weight: var(--weight-black);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  color: #fff;
  text-wrap: balance;
  text-shadow: 0 2px 24px rgba(0, 0, 40, .35);
}

.lp-hero-sub {
  margin: 0 0 var(--space-8);
  max-width: 46ch;
  font-size: var(--text-lead);
  line-height: var(--leading-normal);
  color: rgba(255, 255, 255, .90);
  text-wrap: pretty;
}

/* ── Hero search — the shared /listings control, on a photo ──────────────
   Scoped to .lp, so /listings and /app never see any of this. A solid surface
   and a deep shadow, NO backdrop-filter: the 2026-06-05 ruling is that blur is
   temporary UI, never the content layer. */
.lp-hero-searchlabel {
  margin: 0 0 var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: rgba(255, 255, 255, .82);
}

.lp .mk-search-box {
  max-width: 100%;
  border-radius: var(--lp-r-card);
  border-color: rgba(255, 255, 255, .26);
  box-shadow: 0 24px 64px rgba(0, 0, 40, .40);
}
.lp .mk-search-input,
.lp .mk-dropdown-trigger,
.lp .mk-search-button,
.lp .mk-search-item:focus-within,
.lp .mk-custom-dropdown.is-open { border-radius: var(--lp-r-control); }

/* One control height across the strip, and the page's body size instead of the
   hardcoded 15px — Onest at 15px reads small next to a 76px headline. */
.lp .mk-search-item,
.lp .mk-search-input,
.lp .mk-dropdown-trigger,
.lp .mk-search-button { height: var(--lp-control); }
.lp .mk-search-input,
.lp .mk-dropdown-trigger { font-size: var(--text-body); }

/* One shadow per surface: the box already carries the elevation. */
.lp .mk-search-button,
.lp .mk-search-button:hover { box-shadow: none; }

.lp-hero-more {
  margin: var(--space-5) 0 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}
.lp-hero-more a {
  color: rgba(255, 255, 255, .88);
  text-decoration: none;
}
.lp-hero-more a:hover { color: #fff; text-decoration: underline; }

/* ── Hero foot: counters left, store badges right ────────────────────────
   Stacked on phones, pushed to opposite ends on desktop, sharing one baseline. */
.lp-herofoot {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-6);
  margin-top: var(--space-10);
}

.lp-stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-8);
  margin: 0;
}
.lp-stat > * { margin: 0; }          /* <dd> carries a UA margin-inline-start */
.lp-stat-num {
  font-family: var(--font-display);
  font-size: var(--text-display-md);
  font-weight: var(--weight-bold);
  line-height: 1.1;
  letter-spacing: var(--tracking-tight);
  color: #fff;
  /* Digits line up column-to-column instead of jittering by glyph width. */
  font-variant-numeric: tabular-nums;
}
.lp-stat-label {
  margin-top: 2px;
  font-size: var(--text-sm);
  color: rgba(255, 255, 255, .70);
}

.lp-stores {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}
/* A store badge is a brand surface: near-black with white type in BOTH themes,
   the way the real badges ship. Theming it would make it stop being a badge. */
.lp-store {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  height: var(--lp-control);
  padding-inline: var(--space-4);
  border: 1px solid rgba(255, 255, 255, .22);
  border-radius: var(--lp-r-control);
  background: rgba(0, 0, 0, .55);
  color: #fff;
  text-decoration: none;
  transition: background var(--transition), border-color var(--transition), transform var(--transition);
}
.lp-store:hover {
  background: rgba(0, 0, 0, .74);
  border-color: rgba(255, 255, 255, .42);
  transform: translateY(-2px);
}
.lp-store-icon { display: inline-flex; flex-shrink: 0; }
.lp-store-text { display: flex; flex-direction: column; line-height: 1.15; }
.lp-store-pre {
  font-size: 11px;
  color: rgba(255, 255, 255, .72);
}
.lp-store-name {
  font-size: var(--text-body);
  font-weight: var(--weight-bold);
}

/* ── Admin-editable banner ──────────────────────────────────────────────
   Background colour is set inline from the DB; everything else lives here. */
.lp-banner {
  display: block;
  margin-bottom: var(--space-8);
  padding: var(--space-5) var(--space-6);
  border-radius: var(--lp-r-card);
  color: #fff;
  text-decoration: none;
}
.lp-banner-title {
  display: block;
  font-size: var(--text-h3);
  font-weight: var(--weight-bold);
}
.lp-banner-sub {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  opacity: .9;
}

/* ── Category bento ─────────────────────────────────────────────────────
   The lead tile is chosen by POSITION, not by slug, so nothing breaks if the
   seeder ever renames a category. :has() gates it on the strip really being the
   canonical five: with four tiles it degrades to one honest row, with six to a
   big block plus five. Reuses partials/category_photo untouched — that partial
   is shared with /listings and /app. */
.lp-cats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: var(--lp-tile-h);
  gap: var(--lp-gap);
}
.lp-cats:has(> :nth-child(5)) > .lp-cat:first-child { grid-column: 1 / -1; }

.lp-cat {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--color-border);   /* neutral grey — the 2026-06-25 rule stands */
  border-radius: var(--lp-r-card);
  background: var(--color-primary-soft2);
  color: var(--color-text);
  text-decoration: none;
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}

/* The photo box FILLS its tile instead of a fixed height, so one rule serves
   both the 2×2 lead block and the 1×1 people. Two classes (0,2,0) beat
   app.css's .mk-cat-photo (0,1,0) — no !important needed. */
.lp-cat .mk-cat-photo {
  flex: 1 1 auto;
  height: auto;
  min-height: 0;
  background: transparent;
}
.lp-cat .mk-cat-photo img { transition: transform 480ms cubic-bezier(.22, .61, .36, 1); }

.lp-cat-name {
  padding: var(--space-3) var(--space-4) var(--space-4);
  font-size: var(--text-body-lg);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
  text-wrap: balance;
}

/* Lead tile: the name sits ABOVE the building, filling the sky that the 2.18:1
   тойхана art leaves empty. `order` is visual only — DOM order is unchanged, so
   a screen reader still hears the label after the image it labels. */
.lp-cats:has(> :nth-child(5)) > .lp-cat:first-child .lp-cat-name {
  order: -1;
  padding: var(--lp-pad) var(--lp-pad) var(--space-2);
  font-size: var(--text-display-md);
  font-weight: var(--weight-black);
  letter-spacing: var(--tracking-tight);
}

/* ── How it works ───────────────────────────────────────────────────────  */
.lp-steps {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--lp-gap);
  margin: 0;
  padding: 0;
  list-style: none;
}
.lp-step {
  position: relative;
  padding: var(--lp-pad);
  border: 1px solid var(--color-border);
  border-radius: var(--lp-r-card);
  background: var(--color-surface);
}
.lp-step-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  margin-bottom: var(--space-4);
  border-radius: var(--lp-r-control);
  background: var(--color-violet-soft);
  color: var(--color-primary);
}
.lp-step-icon svg { width: 22px; height: 22px; }
.lp-step-num {
  position: absolute;
  top: var(--space-4);
  right: var(--space-5);
  font-family: var(--font-display);
  font-size: var(--text-display-lg);
  font-weight: var(--weight-black);
  line-height: 1;
  letter-spacing: var(--tracking-display);
  color: var(--color-primary-soft);
}
.lp-step-title {
  margin: 0 0 var(--space-2);
  font-size: var(--text-h3);
  font-weight: var(--weight-bold);
  color: var(--color-text);
  text-wrap: balance;
}
.lp-step-text {
  margin: 0;
  max-width: 42ch;
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  color: var(--color-text-body);
  text-wrap: pretty;
}

/* ── Full-bleed photo band ──────────────────────────────────────────────
   Same construction as the hero, and the same fixed-dark-surface exemption:
   the copy is #fff in both themes because the scrim is not a themed surface. */
.lp-photoband {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--color-navy);
}
.lp-photoband-media {
  position: absolute;
  inset: 0;
  z-index: -2;
  display: block;
}
.lp-photoband-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 40%;
}
.lp-photoband::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(100deg, rgba(0, 0, 60, .92) 0%, rgba(0, 0, 60, .74) 42%, rgba(0, 0, 60, .30) 100%);
  background: linear-gradient(100deg,
      color-mix(in srgb, var(--color-navy) 92%, transparent) 0%,
      color-mix(in srgb, var(--color-navy) 74%, transparent) 42%,
      color-mix(in srgb, var(--color-navy) 30%, transparent) 100%);
}
html[data-theme='dark'] .lp-photoband::after {
  background: linear-gradient(100deg, rgba(5, 5, 31, .94) 0%, rgba(5, 5, 31, .82) 42%, rgba(5, 5, 31, .46) 100%);
  background: linear-gradient(100deg,
      color-mix(in srgb, var(--color-navy) 94%, transparent) 0%,
      color-mix(in srgb, var(--color-navy) 82%, transparent) 42%,
      color-mix(in srgb, var(--color-navy) 46%, transparent) 100%);
}
html[data-theme='dark'] .lp-photoband-media img { filter: brightness(.82) saturate(.92); }

.lp-photoband-inner {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: clamp(360px, 52vh, 520px);
  padding-block: var(--lp-sec-pad);
}
.lp-photoband-title {
  margin: 0 0 var(--space-3);
  max-width: 18ch;
  font-family: var(--font-display);
  font-size: var(--text-display-lg);
  font-weight: var(--weight-black);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tighter);
  color: #fff;
  text-wrap: balance;
}
.lp-photoband-text {
  margin: 0;
  max-width: 44ch;
  font-size: var(--text-lead);
  line-height: var(--leading-normal);
  color: rgba(255, 255, 255, .88);
  text-wrap: pretty;
}
.lp-photoband-more {
  margin: var(--space-5) 0 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}
.lp-photoband-more a { color: rgba(255, 255, 255, .88); text-decoration: none; }
.lp-photoband-more a:hover { color: #fff; text-decoration: underline; }

/* ── Той-planner promo ──────────────────────────────────────────────────  */
.lp-planner {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4);
  align-items: center;
  padding: var(--lp-pad);
  border: 1px solid var(--color-border);
  border-radius: var(--lp-r-card);
  background: var(--color-surface);
}
.lp-planner-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: var(--lp-r-control);
  background: var(--color-violet-soft);
  color: var(--color-primary);
}
.lp-planner-icon svg { width: 26px; height: 26px; }
.lp-planner-title {
  margin: 0 0 var(--space-2);
  font-family: var(--font-display);
  font-size: var(--text-display-md);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text);
  text-wrap: balance;
}
.lp-planner-sub {
  margin: 0;
  max-width: 52ch;
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  color: var(--color-text-body);
  text-wrap: pretty;
}
.lp-planner-cta {
  width: auto;
  height: var(--lp-control);
  padding-inline: var(--space-8);
  border-radius: var(--lp-r-control);
}

/* ── Providers band ─────────────────────────────────────────────────────
   Full-bleed navy. --color-navy stays dark in BOTH themes, unlike
   --color-primary which lightens to #6C6CFF in dark mode and would drop white
   text below 4.5:1. */
.lp-band {
  padding-block: var(--lp-sec-pad);
  background: var(--color-navy);
}
.lp-band-inner {
  max-width: 660px;
  text-align: center;
}
.lp-band-title {
  margin: 0 0 var(--space-3);
  font-family: var(--font-display);
  font-size: var(--text-display-lg);
  font-weight: var(--weight-black);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tighter);
  color: #fff;
  text-wrap: balance;
}
.lp-band-text {
  margin: 0;
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  color: rgba(255, 255, 255, .84);
  text-wrap: pretty;
}
.lp-band-actions { margin: var(--space-6) 0 0; }
.lp-band-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--lp-control);
  padding-inline: var(--space-8);
  border-radius: var(--lp-r-control);
  background: #fff;
  color: var(--color-navy);
  font-size: var(--text-body);
  font-weight: var(--weight-bold);
  text-decoration: none;
  transition: transform var(--transition), box-shadow var(--transition);
}
.lp-band-cta:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 28px rgba(0, 0, 0, .28);
}
.lp-band-note {
  margin: var(--space-4) 0 0;
  font-size: var(--text-sm);
  color: rgba(255, 255, 255, .66);
}

/* ── Motion ─────────────────────────────────────────────────────────────
   `.mk-reveal` is added by initScrollReveal() in app.js and NEVER by the
   markup: a blocked script, a missing IntersectionObserver or an OS
   reduced-motion setting all leave the page fully visible, because none of the
   selectors below can match without that class. app.css's reduced-motion kill
   switch also neutralises every transition here, which is why the JS bails out
   before adding the class in that case — two independent belts. */
.mk-reveal {
  opacity: 0;
  transform: translateY(14px);
}
.mk-reveal.is-revealed {
  opacity: 1;
  transform: none;
  transition: opacity 480ms ease, transform 480ms ease;
}

/* A revealed BAND holds still — a full-bleed ground sliding against the section
   above it reads as a glitch. Its staggered children do the moving instead. */
.lp .mk-reveal { opacity: 1; transform: none; }
.lp .mk-reveal .lp-stagger > * {
  opacity: 0;
  transform: translateY(16px);
}
.lp .mk-reveal.is-revealed .lp-stagger > * {
  opacity: 1;
  transform: none;
  transition: opacity 520ms ease, transform 520ms ease;
}
.lp .mk-reveal.is-revealed .lp-stagger > :nth-child(2) { transition-delay:  70ms; }
.lp .mk-reveal.is-revealed .lp-stagger > :nth-child(3) { transition-delay: 140ms; }
.lp .mk-reveal.is-revealed .lp-stagger > :nth-child(4) { transition-delay: 210ms; }
.lp .mk-reveal.is-revealed .lp-stagger > :nth-child(5) { transition-delay: 280ms; }
.lp .mk-reveal.is-revealed .lp-stagger > :nth-child(6) { transition-delay: 350ms; }

/* Section rule: draws itself left-to-right as the section arrives. The second
   selector is the no-JS path — without initScrollReveal() the section never
   gets .mk-reveal, so the rule is simply drawn. */
.lp .mk-section-title::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 56px;
  height: 2px;
  background: var(--color-primary);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 520ms ease 120ms;
}
.lp .mk-reveal.is-revealed .mk-section-title::after,
.lp .lp-sec:not(.mk-reveal) .mk-section-title::after { transform: scaleX(1); }

/* Hero photo settles on load. It cannot cause CLS — the media is absolutely
   positioned, so a transform reflows nothing — and a composited transform does
   not delay LCP. */
@keyframes lpHeroIn {
  from { transform: scale(1.06); }
  to   { transform: scale(1); }
}
.lp-hero-media img { animation: lpHeroIn 1400ms cubic-bezier(.16, 1, .3, 1) both; }

/* Hero stagger — .mk-animate uses `both` fill, so a delayed element starts
   hidden and settles at opacity:1. Under prefers-reduced-motion the app.css
   kill switch drops the animation and the element keeps that computed 1. */
.lp-d1 { animation-delay:  90ms; }
.lp-d2 { animation-delay: 170ms; }
.lp-d3 { animation-delay: 250ms; }
.lp-d4 { animation-delay: 330ms; }
.lp-d5 { animation-delay: 410ms; }

/* Hover is pointer-gated so a phone tap never leaves a card stuck in its
   hover state. The hover border colour does NOT reopen the 2026-06-25 ruling:
   that was about the RESTING border, which stays --color-border grey. */
@media (hover: hover) and (pointer: fine) {
  .lp-cat:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-lg);
    border-color: var(--color-primary);
  }
  .lp-cat:hover .mk-cat-photo img { transform: translateY(-6px) scale(1.03); }

  /* .mk-listing-img already has overflow:hidden in app.css, so this is clipped. */
  .lp .mk-listing-img img { transition: transform 520ms cubic-bezier(.22, .61, .36, 1); }
  .lp .mk-listing-card:hover .mk-listing-img img { transform: scale(1.06); }
}

/* ── Desktop ────────────────────────────────────────────────────────────  */
@media (min-width: 768px) {
  .lp {
    --lp-tile-h:  208px;
    --lp-sec-pad: var(--space-20);
    --lp-gap:     var(--space-5);
    --lp-pad:     var(--space-8);
  }

  .lp { --lp-shell-gap: var(--space-5); }

  .lp-hero-inner {
    min-height: clamp(560px, 84vh, 760px);
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-block: var(--space-20) var(--space-16);
  }

  /* Left-weighted diagonal instead of a flat vertical wash, so the right third
     of the hall stays legible. This is the change that reads as art direction
     rather than "dark overlay". */
  .lp-hero::after {
    background: linear-gradient(100deg, rgba(0, 0, 60, .90) 0%, rgba(0, 0, 60, .72) 46%, rgba(0, 0, 60, .28) 100%);
    background: linear-gradient(100deg,
        color-mix(in srgb, var(--color-navy) 90%, transparent) 0%,
        color-mix(in srgb, var(--color-navy) 72%, transparent) 46%,
        color-mix(in srgb, var(--color-navy) 28%, transparent) 100%);
  }
  html[data-theme='dark'] .lp-hero::after {
    background: linear-gradient(100deg, rgba(5, 5, 31, .94) 0%, rgba(5, 5, 31, .82) 46%, rgba(5, 5, 31, .46) 100%);
    background: linear-gradient(100deg,
        color-mix(in srgb, var(--color-navy) 94%, transparent) 0%,
        color-mix(in srgb, var(--color-navy) 82%, transparent) 46%,
        color-mix(in srgb, var(--color-navy) 46%, transparent) 100%);
  }

  .lp-hero-search { max-width: 880px; }

  .lp-cats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .lp-cats:has(> :nth-child(5)) > .lp-cat:first-child {
    grid-column: span 2;
    grid-row:    span 2;
  }

  .lp-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  .lp-planner {
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: var(--space-6);
  }
}

/* ── Mobile overflow guard ──────────────────────────────────────────────
   app.css's ≤768px net force-collapses a hardcoded list of `.mk-*` grids; it
   has never heard of `.lp-*`. minmax(0, 1fr) — not bare 1fr, which is
   minmax(auto, 1fr) — is what actually stops a long unbroken Kazakh word from
   pushing a track past the viewport. */
@media (max-width: 768px) {
  .lp, .lp-hero, .lp-photoband, .lp-band, .lp-sec { max-width: 100%; }

  /* A display-sized title and a nowrap "see all" link cannot share one row on a
     360px screen, so the head stacks rather than squeezing the title. */
  .lp .mk-section-head {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
  }

  .lp-cats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lp-cats:has(> :nth-child(5)) > .lp-cat:first-child {
    grid-column: 1 / -1;
    grid-row: auto;
  }
  .lp-steps, .lp-planner { grid-template-columns: minmax(0, 1fr); }
  .lp-cats > *, .lp-steps > *, .lp-planner > * { min-width: 0; }

  .lp-cat-name,
  .lp-step-title,
  .lp-planner-title,
  .lp-photoband-title,
  .lp-band-title,
  .lp-banner-title {
    overflow-wrap: anywhere;
    word-break: break-word;
  }
  .lp-band-cta, .lp-planner-cta { white-space: normal; }

  /* Counters above badges, both left-aligned — side by side they would each get
     half a phone and neither would fit. */
  .lp-herofoot {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-6);
    margin-top: var(--space-8);
  }
  .lp-stats { gap: var(--space-3) var(--space-6); }
  .lp-store { flex: 1 1 auto; justify-content: center; }

  /* The lead tile is a wide banner here, so its big name would crowd a 150px
     row — step it back to the section-title size. */
  .lp-cats:has(> :nth-child(5)) > .lp-cat:first-child .lp-cat-name {
    font-size: var(--text-h2);
  }
}
