/* ══════════════════════════════════════════════════════════════════════════
   PAGE BODY — the anatomy flow, composed in the reference's language.
   Shared primitives first, then each section. Every section has a different
   composition; only the primitives repeat.
   ══════════════════════════════════════════════════════════════════════════ */

/* The reference's own colour family — warm, flat, mid-saturation. Nothing here
   is a gradient and nothing is a pastel wash; each accent has to hold a
   photographed product without going grey behind it. */
:root {
  --tan:    #E7D3B2;
  --peach:  #F0996B;
  --sky-lt: #8CC7DE;
  --butter: #F5C842;
  --sage:   #9CC98C;
  --mint:   #BFE3DC;
}

.shell {
  max-width: calc(var(--shell) - var(--inset) * 2);
  margin-inline: auto;
  padding-inline: var(--inset);
}
.sec { margin-top: 96px; }

/* A label that has a shorter form on a narrow screen. Both are rendered in the
   markup and one is hidden, rather than being swapped by script, so the label
   is correct before any JavaScript runs and correct if none does. */
.narrow-only { display: none; }
.wide-only { display: inline; }
/* Both halves live here rather than in home.css: sections.css is loaded
   second, so a base rule here would have silently overridden a media-query
   rule of equal specificity there — which it did, and the long label went on
   rendering at 390px with nothing to say why. */
@media (max-width: 640px) {
  .wide-only { display: none; }
  .narrow-only { display: inline; }
}

.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
/* `.sr-only` is `position: absolute`, so it needs a positioned ancestor or its
   containing block becomes the initial one — it then escapes whatever
   `overflow: hidden` was meant to clip it and sits at an absolute document
   coordinate. In the manufacturer rail, whose track is 4320px wide inside a
   clipped viewport, the escaped 1px spans landed as far out as 2076px and
   pushed the document's scrollWidth past the viewport at every breakpoint —
   horizontal overflow produced entirely by text nobody can see.

   Every element that carries an `.sr-only` label inside a wide or clipped
   track is given a containing block here, at the source, rather than the
   symptom being chased per-component. */
.bcard, .sp-cart, .sp-cell { position: relative; }

/* small caps label with the reference's trailing dash */
.tag {
  margin: 0 0 12px;
  font-family: var(--display);
  font-size: 12px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: rgba(46, 28, 21, 0.5);
}
.tag-light { color: rgba(246, 238, 226, 0.55); }

.sec-title {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(34px, 3.9vw, 56px);
  line-height: var(--display-lh);
  text-transform: uppercase;
  letter-spacing: -0.005em;
}
.sec-title-sm { font-size: clamp(30px, 3vw, 42px); }
.head-dot {
  display: inline-block;
  width: 0.16em; height: 0.16em;
  margin-left: 0.12em;
  border-radius: 999px;
  background: var(--coral);
  vertical-align: 0.06em;
}

.sec-head {
  display: flex;
  align-items: flex-end;
  gap: 26px;
  margin-bottom: 34px;
}
.rule-pill { display: flex; align-items: center; gap: 16px; margin-left: auto; flex: 0 0 auto; }
.rule { display: block; width: 96px; height: 2.5px; background: var(--cocoa); border-radius: 2px; }
.squiggle { width: 96px; margin-bottom: 12px; flex: 0 0 auto; }
.squiggle > svg { width: 100%; fill: none; stroke: var(--sky); stroke-width: 3.4; stroke-linecap: round; }

