/* ===========================================================================
   CE-48 · Usługi – karty nachodzące (stacking service cards)
   Root:     section.ce-svc-stack – the offer of Usługi, one card per service
   Parts:    __alias (empty span with an old id of the whole offer, e.g.
             #uslugi-zakladki – data-alias-of="oferta"),
             __list (the cards' common parent – the sticky range),
             __card (article, one category – Usługi v6.1: five cards; id =
             the category's anchor, data-num / data-name for the dialog's
             link back, CE-50; sticky from 901 px),
             __anchor (empty span with an old id, e.g. #obszar-02 – links
             from Home and the case studies still land on the right card;
             data-alias-of = the card),
             __shade (the darkening layer over a covered card),
             __in (.lf-wrap; the 1 px line on top of every card but the
             first), __row (number · text · picture), __num („(01)”),
             __text, __title (H2, kit „chars”), __lead, __items (ul of the
             card's services, a line under each; v6.1: __item – the row,
             __link – a link to the service's dialog whose hit area is the
             whole row, a drawn „+” at its right end, span.ai-tag of the kit
             after the link), __media (the picture box), __frame (the clip
             and the corners), __img, __services (the descriptions of the
             card's services – CE-50 articles, hidden until a dialog or
             Ctrl+F shows one; also .ce-svc-popup__list)
   Variants: none
   Mechanics: ce/CE-48-service-stack.js sets two numbers per card, both
             computed from the scroll position on every scroll and resize
             (no rAF – works in the app's preview and with the kit's smooth
             wheel scroll, which scrolls natively):
               --in  0 → 1 while the card rises from the bottom of the
                     window to its sticky place (smoothstep);
               --out 0 → 1 while the next card slides over it (the part of
                     the card that is covered, linear).
             From 901 px every card is sticky under the header (top =
             --header-h; if a card is taller than the window minus the
             header, the script sets .is-flat and nothing sticks – see
             Layout), full window height, white; the next card comes
             up over it and the covered one darkens (#1D1D1E, up to 40%) and
             shrinks to 94% from its top edge, its corners rounding to
             12 px. The picture grows and moves with --in: from 320 × 239 at
             the top right of the row (Figma 608:1699 … 608:1791) to
             480 × 300 at its bottom right (608:1676) – a clip-path on the
             frame and the frame's `top` – while the photo in it settles
             from 1.15 to 1.
             Measured 27.09 on wearemotto.com/services (1024 × 768, the
             page's GSAP ScrollTrigger read from main.js and confirmed at 6
             scroll points): four cards, position sticky top 0, min-height
             100vh, #F2F2F2, 1 px #CFD5D7 on top, no corners; per card a
             timeline scrubbed from „bottom bottom” to „bottom top” (one
             window of scroll), linear: the black layer (#1B1B1C) 0 → .5
             and the card yPercent 0 → −60 (it drifts up at 60% of the
             scroll); only from 650 px. Here: a lighter darkening (0 → .4, linear,
             over the covering – Mateusz: „delikatnie się przyciemnia”), but instead of the drift up –
             which would push the card under our transparent 72 px header –
             a scale to .94 from the top edge (Mateusz's brief: „lekko się
             pomniejsza”), and the card sticks under the header, not at 0.
             ≤ 900 px: no stacking (one column, the cards follow each other,
             104 px apart), the picture under the list is uncovered from
             the top down with --in (the same script) and settles from 1.1.
             prefers-reduced-motion: no stacking, no darkening, pictures at
             rest in their final size. Without JavaScript (no html.cr-js,
             v6.1): no stacking – the descriptions of the services stand
             open in their cards, and a sticky card taller than the window
             would hide its lower part under the next one.
             Anchors (v6.1): a link or an address pointing at a card (or at
             an old anchor of one) lands with the card in its sticky place
             under the header – the script computes the card's place in
             the flow (a sticky card's own box moves with the scroll).
             Keyboard (01.10): a focus that lands in a card the next one
             covers (Shift+Tab from card 02 to the last item of card 01)
             brings that card back to its place under the header, so the
             focus is never hidden (WCAG 2.4.11).
   Layout:   Figma crear-v2.0, frame 608:1669 (1440 px): number column
             224 px (13 px Expanded Regular #778181 at .8), 8 px, text column
             640 px: H2 40 px Expanded Regular (line 1.22, −1.6 px, #1D1D1E),
             20 px, lead 20 px TT Hoves Pro Regular (line 1.4, −0.2 px,
             #0A2526), 56 px, six items 20 px Medium (#0A2526), each with a
             1 px #EBEBEB line 16 px under it and 16 px to the next item;
             the picture at the right edge, corners 8 px. 1 px of the design
             = min(1 px, content width / 1300), so at 1440 px (1340 px
             between the 50 px margins) the text and the picture are 1:1 and
             the number column takes what is left (164 px instead of 224 –
             measured, the H2 at x 222); type floors 28 / 17 / 16 px.
             From 901 px the section has no bottom padding (the last card's
             own white, a window high, is the gap to the next section –
             01.10: 577 px of white before) and 120 instead of 160 on top
             (the first card's 40 px inner padding adds up to the 160 of
             the design between the video and „(01)”).
             Short windows (≤ 820 px high, stacking): a compact rhythm –
             24 / 48 px inner padding, 32 px to the list, 10 px between
             items – so a card fits under the header (01.10: at 1366 × 650
             the H2 of card 01 stood above the window). Should a card still
             be taller than the window minus the header, the script puts
             .is-flat on the section: no sticking, no covering – the cards
             simply follow each other (a card stuck with a negative top hid
             its own heading).
   Base:     uslugi.html#oferta · registry: CE-48 (retired 30.09, back on
             Usługi 01.10 – v6.1)
   =========================================================================== */

