/* ============================================================
   KOBA — home.css
   The homepage's own blocks. Loaded only by index.html.
   ============================================================
   The page is a story in three acts — ДЛЯ ЧОГО → ЯК → ЩО. The section
   furniture that makes that structure readable (kicker, title, lead, text
   link) is shared and lives in style.css as .sec-*; the head layout and the
   actions below are this page's own.

   Rules this file keeps (CLAUDE.md, "Стандарти коду → CSS"):
   - No literal colours. Everything is a token from variables.css; check.sh
     greps this file as well as style.css.
   - Mobile-first; media queries at the bottom of each component; 600/768/1024.
   - Only transform and opacity move. Scroll-driven reveals sit inside THREE
     gates — @media screen, @supports (animation-timeline: view()), and
     prefers-reduced-motion: no-preference — and NOTHING is at opacity 0
     without a running animation.
   - `animation` never takes --t / --t-md (see variables.css); --dur-* and
     --ease-* are the animation tokens.

   The illustrations are an inline SVG sprite at the end of index.html. They
   stroke in currentColor, so every frame that hosts one sets
   `color: var(--c-art-line)`; their other colours come in through custom
   properties, which — unlike class selectors — DO reach inside a <use>.
   ============================================================ */


/* ── Shared section furniture ───────────────────────────────── */

.home-hero,
.home-goals,
.home-spec,
.home-origin,
.home-order,
.home-shelf,
.home-reviews,
.home-finale {
  padding-block: var(--sp-section);
}

.home-head { margin-bottom: var(--sp-8); max-width: 44rem; }
.home-head--center { margin-inline: auto; text-align: center; }

/* The kicker, title, lead and text link that used to live here as .home-* are
   the shared section furniture in style.css now (.sec-kicker, .sec-title,
   .sec-lead, .sec-link): the catalogue and the blog open their sections the
   same way. Only the homepage-specific placement stays below. */
.home-head--center .sec-lead { margin-inline: auto; }

.home-actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--sp-3);
  margin-top: var(--sp-8);
}
.home-actions .btn { width: 100%; justify-content: center; }
.home-actions--center { align-items: center; }

/* Every illustration frame shares this: the plate, the glow from below, the
   hairline. A real photo dropped into the same frame keeps all three. */
.art-frame-base,
.home-hero-art,
.goal-card-art,
.station-art,
.risk-card-art,
.finale-art {
  position: relative;
  overflow: hidden;
  color: var(--c-art-line);
  background-color: var(--c-plate);
  background-image: var(--grad-tile-glow);
  border: 1px solid var(--c-border);
}

/* Hidden sprite container: present for <use>, invisible and out of flow. */
.art-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

@media (min-width: 600px) {
  .home-actions { flex-direction: row; align-items: center; flex-wrap: wrap; }
  .home-actions .btn { width: auto; }
  .home-actions--center { justify-content: center; }
}


/* ══ HERO ══════════════════════════════════════════════════════
   Text first, the client's photo beside it from 1024px (under it on a phone, so
   the heading and the buttons stay on the first screen). The h1 is never
   animated. On a phone it is the LCP element and needs only the preloaded
   Manrope subsets; from 1024px the photo is, and index.html preloads it for
   that width only. */

.home-hero {
  /* Separate properties, never the `background` shorthand (pastka 18): the
     colour must be painted even if the gradient fails. */
  background-color: var(--c-hero-fallback);
  background-image: var(--grad-hero);
  border-bottom: 1px solid var(--c-border);
  padding-top: var(--sp-6);
}

.home-hero-grid { display: grid; gap: var(--sp-6); }

/* The plate behind the photo is the frame's own background (.art-frame-base):
   it is what shows until the image arrives, never a white flash. */
.home-hero-art {
  border-radius: var(--r-xl);
  aspect-ratio: 1088 / 1456;
  width: 100%;
  max-width: 420px;
  margin-inline: auto;
}
.home-hero-art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.home-eyebrow {
  font-family: var(--ff-num);
  font-size: 0.75rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--c-muted);
}

.home-hero-title {
  font-family: var(--ff-head);
  font-weight: 800;
  font-size: clamp(1.875rem, 1.35rem + 2.6vw, 3.5rem);
  line-height: 1.08;
  letter-spacing: -.02em;
  color: var(--c-text);
  text-wrap: balance;
  margin: var(--sp-3) 0;
}

