/* ===========================================================================
   CE-08 · Showreel
   Root:     div.ce-showreel
   Variants: scroll-zoom (Home, 24.09.2026 – Figma crear-v2.0, 608:2037 and
             608:2039): a 356 × 223 thumbnail (at a 1440 px window) in the
             bottom-right corner of the first screen, at the page margin
             and flush with the bottom edge of the window; while the page
             scrolls it grows to fill the whole window. Hover plays it. In
             its bottom-right corner (12 px in) a 40 px round button: a
             play / pause icon inside a 1 px ring that fills clockwise with
             the playback – white, mix-blend-mode difference, as in the
             design.
             statement (with scroll-zoom, Home 26.09 – Figma crear-v2.0,
             608:2100 and 801:1019): once the reel fills the window and the
             page scrolls on, a veil comes over it – #1D1D1E at 50% with a
             15 px backdrop blur and a fine grain – and a statement comes in
             as the section headings do, letter by letter (Expanded Regular
             40 px / 1.22, −1.4 px tracking, white, 1083 px wide at 1440,
             centred); then its picture slots (70 × 49, radius 12, one word
             space before them) open one after the other: a near-black
             ground in the picture's shape makes room in the text, then the
             picture is uncovered on it from left to right. On a scroll
             threshold, every time the page comes down to it; scrolled
             back up, all of it goes the other way round (round 6, 27.09);
             coming back from below it is simply there. The reel with the
             text scrolls away with the page.
             inline (with statement, Usługi v6.1 01.10 – the AI paragraph,
             Mateusz: „one paragraph on a video background, as on the home
             page … a light blur”): the same statement on a full-window
             reel that sits in the flow of the page instead of growing out
             of a thumbnail – a section of 1.75 windows whose stage (one
             window) comes up like any section, sticks for .75 of a window
             and scrolls away; the text comes .25 of a window after the
             stage has stuck. A lighter blur than on Home: 6 px (Home:
             15 px) on #1D1D1E at 62% (01.10: white text at 22 px on a
             phone needs 4.5 : 1 even on a white frame – 60% gave 4.44),
             darker under the header (80% at the top, down to 62% at
             160 px – the header's difference logo and menu were grey on
             grey on bright frames); no picture slots; no scroll hold (see
             the script). The paragraph balances its last line
             (text-wrap: pretty – „wbudowujemy.” stood alone). The veil
             stays in the accessibility tree while it is transparent (the
             paragraph is the section's only content). The button at the
             top right of the stage, under the header, at the page margin
             (01.10: at the bottom the cookie card covered it on a first
             visit – the only way to stop the film, WCAG 2.2.2). An
             address or a link to #ai (or the old #podejscie) lands .25 of
             a window into the section – the paragraph comes at once
             instead of after another 300 px of scrolling.
             base (no variant): a full-width 16:7 box (4:3 on a phone) – the
             lo-fi placeholder.
   Parts:    __alias (inline: an empty old anchor at the top),
             __stage (sticky, one window high), __box (the growing frame;
             its size and corner from --reel-w/-h/-r, set by the script),
             __video, __btn (aria-pressed), __ring (__track, __progress),
             __icon (--play, --pause); statement: __veil (the dark blurred
             layer), __say (the text; site.js kit lines .lf-rl / .lf-rl__in
             and letters .lf-ch made by CE-08-showreel.js), __tie (a word
             and its slot, never split), __slot (the opening mask; its
             ::before is the dark ground), __pic (the picture)
   States:   .is-playing on the root (the pause icon shows); statement:
             .is-shown (the veil is up), .is-said (the text is in / coming
             in; without it the way out runs), .is-settled (the way in is
             over), .is-snap (a state set without transitions),
             __say.is-lines (split into lines), __say.is-measure (slots held
             open while the lines are measured)
   Layout:   the root overlaps the hero by one window (margin-top −100svh).
             The growth waits until the hero text has moved out of the
             box's way and never lets the box within 24 px of text still on
             screen (26.09 – the video used to cover the lead): the script
             solves the start (77–120 px at 901–1920 px wide), grows the
             box over one window, holds it full for 0.3 of a window (0.5
             with the statement: 0.4 of a window of clean film, then the
             text comes and the page is held there until the text and
             pictures are in – rounds 5 and 6, 26–27.09, see the script),
             then
             the video scrolls away with the page – and sets the root's
             height to fit (2.3 windows below is the fallback without the
             script). The stage lets clicks through, except on the box.
   Base:     index.html#showreel · registry: ce-registry.js → CE-08
   =========================================================================== */