.ce-svc-stack {
  --sv-u: min(1px, (100vw - 2 * var(--gut)) / 1300);
  --sv-num: clamp(0px, 100vw - 2 * var(--gut) - 1176 * var(--sv-u), 224 * var(--sv-u));   /* 1176 = 8 + 640 + 8 + 40 (the least gap) + 480 */
  --sv-text: calc(640 * var(--sv-u));
  --sv-img-w: calc(480 * var(--sv-u));   /* the picture at rest (card 01) */
  --sv-img-h: calc(300 * var(--sv-u));
  --sv-img-w0: calc(320 * var(--sv-u));  /* the picture coming in (cards 02–06) */
  --sv-img-h0: calc(239 * var(--sv-u));
  --sv-line: #ebebeb;
  --sv-shade: #1d1d1e;
  --sv-shade-max: .4;                    /* wearemotto.com: .5 of #1B1B1C; here .4 – „delikatnie” */
  --sv-shrink: .06;                      /* scale 1 → .94 while covered */
  --sv-round: 12px;
  --sv-item-gap: max(12px, calc(16 * var(--sv-u)));   /* line under an item, and to the next one */

  padding-top: clamp(80px, calc(160 * var(--sv-u)), 160px);
}

.ce-svc-stack__list { position: relative; }

.ce-svc-stack__card {
  --in: 1;                               /* the script sets both; these are the resting values */
  --out: 0;
  --e: var(--in);
  position: relative;
  background: #fff;
  scroll-margin-top: var(--header-h);    /* an anchor lands with the card in its sticky place */
}

/* an old anchor (#obszar-NN) at the top edge of its card */
.ce-svc-stack__anchor {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  scroll-margin-top: var(--header-h);
  pointer-events: none;
}

.ce-svc-stack__shade {
  position: absolute;
  inset: 0;
  z-index: 3;
  background: var(--sv-shade);
  opacity: calc(var(--sv-shade-max) * var(--out));
  pointer-events: none;
}

.ce-svc-stack__in {
  position: relative;
  padding-top: calc(40 * var(--sv-u));
  padding-bottom: calc(104 * var(--sv-u));
  border-top: 1px solid var(--sv-line);
}
.ce-svc-stack__card:first-child .ce-svc-stack__in { border-top-color: transparent; }   /* hidden in Figma (608:1677) */