.home-hero-lead {
  font-size: 1rem;
  line-height: 1.6;
  color: var(--c-text-soft);
  max-width: 36rem;
}

.home-hero-cta {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  margin-top: var(--sp-6);
}
.home-hero-cta .btn { width: 100%; justify-content: center; min-height: 48px; }

.home-hero-facts {
  list-style: none;
  margin: var(--sp-6) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-3) var(--sp-4);
}
.home-hero-facts li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--c-text-soft);
}
.home-hero-facts svg { flex: none; color: var(--c-accent-ink); margin-top: 1px; }

@media (min-width: 600px) {
  .home-hero-cta { flex-direction: row; }
  .home-hero-cta .btn { width: auto; }
}
@media (min-width: 768px) {
  .home-hero-facts { grid-template-columns: repeat(4, auto); justify-content: start; }
}
@media (min-width: 1024px) {
  .home-hero { padding-block: var(--sp-section); }
  .home-hero-grid {
    grid-template-columns: 7fr 5fr;
    grid-template-areas: "text art";
    gap: var(--sp-12);
    align-items: center;
  }
  .home-hero-text { grid-area: text; }
  .home-hero-art {
    grid-area: art;
    max-width: 440px;   /* = the img's sizes from 1024px and the preload's imagesizes */
    margin-inline: 0;
    justify-self: end;
  }

  /* Corner ticks — a framing gesture, eight hairlines from one gradient token.
     Static: decoration that moves is the opposite of "metal, restrained". */
  .home-hero-art::before {
    content: '';
    position: absolute;
    inset: 10px;
    z-index: 1;
    pointer-events: none;
    background:
      linear-gradient(var(--c-accent-ink), var(--c-accent-ink)) left top / 14px 1px no-repeat,
      linear-gradient(var(--c-accent-ink), var(--c-accent-ink)) left top / 1px 14px no-repeat,
      linear-gradient(var(--c-accent-ink), var(--c-accent-ink)) right top / 14px 1px no-repeat,
      linear-gradient(var(--c-accent-ink), var(--c-accent-ink)) right top / 1px 14px no-repeat,
      linear-gradient(var(--c-accent-ink), var(--c-accent-ink)) left bottom / 14px 1px no-repeat,
      linear-gradient(var(--c-accent-ink), var(--c-accent-ink)) left bottom / 1px 14px no-repeat,
      linear-gradient(var(--c-accent-ink), var(--c-accent-ink)) right bottom / 14px 1px no-repeat,
      linear-gradient(var(--c-accent-ink), var(--c-accent-ink)) right bottom / 1px 14px no-repeat;
  }
}


/* ══ 01 · ДЛЯ ЧОГО — goal tiles ════════════════════════════════ */

.goal-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-3);
}
.goal-grid > li { display: flex; }

.goal-card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  background: var(--c-card);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  overflow: hidden;
  color: var(--c-text);
}
/* Colour changes are instant on purpose — only transform and opacity animate. */
.goal-card:hover { border-color: var(--c-primary); }
.goal-card:active { transform: translateY(1px) scale(.985); }

.goal-card-art {
  aspect-ratio: 4 / 3;
  border: 0;
  border-bottom: 1px solid var(--c-img-bdr);
}
.goal-card-art > svg,
.goal-card-art > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: transform var(--t-md);
}
.goal-card-art > img { object-fit: cover; }
.goal-card:hover .goal-card-art > *,
.goal-card:focus-visible .goal-card-art > * { transform: translateY(-4px) scale(1.03); }