.ce-showreel { width: 100%; }

/* ---- base: lo-fi placeholder ---------------------------------------------------- */
.ce-showreel__media {
  --ratio: 16 / 7;
  font-size: var(--t-sm);
}
@media (max-width: 640px) {
  .ce-showreel__media { --ratio: 4 / 3; }
}

/* ---- scroll-zoom ------------------------------------------------------------------ */
.ce-showreel[data-ce-variant~="scroll-zoom"] {
  /* the thumbnail: 356 × 223 at 1440 px, the page margin from the right */
  --reel-w0: max(220px, 24.72vw);
  --reel-h0: calc(var(--reel-w0) * 223 / 356);
  position: relative;
  z-index: 50;                   /* over the hero, under the header (100) */
  height: 230vh;
  height: 230svh;
  margin-top: -100vh;
  margin-top: -100svh;
  pointer-events: none;
}
@media (max-width: 640px) {
  .ce-showreel[data-ce-variant~="scroll-zoom"] { --reel-w0: 45vw; }
}
.ce-showreel__stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}
.ce-showreel__box {
  position: absolute;
  right: var(--reel-r, var(--gut));
  bottom: 0;
  width: var(--reel-w, var(--reel-w0));
  height: var(--reel-h, var(--reel-h0));
  overflow: hidden;
  background: #111;
  pointer-events: auto;
  cursor: pointer;               /* a click scrolls to the full-window reel */
}
.ce-showreel__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---- play / pause with the progress ring --------------------------------------- */
.ce-showreel__btn {
  position: absolute;
  right: 12px;
  bottom: 12px;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: #fff;
  mix-blend-mode: difference;
  cursor: pointer;
}
.ce-showreel__btn > * { grid-area: 1 / 1; }
.ce-showreel__ring {
  width: 41px;
  height: 41px;
  fill: none;
  stroke: currentColor;
  transform: rotate(-90deg);     /* the ring fills from the top, clockwise */
}
.ce-showreel__track { stroke-opacity: .3; }
.ce-showreel__progress {
  stroke-dasharray: 1;
  stroke-dashoffset: var(--reel-left, 1);
}
.ce-showreel__icon {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.1;
  stroke-linejoin: round;
  stroke-linecap: round;
  transition: transform .3s var(--ease-out-expo);
}
.ce-showreel__btn:hover .ce-showreel__icon { transform: scale(1.12); }
.ce-showreel__icon--pause,
.ce-showreel.is-playing .ce-showreel__icon--play { display: none; }
.ce-showreel.is-playing .ce-showreel__icon--pause { display: block; }
.ce-showreel__btn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