.ce-svc-stack__row {
  position: relative;
  display: grid;
  grid-template-columns: var(--sv-num) var(--sv-text) minmax(0, 1fr);
  column-gap: calc(8 * var(--sv-u));
  align-items: start;
}

.ce-svc-stack__num {
  margin: 0;
  font-family: var(--font-heading);
  font-size: max(11px, calc(13 * var(--sv-u)));
  font-weight: 400;
  line-height: normal;
  color: rgba(119, 129, 129, .8);        /* #778181 at .8 */
  font-variant-numeric: tabular-nums;
}

.ce-svc-stack__text { min-width: 0; }

.ce-svc-stack__title {
  margin: 0;
  font-family: var(--font-heading);
  font-size: max(28px, calc(40 * var(--sv-u)));
  font-weight: 400;
  line-height: 1.22;
  letter-spacing: -.04em;                /* −1.6 px at 40 px */
  color: var(--ui-ink);
  text-wrap: balance;
}

.ce-svc-stack__lead {
  margin: calc(20 * var(--sv-u)) 0 0;
  font-family: var(--font-body);
  font-size: max(17px, calc(20 * var(--sv-u)));
  line-height: 1.4;
  letter-spacing: -.01em;                /* −0.2 px at 20 px */
  color: var(--ui-text);
  text-wrap: pretty;
}

.ce-svc-stack__items {
  margin: calc(56 * var(--sv-u)) 0 0;
  padding: 0;
  list-style: none;
}
.ce-svc-stack__items > li {
  padding-bottom: var(--sv-item-gap);
  border-bottom: 1px solid var(--sv-line);
  font-family: var(--font-body);
  font-size: max(16px, calc(20 * var(--sv-u)));
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -.01em;
  color: var(--ui-text);
}
.ce-svc-stack__items > li + li { margin-top: var(--sv-item-gap); }

/* The picture: a 480 × 300 frame that stands at the top right of the row
   while the card comes in and at its bottom right once the card is in
   place; the clip shows only its top-right 320 × 239 at first. */