.goal-card-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  padding: var(--sp-3);
  padding-right: calc(var(--sp-3) + 16px);
}
.goal-card-title {
  font-size: 0.9375rem;
  font-weight: 700;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* The category's own description: client copy, first sentence only, and never
   on a phone — at 138px it would push the tile to twice its height for text
   the category page says better. */
.goal-card-sub { display: none; }
.goal-card-meta {
  font-family: var(--ff-num);
  font-size: 0.75rem;
  color: var(--c-muted);
  font-variant-numeric: tabular-nums;
}
.goal-card-arrow {
  position: absolute;
  right: var(--sp-3);
  bottom: var(--sp-3);
  color: var(--c-accent-ink);
  transition: transform var(--t-md);
}
.goal-card:hover .goal-card-arrow { transform: translateX(3px); }

/* A tile left alone on the last row stretches to full width and lies down, so a
   seventh category added in the admin panel never leaves a hole in the grid. */
.goal-grid > li:last-child:nth-child(odd) { grid-column: 1 / -1; }
.goal-grid > li:last-child:nth-child(odd) .goal-card {
  display: grid;
  grid-template-columns: 2fr 3fr;
  align-items: center;
}
.goal-grid > li:last-child:nth-child(odd) .goal-card-art { border-bottom: 0; border-right: 1px solid var(--c-img-bdr); }

/* Search — the second way in, for people who already know the name. */
.goal-search { margin-top: var(--sp-8); }
.goal-search-label {
  display: block;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--c-text);
  margin-bottom: var(--sp-2);
}
.goal-search-row { display: flex; gap: var(--sp-2); }
.goal-search-row input {
  flex: 1;
  min-width: 0;
  min-height: 48px;
  padding: 0 var(--sp-4);
  background: var(--c-card);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r);
  color: var(--c-text);
  font: inherit;
  font-size: 1rem;
}
.goal-search-row input::placeholder { color: var(--c-placeholder); }
.goal-search-row .btn { flex: none; min-height: 48px; }

@media (min-width: 600px) {
  .goal-grid { grid-template-columns: repeat(3, 1fr); gap: var(--sp-4); }
  /* The phone rule for a lone tile does not apply at three columns. */
  .goal-grid > li:last-child:nth-child(odd) { grid-column: auto; }
  .goal-grid > li:last-child:nth-child(odd) .goal-card { display: flex; }
  .goal-grid > li:last-child:nth-child(odd) .goal-card-art { border-right: 0; border-bottom: 1px solid var(--c-img-bdr); }
  /* One left over: full width, lying down. Two left over: the second spans two. */
  .goal-grid > li:last-child:nth-child(3n+1) { grid-column: 1 / -1; }
  .goal-grid > li:last-child:nth-child(3n+1) .goal-card {
    display: grid;
    grid-template-columns: 1fr 2fr;
    align-items: center;
  }
  .goal-grid > li:last-child:nth-child(3n+1) .goal-card-art { border-bottom: 0; border-right: 1px solid var(--c-img-bdr); }
  .goal-grid > li:last-child:nth-child(3n+2) { grid-column: span 2; }

  .goal-card-body { padding: var(--sp-4); padding-right: calc(var(--sp-4) + 16px); }
  .goal-card-sub {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 0.8125rem;
    line-height: 1.45;
    color: var(--c-muted);
  }
  .goal-card-arrow { right: var(--sp-4); bottom: var(--sp-4); }
}
@media (min-width: 768px) {
  .goal-search-row { max-width: 520px; }
}
@media (min-width: 1024px) {
  .goal-card-title { font-size: 1.0625rem; }
}
@media (prefers-reduced-motion: reduce) {
  .goal-card-art > svg,
  .goal-card-art > img,
  .goal-card-arrow { transition: none; }
  .goal-card:hover .goal-card-art > *,
  .goal-card:focus-visible .goal-card-art > *,
  .goal-card:hover .goal-card-arrow,
  .goal-card:active { transform: none; }
}


/* ══ 02 · ЯК — reading a label ═════════════════════════════════
   The plate is the SAME plate as a product card, pedestal included: the
   client's cut-out packshot of this product drops into this frame later. */

.spec-layout { display: grid; gap: var(--sp-6); }

.spec-plate {
  position: relative;
  width: min(280px, 100%);
  aspect-ratio: 1;
  justify-self: center;
  color: var(--c-art-line);
  background-color: var(--c-plate);
  background-image: var(--grad-pedestal), var(--grad-plate);
  border: 1px solid var(--c-img-bdr);
  border-radius: var(--r-xl);
  overflow: hidden;
}
.spec-plate > svg,
.spec-plate > img { position: absolute; inset: 0; width: 100%; height: 100%; }
.spec-plate > img { object-fit: contain; }

/* Numbered markers on the drawn jar. A real photo hides them: a marker that
   points at the wrong spot on a real label would be a small lie. */