/* ---- statement over the full-window reel (26.09) ----------------------------
   Figma crear-v2.0, 608:2100 (the text) and 801:1019 (the text with its
   picture slots) at 1440 × 900: veil rgba(29, 29, 30, .5) + backdrop blur
   15 px (annotation „blur + ruże ziarno”, read as a large grain – below); text TT Hoves
   Pro Expanded Regular 40 px, line height 1.22, tracking −1.4 px, white,
   x 178 / width 1083 (centred), vertically centred; slots 70 × 49, radius
   12, top 3 px under their line's top, one word space on either side
   (measured on the frame: 11 px before, 10 px after).
   Motion. The text: the kit's "chars" heading reveal (site.css .lf-rl /
   .lf-rl__in / .lf-ch and @keyframes lf-ch-flash – round 4, 26.09): the
   lines rise from 110% (ease-out-expo, one after the other), the letters
   stand at 5% white (round 5, 26.09: the first colour on a dark ground is
   #FFF at 5%; the kit had 20%) and light up one by one, each flashing
   --ui-brand and settling into white (ease-out-quart); this text holds
   still on the sticky reel, so its letters light in time (--ch-step, set
   by the script). Then the pictures: each slot opens from 0 to a word
   space + 70 px, showing the dark ground (#0E0E0F, radius 12, growing
   with it – the words behind slide on); then the picture is uncovered on
   it from left to right (clip-path); the second slot starts after the
   first. Both on easeInOutCubic (0.65, 0, 0.35, 1). Round 6 (27.09 –
   Mateusz: about 30% quicker): all the times × 0.7 – veil .42 s, lines .7
   s / 49 ms apart, letters .7 s each and .7 s all, slot .245 s, picture
   .28 s, next slot .42 s later; the whole 1.82 s (2.6 s before). Round 7
   (26.09, evening – Mateusz: quicker, both ways): all about × 0.64 again –
   veil .27 s, lines .45 s / 30 ms apart, letters .45 s each and .45 s
   all, slot .155 s, picture .18 s, next slot .27 s later; the whole
   1.165 s.
   The way out (round 6, 27.09 – Mateusz: scrolling back up, the same the
   other way round): the pictures are covered back to the left (.115 s)
   and their grounds fold (.115 s), the last one first; the letters go
   out from the last to the first (.19 s each, .255 s all), each the
   reverse of its light – back through the red to white at 5%; the veil
   with its blur fades last (.225 s) and the lines sink back under it;
   about .8 s in all (round 7; round 6: .18 / .18 / .3 / .4 / .35 s,
   about 1.25 s). The out
   times are the base rules below, the in times the .is-said rules.
   All transitions, so a turn halfway reverses from where things are:
   a letter's whole light is one number, --lit (0 unlit – 1 lit, a
   registered property, so it can be transitioned); its opacity and
   colour are drawn from it – opacity .05 → 1 over the first .15 (the
   kit's .15 s of 1 s), the red share (1 − lit)⁴, as the flash's
   ease-out-quart (.02 of a ramp at the start, so an unlit letter is
   white). A linear transition of --lit then gives the kit's flash on the
   way in and its exact reverse on the way out. The delays are set by the
   script at each turn (--say-at, --c-first, --ch-step, --slot-at,
   --pic-at; --ch-out-at, --c-last, --ch-out-step, --pic-out-at,
   --slot-out-at, --veil-out-at, --line-out-at) from the state read off
   the page; the line breaks are measured with the slots open, so the
   words never jump to another line when the slots open. .is-snap puts
   the end state (coming back from below) or a re-split without any
   transition. */
@property --lit {
  syntax: "<number>";
  inherits: false;
  initial-value: 0;
}
.ce-showreel__veil {
  --pic-ease: cubic-bezier(.65, 0, .35, 1);   /* easeInOutCubic – the slots, pictures and the way out */
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 1;
  /* the size of the full window (the script's --reel-fw / --reel-fh), not
     of the box: the text is laid out once, for the full-window reel, while
     the box is still a thumbnail; the box clips it meanwhile */
  width: var(--reel-fw, 100vw);
  height: var(--reel-fh, 100vh);
  display: grid;
  place-items: center;
  background: rgba(29, 29, 30, .5);
  -webkit-backdrop-filter: blur(15px);
  backdrop-filter: blur(15px);
  opacity: 0;
  visibility: hidden;
  /* out: last, after the letters */
  transition: opacity .225s var(--pic-ease) var(--veil-out-at, 0ms), visibility 0s linear calc(var(--veil-out-at, 0ms) + .225s);   /* .35 s in round 6 */
}
/* the grain of the annotation: fixed noise, soft-light over the veil */
.ce-showreel__veil::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .9 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: .14;
  mix-blend-mode: soft-light;
  pointer-events: none;
}
.ce-showreel.is-shown .ce-showreel__veil {
  opacity: 1;
  visibility: visible;
  transition: opacity .27s var(--ease-out-quart), visibility 0s;   /* .42 s in round 6, .6 s before */
}
.ce-showreel.is-shown .ce-showreel__box { cursor: default; }
.ce-showreel__btn { z-index: 2; }      /* over the veil */

.ce-showreel__say {
  --slot-w: 1.75em;                    /* 70 px at 40 px */
  --slot-h: 1.225em;                   /* 49 px */
  --slot-gap: .28em;                   /* the word space before the picture */
  position: relative;
  width: min(75.21vw, 100% - 2 * var(--gut));   /* 1083 of 1440 */
  margin: 0;
  font-family: var(--font-heading);
  font-size: clamp(1.5rem, 2.7778vw, 3.5rem);   /* 40 px at 1440 */
  font-weight: 400;
  line-height: 1.22;
  letter-spacing: -.035em;             /* −1.4 px at 40 px */
  color: #fff;
  --reveal-color: #fff;                /* where the letter flash settles (kit) */
}
@media (max-width: 900px) {
  .ce-showreel__say { width: calc(100% - 2 * var(--gut)); font-size: clamp(1.375rem, 1rem + 1.6vw, 1.625rem); }   /* 22 px at 375, 26 px from 625 up */
}
.ce-showreel__tie { white-space: nowrap; }
.ce-showreel__slot {
  position: relative;
  display: inline-block;
  width: 0;
  height: calc(var(--slot-h) + .08em);
  margin-bottom: -.085em;              /* the line keeps its height */
  vertical-align: top;
  overflow: hidden;
  /* out: folds once its picture is covered */
  transition: width .115s var(--pic-ease, ease) var(--slot-out-at, 0ms);   /* .18 s in round 6 */
}
/* the dark ground in the picture's shape: it grows with the slot, past
   the word space */
