@layer sections {
  /* Flavour slider and nutrition table (PROD-03, PROD-04, D4-07, D4-08, L-0025). A CSS
     scroll-snap track: without JS it is a native swipe/scroll carousel; slider.js unhides the
     arrows and dots, keeps aria-current / aria-disabled in sync and sets --media-mid (the current
     media-box centre) on .slider, which places the arrows and the dots below 1024 px.

     Geometry is the Figma "SLIDER" frame of each product line, pixel for pixel (L-0052): the
     .slider box is that frame (its top padding is the frame's space above the title, its bottom
     padding the space under the table). The three lines were drawn with small differences, so
     the line layout modifier (slider--image_left = protein, --image_right = nut, --image_center
     = chocolate) sets them through the custom properties below. Mobile values first (375 px
     frame), desktop ones from 1024 px (1280 px frame). Only the first slide is drawn in Figma;
     the other slides repeat its layout (D-12). */

  .slider {
    /* Figma #ffffff @ 70 % behind the dots. */
    --sl-dots-bg: rgb(255 255 255 / 0.7);
    /* Mobile: tastes grid bottom → frame top, frame top → title, table bottom → frame bottom. */
    --sl-gap: 100px;
    --sl-pad-top: 0px;
    --sl-pad-bottom: 57px;
    /* Media drawn above the title top: the slides start that much higher inside the viewport
       (which clips on y) and pad it back, so the title stays put and the image is not cut. */
    --sl-rise: 0px;
    --sl-sub-font: var(--font);
    /* Subtitle → media box; media box 263 × 280 (the dots hang 10 px under it). Below 359 px
       the box narrows to stay 8 px clear of the arrows (Figma only draws 375). */
    --sl-media-gap: 13px;
    --media-w: min(263px, 100vw - 2 * var(--gutter) - 56px);
    --media-h: calc(var(--media-w) * 280 / 263);
    --sl-table-gap: 36px;
    /* Nutrition table: header type and its top inset (Chrome floors the half-leading of a
       10/14 line, Figma rounds it up), cell paddings of the two row groups (the 1 px rule under
       each group comes on top), second column inset. */
    --nt-head-fs: 10px;
    --nt-head-lh: 14px;
    --nt-head-pt: 1px;
    --nt-g1-pt: 6px;
    --nt-g1-pb: 12px;
    --nt-g2-pt: 12px;
    --nt-g2-pb: 14px;
    --nt-col2-pad: 0px;
    position: relative;
    margin-top: var(--sl-gap);
    padding-block: var(--sl-pad-top) var(--sl-pad-bottom);
    /* Card → slide jumps land the slide title 24 px below the top edge. */
    scroll-margin-top: calc(24px - var(--sl-pad-top) - var(--sl-rise));
  }

  .slider--image_left {
    --sl-gap: 45px;
    --sl-pad-top: 59px;
    --sl-pad-bottom: 51px;
    --sl-sub-font: var(--font-alt);
    --nt-g1-pt: 10px;
    --nt-g1-pb: 9px;
    --nt-g2-pt: 10px;
    --nt-g2-pb: 9px;
    --nt-col2-pad: 2px;
  }

  .slider--image_right {
    --sl-gap: 103px;
    --sl-pad-bottom: 70px;
    --sl-media-gap: 8px;
    --nt-g2-pt: 10px;
  }

  /* Chocolate: the Figma table frame ends 12 px under its last rule. */
  .slider--image_center {
    --sl-pad-bottom: 69px;
    --nt-head-fs: 11px;
    --nt-head-lh: 15px;
    --nt-head-pt: 0px;
  }

  /* --- Track --- */
  /* Below 1024 the viewport bleeds into the page gutters and every slide pads them back, so
     text that Figma lets overhang its box (the 11 px table header) is not clipped. */
  .slider__viewport {
    margin-inline: calc(-1 * var(--gutter));
    overflow-x: auto;
    /* The slides hidden by slider.js (`inert`) overhang the active one; clip, never scroll. */
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    scroll-padding: 0;
  }

  .slider__viewport::-webkit-scrollbar {
    display: none;
  }

  .slider__viewport:focus-visible {
    outline: 2px solid var(--c-black);
    outline-offset: 2px;
  }

  .slider__track {
    display: flex;
    align-items: flex-start;
    margin: 0;
    padding: 0;
  }

  .slide {
    flex: 0 0 100%;
    min-width: 0;
    padding-top: var(--sl-rise);
    padding-inline: var(--gutter);
    scroll-snap-align: start;
    scroll-snap-stop: always;
    /* A fragment jump (#slide, a reload after a card click) lands the title 24 px down. */
    scroll-margin-top: calc(24px - var(--sl-rise));
  }

  /* The active slide alone sets the slider height, as the Figma frame does for the drawn one:
     slider.js marks every other slide `inert`, and a large negative bottom margin takes them out
     of the track's height. Without the script no slide is inert and the track keeps the tallest.
     On a slide change slider.js eases the viewport from the old height to the new one (300 ms,
     none with reduced motion), and the arrows and dots below 1024 ease their `top` with it. */
  .slide[inert] {
    margin-bottom: -9999px;
  }

  /* Programmatic focus after a card click: the live region announces the change. */
  .slide:focus {
    outline: none;
  }

  /* --- Slide head (Figma "Frame 47": 280 px box, gap 15) --- */
  .slide__head {
    width: 280px;
    max-width: 100%;
    margin-inline: auto;
    text-align: center;
  }

  /* Figma centres a letter-spaced line without the spacing after its last letter; the negative
     end margin takes that trailing spacing out of the centring. */
  .slide__title {
    margin-inline-end: -2px;
    font-family: var(--font-alt);
    font-size: 20px;
    line-height: 28px;
    font-weight: 400;
    letter-spacing: 2px;
    text-transform: uppercase;
    overflow-wrap: anywhere;
  }

  .slide__sub {
    margin-top: 15px;
    font-family: var(--sl-sub-font);
    font-size: 12px;
    line-height: 17px;
    font-weight: 400;
    text-transform: uppercase;
  }

  /* The --font-alt 12/17 line sets its baseline 1 px higher in Chrome than in Figma. */
  .slider--image_left .slide__sub {
    position: relative;
    top: 1px;
  }

  .slide__info {
    min-width: 0;
    /* Media bottom → dots (10) → dots bar (20) → composition (34). */
    margin-top: 64px;
  }

  /* No image at all: one centred column at the narrow measure on every breakpoint. */
  .slide__body--no-media .slide__info {
    width: 100%;
    max-width: var(--container-narrow);
    margin-inline: auto;
    margin-top: var(--space-5);
  }

  /* --- Media (Figma "image 3": 263 × 280, centred) --- */
  .slide__media {
    position: relative;
    width: var(--media-w);
    max-width: 100%;
    aspect-ratio: 263 / 280;
    margin: var(--sl-media-gap) auto 0;
  }

  .slide__img,
  .slide__img img {
    display: block;
    width: 100%;
    height: 100%;
  }

  .slide__img img {
    object-fit: contain;
    object-position: 50% 50%;
  }

  /* Show box + pack (Figma "IMG" group 257.7 × 234, centred 23 px down in the media box):
     box 169.7 px at (18.3, 23), pack 150 px at (126, 47) on top of it. */
  .slide__media--pair .slide__img,
  .slide__media--pair .slide__img img {
    height: auto;
  }

  .slide__media--pair .slide__img {
    position: absolute;
    top: 8.2143%;
    left: 6.9544%;
    width: 64.5323%;
  }

  .slide__media--pair .slide__img--2 {
    top: 16.7857%;
    left: 47.9087%;
    width: 57.0342%;
    z-index: 1;
  }

  /* --- Composition (Montserrat 14/20: Figma overrides the box font on every character) --- */
  .slide__composition {
    font-size: 14px;
    line-height: 20px;
    font-weight: 400;
    overflow-wrap: anywhere;
  }

  .slide__composition :is(strong, b) {
    font-weight: 700;
  }

  .slide__composition p + p {
    margin-top: var(--space-2);
  }

  .slide__composition + .nutrition {
    margin-top: var(--sl-table-gap);
  }

  /* --- Arrows (Figma 30 px circles at x 10 / 335, 98 px below the media top) --- */
  .slider__arrow {
    --arrow-bg: var(--c-black);
    --arrow-press: 0.96;
    position: absolute;
    top: calc(var(--media-mid, 50%) - 27px);
    translate: 0 -50%;
    z-index: 2;
    transition: top 300ms ease;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--c-white);
    cursor: pointer;
  }

  .slider__arrow[hidden] {
    display: none;
  }

  /* The visible circle: 30 px inside the 44 px hit box below 1024, the whole 48 px box above. */
  .slider__arrow::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 30px;
    height: 30px;
    translate: -50% -50%;
    border-radius: 50%;
    background: var(--arrow-bg);
    transition: background-color 150ms ease;
  }

  /* Figma chevrons: 6.875 × 12.5, strokes 1.5 (left) / 1.7 (right) px, set off-centre. The
     11 × 20 viewBox is drawn at 0.625, so the stroke widths are in viewBox units. Chrome renders
     such thin strokes lighter than Figma: 1.7 / 1.875 px match the Figma ink on 2x crops. */
  .slider__arrow svg {
    position: relative;
    width: 6.875px;
    height: 12.5px;
    stroke-width: 2.72;
    translate: -1px 0;
  }

  .slider__arrow--next svg {
    stroke-width: 3;
    translate: 1.5px 0;
  }

  .slider__arrow--prev {
    left: -17px;
  }

  .slider__arrow--next {
    right: -17px;
  }

  @media (hover: hover) {
    .slider__arrow:not([aria-disabled="true"]):hover {
      --arrow-bg: var(--c-ink);
    }
  }

  /* Below 1024 the 44 px hit box hangs 3 px from the screen edge: the ring goes inside it,
     around the 30 px circle, so it is never cut off. */
  .slider__arrow:focus-visible {
    outline: 2px solid var(--c-black);
    outline-offset: -4px;
    box-shadow: 0 0 0 3px var(--c-white);
  }

  .slider__arrow:active {
    transform: scale(var(--arrow-press));
  }

  /* First / last slide: no looping. Not `disabled`, so focus is not lost. Figma draws the prev
     arrow of the first slide black like the next one (L-0052 over the grey UI-SPEC state), so an
     end arrow keeps its colour and only loses the pointer, hover and press feedback. */
  .slider__arrow[aria-disabled="true"] {
    --arrow-press: 1;
    cursor: default;
  }

  /* --- Dots (Figma "DOTS' BAR": 20 px pill, 8 px dots every 16 px) --- */
  /* <1024 the dots sit 10 px under the fixed-size media box (slider.js sets --media-mid on
     every slide change); .slide__info leaves their row. A slide without media drops
     --media-mid, `top` falls back to auto and the dots keep their static place after the
     viewport. */
  .slider__dots {
    position: absolute;
    top: calc(var(--media-mid) + var(--media-h) / 2 + 10px);
    inset-inline: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    width: fit-content;
    max-width: 100%;
    min-height: 20px;
    margin-inline: auto;
    padding-inline: 4px;
    border-radius: 15px;
    background: var(--sl-dots-bg);
    transition: top 300ms ease;
  }

  .slider__dots[hidden] {
    display: none;
  }

  /* The arrows (44 / 48 px) do the same job, so the dots may stay 16 × 20 (WCAG 2.5.8). */
  .slider__dot {
    display: grid;
    place-items: center;
    width: 16px;
    height: 20px;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
  }

  .slider__dot::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--c-dot);
  }

  .slider__dot[aria-current="true"]::before {
    background: var(--c-black);
  }

  @media (hover: hover) {
    .slider__dot:not([aria-current="true"]):hover::before {
      background: var(--c-muted);
    }
  }

  .slider__dot:focus-visible {
    outline: 2px solid var(--c-black);
    outline-offset: 2px;
    border-radius: 50%;
  }

  @media (prefers-reduced-motion: reduce) {
    .slider__arrow {
      --arrow-press: 1;
    }

    .slider__arrow,
    .slider__arrow::before,
    .slider__dots {
      transition: none;
    }
  }

  /* --- Nutrition table (Figma "TABLE ALL") --- */
  /* Three fixed columns (mobile 210 / 70 / 55), text set at the top of each row group, a 1 px
     rule under the header and under each group. Figma lists the «З них …» rows flush with the
     others (no indent). Values never wrap; a value or header wider than its column overhangs
     to the right, as in Figma. */
  .nutrition {
    width: 100%;
    table-layout: fixed;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 11px;
    line-height: 14px;
    text-align: left;
  }

  .nutrition th,
  .nutrition td {
    box-sizing: border-box;
    padding: 0;
    font-weight: 400;
    text-align: left;
    vertical-align: top;
  }

  .nutrition thead th {
    font-size: var(--nt-head-fs);
    line-height: var(--nt-head-lh);
    font-weight: 700;
    padding-top: var(--nt-head-pt);
    padding-bottom: calc(27px - var(--nt-head-lh) - var(--nt-head-pt));
    border-bottom: 1px solid var(--c-black);
  }

  /* Below the 375 px Figma frame the label column (155 px at 320) keeps 12 px clear of the values:
     a header or row label that would run into "per 100 g" or its number wraps instead. Scoped so
     375+ (Figma) and the 1024 desktop columns, where the title fits on one line, never wrap. */
  @media (max-width: 374.98px) {
    .nutrition thead th:first-child,
    .nutrition tbody :is(th, td):first-child {
      padding-inline-end: 12px;
    }
  }

  .nutrition :is(th, td):nth-child(n + 2) {
    white-space: nowrap;
  }

  .nutrition :is(th, td):nth-child(2) {
    width: 70px;
    padding-inline-start: var(--nt-col2-pad);
  }

  .nutrition :is(th, td):nth-child(3) {
    width: 55px;
  }

  .nutrition__group tr:first-child > * {
    padding-top: var(--nt-g1-pt);
  }

  .nutrition__group tr:last-child > * {
    padding-bottom: var(--nt-g1-pb);
    border-bottom: 1px solid var(--c-black);
  }

  .nutrition__group + .nutrition__group tr:first-child > * {
    padding-top: var(--nt-g2-pt);
  }

  .nutrition__group + .nutrition__group tr:last-child > * {
    padding-bottom: var(--nt-g2-pb);
  }

  /* --- Tablet (>=768 px): the phone layout, info at the narrow measure --- */
  @media (min-width: 768px) {
    .slide__info {
      width: 100%;
      max-width: var(--container-narrow);
      margin-inline: auto;
    }
  }

  /* --- Desktop and wide (>=1024 px): Figma 1280 frame, a 1200 px slider at x 40 --- */
  @media (min-width: 1024px) {
    .slider {
      /* Grid bottom → frame top, frame top → title (60), dots bottom → frame bottom. */
      --sl-gap: 93px;
      --sl-pad-top: 60px;
      --sl-pad-bottom: 82px;
      --sl-sub-fs: 14px;
      --sl-sub-lh: 20px;
      --sl-sub-gap: 12px;
      /* Media box, its offset from the title top and its distance to the info column. */
      --sl-media-w: 396px;
      --sl-media-ratio: 396 / 401;
      --sl-media-dy: 43px;
      --sl-media-dx: 97px;
      /* Header bottom → composition, composition → table, slide bottom → dots. */
      --sl-info-gap: 48px;
      --sl-table-gap: 35px;
      --sl-dots-gap: 44px;
      --nt-head-fs: 13px;
      --nt-head-lh: 18px;
      --nt-head-pt: 0px;
      --nt-g1-pt: 6px;
      --nt-g1-pb: 7px;
      --nt-g2-pt: 8px;
      --nt-g2-pb: 8px;
      --nt-col2-pad: 10px;
      width: min(100% - 80px, 1200px);
    }

    /* The protein image starts 10 px above the title (frame y 50 vs 60). */
    .slider--image_left {
      --sl-gap: 81px;
      --sl-pad-top: 50px;
      --sl-rise: 10px;
      --sl-pad-bottom: 42px;
      --sl-sub-fs: 15px;
      --sl-sub-lh: 21px;
      --sl-sub-gap: 11px;
      --sl-media-w: 482px;
      --sl-media-ratio: 482 / 514;
      --sl-media-dy: -10px;
      --sl-media-dx: 70px;
      --sl-info-gap: 37px;
      --sl-table-gap: 28px;
      --sl-dots-gap: 51px;
      --nt-g1-pb: 8px;
      --nt-g2-pt: 6px;
    }

    .slider--image_right {
      --sl-gap: 70px;
      --sl-pad-bottom: 42px;
      --sl-media-w: 455px;
      --sl-media-ratio: 455 / 468;
      --sl-media-dy: 20px;
      --sl-media-dx: 70px;
      --sl-info-gap: 38px;
      --sl-table-gap: 28px;
      --sl-dots-gap: 51px;
      --nt-g1-pb: 8px;
      --nt-g2-pt: 6px;
    }

    .slider__viewport {
      margin-inline: 0;
    }

    /* Columns 600 / 525 / 75 of the 1200 px frame: the head is centred over all three, the
       media is pinned to the right edge of the first (70 px before the info column at x 640)
       and starts at a fixed offset from the title top, the info fills the second; the dots
       follow the active slide. */
    .slide {
      display: grid;
      grid-template-columns: minmax(0, 600fr) minmax(0, 525fr) minmax(0, 75fr);
      grid-template-rows: auto 1fr;
      align-content: start;
      padding-inline: 0;
    }

    .slide__head {
      grid-area: 1 / 1 / 2 / -1;
      justify-self: center;
      position: relative;
      z-index: 1;
      width: auto;
    }

    .slide__title {
      margin-inline-end: -3.2px;
      font-family: var(--font);
      font-size: 32px;
      line-height: 45px;
      letter-spacing: 3.2px;
    }

    .slide__sub,
    .slider--image_left .slide__sub {
      top: 0;
      margin-top: var(--sl-sub-gap);
      font-family: var(--font);
      font-size: var(--sl-sub-fs);
      line-height: var(--sl-sub-lh);
    }

    .slide__body {
      display: contents;
    }

    .slide__media {
      grid-area: 1 / 1 / 3 / 2;
      justify-self: end;
      align-self: start;
      width: var(--sl-media-w);
      /* Never under the 48 px prev arrow (at 1280 the protein image just meets it). */
      max-width: calc(100% - var(--sl-media-dx) - 48px);
      aspect-ratio: var(--sl-media-ratio);
      margin: var(--sl-media-dy) var(--sl-media-dx) 0 0;
    }

    /* Desktop "IMG" group 396 × 401: box 274 px at (0, 0), pack 227 px at (169, 82). */
    .slide__media--pair .slide__img {
      top: 0;
      left: 0;
      width: 69.1919%;
    }

    .slide__media--pair .slide__img--2 {
      top: 20.4489%;
      left: 42.6768%;
      width: 57.3232%;
    }

    .slide__info {
      grid-area: 2 / 2 / 3 / 3;
      align-self: start;
      max-width: none;
      margin: var(--sl-info-gap) 0 0;
    }

    .slide__body--no-media .slide__info {
      grid-column: 1 / -1;
      justify-self: center;
      max-width: var(--container-narrow);
      margin-top: var(--sl-info-gap);
    }

    .slide__composition {
      font-size: 15px;
      line-height: 21px;
    }

    .slider__arrow {
      top: 296px;
      translate: none;
      width: 48px;
      height: 48px;
    }

    .slider__arrow::before {
      width: 48px;
      height: 48px;
    }

    /* Figma 1.5 px strokes, drawn at 1.6 to match its ink; the offsets put the chevron ink
       centroids on Figma's (±0.05 px, 2x crops). */
    .slider__arrow svg {
      width: 11px;
      height: 20px;
      stroke-width: 1.6;
      translate: -1.9px 0;
    }

    .slider__arrow--next svg {
      stroke-width: 1.6;
      translate: 1.9px 0;
    }

    .slider__arrow:focus-visible {
      outline-offset: 3px;
    }

    .slider__arrow--prev {
      left: 0;
    }

    .slider__arrow--next {
      right: 0;
    }

    .slider__dots {
      position: static;
      margin-top: var(--sl-dots-gap);
    }

    /* Desktop table: 290 / 113 / 100 columns (503 px), 13/17 rows, 13/18 bold header. */
    .nutrition {
      width: 503px;
      max-width: 100%;
      font-size: 13px;
      line-height: 17px;
    }

    .nutrition :is(th, td):nth-child(2) {
      width: 113px;
    }

    .nutrition :is(th, td):nth-child(3) {
      width: 100px;
      padding-inline-start: 10px;
    }
  }
}