.spec-marker {
  position: absolute;
  z-index: 1;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 -11px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--c-accent);
  color: var(--c-on-accent);
  font-family: var(--ff-num);
  font-size: 0.6875rem;
  font-weight: 600;
  box-shadow: 0 0 0 2px var(--c-bg);
}
.spec-marker[data-key="name"] { left: 50%; top: 44%; }
.spec-marker[data-key="conc"] { left: 50%; top: 53%; }
.spec-marker[data-key="dose"] { left: 24%; top: 84%; }
.spec-marker[data-key="pack"] { left: 80%; top: 34%; }
.spec-marker[data-key="lot"]  { left: 50%; top: 14%; }
.spec-plate--photo .spec-marker { display: none; }

.spec-notes { list-style: none; margin: 0; padding: 0; }
.spec-note {
  display: grid;
  grid-template-columns: 28px 1fr;
  column-gap: var(--sp-3);
  padding-block: var(--sp-4);
  border-bottom: 1px solid var(--c-border-light);
}
.spec-note-num {
  grid-row: 1 / span 3;
  font-family: var(--ff-num);
  font-size: 0.75rem;
  color: var(--c-accent-ink);
  padding-top: 2px;
}
.spec-note-label { font-size: 0.8125rem; font-weight: 600; color: var(--c-text); }
.spec-note-value {
  font-family: var(--ff-num);
  font-size: 1.125rem;
  color: var(--c-text);
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
  overflow-wrap: break-word;
}
.spec-note-hint {
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--c-text-soft);
  margin-top: var(--sp-1);
}

/* The way to buy what was just explained — on the same screen. */
.spec-buy {
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-5);
  background: var(--c-card);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
}
.spec-buy-name { font-size: 1rem; font-weight: 700; color: var(--c-text); }
.spec-buy-name:hover { color: var(--c-primary); }
.spec-buy-price {
  font-family: var(--ff-num);
  font-size: 1.25rem;
  color: var(--c-text);
  font-variant-numeric: tabular-nums;
  word-spacing: -0.3em;
}
.spec-buy-price s { font-size: 0.875rem; color: var(--c-placeholder); margin-left: var(--sp-2); }
.spec-buy .btn { width: 100%; justify-content: center; min-height: 48px; }

/* Tablet: the jar on top, the notes as two columns under it. Flanking the
   jar needs ~250px a side, which only exists from 1024 up — at 768 the side
   columns came out ~150px and set the values one word per line. */
@media (min-width: 768px) {
  .spec-layout {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-areas: "plate plate" "a b" "buy buy";
    column-gap: var(--sp-8);
    row-gap: var(--sp-6);
  }
  .spec-plate { grid-area: plate; width: min(320px, 100%); }
  .spec-notes--a { grid-area: a; }
  .spec-notes--b { grid-area: b; }
  .spec-buy {
    grid-area: buy;
    justify-self: center;
    width: 100%;
    max-width: 720px;
    grid-template-columns: 1fr auto auto;
    align-items: center;
  }
  .spec-buy .btn { width: auto; }
  .spec-buy-link { grid-column: 1 / -1; justify-self: center; }
}
/* Desktop: the notes flank the jar and read towards it. minmax(0, 1fr), or a
   long monospaced name sets the column's minimum and the sides go unequal. */
@media (min-width: 1024px) {
  .spec-layout {
    grid-template-columns: minmax(0, 1fr) minmax(320px, 400px) minmax(0, 1fr);
    grid-template-areas: "a plate b" "buy buy buy";
    column-gap: var(--sp-10);
    align-items: center;
  }
  .spec-plate { width: 100%; }
  .spec-notes--a { text-align: right; }
  .spec-notes--a .spec-note { grid-template-columns: 1fr 28px; }
  .spec-notes--a .spec-note-num { grid-column: 2; grid-row: 1 / span 3; text-align: right; }
  .spec-notes--a .spec-note > :not(.spec-note-num) { grid-column: 1; }
}


/* ══ 02 · ЯК — how we choose: three stations ═══════════════════ */

.station-track { position: relative; }
.station-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--sp-10);
}
/* The connector: a hairline through the station numbers. Outside the <ol>,
   because a list may only hold <li>. */
.station-line {
  position: absolute;
  left: 15px;
  top: 16px;
  bottom: 16px;
  width: 1px;
  background: var(--c-art-line-dim);
  transform-origin: top;
}
.station {
  position: relative;
  display: grid;
  grid-template-columns: 32px 1fr;
  column-gap: var(--sp-4);
}
.station-num {
  grid-column: 1;
  grid-row: 1;
  position: relative;
  z-index: 1;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border: 1px solid var(--c-accent);
  border-radius: 50%;
  background: var(--c-bg);
  font-family: var(--ff-num);
  font-size: 0.75rem;
  color: var(--c-accent-ink);
}
.station-art,
.station-title,
.station-text { grid-column: 2; }
.station-art {
  grid-row: 1;
  aspect-ratio: 3 / 2;
  border-radius: var(--r-lg);
}
/* The drawing is 12% taller than its window, so the parallax drift (±5%) never
   shows an edge. A photo replaces the svg inside the same layer. */