.ce-showreel__slot::before {
  content: "";
  position: absolute;
  top: .08em;
  left: var(--slot-gap);
  right: 0;
  height: var(--slot-h);
  border-radius: .3em;
  background: #0e0e0f;
}
.ce-showreel.is-said .ce-showreel__slot {
  width: calc(var(--slot-gap) + var(--slot-w));
  transition: width .155s var(--pic-ease, ease) var(--slot-at, 0ms);   /* .245 s in round 6, .35 s before */
}
.ce-showreel__say.is-measure .ce-showreel__slot { width: calc(var(--slot-gap) + var(--slot-w)); transition: none; }
.ce-showreel__pic {
  position: absolute;
  top: .08em;                          /* 3 px under the line's top */
  left: var(--slot-gap);
  width: var(--slot-w);
  max-width: none;
  height: var(--slot-h);
  object-fit: cover;
  border-radius: .3em;                 /* 12 px */
  background: #0e0e0f;
  /* covered from the right; out: back to the left */
  clip-path: inset(0 100% 0 0);
  transition: clip-path .115s var(--pic-ease, ease) var(--pic-out-at, 0ms);   /* .18 s in round 6 */
}
.ce-showreel.is-said .ce-showreel__pic {
  clip-path: inset(0 0 0 0);
  transition: clip-path .18s var(--pic-ease, ease) var(--pic-at, 0ms);   /* .28 s in round 6, .4 s before */
}
/* the lines and letters (kit classes, see the note above) */
.ce-showreel__say .lf-rl {
  overflow: clip;
  padding-bottom: .14em;               /* room for the descenders and the slot */
  margin-bottom: -.14em;
}
.ce-showreel__say .lf-rl__in {
  white-space: nowrap;
  /* out: back into the masks under the fading veil, the last line first */
  transition: transform .225s var(--pic-ease, ease) calc(var(--line-out-at, 0ms) + (var(--lines, 1) - 1 - var(--i, 0)) * 20ms);   /* .35 s / 30 ms in round 6 */
}
.ce-showreel.is-said .ce-showreel__say .lf-rl__in {
  transform: none;
  transition: transform .45s var(--ease-out-expo) calc(var(--say-at, 65ms) + var(--i, 0) * 30ms);   /* .7 s / 49 ms in round 6, 1 s / 70 ms before */
}
/* a letter's light (see the note above): the first colour on a dark
   ground is #FFF at 5% (round 5); set here in full, whatever the kit's
   .lf-ch does. Out: the last lit letter first. */