.ce-svc-stack__media {
  position: relative;
  align-self: stretch;
  margin: 0;
}
.ce-svc-stack__frame {
  position: absolute;
  right: 0;
  top: calc(var(--e) * (100% - var(--sv-img-h)));
  width: var(--sv-img-w);
  height: var(--sv-img-h);
  overflow: hidden;
  border-radius: 8px;
  clip-path: inset(0 0 calc((1 - var(--e)) * (var(--sv-img-h) - var(--sv-img-h0))) calc((1 - var(--e)) * (var(--sv-img-w) - var(--sv-img-w0))) round 8px);
  background: var(--ui-soft, #f4f4f4);
}
.ce-svc-stack__img {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: var(--sv-pos, 50% 50%);
  transform-origin: 100% 0;
  scale: calc(1 + .15 * (1 - var(--e)));
}

/* ---- the list items: links to the dialogs (v6.1) ---------------------------
   The whole row answers the click (the link's ::before covers it), the
   AI marker of the kit stays outside the link, right after the name; a
   drawn „+” (two 1.2 px strokes, as the FAQ's) at the right end turns a
   quarter on hover and on focus, the name gets the kit's hover line. */
.ce-svc-stack__item {
  position: relative;
  padding-right: 28px;                   /* room for the „+” */
}
.ce-svc-stack__link {
  color: inherit;
  text-decoration: none;
}
.ce-svc-stack__link::before {            /* the hit area: the whole row */
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
.ce-svc-stack__link:focus-visible { outline: none; }
.ce-svc-stack__item:has(> .ce-svc-stack__link:focus-visible) { outline: 2px solid var(--ui-ink); outline-offset: 4px; border-radius: 2px; }
.ce-svc-stack__item::before,
.ce-svc-stack__item::after {
  content: "";
  position: absolute;
  right: 4px;
  top: calc(50% - .5 * var(--sv-item-gap) - .6px);   /* the middle of the text line */
  width: 12px;
  height: 1.2px;
  background: var(--ui-ink);
  transition: transform .35s var(--ease-out-quart), opacity .2s ease;
}
.ce-svc-stack__item::after { transform: rotate(90deg); }
.ce-svc-stack__item:hover::before,
.ce-svc-stack__item:has(> .ce-svc-stack__link:focus-visible)::before { transform: rotate(90deg); }
.ce-svc-stack__item:hover::after,
.ce-svc-stack__item:has(> .ce-svc-stack__link:focus-visible)::after { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
  .ce-svc-stack__item::before,
  .ce-svc-stack__item::after { transition: none; }
}
/* the kit's AI marker after a name: a word space from it (the kit's .22em
   let it touch „(SaaS)” – copy, „Do potwierdzenia” pkt 12) */
.ce-svc-stack__item .ai-tag { margin-left: .4em; }

/* the descriptions of the card's services (CE-50 articles): hidden until
   the dialog takes one or Ctrl+F shows one here – then under the row, in
   the text column */
.ce-svc-stack__services {
  margin-left: calc(var(--sv-num) + 8 * var(--sv-u));
  max-width: var(--sv-text);
}

/* the old anchors of the whole offer, at its top */
.ce-svc-stack__alias {
  display: block;
  width: 1px;
  height: 0;
  scroll-margin-top: var(--header-h);
}

/* ---- stacking: from 901 px, with motion allowed ---------------------------- */
@media (min-width: 901px) and (prefers-reduced-motion: no-preference) {
  .ce-svc-stack {
    padding-top: calc(120 * var(--sv-u));   /* + 40 inside the first card = 160 to „(01)” */
    padding-bottom: 0;                    /* the last card's white is the gap */
  }
  .cr-js .ce-svc-stack__card {
    position: sticky;
    top: var(--header-h);
    min-height: calc(100svh - var(--header-h));
    transform-origin: 50% 0;
    transform: scale(calc(1 - var(--sv-shrink) * var(--out)));
    border-radius: calc(var(--sv-round) * var(--out));
    overflow: clip;                      /* the corners and the shade */
  }
  /* a card taller than the window minus the header (the script): no
     sticking and no covering for the whole section */
  .ce-svc-stack.is-flat { padding-bottom: var(--sp-sec); }
  .cr-js .ce-svc-stack.is-flat .ce-svc-stack__card {
    position: relative;
    top: auto;
    min-height: 0;
    transform: none;
    border-radius: 0;
  }
  .ce-svc-stack.is-flat .ce-svc-stack__shade { opacity: 0; }
}
/* short windows: a compact rhythm, so a card fits under the header */
@media (min-width: 901px) and (max-height: 820px) and (prefers-reduced-motion: no-preference) {
  .ce-svc-stack { --sv-item-gap: 10px; }
  .ce-svc-stack__in {
    padding-top: calc(24 * var(--sv-u));
    padding-bottom: calc(48 * var(--sv-u));
  }
  .ce-svc-stack__items { margin-top: calc(32 * var(--sv-u)); }
}

/* ---- one column ------------------------------------------------------------- */
@media (max-width: 900px) {
  .ce-svc-stack { padding-top: clamp(64px, 12vw, 104px); }
  .ce-svc-stack__in { padding-top: 32px; padding-bottom: 72px; }
  .ce-svc-stack__row {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 16px;
  }
  .ce-svc-stack__lead { margin-top: 16px; }
  .ce-svc-stack__items { margin-top: 32px; }
  .ce-svc-stack__media { margin-top: 24px; }
  .ce-svc-stack__services { margin-left: 0; max-width: none; }   /* a description found by Ctrl+F (or without JS): the whole column */
  .ce-svc-stack__frame {
    position: relative;
    top: auto;
    right: auto;
    width: 100%;
    height: auto;
    aspect-ratio: 480 / 300;
    /* uncovered from the top down (--in: the script, from the picture's
       own position in the window) */
    clip-path: inset(0 0 calc((1 - var(--e)) * 100%) 0 round 8px);
  }
  .ce-svc-stack__img {
    transform-origin: 50% 0;
    scale: calc(1 + .1 * (1 - var(--e)));
  }
}

@media (prefers-reduced-motion: reduce) {
  .ce-svc-stack__card { --in: 1 !important; --out: 0 !important; }
}