.station-layer {
  position: absolute;
  left: 0;
  right: 0;
  top: -6%;
  height: 112%;
}
.station-layer > svg,
.station-layer > img { width: 100%; height: 100%; }
.station-layer > img { object-fit: cover; }
.station-title { margin-top: var(--sp-4); font-size: 1.0625rem; font-weight: 700; color: var(--c-text); }
.station-text { margin-top: var(--sp-2); font-size: 0.9375rem; line-height: 1.6; color: var(--c-text-soft); }

@media (min-width: 768px) {
  .station-art { max-width: 520px; }
}
@media (min-width: 1024px) {
  .station-list { grid-template-columns: repeat(3, 1fr); gap: var(--sp-8); }
  .station { grid-template-columns: 1fr; row-gap: var(--sp-4); }
  .station-num { grid-column: 1; grid-row: 1; }
  .station-art { grid-column: 1; grid-row: 2; max-width: none; }
  .station-title,
  .station-text { grid-column: 1; }
  .station-title { margin-top: 0; }
  .station-text { margin-top: 0; }
  /* The connector turns horizontal and runs through the numbers' row. */
  .station-line {
    left: 16px;
    /* From the first number's centre (16px) to the last one's. With three
       columns of (W − 2g)/3 and gap g, the last centre sits at 2(col + g) + 16,
       so the distance from the right edge is (W − 2g − 48px) / 3. */
    right: calc((100% - 2 * var(--sp-8) - 48px) / 3);
    top: 15px;
    bottom: auto;
    width: auto;
    height: 1px;
    transform-origin: left;
  }
}


/* ══ 02 · ЯК — ordering, and cash on delivery ══════════════════
   A band a step below the page: this is the block that takes the risk off the
   buyer, and it should read as a different, quieter room. */

.home-order {
  background-color: var(--c-dark);
  background-image: var(--grad-dark);
  border-block: 1px solid var(--c-border);
}

.order-layout { display: grid; gap: var(--sp-8); }

.risk-card {
  padding: var(--sp-5);
  background: var(--c-primary-wash);
  border: 1px solid var(--c-accent);
  border-radius: var(--r-xl);
}
.risk-card-art {
  aspect-ratio: 16 / 9;
  border-radius: var(--r-lg);
  margin-bottom: var(--sp-5);
}
.risk-card-art > svg,
.risk-card-art > img { position: absolute; inset: 0; width: 100%; height: 100%; }
.risk-card-art > img { object-fit: cover; }
.risk-card-title { font-size: 1.25rem; font-weight: 800; color: var(--c-text); }
.risk-card-text { margin-top: var(--sp-2); font-size: 0.9375rem; line-height: 1.6; color: var(--c-text-soft); }

/* The timeline. The track is the positioning box for the line and the parcel;
   the list beside them holds only the steps. */
.order-track {
  position: relative;
  padding-left: 48px;
  view-timeline: --order block;
}
.order-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-6); }
.order-line,
.order-traveler {
  position: absolute;
  top: 16px;
  bottom: 16px;
}
.order-line {
  left: 15px;
  width: 1px;
  background: var(--c-accent);
  transform-origin: top;
}
/* The parcel sits at the BOTTOM of a box exactly as tall as the line, so its
   resting state — when nothing animates — is "delivered", at step 04. */
.order-traveler {
  left: 4px;
  width: 24px;
  display: flex;
  align-items: flex-end;
  color: var(--c-accent-ink);
}
.order-traveler svg { transform: translateY(50%); background: var(--c-dark); border-radius: 4px; }

.order-step { position: relative; }
.order-step-num {
  position: absolute;
  left: -48px;
  top: 0;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border: 1px solid var(--c-accent);
  border-radius: 50%;
  background: var(--c-dark);
  font-family: var(--ff-num);
  font-size: 0.75rem;
  color: var(--c-accent-ink);
}
.order-step-title { font-size: 1rem; font-weight: 700; color: var(--c-text); line-height: 32px; }
.order-step-text { font-size: 0.9375rem; line-height: 1.6; color: var(--c-text-soft); }