.ce-showreel__say .lf-ch {
  --lit: 0;
  opacity: calc(.05 + .95 * min(1, var(--lit) / .15));
  color: color-mix(in srgb, var(--ui-brand) calc(min(1, var(--lit) * 50) * (1 - var(--lit)) * (1 - var(--lit)) * (1 - var(--lit)) * (1 - var(--lit)) * 100%), #fff);
  animation: none;
  transition: --lit .19s linear calc(var(--ch-out-at, 0ms) + max(0, var(--c-last, 0) - var(--c, 0)) * var(--ch-out-step, 1ms));   /* .3 s in round 6 */
}
.ce-showreel.is-said .ce-showreel__say .lf-ch {
  --lit: 1;
  /* in: from the first letter not yet lit on */
  transition: --lit .45s linear calc(var(--say-at, 65ms) + max(0, var(--c, 0) - var(--c-first, 0)) * var(--ch-step, 3ms));   /* .7 s in round 6 */
}
/* the state at once, without transitions */
.ce-showreel.is-snap .ce-showreel__veil,
.ce-showreel.is-snap .ce-showreel__say .lf-rl__in,
.ce-showreel.is-snap .ce-showreel__say .lf-ch,
.ce-showreel.is-snap .ce-showreel__slot,
.ce-showreel.is-snap .ce-showreel__pic { transition: none; animation: none; }

/* ---- inline (Usługi v6.1, 01.10.2026) ------------------------------------------ */
.ce-showreel[data-ce-variant~="inline"] {
  position: relative;
  padding: 0;                            /* a <section> – not the kit's section rhythm */
  height: 175vh;                         /* 1 + .75 windows – the script sets it to the pixel */
  height: 175svh;
  background: #111;
}
.ce-showreel__alias {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
.ce-showreel[data-ce-variant~="inline"] .ce-showreel__box {
  inset: 0;
  width: auto;
  height: auto;
  cursor: default;
}
/* the light veil (a lighter blur than on Home, a little darker to keep the
   white text readable on bright frames: 62% – 4.7 : 1 on a white frame –
   and 80% under the header); it stays visible to assistive technology
   while transparent – opacity alone hides it */
.ce-showreel[data-ce-variant~="inline"] .ce-showreel__veil {
  background: linear-gradient(rgba(29, 29, 30, .8), rgba(29, 29, 30, .62) 160px);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  visibility: visible;
}
/* the last line not a lone word (the kit's line split keeps the breaks) */
.ce-showreel[data-ce-variant~="inline"] .ce-showreel__say { text-wrap: pretty; }
/* without JavaScript (no html.cr-js): the paragraph simply stands on the
   poster */
html:not(.cr-js) .ce-showreel[data-ce-variant~="inline"] .ce-showreel__veil { opacity: 1; }
/* the button at the top right, under the header – clear of the cookie
   card (bottom right, full width on a phone) */
.ce-showreel[data-ce-variant~="inline"] .ce-showreel__btn {
  top: calc(var(--header-h, 72px) + 16px);
  right: var(--gut);
  bottom: auto;
}
/* an address or a link to #ai (or the old #podejscie) lands just past the
   threshold of the paragraph (.25 of the stage), so it comes at once; with
   reduced motion the section is a plain block – the kit's margin stands */
@media (prefers-reduced-motion: no-preference) {
  .ce-showreel[data-ce-variant~="inline"] {
    scroll-margin-top: calc(-25vh - 2px);
    scroll-margin-top: calc(-25svh - 2px);
  }
  .ce-showreel[data-ce-variant~="inline"] .ce-showreel__alias {
    top: calc(25vh + 2px);
    top: calc(25svh + 2px);
    scroll-margin-top: 0;
  }
}
/* links in the statement (none in the copy of 01.10): white, the kit's
   line; a link is one token of the split, so it never breaks */
.ce-showreel__say .lf-link { color: #fff; white-space: nowrap; }

/* reduced motion: no growing – a plain full-width video in the flow; the
   statement stands on it at once, slots open */
@media (prefers-reduced-motion: reduce) {
  .ce-showreel[data-ce-variant~="scroll-zoom"] { height: auto; margin-top: 0; pointer-events: auto; }
  .ce-showreel[data-ce-variant~="scroll-zoom"] .ce-showreel__stage { position: static; height: auto; }
  .ce-showreel[data-ce-variant~="scroll-zoom"] .ce-showreel__box { position: relative; right: auto; width: 100%; height: auto; aspect-ratio: 16 / 9; }
  .ce-showreel[data-ce-variant~="statement"] .ce-showreel__box { aspect-ratio: auto; height: 100vh; height: 100svh; min-height: 32rem; cursor: default; }
  .ce-showreel[data-ce-variant~="inline"] { height: auto; }
  .ce-showreel[data-ce-variant~="inline"] .ce-showreel__stage { position: static; height: auto; }
  .ce-showreel[data-ce-variant~="inline"] .ce-showreel__box { position: relative; inset: auto; width: 100%; }
  .ce-showreel__veil { width: 100%; height: 100%; }
  /* as specific as the state rules above (they carry the in times) */
  .ce-showreel__veil,
  .ce-showreel.is-shown .ce-showreel__veil,
  .ce-showreel__slot,
  .ce-showreel.is-said .ce-showreel__slot,
  .ce-showreel__pic,
  .ce-showreel.is-said .ce-showreel__pic,
  .ce-showreel__say .lf-rl__in,
  .ce-showreel.is-said .ce-showreel__say .lf-rl__in,
  .ce-showreel__say .lf-ch,
  .ce-showreel.is-said .ce-showreel__say .lf-ch { transition: none; animation: none; }
  .ce-showreel__say .lf-ch { --lit: 1; opacity: 1; }
}