.btn-pill-green { background: var(--green); color: #fff; }
.btn-pill-cocoa { background: var(--cocoa); color: var(--canvas); border-color: var(--cocoa); }
.txt-link-light { color: var(--canvas); border-color: rgba(246, 238, 226, 0.6); }
.txt-link-light:hover { color: var(--amber); border-color: var(--amber); }

/* ── seals ────────────────────────────────────────────────────────────────
   A pressed rubber stamp: cocoa disc, the shop's own words set around it, and
   a tick struck through the middle. It is the page's one hand-made mark, and
   it is what lets a claim-safe statement ("kereskedő, nem guru") carry the
   weight a review score would carry on a shop that had reviews.

   These rules had gone missing while the markup that needs them stayed. An SVG
   <circle> with no fill declared paints solid black, so every seal on the page
   was rendering as a black disc dropped on the composition. */

.stamp, .say-mark { display: block; }
.stamp > svg, .say-mark > svg { width: 100%; height: 100%; display: block; overflow: visible; }

.seal-disc { fill: var(--cocoa); }
/* Set once around the ring, not twice. Two repetitions of the phrase halved
   the type to about 7px on screen and made the seal an illegible grey smudge —
   a stamp nobody can read is decoration pretending to be a claim. */
.seal-text {
  fill: var(--canvas);
  font-family: var(--display);
  font-size: 13px;
  text-transform: uppercase;
}
/* struck, not drawn: the tick is the mark of something checked off */
.seal-tick {
  fill: none;
  stroke: var(--amber);
  stroke-width: 6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* the statement's seal carries no tick, so its ring sits on the accent instead
   and the mark does not read as a second verification badge */
.say-mark .seal-disc { fill: var(--coral); }
.say-mark .seal-text { fill: var(--canvas); }
.seal-dot { fill: var(--canvas); }

/* photographic contact shadow, reused wherever a pack is staged */
.plate-shadow {
  position: absolute;
  left: 50%; bottom: 8%;
  width: 62%; height: 30px;
  transform: translateX(-50%);
  border-radius: 999px;
  background: radial-gradient(closest-side, rgba(60, 36, 6, 0.4), rgba(60, 36, 6, 0) 78%);
  z-index: 1;
}

/* ── brand rail ──────────────────────────────────────────────────────────── */

/* A dense, quiet strip immediately after the generous hero — the reference's
   own dense/generous alternation.

   Cocoa rather than cream, for two reasons. The marks arrive in five different
   colourways, and laying them on one dark field as a single silhouette is what
   makes the row read as a set instead of a pile of borrowed files. And the
   page needs the beat: cream page, white panel, dark strip, cream again is the
   contrast rhythm the reference keeps up the whole way down, where this page
   had been running four light sections in a row. */
.rail {
  margin-top: 34px;
  background: var(--cocoa);
  color: var(--canvas);
  padding-bottom: 6px;
}
/* The label and its stop control sit above the strip rather than beside it, so
   the moving track gets the full page width. Sharing one row with the label —
   which is what the previous structure did — cost the rail a fifth of its
   width and left the last manufacturer permanently half-masked. */
.rail-head {
  max-width: calc(var(--shell) - var(--inset) * 2);
  margin-inline: auto;
  padding: 18px var(--inset) 0;
  display: flex;
  align-items: center;
  gap: 18px;
}
.rail-head .rail-lead { margin-right: auto; }
.rail-lead {
  margin: 0;
  flex: 0 0 auto;
  font-family: var(--display);
  font-size: 13px;
  line-height: 1.24;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: rgba(246, 238, 226, 0.52);
}
/* The moving strip. Edges are masked rather than cut, so cards arrive and
   leave instead of popping at a hard boundary. */
.rail-view {
  min-width: 0;
  overflow: hidden;
  padding: 10px 0 14px;
  /* The maker cards are written by the script from the live brand taxonomy, so
     the track is empty on first paint and the band grew by its own height when
     they arrived — a shift at the top of the document with the hero's on it.
     One card's height, which is the height the band has whatever the catalogue
     does: the marquee is one row and adding a maker makes the loop longer, not
     taller. */
  min-height: 62px;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
}
.rail-track { display: flex; width: max-content; }
/* Spacing lives on the card, not as a flex gap on the sequence: a gap would
   not be reproduced between the last card of one sequence and the first of the
   next, so the loop would visibly stutter once per revolution. */
.rail-seq {
  display: flex;
  align-items: flex-end;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* ── the honest-density rule, as a state ───────────────────────────────────
   `docs/homepage-f10-gates.md` Gate 4 sets the marquee's launch condition:
   the strip animates only when the available marks fill one viewport width
   at the target cell size WITHOUT repeating, and until then it renders as the
   static, celled row — which the Hippeas reference shows reads as
   authoritative at seven marks, so this is a good state, not a failure state.

   It was decided but never enforced. With five marks the sequence measured
   ~1080px, so at 1440 the band showed Optimum Nutrition, PureGold and MHN
   TWICE inside one viewport and cut PureGold through the middle of its own
   wordmark at the left edge. A wall that repeats is not a wall of
   manufacturers, it is a wall of one manufacturer's file.

   The strip now renders all eight stocked manufacturers rather than only the
   five with artwork, which is 1728px of cells — so 1440 clears the rule and
   drifts again, and 1920 does not and stays static. Both outcomes come from
   the same measurement; nothing here was tuned to produce either.

   home.js measures the sequence and sets `is-static` when it cannot fill the
   viewport. The presentation is the one `prefers-reduced-motion` already
   ships and `tools/raillive.js` already proves: no animation, one sequence
   only — the clones exist solely to hide a moving seam, so a still strip that
   kept them would list every manufacturer twice for a second reason — and the
   marks wrapped into a centred block, which reaches all of them at a glance
   and leaves nothing to scroll. The edge mask goes with it: with nothing
   travelling past the edge there is no continuation to imply, and the mask
   would only fade the outermost mark for no reason. */
.rail.is-static .rail-track { animation: none; transform: none; width: 100%; }
/* Reduced motion takes the static branch (see buildRail) and, unlike the
   under-filled case, has more marks than fit on one line — so they wrap into a
   wall rather than being cropped by a window that will never move again. */
.rail.is-still .rail-track { flex-wrap: wrap; justify-content: center; row-gap: 10px; }
.rail.is-still .rail-view { -webkit-mask-image: none; mask-image: none; }
.rail.is-static .rail-seq + .rail-seq { display: none; }
.rail.is-static .rail-seq {
  flex-wrap: wrap;
  justify-content: center;
  width: 100%;
  row-gap: 4px;
}
.rail.is-static .rail-view {
  overflow: visible;
  -webkit-mask-image: none;
  mask-image: none;
}
/* Nothing is moving, so a control that offers to pause it is a lie. */
.rail.is-static .rail-toggle { display: none; }

/* One manufacturer's own mark, painted rather than placed. No card, no tint,
   no packshot: the packs already appear at full size three times on this page,
   and repeating them here at thumbnail scale only made the strip busy while
   dragging each cutout's white rim onto the dark field with it. */
.bcard {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  height: 62px;
  /* 46px each side put ~92px between marks, which at desktop width spread five
     logos so thinly the band read as mostly empty cocoa. The strip has to look
     like a set of makers, not five objects adrift on a dark field. */
  padding-inline: 30px;
}
.bcard-mark {
  display: block;
  width: 156px;
  height: calc(34px * var(--mark-s, 1));
  object-fit: contain;
  /* five colourways flattened to one cream silhouette, the same result the
     mask gave without the file:// failure mode */
  filter: brightness(0) invert(1);
  opacity: 0.92;
  transition: opacity 0.18s ease;
}
.bcard:hover .bcard-mark { opacity: 1; }

/* ── the makers we hold no artwork for ─────────────────────────────────────
   Ghost, ABE and BSN are stocked and purchasable; Rutriven simply holds no
   licensed file for them. Omitting them made the band understate the range,
   and a placeholder box or a borrowed mark would each be worse than that
   (CONTEXT.md, Brands-Carried Row). So the name is set in the page's own
   display face and treated as a mark in its own right.

   Optically matched, not merely styled: `.bcard-mark` renders into a 34px
   box and Titan One's caps stop at 0.72em, so 21px puts the cap height at
   ~15px, against the ~15-17px the real wordmarks carry inside their own
   built-in padding. Same cream, same 0.92 resting opacity, same hover lift —
   the row has to read as ONE set of eight, not as five logos with three
   captions among them. The cell keeps its `padding-inline` either way, so the
   density rule measures a wordmark cell and a mark cell on the same terms. */
/* `min-width` matches `.bcard-mark`'s fixed 156px box, so a wordmark cell and
   a mark cell are the same object. Measured without it: the marks sat in
   216px cells and Ghost, ABE and BSN in 103-126px ones, so three of the eight
   read as squeezed in after the fact rather than as members of the set — the
   pitch of the row broke exactly where the artwork ran out, which is the one
   place it must not, because that is the difference the strip is trying NOT
   to make into a hierarchy. A mark is already centred with slack inside its
   own box (`object-fit: contain`), so a short name centred in the same box is
   the same treatment, not a special case. `min-` rather than a fixed width so
   a longer name than any now in the registry sets its own cell instead of
   being crushed into a box tuned for today's list. */
.bcard-word {
  min-width: 156px;
  text-align: center;
  font-family: var(--display);
  font-size: 21px;
  line-height: 1;
  letter-spacing: 0.005em;
  white-space: nowrap;
  color: var(--cream);
  opacity: 0.92;
  transition: opacity 0.18s ease;
}
.bcard:hover .bcard-word { opacity: 1; }

/* The cell's anchor. The cell already owns the pitch and the padding the
   density rule measures, so the link fills it rather than sizing itself and
   changing what the row measures. */
.bcard-a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%; height: 100%;
  text-decoration: none;
  color: inherit;
}
.bcard-a:hover .bcard-mark,
.bcard-a:hover .bcard-word { opacity: 1; }
.bcard-a:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; border-radius: 8px; }

.rail-toggle {
  flex: 0 0 auto;
  position: relative;
  width: 40px; height: 40px;
  border-radius: 999px;
  border: 2px solid rgba(246, 238, 226, 0.34);
  background: transparent;
  color: rgba(246, 238, 226, 0.7);
  display: grid; place-items: center;
  cursor: pointer;
  padding: 0;
}
.rail-toggle > svg { width: 12px; height: 12px; fill: currentColor; }
/* The only control on the page that stops motion, at 40px of ink and 44 of
   target. It sits in a band's own padding, so the two extra pixels a side
   overlap nothing.

   `z-index` because `.rail-view` is a later sibling and was painting over the
   two pixels below the ink: hit-testing the button found `.rail-view` from 20px
   below its centre, so the control that stops the motion measured 43px of
   target against a 44px floor while the CSS above said 44. Raising the toggle
   puts its own hit area back on top of the strip it pauses. */
.rail-toggle { z-index: 1; }
.rail-toggle::before { content: ''; position: absolute; inset: -2px; border-radius: inherit; }
.rail-toggle:hover { border-color: var(--amber); color: var(--amber); }
.rail-toggle[aria-pressed="true"] { background: var(--amber); border-color: var(--amber); color: var(--cocoa); }

.tmark {
  width: 34px; height: 34px; flex: 0 0 34px;
  border-radius: 11px;
  display: grid; place-items: center;
}
.tmark > svg { width: 19px; height: 19px; fill: none; stroke: var(--cocoa); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.tmark-amber { background: var(--amber); }
.tmark-coral { background: var(--coral); }
.tmark-sky { background: var(--sky); }
.tmark-cocoa { background: var(--cocoa); }
.tmark-cocoa > svg { stroke: var(--amber); }

/* ── bands (cocoa / amber) ───────────────────────────────────────────────── */

.band {
  position: relative;
  border-radius: var(--radius-panel);
  padding: 52px 54px;
  overflow: hidden;
}
.band-cocoa { background: var(--cocoa); color: var(--canvas); }
.band-amber { background: var(--amber); color: var(--cocoa); }
/* The band field green from the contract's accessibility split — the shade
   whose job is carrying a surface, not text and not an action. Cream on it
   measures well past the body-text floor. Do not merge it with the action
   green: the split is a contract, not a palette preference. */
.band-green { background: #1A5C33; color: #F4EBDB; }
/* Shorter than the other bands on purpose. Célpakk is offered to a shopper who
   has already been given twenty products, a shelf and five families; at the
   full band height it was the second-largest object on the page for one
   sentence and one button. */
.cp.band { padding-block: 40px; }

.band-panel {
  background: var(--panel);
  color: var(--cocoa);
  box-shadow: 0 1px 0 rgba(46, 28, 21, 0.08);
}
/* ── de-carded ────────────────────────────────────────────────────────────
   This section used to sit on a warm-white rounded panel. Rendered at 1440 on
   the cream page the panel was all but invisible — a 1px shadow and four
   points of tone between it and the ground — so it was not separating
   anything; it was the fourth rounded rectangle in a run of them, and it was
   spending 52px of padding and ~110px of dead column to say nothing.
   The content stays, the container goes. An ink rule opens the section, the
   page ground carries it, and the density change against the green panel
   above and the cocoa field below is now real rather than nominal. */
/* The drawn label existed to stop the panel's bottom-right corner from being
   an empty quarter of warm white. With the panel gone there is no corner to
   fill, and the mark's only remaining option was to lie under the packshots.
   Removed rather than clipped by accident. */
/* On a light panel the cream stroke is invisible; the mark takes ink at the
   same weight the dark bands give it. */
.band-mark-ink > svg { stroke: rgba(46, 28, 21, 0.10); }

.band-title-em { color: var(--coral-ink); }

/* The second constraint, named on the small tile so the pair reads as two
   different exclusions rather than two products.

   It rides in the label row now. Absolutely positioned in the tile's top-right
   corner it was drawn straight over the packshot — the pack is centred and is
   at its widest exactly where the pill sat — so at 1440 the pill read
   "EJMENTES" behind the jar and at 390 it lay across the label artwork. */

/* tone-on-tone watermark, the reference's device inside its dark band */
/* Each band's watermark is a DIFFERENT drawing, set large and cropped by the
   panel edge so it reads as an illustration the panel was laid over rather
   than an ornament dropped in a corner. */
.band-mark { position: absolute; left: -84px; bottom: -150px; width: 470px; height: 470px; transform: rotate(-8deg); }
.band-mark > svg {
  width: 100%; height: 100%;
  fill: none;
  stroke: rgba(246, 238, 226, 0.11);
  stroke-width: 7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.band-mark-right { left: auto; right: -130px; bottom: -160px; transform: rotate(7deg); }
/* The closing burst sits in the panel's dead middle — the gap between the
   heading and the call to action — and stays clear of the button rather than
   scribbling underneath it. */
/* The burst sat at 33% from the right, which was the middle of the band while
   the founder's line ran centred across the bottom. With the line in its own
   column the same position puts the drawing through the quotation; it moves
   out to the band's right edge, behind the text rather than across it. */
.band-mark-amber {
  left: auto; right: 2%; top: 46%; bottom: auto;
  width: 250px; height: 250px;
  transform: translateY(-50%) rotate(-6deg);
}
.band-mark-amber > svg { stroke: rgba(46, 28, 21, 0.13); stroke-width: 7; }

.band-title {
  margin: 0 0 16px;
  font-family: var(--display);
  font-size: clamp(32px, 3.6vw, 50px);
  line-height: var(--display-lh);
  text-transform: uppercase;
}
.band-body { margin: 0 0 16px; max-width: 44ch; font-size: 14.5px; line-height: 1.62; opacity: 0.76; }

/* ── Célpakk ─────────────────────────────────────────────────────────────── */

/* ONE COLUMN, and a measure rather than a half. The band was two columns with
   a drawn "result card" in the right one; that card read as a loading skeleton
   and carried nothing, so the section spent half its width and a third of its
   height on an apology. What is left is what was always doing the work: the
   mark, the proposition, the sentence, the control and the disclaimer, set to a
   readable measure inside the band's own mark artwork.

   It is deliberately NOT centred. Every other chapter on this page sets its
   heading from the left gutter, and a centred block here would make Célpakk the
   one section that announces itself differently — which is the opposite of
   "a route, not the main event". */
/* Statement and action, side by side where there is room for both and stacked
   where there is not — and the width at which that flips is the sentence's own
   measure rather than a breakpoint somebody has to keep in step with it. */
.cp {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 26px 56px;
}
.cp-copy { flex: 1 1 24rem; max-width: 46ch; }
.cp-go { flex: 0 1 auto; display: grid; justify-items: start; gap: 14px; }

/* A product mark, not a section eyebrow: it names a thing the shop sells the
   use of, so it is set as a stamped chip in the page's own pill language. */
.cp-badge { margin: 0 0 18px; }
.cp-badge > span {
  display: inline-block;
  padding: 6px 15px 7px;
  border-radius: 999px;
  background: var(--amber);
  color: var(--cocoa);
  font-family: var(--display);
  font-weight: 400;
  font-size: 12.5px;
  letter-spacing: 0.045em;
  text-transform: uppercase;
  box-shadow: 2px 3px 0 rgba(0, 0, 0, 0.32);
}
.cp-copy, .cp-go { position: relative; z-index: 2; }

/* A 2×2 block, so the goals read as one object rather than a ragged 3+1. */
/* Solid, not an alpha of the ink. Dimming type is how a page ends up with
   secondary copy nobody can read: the contrast audit found six of these, every
   one of them a colour that was never chosen, only faded. Rank comes from
   size, weight and position; the colour stays above the floor. */
.cp-foot { margin: 0; font-size: 12.5px; color: #D9D0C2; }

/* ── the outcome, drawn ────────────────────────────────────────────────────
   The old device here was three pills in a well, reading as a flow chart of
   the mechanic: a few questions, an arrow, one product, and what was ruled
   out. It explained the PROCESS, and a shopper choosing between browsing and
   answering questions is weighing the RESULT.

   So the panel draws the result card instead: a product slot, a reason slot
   and a ruled-out slot, in the shape Célpakk returns them. Nothing in it is a
   name, a price or a packshot — the system that picks them is a separate
   build and this page does not own its taxonomy — so every content slot is a
   blank bar. It is `aria-hidden` and holds no control.

   That is also why the card is set on the panel rather than centred in a
   well: it is an object being shown, the same way the Újratöltés band shows
   the choice it is introducing. */
/* `.cp-pick` and the eleven `.cp-card-*` rules that drew the result card are
   gone with it. Nothing else read them. */

.pick-actions { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }

/* ── the products section ─────────────────────────────────────────────────
   One job now, not three. The section used to run a full-width staged product,
   then a horizontally scrolled row of the rest, under a heading promising a
   beginner somewhere to start. The staged product went with the pinned id
   behind it; the row is a grid; what is left is the shop's range with controls
   over it.
   ───────────────────────────────────────────────────────────────────────── */

/* The rhythm rule at the foot of this file owns this now: the products field
   meets the maker band rather than floating 92px below it. */

/* `.lead` and `.lead-*` are gone with "Amivel érdemes kezdeni", and so are
   `.floor-head` and `.floor-note`, which only ever framed it. A full-width
   plate, a 74px break-out packshot, an arrow drawn toward one product and a
   buy row: a great deal of composition spent arguing for a single SKU that an
   editor had pinned. The shopper problem it was aimed at is answered in the
   hero by a control, and every product it staged is on the grid below. */

/* ── the breadth rail ─────────────────────────────────────────────────────
   Full-bleed, and deliberately unbounded on the right: it starts on the shell
   gutter and runs off the edge of the viewport. A row of products that ends
   neatly inside the container implies the catalogue ends there too, which is
   the one thing a shop designed for a supplier-scale range must never say.
   It also means the section costs nothing as the catalogue grows — no slot to
   fill, no layout to rebalance. */

/* ── the products grid ─────────────────────────────────────────────────────
   The cards used to float on the page's own cream, which is why every one read
   as a loose swatch rather than as an item on a shelf. So the section gets a
   FIELD: one contained ground with a rule top and bottom, and the range
   inside it.

   WHAT CHANGED IS THE AXIS. The products used to run off the right edge of the
   viewport in a horizontally scrolled track, with a drawn progress thumb under
   it. The argument for that was breadth — a row that ends neatly implies the
   catalogue ends too — and it is a good argument on a phone, where a swipe is
   the native gesture. On a desktop it is the worst interaction available: a
   mouse has no horizontal wheel, the thumb is a 4px drag target, a trackpad
   swipe is discoverable only by accident, and tabbing moves a viewport the
   shopper cannot see the ends of. Twenty products were behind a gesture most
   visitors do not have.

   A grid needs none of it. Every input already knows how to scroll a page
   down, the cards wrap to whatever the width allows, and "there is more" is
   said by a button rather than by a fade. Breadth is still not bounded by the
   composition: eight cards open, one press reveals the rest, and the full
   listing is one link away. */
/* The comparison's footnote. Set as a note rather than as a warning: nothing
   has gone wrong, the shop simply has not accepted a pack quantity for every
   product yet, and the shopper is owed the reason the grid changed under them.
   It sits in the field, above the cards it is about. */
.shelf-note {
  margin: 0 0 16px;
  font-size: 12.5px;
  line-height: 1.45;
  color: #5A473F;
}

.shelf {
  position: relative;
  padding: 62px 0 44px;
  background: var(--shelf-field);
  border-top: 3px solid var(--cocoa);
  border-bottom: 3px solid var(--cocoa);
}

.shelf-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px 40px;
  flex-wrap: wrap;
  margin-bottom: 22px;
}
.shelf-h {
  margin: 0;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(30px, 3.6vw, 52px);
  line-height: var(--display-lh);
  text-transform: uppercase;
  letter-spacing: -0.015em;
}

/* The two control groups share one row and separate by weight, not by a rule:
   the facets narrow the set and are the loud ones, the sort re-orders it and
   is quiet. On a narrow screen the row stacks rather than scrolling
   horizontally — the one gesture this section has just stopped relying on. */
.shelf-tools {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px 26px;
  flex-wrap: wrap;
  margin-bottom: 30px;
}

/* FOUR TRACKS, STATED, not `auto-fill` with a minimum. The number of cards the
   section opens with has to be a whole number of rows or the grid ends on a
   ragged half-row, and `auto-fill` decides the track count from the viewport
   while the reveal limit is decided here. Eight cards in four tracks is two
   full rows at every desktop width; the same eight in five tracks left three
   cards and two empty cells. */
.shelf-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 20px;
  padding-inline: var(--gutter);
  align-items: stretch;
}
@media (max-width: 1100px) { .shelf-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 820px)  { .shelf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.shelf-more {
  display: flex;
  justify-content: center;
  margin-top: 30px;
}
/* The page's own pill, unfilled: revealing more of a list is navigation, and
   the only filled controls on this ground are the ones that add to a cart. */
.btn-pill-ghost {
  background: transparent;
  box-shadow: 3px 3px 0 var(--cocoa);
}
.btn-pill-ghost:hover { background: rgba(46, 28, 21, 0.06); }

/* ── the sort control ──────────────────────────────────────────────────────
   Where the unit-price comparison lives now that it is not a section.

   It is a segmented pair rather than two chips, because the two options are
   one question with two answers and a shopper must be able to see which
   answer is in force. It renders only where the visible set has at least two
   cards carrying a comparable number — see home.js. */
.sorts {
  display: inline-flex;
  border: 2.5px solid var(--cocoa);
  border-radius: 999px;
  overflow: hidden;
  flex: none;
}
.sortb {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--cocoa);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  min-height: 40px;
  padding: 0 15px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.14s ease;
}
.sortb + .sortb { border-left: 2.5px solid var(--cocoa); }
.sortb:hover { background: rgba(46, 28, 21, 0.07); }
.sortb[aria-pressed="true"] { background: var(--cocoa); color: var(--canvas); }
/* The group clips to its own pill, so an outward focus ring would be cut off
   at the segment's edge. It is drawn inside instead, which is the same ring at
   the same weight in the only place this control can show one. */
.sortb:focus-visible { outline-offset: -3px; }
.sortb[aria-pressed="true"]:focus-visible { outline-color: var(--canvas); }

/* ── the shelf card ────────────────────────────────────────────────────────
   THE PICTURE WINDOW TAKES THE FAMILY'S COLOUR.

   The card used to be cream on cream: a constant light box with a packshot
   floating in it and a 5px colour band along the top edge. It was defensible —
   an earlier pass had found that a FULL family-coloured plate behind every
   card turned the widest block on the page into a colour chart — but the
   result read as a template. Every reference the owner set (Hippeas, Adùn,
   wildwonder, De La Calle) does the same thing and it is the thing that makes
   their grids look like shops: the product sits in a saturated window and the
   commerce sits on a quiet ground beneath it.

   That is the split here. The CARD stays constant — cream, ink border, one
   radius — and the WINDOW takes the accent, so the colour is contained by an
   object rather than being the object. The ring motif is the hero's, drawn in
   gradient rather than markup so twenty cards cost no extra elements.

   Everything that made the card generic is gone with it: the corner tab
   repeating a family the colour already states, the full-width amber slab
   under every card, and the stepped rows of reserved height they needed. */
.sp-cell {
  /* The card has no width of its own: as a grid child it takes the track it is
     given, and the track count is the decision instead. `min-width: 0` is what
     stops a long product name setting the column width. */
  min-width: 0;
  display: grid;
  align-content: start;
  background: var(--panel);
  border: 2.5px solid var(--cocoa);
  border-radius: 20px;
  padding: 12px 12px 13px;
  transition: transform 0.16s ease, box-shadow 0.16s ease;
}
.sp-cell:hover { transform: translateY(-3px); box-shadow: 0 6px 0 rgba(46, 28, 21, 0.14); }
.sp { text-decoration: none; display: grid; align-content: start; }

.sp-box {
  position: relative;
  height: 198px;
  border-radius: 14px;
  background: var(--accent, var(--canvas));
  /* The hero's motif, as a gradient. Concentric rings at the same low ink
     alpha the panel carries, so a card and the first screen read as the same
     shop without a second SVG per cell. */
  background-image:
    repeating-radial-gradient(circle at 50% 62%,
      rgba(46, 28, 21, 0.075) 0 2px, rgba(46, 28, 21, 0) 2px 26px);
  display: grid; place-items: center;
  overflow: hidden;
}
.sp-box > img {
  /* Height sets the optical size, and for this catalogue that is the right
     normaliser: every authored packshot is portrait between 0.67 and 0.83
     wide-to-tall, so equal heights land within about 23% on width and the row
     reads as one system. The width bound is a guard — no current pack reaches
     it — but `max-width: none` against an `overflow: hidden` box means the
     first landscape packshot anyone authors is silently cut instead of scaled. */
  height: 172px; width: auto;
  max-width: calc(100% - 22px);
  object-fit: contain;
  filter: drop-shadow(0 12px 14px rgba(60, 36, 6, 0.26));
  transition: transform 0.16s ease;
}
.sp:hover .sp-box > img { transform: scale(1.045) translateY(-3px); }
/* A WooCommerce studio photograph that was never cut out arrives on a white
   rectangle. On the old cream box a radius was enough; on a saturated one the
   rectangle has to become an object, so it takes the page's own frame. See
   data.js §2 for why a product without a cut-out is on the page at all. */
.sp-box[data-shot="photo"] > img {
  border: 2.5px solid var(--cocoa);
  border-radius: 12px;
  background: var(--panel);
  filter: none;
  box-shadow: 4px 5px 0 rgba(46, 28, 21, 0.22);
  height: 162px;
}

/* THE ONE MARKER ON THE PICTURE, and it is the fact a shopper filters for.
   The corner tab this replaces carried the product's family — which is the
   colour of the box it was printed on — in a pill that ran to
   "TEJSAVÓFEHÉRJE" and ellipsed on two phone columns. The constraint is
   shorter, rarer and the only thing here a shopper might be scanning the grid
   to find. Cream on cocoa rather than family ink, because on six different
   accents an ink-filled pill is six different levels of contrast. */
.sp-flag {
  position: absolute;
  left: 9px; top: 9px;
  z-index: 2;
  max-width: calc(100% - 18px);
  padding: 4px 9px 5px;
  border-radius: 999px;
  background: var(--cocoa);
  color: var(--canvas);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.045em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── the maker ─────────────────────────────────────────────────────────────
   Above the name, at the smallest size on the card and in the family's own
   ink, because it is a fact a shopper SCANS for rather than reads: on a shelf
   where two items are both called "Kreatin monohidrát", whose it is is the
   first thing that separates them. It is set apart from the name by case,
   weight, size and colour rather than by a rule, so it costs one line and no
   furniture.

   The family ink rather than the muted grey the other secondary lines use: it
   is the one line on the card that is not about the pack, and the ink already
   means "this family" everywhere else on the page. Every ink in the palette is
   chosen against this ground — see data.js §6. */
.sp-maker {
  display: block;
  margin-top: 12px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink, #5A473F);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sp-maker + .sp-name { margin-top: 3px; }

.sp-name {
  margin-top: 12px;
  min-width: 0;
  overflow-wrap: anywhere;
  /* Two lines, always. Names run from "3R- PWO" to "100% Whey Gold Standard",
     and a name that wraps pushed its price and its action a line lower than
     its neighbours' — so a row of otherwise identical cards had its buy
     controls stepping up and down across the shelf. Reserving the second line
     costs one line on the short names and buys a straight line of actions. */
  min-height: calc(2 * 1.14em);
  color: var(--cocoa);
  font-family: var(--display);
  font-weight: 400;
  font-size: 14px;
  text-transform: uppercase;
  line-height: 1.14;
}
/* What it is and how much of it, under the name and at label weight. This is
   where the family went when the corner tab was retired, and it is the more
   useful form of it: the tab carried one of the two facts and had to truncate
   to do it. */
.sp-meta {
  margin-top: 5px;
  min-height: 1.25em;
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: #5A473F;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* The shop's own sentence. TWO lines, not three: the third was the line that
   ended mid-clause on the narrow tracks, and two full lines say more than
   three broken ones. The fixed min-height keeps the baselines even. */
.sp-why {
  margin-top: 8px;
  font-size: 12px;
  line-height: 1.42;
  color: #5A473F;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: calc(2 * 1.42em);
}

/* ── price and action, one row ────────────────────────────────────────────
   The price is the number a shopper compares across the row, so it is set at
   display scale and sits on the same line as the control that acts on it. */
.sp-buy {
  margin-top: 11px;
  padding-top: 10px;
  border-top: 2px solid var(--ink);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
/* The comparable number's line is reserved for the same reason the meta line
   is: two products in five carry no accepted quantity, and without the
   reservation their price sat centred against a row of neighbours whose price
   sat above a second line. The element is always rendered and is empty where
   the number is withheld. */
.sp-price { display: grid; gap: 1px; min-width: 0; }
.sp-unit { min-height: 1.2em; }
.sp-price > b {
  font-family: var(--display); font-weight: 400; font-size: 20px;
  letter-spacing: -0.01em;
  color: var(--cocoa);
  font-variant-numeric: tabular-nums;
}
.sp-unit { font-size: 10.5px; font-style: normal; color: #5A473F; white-space: nowrap; }

.sp-cart {
  flex: none;
  min-height: 44px;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 0 14px;
  border: 2.5px solid var(--cocoa);
  border-radius: 999px;
  background: var(--amber);
  box-shadow: 3px 3px 0 var(--cocoa);
  color: var(--cocoa);
  text-decoration: none;
  font-family: var(--display); font-weight: 400;
  text-transform: uppercase; letter-spacing: 0.03em;
  font-size: 12px;
  transition: transform 0.14s ease, box-shadow 0.14s ease;
}
.sp-cart > .ic {
  width: 16px; height: 16px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.9;
  stroke-linecap: round; stroke-linejoin: round;
}
.sp-cart:hover { transform: translate(1px, 1px); box-shadow: 2px 2px 0 var(--cocoa); }
.sp-cart:active { transform: translate(3px, 3px); box-shadow: 0 0 0 var(--cocoa); }
/* A product with variations cannot be added from a grid, so its control says
   so and routes to the page that can. The label is longer than "Kosárba", so it
   takes the whole row rather than squeezing the price.

   NO GLYPH, and that is deliberate: the words are the message, and the hero's
   equivalent control (`.fr-cta-ghost`) drops its mark for the same reason. */
.sp-cart[data-act="choose"] { font-size: 11px; letter-spacing: 0.02em; padding: 0 12px; }
.sp-cart[data-act="choose"] > .ic { display: none; }
/* `view` is the other non-buying control — what a product WooCommerce says is
   not purchasable gets — and unlike `choose` its label IS clipped below 641. It
   carries a chevron rather than inheriting the cart glyph. */
.sp-cart[data-act="view"] > .ic { width: 15px; height: 15px; stroke-width: 2.2; }

/* ── retired: the doors, the authority band and the editorial collage ─────
   Three blocks, roughly 460 lines, removed with the sections they painted.

   THE DOORS were a full-bleed butter field carrying a typographic index of six
   family names. They now live above the shelf as picture tiles (`.fam-*`),
   because on this catalogue the family IS the fastest route to a product and a
   route arriving after the whole shelf has gone past is not a route.

   THE AUTHORITY BAND listed what the checkout shows, how you pay, that an
   order is confirmed by e-mail and that withdrawal follows the terms. All four
   are true, none sells anything, and all four are now rows in the card beside
   the FAQ, which is where a shopper looks for them. Its `.label-*` rules are
   kept below and still in use; only the full-bleed cocoa room around them is
   gone.

   THE COLLAGE pinned two products under "Ha valamit ki kell hagynod". The
   constraint it was really about is `badge`, and reading it as a facet on the
   shelf covers every constrained product rather than two. */

/* ── FAQ ─────────────────────────────────────────────────────────────────── */

/* The reference's wide tinted panel with a rule down the middle: the ask on one
   side, the answers on the other. Panel-local ink, not the page's cocoa. */
/* ── the orphan hue, and why it is gone ───────────────────────────────────
   This panel was mint, with its own private ink (#17453D), its own secondary
   value and its own button treatment. Mint is a FAMILY colour — it means
   "vitamins and daily basics" everywhere else on this page — so spending it
   here meant the one place a shopper met that colour at full panel scale was
   the one place it carried no meaning at all. It also made nine hues on one
   page, and nine hues at equal confidence is the signature of a page nobody
   composed.

   The page system is now cocoa, cream and amber, plus green where it is the
   assisted layer's semantic (ADR 0023) and the family scale where family
   membership is actually the point — the hero plate, the lead plate, and the
   shelf card's ink. The FAQ is none of those, so it takes the system: the soft
   panel white the hero already uses, with the page's own cocoa. It loses
   nothing but a colour it was borrowing. */
.qa {
  display: grid;
  grid-template-columns: minmax(0, 0.72fr) minmax(0, 1.28fr);
  gap: 54px;
  background: var(--panel);
  border: 2.5px solid var(--cocoa);
  border-radius: var(--radius-panel);
  padding: 52px 54px 46px;
  position: relative;
}
/* `start`, not `stretch`. The accordion was being stretched to the height of
   the column beside it, so its last rule sat 120px above the end of an empty
   box. It ends where its last question ends now. */
.qa { align-items: start; }
.qa-side { position: relative; }   /* the accordion is much taller than the side; centring it stops the panel reading as half-empty */
.qa-squiggle { display: block; width: 92px; margin-bottom: 18px; }
.qa-squiggle > svg { width: 100%; fill: none; stroke: var(--coral); stroke-width: 3.4; stroke-linecap: round; }
.qa-title { color: var(--cocoa); }
/* Solid, not an alpha of the ink. Dimming body copy to signal "secondary" is
   how the contrast audit found four separate failures on this page; rank comes
   from size and measure here, and the colour stays readable. */
.qa-note { margin: 18px 0 24px; max-width: 26ch; font-size: 14.5px; line-height: 1.6; color: #5A473F; }

.faq { display: grid; grid-template-columns: minmax(0, 1fr); border-top: 2.5px solid rgba(46, 28, 21, 0.24); }
.faq-item { border-bottom: 2.5px solid rgba(46, 28, 21, 0.24); color: var(--cocoa); }
/* 26, not 20. The accordion column ended about 100px above the facts card
   beside it, which on a two-column panel reads as an unfinished column rather
   than as rhythm. The 48px the four questions gain closes most of it, and a
   question is a click target that was worth the room anyway. */
.faq-item > summary {
  list-style: none; cursor: pointer;
  padding: 26px 2px;
  font-family: var(--display);
  font-size: 18px;
  text-transform: uppercase;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::after {
  content: '+';
  width: 30px; height: 30px; flex: 0 0 30px;
  border-radius: 999px;
  background: var(--amber);
  border: 2.5px solid var(--cocoa);
  display: grid; place-items: center;
  font-size: 16px;
}
.faq-item[open] > summary::after { content: '\2013'; }
.faq-item > p { margin: -4px 0 22px; padding-right: 54px; font-size: 14.5px; line-height: 1.6; color: #5A473F; }
.faq-item a { color: inherit; }

/* ── final CTA ───────────────────────────────────────────────────────────── */

/* Two columns, and the left one reads downward: the statement, then the thing
   to press. The band used to put the call to action in the right column at the
   heading's baseline and hang the founder's line centred underneath both, so
   the three elements formed a T with an empty quarter under the heading. The
   action now sits under the words it belongs to, and the voice takes the
   column beside them. */
.close {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.82fr);
  align-items: center;
  gap: 26px 48px;
  padding: 54px;
}
.close-title { grid-column: 1; grid-row: 1; align-self: end; }
.close-cta   { grid-column: 1; grid-row: 2; align-self: start; }
.close-say   { grid-column: 2; grid-row: 1 / span 2; }
/* The drawn arc occupies real space under the last word and the row gap has to
   clear it, or the primary action lands on the stroke. */
.close { row-gap: 56px; }
/* The final ask is the largest type on the page after the hero. It used to be
   set within a few pixels of every section heading, which is why the closing
   panel read as one more section rather than as the end of the argument. */
.close-title {
  position: relative; z-index: 2;
  margin: 0;
  font-family: var(--display);
  font-size: clamp(40px, 5.6vw, 82px);
  line-height: var(--display-lh);
  letter-spacing: -0.012em;
  text-transform: uppercase;
}
/* the drawn underline is struck through the last word, by hand */
/* The arc gets RESERVED SPACE rather than being hung off the bottom of the
   word. Hung, it depended on the display face's overshoot below its own line
   box, and being absolutely positioned it could escape the heading entirely
   and land across the row beneath — which it did, twice, first through the
   letters and then through the terms line. Padding makes the room real, so
   the arc cannot collide with anything. */
/* A BLOCK in normal flow, not an absolutely positioned overlay. Registering an
   overlay against the word meant registering it against this display face's
   line box, which sits well below its glyphs — so the arc landed first through
   the letters and then across the row beneath. In flow it simply starts on the
   next line and is pulled up by a fixed amount, and it can collide with
   nothing because it occupies real space. */
.close-arc {
  display: block;
  /* Sized to the word it strikes, not to the column. At 60% it ran past the
     end of "KEZDJÜK" and finished against the primary action now sitting on
     the row below, which read as a collision rather than as a drawn mark. */
  width: 56%;
  height: 0.16em;
  /* Titan One carries a deep descent, so its 0.88 line box ends ~0.55em below
     the glyphs. The arc is lifted by that much to sit against the word. */
  margin: -0.52em 0 0 -0.01em;
  pointer-events: none;
}
.close-arc > svg { width: 100%; height: 100%; fill: none; stroke: var(--coral); stroke-width: 9; stroke-linecap: round; }
.close-cta { position: relative; z-index: 2; display: flex; align-items: center; gap: 24px; flex-wrap: wrap; }
/* The last button on the page was the only primary action wearing no chrome:
   every pill on this page is drawn with a hard offset shadow in cocoa, and a
   cocoa pill casting a cocoa shadow casts nothing. So the final ask — the one
   click the whole scroll has been arguing for — sat flat on the loudest field
   on the page and read lighter than the FAQ's button. It takes the shadow in
   coral, which is the accent already struck under this heading. */
.close .btn-pill-cocoa { box-shadow: 4px 5px 0 var(--coral); }
.close .btn-pill-cocoa:hover { box-shadow: 1px 2px 0 var(--coral); }

/* The terms of the sale, set as one quiet line under the rule. These are the
   mechanics of paying, not reasons to buy, so they get the smallest voice on
   the panel — dressing them as four proposition tiles is what made the earlier
   version argue its case with a payment logo. */
.close-terms {
  grid-column: 1 / -1;
  position: relative; z-index: 2;
  margin: 26px 0 0; padding: 26px 0 0;
  border-top: 2.5px solid rgba(46, 28, 21, 0.24);
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.5;
  color: rgba(46, 28, 21, 0.66);
}
.close-terms > span { color: rgba(46, 28, 21, 0.38); margin: 0 6px; }

/* ══ tablet ══════════════════════════════════════════════════════════════ */

/* This block used to carry `.cp`, `.doors-in` and `.doors` straight to a
   single column at 1100px and below — the phone's own composition, printed
   unchanged onto 700px (768) and 956px (1024) of usable line (`.shell` minus
   two `--inset`s at both widths, per `gan-harness/evidence/baseline.md`). 768
   and 1024 got the same one-column stack despite a 256px difference in line
   length between them, which is the opposite of a tablet composition. Those
   three rules now live in the two width-scoped bands below, each reasoned
   from its own measured line length. Everything else here — the lead, the
   collage, the QA grid, the footer's two top zones — was never part of that
   defect and is unchanged. */
@media (max-width: 1100px) {
  /* The overlap is a wide-layout composition. Once the collage folds to two
     columns the negative margins would just drive the card off the grid, so
     every offset is reset explicitly rather than only the one that happens to
     be in a shorthand. */
  .qa { grid-template-columns: 1fr; gap: 30px; padding: 40px 38px 36px; }
}

/* ── 1024 · landscape tablet, "desktop composition at a tighter measure" ────
   956px of line length is most of what 1440 has (`.doors-in` resolves
   449px/799px there); it just needs a smaller gutter and a shorter arm on
   the drawn "runway" that used to assume a much taller heading column. The
   base rules already carry the right RATIO — `.doors-in`'s 0.72fr/1.28fr and
   `.cp`'s 1fr/0.86fr are the same split that renders 449/799 and 611/525 at
   1440 — so nothing here changes the ratio, only the gap and the vertical
   offsets that were tuned for a wider column. */
@media (min-width: 901px) and (max-width: 1100px) {
  /* 956px puts the right-hand column at ~586px (900px available minus the
     40px gap above, split 0.72:1.28) — the 56px column-gap `.doors` uses at
     1440 would leave each door cell 265px; 32px keeps both cells over 275px
     without touching the 2-up template itself. */
  /* 116px of runway assumes the 74px display heading 1440 sets at `clamp`'s
     ceiling; at 1024 the same clamp is close to its floor (`5.2vw` = ~53px),
     so the arrow's travel and the gap beneath it are both shortened by the
     same proportion rather than left to overshoot a heading that is a third
     shorter here. */

  /* ── inter-section rhythm, 1024 ─────────────────────────────────────────
     Every one of these fell through to the desktop `margin-top` unchanged —
     the only downward step was `max-width: 640px`, so 1024 was paying a gap
     tuned for 1440's much longer page. None of this is inside any section's
     own measured height (`gan-harness/measure.js` reads `getBoundingClientRect`,
     which excludes margin); it is the ~463px of AIR the baseline evidence
     found between sections rather than inside them. Values sit roughly
     two-thirds of the desktop figure — between the 96/120/108/190 desktop
     defaults and the 48/54/54/118 the phone eventually reaches, not a copy of
     either. */
  .sec { margin-top: 78px; }
}

/* ── 768 · portrait tablet, an honest intermediate ratio ─────────────────
   700px does not hold `.doors-in`'s two columns without breaking `.doors`
   itself: the same 0.72fr/1.28fr split that gives 1024 a healthy ~586px right
   column leaves 768 only ~412px for it, and a further 2-up split inside that
   drops each door cell to ~178px — narrower than the 296px the PHONE gives a
   2-up door cell at 640px and away, which would be a regression dressed as a
   composition. So 768 gets a real, authored stack instead of the phone's
   collapse: `.doors-else` moves after `.doors` (the same "read the question,
   run the list, meet the alternative last" order the phone uses, because the
   reasoning holds the moment the layout is single-column, not only below
   640px) and `.doors` itself goes 2-up at the FULL 700px line — the fix the
   baseline evidence asked for ("a nav that already knows how to be two
   columns"), at tablet scale rather than the phone's compact door cells. */
@media (min-width: 641px) and (max-width: 900px) {
  /* One column here too. In this range the side column has already stacked
     ABOVE the index, so the index owns the full shell width — which is the
     one width where two columns cost the label everything and buy nothing.
     `2.65vw` of the base clamp only comes to ~22px at 820, so the labels had
     quietly returned to the mid-scale the desktop fix was made to escape;
     they get their own step here rather than inheriting a viewport unit
     calibrated for a column half this wide. */

  /* `.cp` is a single column now, so nothing here sets its tracks. The note
     below is kept because it records why the surrounding band widths are what
     they are.

     `.cp`'s two children WERE a copy column and a small pill diagram, not a
     second product stage — 311px is plenty for the well and its three pills
     to wrap on, so 700px keeps the two-column composition `.cp` already has
     at 1440, just at a tighter gap and the same 1fr/0.86fr ratio. */

  /* ── inter-section rhythm, 768 ──────────────────────────────────────────
     Same fall-through as 1024 (see the block above), scaled to the shorter
     line: roughly halfway between the desktop default and where the phone
     eventually lands at 640px, so 768 reads as its own step rather than
     either end borrowed. */
  .sec { margin-top: 70px; }
}

/* The order field keeps its two columns down to the burger breakpoint.
   Stacking it at 1100 laid a 460px card against the left of a full-bleed cocoa
   field and left 500px of empty brown beside it, with the heading dropped
   underneath — the one composition on the page that read as unfinished rather
   than as spacious. The card and the copy still fit side by side at 1024; they
   only stop fitting when the page itself goes to one column. */
@media (max-width: 900px) {
  .label-card { margin-top: -150px; justify-self: start; max-width: 460px; }
}

/* 150px is the value the phone (`max-width: 640px`, below) still overrides
   to 118px — but nothing between 641 and 900 ever re-tuned it, so 768 alone
   was paying a desktop-adjacent 150px margin its own `.auth` grid (one column
   here, not two) does not need. Scoped to 641–900 rather than folded into the
   rule above, so 390 keeps the exact -150px `.label-card` break-over it had
   before this pass — only 768 moves. `.label-card`'s negative offset must
   move with `.auth-sec`'s margin or the card stops breaking over the same
   amount of the top edge. */
@media (min-width: 641px) and (max-width: 900px) {
  .label-card { margin-top: -130px; }

  /* …and 768 keeps the two-column band rather than taking the phone's stack.
     The rule above this one stacks everything below 900 on the argument that
     the card and the copy "only stop fitting when the page itself goes to one
     column". That was true when the whole tablet page was a phone stack; it
     stopped being true in the same pass that made `.doors` and `.cp` two-up
     at 768. Stacked, this band was measured at 710px against 468px at 1440 —
     the largest single section penalty left at this width, and the only place
     the phone composition still survived.

     The card breaks over the top edge on a negative margin, so in one column
     it charges its own height to the section twice: once for the break-over
     and once for the copy pushed below it. Side by side, the row is the taller
     of the two, which is what the desktop band already does.

     Narrower ratio and gap than desktop's 0.8fr/1fr at 76px: 700px of shell
     cannot spend 76px on a gutter and still leave the card a column it can
     set its own label in. */
  .label-card { justify-self: stretch; max-width: none; }
}

@media (max-width: 860px) {
  /* The lead sits above the strip rather than beside it — at this width a
     three-line label beside the cards leaves the cards nothing to move in. */
  .rail-in { flex-wrap: wrap; gap: 10px 16px; }
  .rail-lead { flex: 1 1 auto; }
  .rail-lead > br { display: none; }
  .rail-view { flex: 1 1 100%; order: 3; width: 100%; }
  .rail-toggle { order: 2; }
}

/* ══ phone ═══════════════════════════════════════════════════════════════ */

@media (max-width: 640px) {
  .sec { margin-top: 62px; }
  .band { padding: 32px 20px 34px; border-radius: 26px; }
  .sec-head { flex-wrap: wrap; gap: 16px; margin-bottom: 24px; }
  .rule-pill { margin-left: 0; }
  .rule { width: 40px; }
  .squiggle { display: none; }

  .rail { margin-top: 22px; }
  .rail-in { padding-block: 14px 18px; }
  .rail-view { padding-top: 22px; }
  .bcard { height: 52px; padding: 0 14px 0 54px; margin-right: 12px; border-radius: 12px; }
  .bcard-pack { height: 66px; width: 42px; left: 7px; }
  .bcard-name { font-size: 12.5px; }

  /* `grid-template-columns` used to arrive here from the old shared
     `max-width: 1100px` collapse too — restored explicitly now that 768 and
     1024 keep two columns and the phone alone still needs one. */
  .pick-why { margin-top: 22px; font-size: 14px; }
  .plate { height: 210px; margin: 52px 0 22px; border-radius: 26px; }
  .plate-pack { height: 250px; top: -48px; }
  .plate-motif { width: 380px; height: 380px; }

  /* name, meta and price cannot share a line at this width without the name
     shredding into three lines — so the price drops under its own rule */

  /* Consecutive rows share one rule instead of stacking two. */
  /* The cart drops under the row rather than competing with the price for the
     same line — side by side it was pushing the whole page 68px wide at 375. */
  /* Two lines, and the second one is the transaction: the price and the button
     that acts on it, together, indented to the text column so they read as
     belonging to the product named above rather than to the rule below.

     This replaces a row that put the price at the top right and the Kosárba
     alone on a third line 60px under it, with an empty quarter of the cell in
     between — the two halves of a purchase decision separated by the widest
     gap in the row. Nothing here is compressed to achieve it; the row is 20px
     SHORTER than the version it replaces. */
  /* Right-aligned, sized to its label. Full width, the two companion carts
     were three identical full-bleed amber bars in a column with the lead's
     cart — same size, same weight, same colour — and the lead stopped being
     the lead. */

  /* The cell takes its grid track; nothing here sets a width. `min-width: 0`
     on both the cell and the link is what keeps a long product name from
     widening its own column past the track it was given. */
  .sp { min-width: 0; }
  .sp-box { height: 156px; border-radius: 14px; }
  .sp-box > img { height: 134px; }
  .sp-box[data-shot="photo"] > img { height: 126px; }
  .sp-name { font-size: 12.5px; margin-top: 10px; }
  .sp-why { -webkit-line-clamp: 2; min-height: calc(2 * 1.42em); }
  .sp-price > b { font-size: 17px; }
  .sp-cart { font-size: 11px; padding: 0 11px; gap: 5px; }
  .sp-cart > .ic { width: 15px; height: 15px; }

  /* ── the phone doors ─────────────────────────────────────────────────────
     Reordered, not restacked: on a phone the shopper reads the question, runs
     the list, and only meets the Célpakk alternative once the list has failed
     them. On desktop both are visible at once and the order does not matter. */
  /* Both used to arrive here as a side-effect of the old shared `max-width:
     1100px` collapse, which forced `.doors-in` to one column and hid the
     arrow at every width from 1100px down to the phone. Now that 768 and
     1024 each have their own composition (above), the phone needs its own
     explicit copy of the one rule it still relies on — `.doors-in` single
     column — plus the mark, which still has nothing to point across once
     `.doors-side` is dissolved by `display: contents` below. */
  /* `max-width: none` also used to arrive here from the old shared collapse
     (it removed the desktop 27ch clamp everywhere <=1100px); restored
     explicitly for the same reason as `.doors-in` and the mark above it. */

  .creed { margin-top: 84px; margin-bottom: 84px; }
  .say-quote { max-width: none; margin-bottom: 28px; }
  .say-br { display: none; }
  /* 86px put the seal's ring of type at about seven effective pixels, which is
     not small lettering, it is texture — an orange disc with a grey fringe.
     The mark either reads or it is not a mark. */
  .say-mark { position: static; width: 116px; height: 116px; margin: 0 0 26px; transform: rotate(-9deg); }
  .say-foot { gap: 14px; }
  .say-rule { width: 44px; }

  .label-card { padding: 22px 22px 24px; border-radius: 22px; max-width: none; }
  .label-card-top { font-size: 12px; }
  .label-k { font-size: 13.5px; }
  .label-stamp { width: 84px; height: 84px; right: -10px; bottom: -18px; }

  .qa { padding: 32px 20px 30px; border-radius: 26px; gap: 26px; }
  .faq-item > summary { font-size: 15.5px; padding: 17px 0; gap: 12px; }
  .faq-item > p { padding-right: 0; }

  .close { grid-template-columns: 1fr; padding: 32px 20px 34px; gap: 24px; }
  /* 18 was not enough vertical room between the two. Both wrap to their own
     line here, and the primary's 56px pill overlapped the secondary's 44px
     invisible hit overlay from above — so the last text route on the page had
     about 37px of it left. The same failure the footer's link stack is already
     written up for; the fix is the same, which is to stop the targets touching. */
  .close-cta { gap: 18px 24px; }
  .close-cta > .txt-link { margin-top: 6px; }
  /* The arc's negative top margin pulls the heading's box up onto itself, so
     on the stacked phone layout the button below rode straight over it and the
     only thing visible were the two ends poking out either side. It gets its
     space back here. */
  .close-arc { margin-bottom: 0.3em; }
  /* No room for the burst once the panel is one narrow column: it sat behind
     the full-width button and read as scribble leaking out from under it. */
  .band-mark-amber { display: none; }

  /* Several links are visually small by design — a 14px footer link, an
     underlined text link whose rule has to stay on the baseline. Rather than
     inflate the type, expand the hit area with an invisible overlay so the tap
     target clears 44px while the drawing is untouched. */
  .txt-link, .say-foot .txt-link { position: relative; }
  .txt-link::after{
    content: '';
    position: absolute;
    left: 0; right: 0;
    top: 50%; transform: translateY(-50%);
    height: 44px;
    min-width: 44px;
  }   /* 43px was one pixel under the WCAG target floor */

  /* Where the strip wraps, the per-brand optical scaling has to be capped.
     Those factors are tuned for a single horizontal row, where a tall stacked
     lockup needs extra height to hold its own beside five wordmarks; stacked
     vertically on a phone the same factor makes that one mark tower over the
     rest and the row stops reading as a set. */
  .bcard { height: 50px; padding-inline: 14px; }
  .bcard-mark {
    width: 108px;
    height: calc(24px * var(--mark-s, 1));
    max-height: 38px;
  }
  /* Tracks the mark box down at the same ratio it was matched at (21/34), so
     the wordmarks do not become the loudest thing in the wrapped block, and
     the cell floor follows `.bcard-mark`'s 108px for the same reason it
     matches 156px on the desktop row. */
  .bcard-word { min-width: 108px; font-size: 15px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   TARGET SIZE
   Every control reaches 44px of touchable height at every width, without any
   of them being drawn larger. Nothing below changes a colour, radius, weight
   or position.

   F7 already solved this for `.txt-link` and `.hd-mark`, but only inside the
   phone media query — on a desktop pointer the same links measured 23px. This
   promotes that exact overlay to all viewports and extends it to the controls
   it never covered, rather than inventing a second mechanism: two overlapping
   overlay geometries on one element is what made the hero CTA measure 26px.

   Inline links inside a paragraph, and inside the consent label, are exempt
   under WCAG 2.5.8 — their height is set by the line-height of the prose they
   sit in, and expanding them would make the text between them un-tappable.
   ══════════════════════════════════════════════════════════════════════════ */

.txt-link,
.rail-toggle { position: relative; }

.txt-link::after{
  content: '';
  position: absolute;
  left: 0; right: 0;
  top: 50%; transform: translateY(-50%);
  height: 44px;
}

/* The maker rail's pause button is 40px square, so it needs the overlay to
   grow in both directions rather than only downward from a text baseline. It
   is the last of the two: the hero's rotation, and the toggle that stopped it,
   are gone. */
.rail-toggle::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 48px; height: 48px;
  border-radius: 999px;
}

/* The pills were a pixel pair short of the floor. Two pixels of height is not
   a visual change; failing the floor on every primary action is. */
.btn-pill { min-height: 44px; }

/* …and the large pill has to be restated after it, or the floor becomes the
   ceiling. `.btn-pill-lg` is declared in home.css and this rule is the last
   sheet loaded, so at equal specificity 44px won and EVERY primary action on
   the page — the hero's Válassz célt, the shop floor's Kosárba, Indítsd el a
   Célpakkot and the closing ask — was rendering at the accessibility minimum
   instead of at hero scale. They kept their width and their 16px type, which
   is exactly why it never looked like a bug: the buttons were simply squashed,
   everywhere, and the page's whole action hierarchy flattened with them. */
.btn-pill-lg { min-height: 60px; }
@media (max-width: 640px) { .btn-pill-lg { min-height: 56px; } }

/* ══════════════════════════════════════════════════════════════════════════
   F10 · the phone composition
   ══════════════════════════════════════════════════════════════════════════
   The page was 10 660px at 390 against 7 789px at 1440 — 66% longer in
   viewport counts for the screen most visitors actually use. Three quarters of
   that gap was never content. It was a desktop vertical rhythm rendered at
   phone width: 96–120px section margins and 60–80px field padding, measured
   for a 1440px composition where they are a proportion of a wide page, and
   printed unchanged onto a 390px one where they are a third of a screen of
   nothing between every two things.

   The structural cuts came first and they are real: the companion rows, the
   shows-proof list and the footer's duplicated fact table are gone, and the
   claim that had a section to itself is now the shelf's heading. What is left
   here is the air between what remains, recomposed for the screen it is on
   rather than scaled down from the screen it was designed for. */
@media (max-width: 640px) {
  /* ── the products field ─────────────────────────────────────────────────
     The heading, then the controls, then two cards per row. Two, not one: a
     grid one card wide is a list, and the shopper loses the comparison the
     grid exists to give them. The packs shrink to pay for it and still hold a
     third of the card, which is more than the old horizontal row gave them.

     `auto-fill` with the desktop's 228px floor would drop to one column at
     390px, so the phone sets its own track count explicitly. */
  .shelf { padding: 32px 0 28px; }
  .shelf-head { gap: 10px; margin-bottom: 16px; }
  /* ── the phone filter row is the constraints, and only the constraints ───
     Eight wrapped chips came to three rows and 150px of control furniture in front
     of four product cards, and six of the eight were families — which this
     page already offers twice on the same screen, in the hero's chooser above
     and in the picture tiles below. What it does NOT offer anywhere else is
     "no dairy" and "no stimulants", and those were the two a shopper is most
     likely to be filtering for. One row, three options, every one of them at a
     44px target and none of them a duplicate. */
  .facet[data-kind="family"] { display: none; }
  .shelf-tools { margin-bottom: 14px; }
  .shelf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .sp-cell { padding: 10px 10px 11px; border-radius: 18px; }
  .sp-box { height: 150px; }
  .sp-box > img { height: 128px; }
  .sp-box[data-shot="photo"] > img { height: 120px; }
  .sp-flag { left: 7px; top: 7px; font-size: 9px; padding: 3px 7px 4px; }
  .sp-name { margin-top: 9px; font-size: 12.5px; }
  .sp-meta { margin-top: 4px; font-size: 10.5px; }
  /* THE SENTENCE COMES OFF THE PHONE CARD. On two 165px columns it clamped
     mid-word on most of the catalogue — the shop's own promise visibly
     failing on the widest block it has — and it was 38px of every card in a
     section that is a sample, not a listing. It is on the product page and on
     the desktop card, at a size it can be read at. */
  .sp-why { display: none; }
  .sp-buy {
    margin-top: 8px;
    padding-top: 8px;
    /* The price and the action stack rather than sharing a line: at this width
       "8 390 Ft" plus a labelled pill is 40px wider than the column, and
       shrinking either one to fit is how a card ends up unreadable. */
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 8px;
  }
  .sp-price > b { font-size: 16px; }
  .sp-unit { font-size: 9.5px; }
  /* Icon only, at the 44px touch minimum. The accessible name is unchanged —
     it still reads "Kosárba, <product>" — so nothing is lost but the glyph's
     caption, which is the one word on this page a shopper already knows by
     its colour and its shape. */
  .sp-cart { padding: 0; width: 44px; min-height: 44px; gap: 0; }
  .sp-cart > .ic { width: 19px; height: 19px; }
  .sp-cart-t { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  /* …except where the label IS the information: a product with variations
     cannot be added from a grid and its control must say what it does. */
  .sp-cart[data-act="choose"] {
    grid-column: 1 / -1;
    width: auto; padding: 0 12px;
  }
  .sp-cart[data-act="choose"] .sp-cart-t {
    position: static; width: auto; height: auto; clip-path: none;
  }
  /* The route out of a sample is the section's own next step, so it takes the
     width a next step takes on a phone rather than sitting as a small pill in
     the middle of an empty row. */
  .shelf-more { margin-top: 20px; }
  .shelf-all { width: 100%; }

  /* ── the doors ──────────────────────────────────────────────────────────
     The drawn arrow needs 116px of clear space above the alternative route to
     travel through, and it is drawn for a two-column composition where the
     heading sits beside the doors. Stacked, it has nothing to point across —
     it points at the thing directly under it, which needs no arrow. It goes,
     and the 116px of runway goes with it. */

  /* ── the rest of the rhythm ─────────────────────────────────────────────
     One step, applied once, rather than a per-section tuning nobody can hold
     in their head. */
  .sec { margin-top: 48px; }
  .band { padding: 28px 20px 30px; }
  .qa { padding: 26px 20px 24px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   F10 · the phone composition, part two — the surfaces that were still
   spending desktop proportions on a 390px screen
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {

  /* ── the doors ──────────────────────────────────────────────────────────
     Six full-width rows, each ~90px, for what is a six-item index. Two up at
     the same cell treatment the mega panel and the Termékek sheet already use
     makes this the third printing of ONE navigation component rather than a
     third design of it — which is the actual argument for the change; the
     350px it returns is the dividend. The label still leads, the note still
     sits under it, and the family swatch still opens the row. */
  /* The chevron is a second affordance on a cell that is already a link, and
     at this width it costs the label the room it needs to set on one line. */

  /* ── the constraint pair ────────────────────────────────────────────────
     This section carries TWO products and was taking 977px — more than the
     shelf spends on ten. The collage is a composition of overlapping objects
     at three scales, and overlap is a wide-screen idea: stacked at 390 the
     three pieces simply become three tall blocks with the offsets that made
     them a composition now reading as stray margins.

     On a phone it becomes what it actually is — two constraint objects, one
     after the other, each at the size of the fact it carries. The stamp, the
     blob and the negative offsets go with the composition they belonged to
     rather than being shrunk into illegibility. */

    /* The drawn result card stretches to the column on a phone rather than
     sitting beside a proposition there is no room to sit beside. */

  /* ── the marquee band ───────────────────────────────────────────────────
     Demoted to what it is: reassurance that recognised makers are carried.
     Márkák is the route now, and it lives in the menu, the sheet and the
     footer — so this band no longer has to be large enough to browse. */
  .rail-view { padding-top: 14px; padding-bottom: 4px; min-height: 50px; }

  /* ── the authority field and the newsletter ─────────────────────────────
     Both were composed as two-column objects and both stack here, which turns
     their column gaps into vertical dead space nobody chose. */
  .label-card { padding: 20px 20px 22px; }

}

/* ── the closing statement, inside the closing band ────────────────────────
   The founder's line used to be a section: an oversized statement on the page
   ground, with a seal and a signature rule. That worked as a hard change of
   density after the collage — and then the page immediately did it again, one
   section later, with a heading and the hero's own two actions.

   Here it is the band's last line rather than its own room, so the closing
   moment is one object: the ask, the two doors, and the person asking. It is
   set below the actions on purpose. A shopper who is ready acts on the button;
   a shopper who is not gets one more reason from a named human, in the place
   where they would otherwise leave. */
.close-say {
  position: relative;
  z-index: 2;
  display: grid;
  gap: 10px;
  justify-items: start;
  align-content: center;
  margin: 0;
  padding-left: 34px;
  border-left: 2.5px solid rgba(46, 28, 21, 0.28);
  text-align: left;
}
.close-say-q {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(19px, 2.1vw, 27px);
  line-height: 1.18;
  max-width: 22ch;
}
.close-say-q > em { font-style: normal; color: var(--coral-ink); }
.close-say-who {
  font-family: var(--display);
  font-size: 12.5px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: #5C4008;                      /* on amber — measured, not faded */
}
.close-say-who > i { font-style: normal; color: var(--coral-ink); }

@media (max-width: 640px) {
  /* Stacked, the voice goes back under the action with a rule above it: a
     left border on a full-width block is a stripe down the side of a phone,
     not a division between two columns. */
  .close-say {
    grid-column: 1; grid-row: 3;
    margin-top: 22px; padding: 18px 0 0;
    border-left: 0;
    border-top: 2.5px solid rgba(46, 28, 21, 0.28);
  }
}

@media (max-width: 640px) {
  /* Reassurance, not navigation — Márkák is the route now. */
  .rail-view { padding-top: 10px; min-height: 44px; }
  .bcard { height: 44px; }
}

/* `--coral-ink` was measured against cream and the soft panel, where it clears
   the floor comfortably. Amber is a much lighter ground than either, and the
   same value lands at 3.98:1 on it — so the closing band gets its own step of
   the same hue rather than the emphasis being dropped or the band being
   recoloured. 4.96:1, and it reads as the same coral at a glance. */
.close .close-say-q > em,
.close .close-say-who > i { color: #A32E0C; }

/* The two order rows that carry a route to their detail. As bare inline
   anchors they were 49x21 and 49x13 — real destinations with a target a thumb
   cannot reliably hit, and not exempt as inline links in a sentence, because
   the anchor IS the whole value of its row rather than a word inside a
   sentence. The target fills the row's height; the type does not change. */
.label-v a {
  display: inline-flex;
  align-items: center;
  /* 50, not 44. The row is a baseline-aligned flex line, so the anchor box
     and the reachable area are not the same figure: the outermost few pixels
     of the box fall on the row rule and the line-box edge, and a probe from
     the centre stops there. Measured, not assumed — the harness reports the
     area a finger actually gets. */
  min-height: 50px;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
}
/* The row's own padding would otherwise stack on top of the taller target. */
.label-rows > li:has(.label-v a) { padding-block: 2px; }

/* The last row's taller target ran under the card's footing line, which is
   laid over it — so the anchor measured 44px in its own box and 27px of
   reachable area. The rows get the room back and the link wins the stack. */
.label-rows { padding-bottom: 8px; }
.label-v a { position: relative; z-index: 1; }

/* ══════════════════════════════════════════════════════════════════════════
   THE 2026-09-10 COMPOSITION PASS
   Four new surfaces and the adjustments the sections around them needed:
   the value rail, the family tiles, the shelf's facets, and the unit-price
   ladder that replaced the merchant-authority band.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── the value rail ───────────────────────────────────────────────────────
   Part of the fascia, not a bar floating above it: one step down in value from
   the header so the two read as layers of one dark object, which is the move
   the whole shell already turns on. Cream on #23130E is 13.9:1, so nothing
   here needs a size floor to stay legible.

   Two facts and a route. It is capped at the shell and centred, because a
   value that reaches both screen edges at 1440 reads as a sale banner. */
.facets-lead { display: none; }

/* `.hero-pts` is gone with the three benefit points it set.

   Each of them named something the page then did — the sentence on every card,
   the unit price beside every price, the Célpakk band — which made them a
   table of contents for the next two screens rather than a reason to stay on
   this one. The hero puts a product, its price and its purchase in that space
   now, and performs one of them instead of listing three. (This note used to
   point at `.hero-pick`; that composition went with the hero it belonged to —
   see Homepage Direction 6.) */

/* ── the family tiles ─────────────────────────────────────────────────────
   The category entry, promoted above the shelf and given pictures.

   The tile is one object: a coloured plate with the family's own hue, a real
   pack standing on it and breaking out over the top edge, and the label block
   below. `auto-fill` with a 210px floor rather than a fixed column count, so
   the row stays correct when the catalogue grows a family — and the first
   tile spans two tracks, because a grid where every cell is identical has
   declined to rank anything and the widest family is the one most people here
   are after. */
.fam-sec { margin-top: 88px; }
.fam-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: 34px;
}
.fam-head .sec-title { margin: 0; }

.fam-grid {
  /* N tiles where the lead spans two tracks is N+1 tracks, so the row fills
     exactly and the last family never lands alone on a second row. The count
     is written by the builder; the fallback keeps the grid honest if it does
     not run. */
  grid-template-columns: repeat(var(--fam-cols, 3), minmax(0, 1fr));
  display: grid;
  gap: 18px;
}
.fam[data-wide] { grid-column: span var(--fam-span, 1); }

/* ── the category tile ────────────────────────────────────────────────────
   EVERY TILE IS THE SAME COMPOSITION: the product on the left, the words on
   the right. Only the lead gets more of both.

   It used to be five tiles in one row of six tracks — a 170px cell with the
   pack stacked over the label — and the stack was the defect. The picture row
   was `1fr` and the pack a fixed 138px, so any family whose name ran to two
   lines ("Edzés előttiek", "Mindennapi támogatás") squeezed the row under the
   pack's own height and the tub sat down on top of its own label. The two
   families it happened to were the two with the longest names, which is to
   say: it would happen to every family the catalogue grows a long name for.

   Side by side there is no row to squeeze. The label takes the width it needs,
   the pack keeps one height across the whole set, and three tracks at 445px
   give both of them room instead of five at 170px giving neither any. */
.fam {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: 18px;
  min-height: 176px;
  padding: 14px 22px 14px 14px;
  border: 2.5px solid var(--cocoa);
  border-radius: 24px;
  background: var(--fam, var(--peach));
  color: var(--cocoa);
  text-decoration: none;
  overflow: hidden;
  transition: transform 0.16s ease, box-shadow 0.16s ease;
}
.fam:hover { transform: translateY(-4px); box-shadow: 0 8px 0 rgba(46, 28, 21, 0.16); }
/* The ring texture at tile scale. Same motif as the hero field and the card
   window, which is what makes these read as the same shop's objects. */
.fam-plate {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background:
    radial-gradient(circle at 24% 46%,
      rgba(255, 255, 255, 0.30) 0 13%,
      rgba(255, 255, 255, 0) 13.6% 23%,
      rgba(255, 255, 255, 0.22) 23.6% 33%,
      rgba(255, 255, 255, 0) 33.6% 45%,
      rgba(255, 255, 255, 0.16) 45.6% 57%,
      rgba(255, 255, 255, 0) 57.6%);
}
.fam-pack {
  position: relative;
  z-index: 2;
  /* Both cells name their ROW as well as their column. Grid auto-placement is
     sparse: an item with a definite column but an auto row cannot be placed
     behind the cursor, so the lead tile — whose words are in column 1 and are
     written after the pack in column 2 — put its text on a second row and grew
     to 303px, dragging the tile beside it up with it. */
  grid-column: 1; grid-row: 1;
  justify-self: center;
  align-self: center;
  height: 142px; width: auto;
  max-width: 150px;
  object-fit: contain;
  filter: drop-shadow(0 14px 16px rgba(60, 36, 6, 0.26));
  transition: transform 0.16s ease;
}
.fam:hover .fam-pack { transform: translateY(-4px) scale(1.03); }

/* The lead is not the tile stretched: the extra track is spent on the product
   and on the display size of the name, so the family the shop carries most of
   is the one tile that reads as a shelf rather than as a row. */
/* THE LEAD TILE IS THE ONLY ONE THAT READS RIGHT TO LEFT, and that is why it
   reads as the lead. With the pack on the left like its siblings, its extra
   track became 380px of empty colour past the end of a short note — the
   largest blank area on the page. Words first, product last is also the hero's
   order directly above it, so the two biggest objects on the page open the
   same way. */
.fam[data-wide] {
  /* The tracks swap with the contents. The base grid is `auto | 1fr` — pack,
     then words — so moving the pack to column 2 without this line put it in
     the 1fr track and floated it in the middle of 700px of colour. */
  grid-template-columns: minmax(0, 1fr) auto;
  padding: 14px 18px 14px 30px;
  column-gap: 26px;
}
.fam[data-wide] .fam-pack { grid-column: 2; grid-row: 1; height: 168px; max-width: 210px; }
.fam[data-wide] .fam-txt { grid-column: 1; grid-row: 1; }
.fam[data-wide] .fam-plate {
  background:
    radial-gradient(circle at 76% 46%,
      rgba(255, 255, 255, 0.30) 0 13%,
      rgba(255, 255, 255, 0) 13.6% 23%,
      rgba(255, 255, 255, 0.22) 23.6% 33%,
      rgba(255, 255, 255, 0) 33.6% 45%,
      rgba(255, 255, 255, 0.16) 45.6% 57%,
      rgba(255, 255, 255, 0) 57.6%);
}

/* A product with no authored cut-out takes the same frame the hero and the
   grid card give it, rather than bleeding a white rectangle across the plate. */
.fam-pack[data-shot="photo"] {
  background: #fff;
  border: 2px solid rgba(46, 28, 21, 0.32);
  border-radius: 14px;
}

.fam-txt {
  position: relative;
  z-index: 3;
  grid-column: 2; grid-row: 1;
  display: grid;
  gap: 4px;
  align-content: center;
  justify-items: start;
}
.fam-label {
  font-family: var(--display);
  font-weight: 400;
  font-size: 24px;
  line-height: 1.05;
  text-transform: uppercase;
  letter-spacing: -0.005em;
}
.fam[data-wide] .fam-label { font-size: 34px; }
/* Solid cocoa at 0.88, not 0.74. The family plates are a PLATE scale and the
   peach is the darkest of them, so a note dimmed to signal "secondary"
   measured 4.32:1 on the widest tile — under the floor at that size. Rank
   comes from size and measure here; the colour stays readable on every plate
   in the registry, including the darkest. */
.fam-note { font-style: normal; font-size: 13px; line-height: 1.35; color: rgba(46, 28, 21, 0.88); }
.fam[data-wide] .fam-note { font-size: 14px; }
.fam-from {
  justify-self: start;
  margin-top: 9px;
  text-decoration: none;
  font-family: var(--display);
  font-size: 13px;
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
  background: var(--cocoa);
  color: var(--canvas);
  border-radius: 999px;
  padding: 6px 12px;
}

/* ── the shelf's facets ───────────────────────────────────────────────────
   The row's only control. Pressed state is fill AND the ink, never colour on
   its own; the family chips carry a swatch of their own hue so the chip and
   the card it filters to agree. 44px minimum on the phone, where they are the
   most-pressed things on the page after the buy pills. */
.facets { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.facet {
  appearance: none;
  min-height: 38px;
  padding: 0 15px;
  border: 2px solid var(--cocoa);
  border-radius: 999px;
  background: transparent;
  color: var(--cocoa);
  font-family: var(--body);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.005em;
  cursor: pointer;
  white-space: nowrap;
  display: inline-flex; align-items: center; gap: 8px;
  transition: background 0.14s ease, color 0.14s ease;
}
.facet[style*='--facet']::before {
  content: '';
  width: 10px; height: 10px;
  border-radius: 3px;
  border: 1.5px solid rgba(46, 28, 21, 0.5);
  background: var(--facet);
}
.facet-badge { border-style: dashed; }
.facet:hover { background: rgba(46, 28, 21, 0.08); }
.facet[aria-pressed='true'] {
  background: var(--cocoa);
  color: var(--canvas);
  border-style: solid;
}
.facet[aria-pressed='true']::before { border-color: rgba(246, 238, 226, 0.6); }
.shelf-all { white-space: nowrap; }

/* ── the unit price, on the objects that carry one ────────────────────── */
.sp-unit { font-variant-numeric: tabular-nums; }

/* ── Újratöltés ───────────────────────────────────────────────────────────
   The replenishment band, in the slot the retired "A rendelés menete" held and
   the unit-price ladder held after it.

   A cocoa band, contained rather than full-bleed, so it reads as one object
   the page is putting forward rather than as a strip of page furniture. Two
   columns: the proposition, and a drawing of the choice it introduces.

   THE DEMO IS A DRAWING, and everything about how it is drawn says so. It is
   `aria-hidden`, it contains no control, it carries no price where the second
   price would go, and the only word in the Újratöltés row is "Hamarosan".
   That is deliberate: the strongest honest way to sell a model that has not
   shipped is to show its SHAPE, because the shape is decided, and to quote
   none of its numbers, because they are not. Nothing in this section states
   an interval, a saving, a minimum term or a cancellation right.
   ───────────────────────────────────────────────────────────────────────── */
.renew-sec { margin-top: 100px; }
.renew {
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, 0.82fr);
  gap: 54px;
  align-items: center;
  padding: 54px 56px 52px;
}

/* The name and its status, one line, and the status is a pill rather than a
   sentence: a shopper reading a proposition for something they cannot buy
   yet should learn that in the same glance as the name. */
.renew-kicker {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 14px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--amber);
}
.renew-kicker > i {
  font-style: normal;
  letter-spacing: 0.08em;
  font-size: 10.5px;
  font-weight: 700;
  padding: 4px 9px;
  border-radius: 999px;
  border: 2px solid rgba(246, 238, 226, 0.42);
  color: var(--cream);
}
.renew-title {
  margin: 0 0 16px;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(32px, 3.9vw, 56px);
  line-height: var(--display-lh);
  text-transform: uppercase;
  letter-spacing: -0.015em;
  color: var(--cream);
}
.renew-lede {
  margin: 0 0 24px;
  max-width: 38ch;
  font-size: 15px;
  line-height: 1.6;
  color: #D9D0C2;
}

/* What is true TODAY, under a proposition about tomorrow. Both rows are real
   WooCommerce behaviour or Rutriven's own published term; neither is a term
   of the coming model. */
.renew-facts { margin: 0 0 22px; padding: 0; list-style: none; display: grid; gap: 11px; }
.renew-facts > li {
  position: relative;
  padding-left: 30px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--cream);
}
.renew-facts .ic {
  position: absolute;
  left: 0; top: 1px;
  width: 18px; height: 18px;
  fill: none;
  stroke: var(--green);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.renew-facts > li > b { color: var(--amber); font-weight: 600; }
.renew-facts a { color: inherit; text-underline-offset: 3px; }
/* The section's one action. It was a text link with a chevron, which on a band
   whose subject is a thing nobody can buy yet made the only available step the
   quietest element in it. */
.renew-cta { font-family: var(--display); text-transform: uppercase; }

/* ── the example ──────────────────────────────────────────────────────────
   A REAL PRODUCT WITH THE CHOICE DRAWN ON IT.

   What stood here was a wireframe: a bordered panel with two abstract option
   rows and a caption saying where they would appear. It explained a mechanic
   to a shopper who had not been given a reason to want it, and it was the
   least ecommerce object on an ecommerce page.

   This is the shape every supplement shop makes this offer in: the product,
   then the two ways to buy it. The pack, the name, the maker, the size and the
   price are written from the catalogue by `buildRenew` and the card links to
   its own product page, so the strongest object in the section is a real route
   into the shop rather than a drawing.

   The second row carries the word where the second price would go, and it is
   not a control. That is the whole discipline of this section: show the shape,
   quote none of the numbers. */
.renew-demo {
  border: 2.5px solid rgba(246, 238, 226, 0.3);
  border-radius: 22px;
  padding: 14px 14px 14px;
  background: rgba(246, 238, 226, 0.05);
}

/* THE PRODUCT LEADS. It used to be a 104px thumbnail beside its own name, so
   the largest object in a section selling a product was a pair of option rows
   under it. The pack now takes a full-width plate at the top of the card, at
   the size and on the colour it has everywhere else on this page, and the name
   sits under it — which is the shape of the grid card two sections up, and the
   shape the shopper will meet this decision in. */
.renew-card {
  display: grid;
  gap: 12px;
  text-decoration: none;
  color: var(--cream);
  padding-bottom: 14px;
  margin-bottom: 14px;
  border-bottom: 2px solid rgba(246, 238, 226, 0.2);
}
/* The pack stands on the family's own colour, the same plate the hero and the
   tiles give it, with the same ring motif the cards carry. A product without
   an authored cut-out gets a frame instead, because a studio-white photograph
   on a coloured plate reads as a rectangle pasted onto a card. */
.renew-card-shot {
  position: relative;
  height: 186px;
  display: grid; place-items: center;
  border-radius: 16px;
  background: var(--accent, var(--peach));
  background-image:
    repeating-radial-gradient(circle at 50% 60%,
      rgba(46, 28, 21, 0.075) 0 2px, rgba(46, 28, 21, 0) 2px 26px);
  overflow: hidden;
}
.renew-card-shot > img {
  max-width: calc(100% - 28px); max-height: 162px;
  width: auto; height: auto;
  object-fit: contain;
  filter: drop-shadow(0 12px 14px rgba(60, 36, 6, 0.26));
  transition: transform 0.16s ease;
}
.renew-card:hover .renew-card-shot > img { transform: scale(1.04) translateY(-3px); }
.renew-card-shot[data-shot="photo"] > img {
  border: 2.5px solid var(--cocoa);
  border-radius: 12px;
  background: var(--panel);
  filter: none;
  box-shadow: 4px 5px 0 rgba(46, 28, 21, 0.22);
  max-height: 150px;
}
.renew-card-id { display: grid; gap: 4px; min-width: 0; }
.renew-card-id > b {
  font-family: var(--display);
  font-weight: 400;
  font-size: 19px;
  line-height: 1.12;
  text-transform: uppercase;
  letter-spacing: 0.004em;
}
.renew-card:hover .renew-card-id > b { color: var(--amber); }
.renew-card-id > i { font-style: normal; font-size: 12.5px; color: #B7A697; }

/* Two rows of a two-column micro-table, and the key column is shared: a
   `min-width` guess either wraps the longer key or leaves the shorter one
   floating, and both were happening at different widths. `subgrid` lets the
   rows inherit one column set sized by the longest label there actually is, so
   the Hungarian can change without a number changing with it. A browser without
   subgrid drops to auto columns: unaligned, never overlapping. */
.renew-opts { display: grid; grid-template-columns: max-content minmax(0, 1fr) auto; gap: 10px; }
.renew-opt {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
  align-items: center;
  gap: 12px;
  min-height: 50px;
  padding: 0 16px;
  border: 2.5px solid rgba(246, 238, 226, 0.34);
  border-radius: 14px;
  color: var(--cream);
  font-size: 14.5px;
  font-weight: 600;
}
/* `.renew-opt-dot` is gone with the two drawn radio buttons it filled. See the
   note in body.html: a selected/unselected pair on a card carrying a real
   product at a real price is an offer to choose, and there was nothing to
   choose. What is left is a WHEN and a WHAT, which is the same two facts
   without the affordance. */
.renew-opt-k {
  white-space: nowrap;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #C8B9A8;
}
.renew-opt-n { min-width: 0; }
.renew-opt.is-on { border-color: rgba(246, 238, 226, 0.62); }
/* The row that is not there yet: dashed, and its label in the amber the page
   uses for what is coming. */
.renew-opt-soon {
  border-style: dashed;
  border-color: rgba(255, 210, 63, 0.52);
}
.renew-opt-soon .renew-opt-k { color: var(--amber); }
.renew-opt-v {
  margin-left: auto;
  font-family: var(--display);
  font-weight: 400;
  font-size: 17px;
  letter-spacing: 0.004em;
  font-variant-numeric: tabular-nums;
  color: var(--cream);
}
.renew-opt-soon .renew-opt-v {
  font-family: var(--body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #C8B9A8;
}

/* ── the order facts, now in the FAQ column ───────────────────────────────
   The card is the retired authority band's, kept whole: a supplement label
   rebuilt as a page object, keys left and values right, hard rules, and a
   green mark only on the rows the shop guarantees rather than on all five.
   What it loses is the staging it had against a full-bleed cocoa field — the
   lift over the boundary, the tilt and the seal straddling the corner were all
   drawn for a dark room that is gone, and inside the FAQ's cream panel the
   seal simply landed on top of the answers. It sits flat now, and the panel
   around it is the frame.

   It is rendered from the model, so a term the shop stops publishing loses its
   row rather than going stale in the markup. */
.qa-side { align-self: start; }
.label-card {
  position: relative;
  margin-top: 26px;
  background: var(--canvas);
  color: var(--cocoa);
  border-radius: 22px;
  border: 2.5px solid var(--cocoa);
  padding: 20px 22px 20px;
}
.label-card-top {
  margin: 0 0 10px; padding-bottom: 12px;
  border-bottom: 2.5px solid var(--cocoa);
  font-family: var(--display);
  font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase;
}
.label-card-top > span { color: var(--coral-ink); }
.label-rows { margin: 0; padding: 0 0 4px; list-style: none; }
.label-rows > li {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 9px 0;
  border-bottom: 1.5px solid rgba(46, 28, 21, 0.18);
}
.label-rows > li:last-child { border-bottom: 0; }
.label-k { font-family: var(--display); font-size: 14px; text-transform: uppercase; letter-spacing: 0.01em; }
.label-v { font-size: 12.5px; color: #5A473F; text-align: right; display: flex; align-items: center; gap: 7px; }
/* The guaranteed rows carry the mark; the qualified row does not. */
.label-v[data-ok] { color: #4A382F; font-weight: 500; }
.label-v[data-ok]::before {
  content: '';
  flex: 0 0 15px;
  width: 15px; height: 15px;
  border-radius: 999px;
  background: var(--green);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 12.4l4 4 8-8.6' fill='none' stroke='%23000' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 12.4l4 4 8-8.6' fill='none' stroke='%23000' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  -webkit-mask-size: 15px 15px; mask-size: 15px 15px;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.label-card-foot {
  margin: 12px 0 0; padding-top: 12px;
  border-top: 1.5px solid rgba(46, 28, 21, 0.2);
  font-size: 12px; line-height: 1.5; color: #6A5348;
}
.label-card-foot > span { display: block; max-width: 30ch; }
/* The rows are baseline-aligned flex lines and two of them carry a route, so
   the reachable area and the anchor box are not the same figure. */
.label-v a { display: inline-flex; align-items: center; min-height: 44px; position: relative; z-index: 1;
  text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
.label-rows > li:has(.label-v a) { padding-block: 0; }

/* The accordion is a stack of rows, not a column that has to fill the panel's
   height: without this the four closed questions share the left column's
   height between them and the section reads as four empty boxes. */
.faq { align-content: start; }

/* ══ tablet ══════════════════════════════════════════════════════════════ */
@media (max-width: 1100px) {
  .renew { grid-template-columns: 1fr; gap: 30px; padding: 44px 40px 40px; }
  .renew-lede { max-width: 52ch; }
  .fam[data-wide] .fam-label { font-size: 23px; }
}

@media (max-width: 1100px) {
  .fam-grid { grid-template-columns: repeat(var(--fam-cols-mid, 2), minmax(0, 1fr)); }
  .fam[data-wide] { grid-column: span var(--fam-span-mid, 1); }
  .fam { min-height: 168px; }
  .fam-pack { height: 128px; max-width: 132px; }
  .fam[data-wide] .fam-pack { height: 150px; max-width: 168px; }
  .fam[data-wide] { padding-left: 22px; column-gap: 18px; }
  .fam-label { font-size: 21px; }
  .fam[data-wide] .fam-label { font-size: 26px; }
}

@media (max-width: 900px) {
  .shelf-head { grid-template-columns: minmax(0, 1fr); }
  .shelf-tools { justify-content: flex-start; }
}

/* ══ phone ═══════════════════════════════════════════════════════════════
   The phone is not the desktop stacked. Three things are recomposed rather
   than reflowed:

   · the family tiles go to a two-up grid and stay a GRID — a horizontal
     scroller here would hide half the shop's entry points behind a gesture,
     on the one screen where the entry points matter most;
   · the facets become a single edge-to-edge scrolling row, which is the
     native shape for a filter bar on a phone and keeps the shelf directly
     under it rather than pushed down by three wrapped lines of chips;
   · the Újratöltés band stacks, and its drawing follows the proposition
     rather than sitting beside it. */
@media (max-width: 640px) {

  .fam-sec { margin-top: 64px; }
  .fam-head { margin-bottom: 18px; gap: 10px; }
  /* ── the phone tiles are one column, and that is the composition ─────────
     Two 173px columns is where the category names went to wrap: "Mindennapi
     támogatás" broke to two lines, the note under it to two more, and the
     text block grew tall enough to push the pack into it — the same collapse
     the desktop grid had, arriving from the other end. One full-width row per
     family gives every name one line, puts the pack, the name, the note and
     the price on one horizontal read, and is shorter than the grid it
     replaces because nothing wraps. */
  .fam-grid { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .fam, .fam[data-wide] {
    grid-column: auto;
    min-height: 104px;
    padding: 10px 16px 10px 10px;
    border-radius: 18px;
    column-gap: 14px;
  }
  /* Five identical rows on a phone: the lead's reversal is a two-column
     gesture and there is one column here. */
  .fam[data-wide] { grid-template-columns: auto minmax(0, 1fr); }
  .fam[data-wide] .fam-pack { grid-column: 1; grid-row: 1; }
  .fam[data-wide] .fam-txt { grid-column: 2; grid-row: 1; }
  .fam[data-wide] .fam-plate { background: none; }
  .fam-pack, .fam[data-wide] .fam-pack { height: 84px; max-width: 88px; }
  .fam-label, .fam[data-wide] .fam-label { font-size: 19px; }
  .fam-note, .fam[data-wide] .fam-note { font-size: 12px; }
  .fam-txt { gap: 2px; }
  .fam-from { margin-top: 7px; font-size: 12px; padding: 5px 10px; }

  .shelf-tools { gap: 10px; }
  /* THE FILTER ROW WRAPS ON A PHONE. IT DOES NOT SCROLL.

     It used to be an edge-to-edge horizontal scroller, which is the native
     shape for a filter bar and also the shape in which three of eight options
     are invisible until somebody guesses that the row moves. A cut-off chip at
     the right edge is a hint, not an affordance, and the two options a shopper
     is most likely to be filtering FOR here — Stimulánsmentes and Tejmentes,
     the constraint filters — were the two furthest off screen.

     Wrapped, every option is on the screen and every option is a 44px target.
     It costs a third row of chips, and the products section gave back four
     times that by becoming a sample. */
  .facets {
    flex-wrap: wrap;
    overflow: visible;
    width: auto;
    margin-left: 0;
    padding: 0;
    gap: 7px;
  }
  .facet { min-height: 44px; font-size: 13px; padding: 0 12px; gap: 7px; }
  .facets-lead {
    display: block;
    margin: 0 0 9px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #5A473F;
  }
  /* The sort is a listing control. Over four cards there is nothing to
     re-order, and the number it sorts on is printed on every card anyway. */
  .sorts { display: none; }

  .renew-sec { margin-top: 60px; }
  .renew { padding: 30px 20px 28px; gap: 24px; }
  /* One line for "Egyszeri vásárlás" beside a 6.6em key and a price, at 390. */
  .renew-opt { font-size: 13px; padding-inline: 13px; gap: 9px; }
  .renew-opt-k { font-size: 9.5px; letter-spacing: 0.07em; }
  .renew-lede { font-size: 14px; }
  .renew-facts > li { font-size: 13px; }

}

/* ── the page's vertical rhythm ───────────────────────────────────────────
   The products section is one thing now — a heading, its controls and a grid —
   so the internal gaps that used to hold a staged product apart from a shelf
   are gone with it. What is left is the distance between sections.

   ONE EXCEPTION, AND IT IS THE TOP OF THE PAGE. `.floor-sec` used to carry the
   same 92px as everything else, which put a strip of bare cream between the
   cocoa maker band and the products field's own 3px cocoa rule: two heavy
   horizontals ninety pixels apart with nothing between them, so the rule read
   as a divider somebody had left behind rather than as the top edge of a
   surface. The products field meets the band instead, and the field's 62px of
   internal padding is the breath — which is what it was already there for.

   The effect is that the first three things a shopper meets — the hero, the
   makers who supply it and the shelf itself — read as one connected block, and
   the 88px rhythm starts below them, where the page turns into chapters. */
.floor-sec { margin-top: 0; }
.shelf { margin-top: 0; }
.sec { margin-top: 88px; }

@media (max-width: 640px) {
  .sec { margin-top: 54px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   THE PHONE FAQ IS A DIFFERENT COMPOSITION, not the desktop one stacked.

   Stacked, it ran: a two-line display heading, then a 480px order card, then
   the four questions — so on the one section whose entire job is answering a
   question, the questions started 600px below the heading and nobody scrolling
   past ever saw one. The section measured 1 053px on a 390 screen, the tallest
   thing on the page after the footer, for four sentences and five facts.

   Three changes, and the first two are the composition:

   1 · THE ORDER IS THE QUESTIONS FIRST. `.qa-side` dissolves with
       `display: contents`, which hands its heading and its card to the section
       grid as real children, and the three are placed explicitly: heading,
       accordion, facts. A shopper who opened a FAQ gets a FAQ.

   2 · THE FACTS CARD IS A LIST AGAIN, not a stack of stacked pairs. Each row
       stacked its value under its key because the value would not fit beside
       a 14px display key at 390 — so five facts cost ten lines and 480px. The
       key drops two points and the value one, both stay above the contrast
       floor, and the whole card comes in at about 320.

   3 · The heading sets on one line. `Gyakori kérdések` is sixteen characters
       and the markup's line break was written for a narrow desktop column.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  .qa { grid-template-columns: minmax(0, 1fr); }
  .qa-side { display: contents; }
  .qa-title { order: 1; margin-bottom: 20px; }
  .qa-title br { display: none; }
  .faq { order: 2; }
  .qa-side .label-card {
    order: 3;
    margin-top: 26px;
    transform: rotate(-0.8deg);
  }

  .label-card { padding: 18px 18px 20px; }
  .label-rows > li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 7px 0;
  }
  .label-k { font-size: 12px; }
  .label-v { font-size: 12px; text-align: right; }
  .label-v[data-ok]::before { flex-basis: 13px; width: 13px; height: 13px; -webkit-mask-size: 13px 13px; mask-size: 13px 13px; }
  .label-rows > li:has(.label-v a) { padding-block: 0; }
  /* 44, not 42. The phone card tightens every row, and this one carries the
     only three routes in the block; two pixels is not worth failing the rule
     the rest of the page keeps. */
  .label-v a { min-height: 44px; }
  .label-card-foot { margin-top: 10px; padding-top: 10px; font-size: 11.5px; }
}