.order-terms { margin: var(--sp-8) 0 0; }
.order-term {
  padding-block: var(--sp-3);
  border-bottom: 1px solid var(--c-border-light);
}
.order-term dt { font-size: 0.8125rem; color: var(--c-muted); }
.order-term dd { margin: var(--sp-1) 0 0; font-size: 0.9375rem; color: var(--c-text); }

.pay-chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.pay-chips li {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 36px;
  padding: 0 var(--sp-3);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-pill);
  font-size: 0.8125rem;
}
.pay-chips img { width: 20px; height: 20px; }

.order-note { margin-top: var(--sp-4); font-size: 0.875rem; color: var(--c-muted); }

/* Tablet: the card spans the full width, so the parcel goes beside the text —
   stacked at 768 it was a 16:9 drawing half a screen tall. */
@media (min-width: 768px) {
  .order-term { display: grid; grid-template-columns: 180px 1fr; gap: var(--sp-4); align-items: baseline; }
  .order-term dd { margin: 0; }
  .risk-card {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    column-gap: var(--sp-6);
  }
  .risk-card-art { grid-row: 1 / span 2; margin-bottom: 0; }
  .risk-card-title { align-self: end; }
  .risk-card-text { align-self: start; }
}
/* Desktop: the card has its own narrow column again — back to stacked. */
@media (min-width: 1024px) {
  .order-layout { grid-template-columns: 5fr 7fr; gap: var(--sp-12); align-items: start; }
  .risk-card { display: block; position: sticky; top: var(--sticky-top); }
  .risk-card-art { margin-bottom: var(--sp-5); }
}


/* ══ 03 · ЩО — the shelf ═══════════════════════════════════════
   Cards are the shared component. Only the layout is the homepage's. */

.home-head--split { max-width: none; }
.home-head--split > div { max-width: 44rem; }

.shelf-grid.catalog-grid { grid-template-columns: repeat(2, 1fr); gap: var(--sp-3); }
.shelf-grid .product-card--feature { grid-column: 1 / -1; }

.shelf-empty {
  display: grid;
  justify-items: start;
  gap: var(--sp-4);
  padding: var(--sp-6);
  background: var(--c-card);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  color: var(--c-text-soft);
}

@media (min-width: 600px) {
  .home-head--split {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--sp-6);
  }
}
/* From 768: the feature card holds the left half over two rows, the other four
   sit 2×2 beside it — five cards, no empty cell at any width. */
@media (min-width: 768px) {
  .shelf-grid.catalog-grid {
    grid-template-columns: minmax(0, 2fr) repeat(2, minmax(0, 1fr));
    gap: var(--sp-4);
  }
  .shelf-grid .product-card--feature { grid-column: 1; grid-row: span 2; }
  /* The picture takes whatever height the two rows leave after the text. A
     zero basis keeps it out of the row sizing, so the small cards set the rows
     and the feature never stretches them. */
  .shelf-grid .product-card--feature .card-img-link { flex: 1 1 0; min-height: 15rem; display: flex; }
  .shelf-grid .product-card--feature .card-img-wrap { aspect-ratio: auto; flex: 1; }
  .shelf-grid .product-card--feature .card-body { flex: 0 0 auto; }
  /* A shop with a single product on the shelf: nothing to sit beside. */
  .shelf-grid .product-card--feature:only-child { grid-column: 1 / -1; }
}
/* 768–1023: a small card is ~172px wide, and the price beside a nowrap button
   needs more than that — the same column footer the catalogue uses under 600. */
@media (min-width: 768px) and (max-width: 1023px) {
  .shelf-grid .product-card:not(.product-card--feature) .card-footer { flex-direction: column; align-items: stretch; }
  .shelf-grid .product-card:not(.product-card--feature) .card-footer .btn { width: 100%; }
}
/* style.css drops the catalogue to one column under 380px; the shelf keeps two
   down to 320, because a single column of five cards is a long scroll to reach
   the reviews. The card's own column footer keeps the button full width. */
@media (max-width: 380px) {
  .shelf-grid.catalog-grid { grid-template-columns: repeat(2, 1fr); }
}


/* ══ 03 · ЩО — reviews ═════════════════════════════════════════ */

.review-rail {
  list-style: none;
  /* Bleeds to the screen edge by exactly the container's side padding — 16px up
     to 600px, 24px above (style.css, .container) — so the next tile peeks in and
     the page itself never scrolls sideways. */
  margin: 0 calc(var(--sp-4) * -1);
  padding: 0 var(--sp-4) var(--sp-2);
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 220px;
  gap: var(--sp-3);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--sp-4);
  scrollbar-width: none;
}
.review-rail::-webkit-scrollbar { display: none; }
.review-rail > li { scroll-snap-align: start; display: flex; }

.review-tile,
.review-all {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;
  background: var(--c-plate);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  overflow: hidden;
  padding: 0;
  cursor: pointer;
}
.review-tile img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: transform var(--t-md);
}
.review-tile:hover img { transform: scale(1.02); }
.review-tile--video img { object-fit: cover; }
.review-tile-play {
  position: absolute;
  left: 50%;
  top: 50%;
  margin: -24px 0 0 -24px;
  color: var(--c-accent-ink);
}
.review-tile-author {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: var(--sp-6) var(--sp-3) var(--sp-2);
  background-image: var(--grad-img-fade);
  font-size: 0.75rem;
  color: var(--c-on-dark-75);
  text-align: left;
}
.review-all {
  display: grid;
  place-content: center;
  gap: var(--sp-1);
  background: var(--c-card);
  border-color: var(--c-accent);
  color: var(--c-text);
  font-weight: 700;
  text-align: center;
}
.review-all-count { font-family: var(--ff-num); color: var(--c-accent-ink); }

@media (min-width: 601px) {
  .review-rail { margin: 0 calc(var(--sp-6) * -1); padding: 0 var(--sp-6) var(--sp-2); scroll-padding-inline: var(--sp-6); }
}
@media (min-width: 1024px) {
  .review-rail {
    margin: 0;
    padding: 0;
    grid-auto-flow: row;
    grid-template-columns: repeat(4, 1fr);
    overflow: visible;
  }
  /* Three reviews and the closing tile. Four to six stay in the HTML for the
     phone rail. */
  .review-rail > li:nth-child(n+4):not(:last-child) { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .review-tile img { transition: none; }
  .review-tile:hover img { transform: none; }
}


/* ══ CLOSE — the finale band ═══════════════════════════════════ */

.home-finale {
  background-color: var(--c-dark);
  background-image: var(--grad-dark);
  border-top: 1px solid var(--c-border);
}
.finale-grid { display: grid; gap: var(--sp-8); }
.finale-art {
  order: -1;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-xl);
}
/* The hero's still life, mirrored — the page closes on the image it opened with. */
.finale-art-inner { position: absolute; inset: 0; transform: scaleX(-1); }
.finale-art-inner svg { width: 100%; height: 100%; }

.finale-lead { margin-top: var(--sp-4); font-size: 1.0625rem; line-height: 1.6; color: var(--c-text-soft); }
.finale-note {
  margin-top: var(--sp-4);
  padding-left: var(--sp-3);
  border-left: 2px solid var(--c-border-strong);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--c-muted);
}

.finale-cats { margin-top: var(--sp-8); }
.finale-cats:not(:has(a)) { display: none; }
.finale-cats-label { font-size: 0.875rem; color: var(--c-muted); margin-bottom: var(--sp-3); }
.finale-chip-list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.finale-chip {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--sp-4);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-pill);
  font-size: 0.875rem;
  color: var(--c-text);
}
.finale-chip:hover { border-color: var(--c-primary); }

@media (min-width: 768px) {
  .finale-art { max-width: 600px; }
}
@media (min-width: 1024px) {
  .finale-grid { grid-template-columns: 6fr 5fr; gap: var(--sp-12); align-items: center; }
  .finale-art { order: 0; max-width: none; }
}


/* ══ Mini-cart ═════════════════════════════════════════════════
   The cart in the thumb zone below 1024px. At desktop widths the header cart is
   in view, so the bar is never shown there. */

.mini-cart {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  min-height: var(--mini-cart-h);
  padding: 0 var(--sp-4) env(safe-area-inset-bottom);
  background: var(--c-surface);
  border-top: 1px solid var(--c-border);
  transition: transform var(--t-md), opacity var(--t-md);
}
/* `hidden` → shown slides the bar up. @starting-style supplies the from-state
   of that transition with no reflow trick; a browser without it just shows the
   bar, which is the right fallback. */
@starting-style {
  .mini-cart { transform: translateY(100%); opacity: 0; }
}
.mini-cart-sum { font-family: var(--ff-num); font-size: 0.875rem; color: var(--c-text); word-spacing: -0.3em; }
.mini-cart-count { color: var(--c-accent-ink); }

/* Keep the page's last line and the toasts above the bar while it is shown. */
body:has(#mini-cart:not([hidden])) { padding-bottom: calc(var(--mini-cart-h) + env(safe-area-inset-bottom)); }
body:has(#mini-cart:not([hidden])) .toast-container { bottom: calc(var(--mini-cart-h) + env(safe-area-inset-bottom) + var(--sp-3)); }

@keyframes count-bump { 50% { transform: scale(1.15); } }
.is-bumped { display: inline-block; animation: count-bump var(--dur-md) var(--ease-out); }

@media (min-width: 1024px) {
  .mini-cart { display: none; }
  body:has(#mini-cart:not([hidden])) { padding-bottom: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .mini-cart { transition: none; }
  .is-bumped { animation: none; }
}


/* ══ З БЛОГУ ══════════════════════════════════════════════════
   The section around the blog's own post cards. The cards themselves are
   css/blog.css (the slot links it), so the homepage and /blog cannot show
   two versions of one card. Only the section's placement is this page's. */

.home-blog {
  padding-block: var(--sp-section);
  border-top: 1px solid var(--c-border-light);
}


/* ══ MOTION ════════════════════════════════════════════════════
   Everything that moves on this page, in one place, behind the three gates.
   Outside them every element is already in its final state. */

@keyframes rake {
  0%       { transform: translateX(-120%); opacity: 0; }
  20%, 80% { opacity: 1; }
  100%     { transform: translateX(120%); opacity: 0; }
}
@keyframes line-y    { from { transform: scaleY(0); } }
@keyframes line-x    { from { transform: scaleX(0); } }
@keyframes travel    { from { transform: translateY(-100%); } }
@keyframes drift     { from { transform: translateY(-5%); } to { transform: translateY(5%); } }
@keyframes mark-on   { from { opacity: .4; } }

@media screen {
  @media (prefers-reduced-motion: no-preference) {

    /* Hero photo — the page's ONE light sweep across it, which stops after
       three. Nothing here loops forever: decoration that never rests reads as
       plastic, not metal. The photo itself does not move. */
    .home-hero-art::after {
      content: '';
      position: absolute;
      inset: 0;
      z-index: 1;
      pointer-events: none;
      background-image: var(--grad-rake);
      opacity: 0;
      animation: rake var(--dur-rake) var(--ease-in-out) 1.2s 3 both;
    }

    @supports (animation-timeline: view()) {
      /* Reveals — attached to components, never to page sections. */
      .goal-card,
      .spec-note,
      .station,
      .order-step,
      .finale-art {
        animation: reveal-rise linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 55%;
      }
      .goal-card:focus-within,
      .spec-note:focus-within,
      .station:focus-within,
      .order-step:focus-within {
        animation: none;
        opacity: 1;
        transform: none;
      }

      .spec-marker {
        animation: mark-on linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 40%;
      }

      /* The station connector draws itself as the list scrolls through. */
      .station-line {
        animation: line-y linear both;
        animation-timeline: view();
        animation-range: cover 10% cover 60%;
      }

      /* Parallax INSIDE a static frame: the window stays put, the drawing drifts
         ±5% of a 112%-tall layer, so no edge ever shows. */
      .station-art { view-timeline: --station block; }
      .station-layer {
        animation: drift linear both;
        animation-timeline: --station;
        animation-range: cover 0% cover 100%;
      }

      /* The order timeline: the line draws and the parcel travels from step 01
         to step 04 as the steps scroll past — the page's one memorable motion
         beat, transform only. Ungated, the parcel rests at 04: delivered. */
      .order-line {
        animation: line-y linear both;
        animation-timeline: --order;
        animation-range: cover 15% cover 65%;
      }
      .order-traveler {
        animation: travel linear both;
        animation-timeline: --order;
        animation-range: cover 15% cover 65%;
      }
    }
  }
}

@media screen and (min-width: 1024px) {
  @media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) {
      .station-line {
        animation-name: line-x;
      }
    }
  }
}
