/* ===========================================================================
   site.css – lo-fi kit of the crear.pl prototype
   ---------------------------------------------------------------------------
   Tokens, reset, base, container, typography, buttons, links, form fields,
   media placeholders, notes and helpers. Grayscale only: type, scale and
   spacing carry the hierarchy; colour and UI come in later stages.
   Visual reference: ../makiety/home-wireframe.html (29.07.2026).

   Type (23.09.2026): TT Hoves Pro for text (--font-body), TT Hoves Pro
   Expanded for headings (--font-heading); files in assets/fonts/. Both
   families have 400 and 500 only – never use 600 or 700, the browser would
   fake a bold.

   Prefixes: lf- = this kit, cr- = shared chrome (injected by chrome.js),
   ce- = content elements (ce/CE-NN-*.css, one file per CE).
   Breakpoints: 640 px and 900 px (the side panels also use 768 px, spec §6).
   Stacking order: header 100 < cookie notice 600 < scrim 1000 < panels 1010.

   Spec: ../koncepcja/prototyp-lofi-spec.md §5
   =========================================================================== */

/* ---- fonts --------------------------------------------------------------- */
/* Trial versions (a licence is needed before DEV). local() picks up a trial
   font installed on the machine first; the url() is relative to this file.
   Declarations as in ../makiety/home-main.html, plus Expanded Medium. */
@font-face {
  font-family: "TT Hoves Pro";
  src: local("TT Hoves Pro Trial Regular"), local("TTHovesProTrial-Rg"),
       url("assets/fonts/TTHovesPro-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "TT Hoves Pro";
  src: local("TT Hoves Pro Trial Medium"), local("TTHovesProTrial-Md"),
       url("assets/fonts/TTHovesPro-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "TT Hoves Pro Expanded";
  src: local("TT Hoves Pro Trl Expanded Regular"), local("TTHovesProTrlExp-Rg"),
       url("assets/fonts/TTHovesProExp-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "TT Hoves Pro Expanded";
  src: local("TT Hoves Pro Trl Expanded Medium"), local("TTHovesProTrlExp-Md"),
       url("assets/fonts/TTHovesProExp-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* ---- tokens ------------------------------------------------------------- */
:root {
  /* ink and surfaces */
  --ink: #111;
  --ink-2: #4a4a4a;
  --ink-3: #8a8a8a;
  --line: #dcdcdc;
  --line-2: #9a9a9a;
  --bg: #fff;
  --box: #f5f5f5;
  --box-2: #ececec;

  /* type scale */
  --t-hero: clamp(2.4rem, 5.4vw, 4.75rem);
  --t-intro: clamp(1.5rem, 2.9vw, 2.35rem);
  --t-h2: clamp(1.6rem, 2.9vw, 2.5rem);
  --t-h3: clamp(1.2rem, 1.8vw, 1.5rem);
  --t-lead: clamp(1.0625rem, 1.25vw, 1.25rem);
  --t-body: 1rem;
  --t-sm: .875rem;
  --t-xs: .75rem;

  /* tracking of the heading steps: TT Hoves Pro Expanded is wide, so the
     headings stay between 0 and -.01em (small caps keep their .06–.16em) */
  --track-hero: -.01em;          /* H1, large figures */
  --track-h2: -.005em;           /* H2, large statement, row names, menu */
  --track-h3: 0;                 /* H3 step: cards, steps, FAQ questions */

  /* rhythm and layout */
  --sp-sec: clamp(4.5rem, 9vw, 8rem);
  --sp-blk: clamp(2rem, 3.5vw, 3rem);
  /* Full window width with 50 px side margins (Mateusz, 24.09.2026);
     20 px on a phone, where 50 px would eat a quarter of the screen. */
  --wrap: 100%;
  --gut: 50px;
  --header-h: 4.5rem;

  /* stacking (see the order in the file header) */
  --z-header: 100;
  --z-scrim: 1000;
  --z-panel: 1010;
  --z-cookies: 600;

  /* type families (see the fonts above) */
  --font-body: "TT Hoves Pro", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-heading: "TT Hoves Pro Expanded", "TT Hoves Pro", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font: var(--font-body);      /* older alias of --font-body */
  --font-system: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;   /* dev tools only */
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
@media (max-width: 640px) {
  :root { --gut: 20px; }
}

/* ---- reset -------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

/* Anchors, keys and scrolls from code glide natively (smooth); the wheel
   has its own Lenis-like glide in site.js §8, which sets scroll-behavior
   to auto on <html> while it runs (26.09). */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: 1.6;
  font-synthesis: none;          /* never a faux bold or faux italic: only 400/500 upright exist */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-wrap: break-word;
}

h1, h2, h3, h4, h5, h6,
p, ul, ol, dl, dd, figure, blockquote, address, fieldset { margin: 0; }
h1, h2, h3, h4, h5, h6 { font-family: var(--font-heading); font-size: inherit; font-weight: 500; }
ul, ol { padding: 0; list-style: none; }
fieldset { padding: 0; border: 0; min-width: 0; }
img, svg, video, canvas { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
button { cursor: pointer; }
a { color: inherit; }
b, strong { font-weight: 500; }         /* Medium: there is no bold */
address { font-style: normal; }
table { border-collapse: collapse; }

/* The UA rule loses against any author `display`, so it is restated. */
[hidden] { display: none !important; }

:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
::selection { background: var(--ink); color: var(--bg); }

/* Anchor targets land below the sticky header. */
[id] { scroll-margin-top: calc(var(--header-h) + 1rem); }

/* ---- layout ------------------------------------------------------------- */
section { padding-block: var(--sp-sec); }

.lf-wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gut);
}

.lf-rule { border-top: 1px solid var(--line); }

/* Section head: optional kicker, H2 and lead above the blocks of a section. */
.lf-head { margin-bottom: var(--sp-blk); }
.lf-head > * + * { margin-top: .75rem; }

/* ---- typography --------------------------------------------------------- */
.lf-h1 {
  font-family: var(--font-heading);
  font-size: var(--t-hero);
  line-height: 1.06;
  letter-spacing: var(--track-hero);
  font-weight: 500;
  max-width: 15ch;
  text-wrap: balance;
}

.lf-h2 {
  font-family: var(--font-heading);
  font-size: var(--t-h2);
  line-height: 1.15;
  letter-spacing: var(--track-h2);
  font-weight: 500;
  max-width: 22ch;
  text-wrap: balance;
}

.lf-h3 {
  font-family: var(--font-heading);
  font-size: var(--t-h3);
  line-height: 1.25;
  letter-spacing: var(--track-h3);
  font-weight: 500;
  text-wrap: balance;
}

.lf-lead {
  font-size: var(--t-lead);
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 56ch;
}

.lf-kicker {
  font-size: var(--t-xs);
  line-height: 1.4;
  letter-spacing: .16em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--ink-3);
}

.lf-note {
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--ink-2);
}

.lf-prose > * + * { margin-top: 1em; }
.lf-prose p { max-width: 64ch; }

/* List with en dash markers (sentences, not deliverables). */
.lf-list li { position: relative; padding-left: 1.1rem; }
.lf-list li + li { margin-top: .35rem; }
.lf-list li::before {
  content: "\2013";
  position: absolute;
  left: 0;
  color: var(--ink-3);
}

/* ---- buttons and links ---------------------------------------------------- */
.lf-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5em;
  min-height: 2.75rem;
  padding: .7rem 1.3rem;
  border: 1px solid var(--ink);
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font-size: var(--t-sm);
  font-weight: 500;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}
.lf-btn:hover { background: var(--box-2); }
.lf-btn:focus-visible { outline-offset: 3px; }

.lf-btn--solid {
  background: var(--ink);
  color: var(--bg);
}
.lf-btn--solid:hover {
  background: var(--ink-2);
  border-color: var(--ink-2);
}

.lf-btn--block { display: flex; width: 100%; }
/* Primary button of the UI standard (Figma crear-v2.0, node 608:2087,
   24.09.2026): #1E1E1E, radius 3, 203 × 40, label 15 px Expanded Regular
   on the left, the arrow-up-right icon (20 px box) on the right. Markup:
   <button class="lf-btn lf-btn--ui"><span>…</span><span class="lf-btn__icon"
   aria-hidden="true"><img src="assets/icons/arrow-up-right.svg" alt=""></span></button> */
.lf-btn--ui {
  justify-content: space-between;
  gap: 24px;
  min-width: 203px;
  height: 40px;                  /* the 20 px icon box must not stretch it */
  min-height: 0;
  padding: 0 16px 1px;           /* the design's 12 / 13: the label 0.5 px above centre */
  border: 0;
  border-radius: 3px;
  background: var(--ui-button-2);
  color: #fff;
  font-family: var(--font-heading);
  font-size: .9375rem;
  font-weight: 400;
  line-height: 15px;
  text-align: left;
  transition: background-color .2s ease;
}
.lf-btn--ui:hover { background: #3a3a3a; }
.lf-btn__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 20px;
  height: 20px;
}
.lf-btn__icon img { width: 9.3333px; height: 9.3333px; }

/* Hover of the UI buttons (24.09, after aventuradentalarts.com; tempo and
   curve since 26.09 after the „READ BIO +” button of sharplink.com/about,
   measured 26.09: label and icon 0.5 s easeInOutCirc
   cubic-bezier(.785, .135, .15, .86); on hover the label goes first and the
   icon follows 70 ms later, on leave the icon goes first and the label
   follows 70 ms later).
   .lf-roll – the label and its copy stacked; on hover both move up by one
              full mask, so the label rolls out and its copy rolls in; back
              on leave. The mask (26.09): each copy carries --roll-pad above
              and below (room for Ż, Ą, j, g…) and the box takes it back with
              a negative margin, so the layout keeps the line's own height,
              no letter is clipped and the resting copy sits wholly below
              the mask – not a pixel of it shows.
   .lf-swap – the arrow and its copy in a clipping box; on hover the arrow
              flies out to the top-right and the copy comes in from the
              bottom-left; on leave they go back the same way. (sharplink
              rolls its „+” up like the label – our diagonal stays.) */
.lf-roll {
  --roll-pad: .3em;
  position: relative;
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  margin-block: calc(-1 * var(--roll-pad));
  white-space: nowrap;
}
.lf-roll > span {
  display: block;
  padding-block: var(--roll-pad);
  transition: transform .5s var(--ease-in-out-circ) 70ms;
}
.lf-roll > span + span { position: absolute; left: 0; top: 100%; }
:is(a, button):hover .lf-roll > span { transform: translateY(-100%); transition-delay: 0ms; }
.lf-swap { position: relative; overflow: hidden; }
.lf-swap > img { position: absolute; top: 50%; left: 50%; margin: -4.6667px 0 0 -4.6667px; transition: transform .5s var(--ease-in-out-circ); }
.lf-swap > img + img { transform: translate(-200%, 200%); }
:is(a, button):hover .lf-swap > img { transition-delay: 70ms; }
:is(a, button):hover .lf-swap > img:first-child { transform: translate(200%, -200%); }
:is(a, button):hover .lf-swap > img + img { transform: none; }
@media (prefers-reduced-motion: reduce) {
  .lf-roll > span, .lf-swap > img { transition: none; }
}

/* Pop – [data-pop]: a UI button's entrance (after the pills of wembi.ai,
   measured 24.09): it grows out of a small round blob – width from 44 px
   (min-width too) and scale 0.5 to its own size (--pop-w, measured by
   site.js), radius from 22 px to its own – 1.25 s on GSAP's elastic(0.25,
   0.25), seen through the "gooey" filter #cr-goo on its parent (blur 6 → 0
   between 0.5 and 1 s, site.js); the label and the icon rise into it 0.25 s
   later (1 s, ease-out-expo). Starts when the button scrolls into view
   (.is-in), after data-pop-delay ms. Entrance only – the hover stays. */
@keyframes lf-pop-grow {
  from { min-width: 44px; width: 44px; border-radius: 22px; transform: scale(.5); }
  to { min-width: var(--pop-w); width: var(--pop-w); border-radius: var(--pop-r, 3px); transform: none; }
}
@keyframes lf-pop-content {
  from { opacity: 0; transform: translateY(120%); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: no-preference) {
  .cr-js [data-pop]:not(.is-in) { visibility: hidden; }
  .cr-js [data-pop].is-in {
    overflow: hidden;
    transform-origin: left center;
    animation: lf-pop-grow 1.25s var(--ease-elastic) var(--pop-delay, 0ms) both;
  }
  .cr-js [data-pop].is-in > * { animation: lf-pop-content 1s var(--ease-out-expo) calc(var(--pop-delay, 0ms) + 250ms) both; }
  .lf-goo { filter: url(#cr-goo); }
}

/* A row of buttons and links. */
.lf-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem 1.25rem;
}

/* Text links and text buttons – the hover line of noomoagency.com (nav
   „INSIGHTS”, measured 26.09): a 1 px line in the text colour, .36em below
   the baseline (5 px at 14 px), drawn from the left edge to the right in
   0.3 s ease-in-out and gone to the right in 0.3 s ease-in-out (there a
   full-width ::before sliding from −100% to 0 and on to 100% under
   overflow:hidden – here the same picture with background-size, which also
   runs across the lines of a wrapped link and never plays on load).
   .lf-line        – the line alone (links of the chrome, text buttons); on
                     an inline element, or on a span inside the link or
                     button (the parent's hover draws it).
   .lf-line--rest  – plus a faint resting line (30% of the text colour) under
                     it, for links that must read as links at rest.
   .lf-link        – the kit's text link: rest line + hover line. A link laid
                     out as a block (display other than inline) gets its text
                     wrapped in span.lf-line by site.js (.lf-link--box), so
                     the line spans the words, not the box.
   Metrics: TT Hoves Pro and its Expanded cut both have ascent 1em and
   descent .26em, so the line sits 1.36em below the top of the inline box;
   padding-bottom .2em makes room for it (vertical padding of an inline
   element does not move the lines). Not used where an element has its own
   hover motion (UI buttons, .lf-roll, the header's „zapytanie ofertowe”,
   footer rows, cards, CE-29 rows). */
.lf-link { color: var(--ink); }
.lf-link,
.lf-line {
  --line-y: 1.36em;
  text-decoration: none;
  padding-bottom: .2em;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 0% 1px;
  background-position: 100% var(--line-y);
  transition: background-size .3s ease-in-out;
}
.lf-link,
.lf-line--rest {
  --line-rest: color-mix(in srgb, currentColor 30%, transparent);
  background-image: linear-gradient(currentColor, currentColor), linear-gradient(var(--line-rest), var(--line-rest));
  background-size: 0% 1px, 100% 1px;
  background-position: 100% var(--line-y), 0 var(--line-y);
}
.lf-link:is(:hover, :focus-visible),
.lf-line:hover,
:is(a, button):is(:hover, :focus-visible) > .lf-line {
  background-size: 100% 1px, 100% 1px;
  background-position: 0 var(--line-y), 0 var(--line-y);
}
.lf-link--box { background: none; padding-bottom: 0; }
@media (prefers-reduced-motion: reduce) {
  .lf-link, .lf-line { transition: none; }
}

/* ---- form fields ---------------------------------------------------------- */
/* Label above the control. Controls take the kit classes (lf-input,
   lf-select, lf-textarea, lf-file) or sit directly in .lf-field. */
.lf-field {
  display: flex;
  flex-direction: column;
  gap: .4rem;
  min-width: 0;
}

.lf-label,
.lf-field > label {
  font-size: var(--t-sm);
  line-height: 1.4;
  color: var(--ink-2);
}

.lf-input,
.lf-select,
.lf-textarea,
.lf-field > input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
.lf-field > select,
.lf-field > textarea {
  display: block;
  width: 100%;
  min-height: 2.75rem;
  padding: .65rem .85rem;
  border: 1px solid var(--line-2);
  border-radius: 0;
  background-color: var(--bg);
  color: var(--ink);
  font-size: 1rem;              /* 16 px: no zoom on focus in iOS Safari */
  line-height: 1.4;
  -webkit-appearance: none;
  appearance: none;
}

.lf-textarea,
.lf-field > textarea {
  min-height: 7.5rem;
  resize: vertical;
}

/* Select chevron drawn with two gradients – no image, no icon font. */
.lf-select,
.lf-field > select {
  padding-right: 2.5rem;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ink-2) 50%),
    linear-gradient(135deg, var(--ink-2) 50%, transparent 50%);
  background-position: calc(100% - 1.2rem) 50%, calc(100% - .85rem) 50%;
  background-size: .36rem .36rem;
  background-repeat: no-repeat;
}

.lf-input:hover,
.lf-select:hover,
.lf-textarea:hover { border-color: var(--ink-2); }

.lf-input:focus-visible,
.lf-select:focus-visible,
.lf-textarea:focus-visible,
.lf-field > input:focus-visible,
.lf-field > select:focus-visible,
.lf-field > textarea:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 0;
  border-color: var(--ink);
}

.lf-input::placeholder,
.lf-textarea::placeholder { color: var(--ink-3); }

.lf-file {
  display: block;
  width: 100%;
  max-width: 100%;
  font-size: var(--t-sm);
  color: var(--ink-2);
}
.lf-file::file-selector-button {
  margin-right: .85rem;
  padding: .55rem 1rem;
  border: 1px solid var(--ink);
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  cursor: pointer;
}
.lf-file::file-selector-button:hover { background: var(--box-2); }

/* Checkbox or radio with its label on the right. */
.lf-check {
  display: flex;
  align-items: flex-start;
  gap: .65rem;
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--ink-2);
}
.lf-check input[type="checkbox"],
.lf-check input[type="radio"] {
  flex: none;
  width: 1.125rem;
  height: 1.125rem;
  margin: .125rem 0 0;
  accent-color: var(--ink);
}

/* ---- media placeholder ---------------------------------------------------- */
/* Gray box with a small uppercase label; proportion via --ratio (16/9, 4/3…). */
.lf-placeholder {
  display: grid;
  place-items: center;
  width: 100%;
  min-height: 4rem;
  aspect-ratio: var(--ratio, auto);
  padding: 1rem;
  background: var(--box);
  color: var(--ink-3);
  font-size: var(--t-xs);
  line-height: 1.4;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-align: center;
}

/* ---- helpers -------------------------------------------------------------- */
/* .lf-nowrap (30.09): a word that must not break at its own hyphen –
   „e-commerce” (TT Hoves has no U+2011, and a no-break hyphen would change
   the text for Ctrl+F and text fragments) */
.lf-nowrap { white-space: nowrap; }
.lf-sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

@media print {
  html { scroll-behavior: auto; }
  section { padding-block: 2rem; }
}

/* ---- UI tokens from Figma crear-v2.0 -------------------------------------- */
/* Frame 316:494 (drawer CE-03 with the form CE-24), 23.09.2026. The first
   colours of the UI stage – used by the drawer and the form only; the lo-fi
   kit above stays grayscale. Motion curves measured on amaterasu.ai (menu,
   23.09.2026): GSAP power3.out = easeOutQuart for opening, power3.inOut =
   easeInOutQuart and power1.out = easeOutQuad for closing. */
:root {
  --ui-ink: #1D1D1E;                     /* "Dark": titles, checked box, hover of the button */
  --ui-text: #0A2526;                    /* labels, typed text */
  --ui-text-60: rgba(10, 37, 38, .6);    /* the note under the button, file names */
  --ui-text-65: rgba(10, 37, 38, .65);   /* small secondary text that must pass AA: 5 : 1 on white (30.09 – „Dotyczy”, CE-49, CE-50) */
  --ui-text-40: rgba(10, 37, 38, .4);    /* placeholders, the drop zone text */
  --ui-stroke: #ACB0B8;                  /* field and checkbox outline */
  --ui-stroke-soft: #EBEBEB;             /* "Stroke": the icon tile in the drop zone */
  --ui-close-bg: #EDEDED;                /* the drawer's close button */
  --ui-button: #272727;                  /* primary button */
  --ui-button-2: #1E1E1E;                /* primary button of the page (608:2087) */
  --ui-error: #FF502F;                   /* error text and outline */
  --ui-blob-1: #37FFDC;                  /* the colour blob of the primary button */
  --ui-blob-2: #73FFD6;
  --ui-blob-3: #FF502F;
  --ui-blob-4: #51DACF;
  --ui-blob-5: #9EF5CF;
  --ui-scrim: rgba(29, 29, 30, .55);     /* the page behind the drawer */

  --ease-out-quart: cubic-bezier(.25, 1, .5, 1);
  --ease-in-out-quart: cubic-bezier(.76, 0, .24, 1);
  --ease-out-quad: cubic-bezier(.5, 1, .89, 1);
  --ease-out-expo: cubic-bezier(.19, 1, .22, 1);   /* verostudio.com, CE-27 reveal */
  --ease-in-out-quad: cubic-bezier(.455, .03, .515, .955);   /* GSAP power1.inOut, CE-06 reveal */
  --ease-out-power2: cubic-bezier(.215, .61, .355, 1);       /* GSAP power2.out, CE-27 reveal (ref.digital) */
  --ease-out-power4: cubic-bezier(.23, 1, .32, 1);           /* GSAP power4.out, CE-13 quote in (oci) */
  --ease-in-out-circ: cubic-bezier(.785, .135, .15, .86);    /* easeInOutCirc, UI button hover (sharplink.com, 26.09) */
  --ease-in-power4: cubic-bezier(.755, .05, .855, .06);      /* GSAP power4.in, CE-13 quote out */
  /* GSAP elastic(0.25, 0.25) – wembi.ai pills; amplitude clamps to 1, so the
     period is 1: one soft overshoot (sampled into linear()) */
  --ease-elastic: linear(0 0%, .202 3%, .387 6%, .595 10%, .758 14%, .878 18%, .959 22%, 1.01 26%, 1.039 30%, 1.052 35%, 1.051 40%, 1.042 45%, 1.031 50%, 1.013 60%, 1.002 70%, .999 80%, 1 100%);
  --ui-brand: #BC3121;                   /* the leading edge of the text sweep */
  --ui-muted: #778181;                   /* eyebrows, sectors, roles (crear-v2.0) */
  --ui-muted-2: #969B9B;                 /* eyebrow on the #F4F4F4 background */
  --ui-soft: #F4F4F4;                    /* soft section background (CE-27, CE-13) */
}

/* ---- UI kit: eyebrow, text reveal, appear, scroll background -------------- */
/* 24.09.2026, for the sections redone after Figma crear-v2.0 (CE-06, CE-13,
   CE-27, CE-29, footer CE-04). Behaviour in site.js §7.

   Eyebrow: a 4 px dot and a small uppercase label in Expanded Medium, as
   „• NASZE REALIZACJE” (440:227) and „• CORE USŁUGI” (452:457). */
.lf-eyebrow {
  display: flex;
  align-items: center;
  gap: 20px;
  font-family: var(--font-heading);
  font-size: .8125rem;               /* 13 px */
  font-weight: 500;
  line-height: normal;
  letter-spacing: .015em;            /* 0.195 px at 13 px */
  text-transform: uppercase;
  color: var(--ui-muted);
}
.lf-eyebrow::before {
  content: "";
  flex: none;
  width: 4px;
  height: 4px;
  border-radius: 1px;
  background: currentColor;
}
.lf-eyebrow--dim { color: rgba(119, 129, 129, .75); }   /* the design's opacity .7–.8 */

/* Code-in of the labels – .lf-eyebrow, .lf-kicker and [data-code] (26.09,
   after the hover scramble of noartmusic.com/gallery – GSAP there, measured
   26.09 from its script): once a label scrolls into view (instead of its
   data-appear), about 60% of its letters, picked at random, turn into
   random signs from A–Z, 0–9, #$%&@, drawn anew every 60 ms; each drawn
   sign has a 15% chance to take the accent colour (there #ff2b29, here
   --ui-brand #BC3121, the red edge of the hero's text sweep). The run is
   0.65 s on power1.out and the signs stop at 75% of its progress (about
   0.33 s), when the whole label settles at once. site.js freezes the width
   of every letter (.lf-code__c), so the label never changes its width, and
   keeps the real text for screen readers (.lf-sr-only) while the signs are
   aria-hidden; afterwards the plain text is back. Hidden (opacity 0, so it
   is still read out) until then; reduced motion: no effect. */
.lf-code__c {
  display: inline-block;
  text-align: center;
  white-space: pre;
}
.lf-code__c.is-hot { color: var(--ui-brand); }
@media (prefers-reduced-motion: no-preference) {
  .cr-js [data-code]:not(.is-in) { opacity: 0; }
}

/* Rolling digits – [data-reel] (27.09, site.js §10; CE-35 Funk, CE-12 O nas):
   a figure as the wheels of a mechanical combination lock. site.js builds
     span.lf-sr-only                    – the value, for screen readers
     span.lf-reel (aria-hidden)         – a row: one block per sign
       span.lf-reel__ch                 – a sign that stands (%, ×, +, ,)
       span.lf-reel__col                – a wheel: the mask
         span.lf-reel__strip            – the digits, one .lf-reel__cell each
   Every block is one line (1lh) tall and top-aligned, so each sign sits
   exactly where it sits in the plain text (the figure's own line-height,
   letter-spacing and tabular digits – the width never changes). The mask
   has --reel-pad of room above and below the line (taken back with
   negative margins, so the layout does not move) and each cell has the
   same padding; its top and bottom --reel-edge fade out (mask-image), so
   the digits rolling past soften at the edges like a drum. A resting digit
   is never cut or faded: measured 27.09 in TT Hoves Pro Expanded, the
   digits' ink runs from .185 to .905 em of a 1.05 em line (CE-12; 1.09 em
   in CE-35 leaves more), so .04 em of room and a .14 em fade stay clear
   of it by .045 em or more; the room is small enough not to reach the
   hairline or text next to the figure. The strip is moved by --reel-y (in cells) through a
   CSS transition set by site.js; before it starts the figure is hidden
   (it is still read out) and it fades in as the wheels start. Afterwards
   site.js puts the plain text back. Reduced motion: nothing is built. */
[data-reel] { font-variant-numeric: tabular-nums; }
.lf-reel {
  --reel-pad: .04em;                 /* room above and below the line */
  --reel-edge: .14em;                /* the fade at the top and the bottom of the mask */
  display: inline-flex;
  align-items: flex-start;
  vertical-align: top;
}
.lf-reel__ch { display: block; height: 1lh; white-space: pre; }
.lf-reel__col {
  display: block;
  height: calc(1lh + 2 * var(--reel-pad));
  margin-block: calc(-1 * var(--reel-pad));
  overflow: clip;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 var(--reel-edge), #000 calc(100% - var(--reel-edge)), transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 var(--reel-edge), #000 calc(100% - var(--reel-edge)), transparent);
}
.lf-reel__strip {
  display: block;
  transform: translateY(calc(var(--reel-y, -1) * (1lh + 2 * var(--reel-pad))));
  will-change: transform;
}
.lf-reel__cell { display: block; height: 1lh; padding-block: var(--reel-pad); box-sizing: content-box; }
[data-reel].is-armed { opacity: 0; }
[data-reel].is-armed.is-in { opacity: 1; transition: opacity var(--reel-fade, 200ms) linear; }

/* Text reveal – [data-reveal-text="sweep|rise|chars"]: site.js splits the text
   into its lines (after the fonts are in) and starts them once the element
   scrolls into view (.is-in), line by line (--i).
   sweep – the gradient of the CE-06 hero (unitedcarriers.com): final colour,
           a red edge (--ui-brand), transparent; 30 → 100 in --sweep-dur.
   rise  – each line slides up out of its own mask (ease-out-expo).
   chars – the headings (every main .lf-h2 gets it, 24.09 – after wembi.ai;
           26.09 – run in time, new unlit colour): the lines rise out of
           their masks and the letters, unlit in --ch-dim (#1D1D1E at 5%,
           white at 5% on a dark ground – .is-on-dark, site.js), light up
           one after another – evenly over 900 ms, each at its own --ch-d –
           each flashing --ui-brand (at 20% → 100% opacity in .15 s) and
           settling into the text colour in 1 s. Started once, when the
           heading scrolls into view; it runs to its end whatever the scroll
           does.
   When the lines are done the plain text comes back (.is-done), so it
   reflows freely. Hidden only while the script is on its way (html.cr-js);
   reduced motion: shown at once. */
@property --lf-sweep {
  syntax: "<number>";
  inherits: true;
  initial-value: 100;
}
@keyframes lf-sweep {
  from { --lf-sweep: 30; }
  to { --lf-sweep: 100; }
}
.cr-js [data-reveal-text]:not(.is-split):not(.is-done) { visibility: hidden; }
.lf-rl { display: block; }
[data-reveal-text="sweep"] .lf-rl {
  display: inline-block;             /* the gradient spans the line's own text */
  color: transparent;
  background-image: linear-gradient(90deg, var(--reveal-color) 0%, var(--reveal-color) 30%, var(--ui-brand) 40%, transparent 50%, transparent 100%);
  background-repeat: no-repeat;
  background-size: 350% 100%;
  background-position: calc((100 - var(--lf-sweep)) * 1%) 0;
  -webkit-background-clip: text;
  background-clip: text;
  --lf-sweep: 30;
}
[data-reveal-text="sweep"].is-in .lf-rl {
  animation: lf-sweep var(--sweep-dur, .55s) var(--ease-in-out-quad) calc(var(--i, 0) * 60ms) both;
}
[data-reveal-text="rise"] .lf-rl,
[data-reveal-text="chars"] .lf-rl {
  overflow: clip;
  padding-bottom: .14em;             /* room for the descenders inside the mask */
  margin-bottom: -.14em;
}
.lf-rl__in {
  display: block;
  transform: translateY(110%);
  transition: transform 1s var(--ease-out-expo) calc(var(--rise-delay, 0ms) + var(--i, 0) * 70ms);
}
[data-reveal-text="rise"].is-in .lf-rl__in,
[data-reveal-text="chars"].is-in .lf-rl__in { transform: none; }
/* .lf-ch / .is-lit – the letter classes of the kit, also used on their own
   (CE-08 lights its letters itself): 20% until lit */
.lf-ch { opacity: .2; transition: opacity .15s linear; }
.lf-ch.is-lit { opacity: 1; animation: lf-ch-flash 1s var(--ease-out-quart) both; }
@keyframes lf-ch-flash {
  from { color: var(--ui-brand); }
  to { color: var(--reveal-color, currentColor); }
}
@keyframes lf-ch-in {
  from { opacity: .2; }
  to { opacity: 1; }
}
/* the chars headings: unlit letters in --ch-dim; each lights at its --ch-d
   (no backwards fill – until then it keeps the unlit colour) and keeps the
   text colour afterwards (forwards) */
[data-reveal-text="chars"] { --ch-dim: rgba(29, 29, 30, .05); }
[data-reveal-text="chars"].is-on-dark { --ch-dim: rgba(255, 255, 255, .05); }
[data-reveal-text="chars"] .lf-ch { opacity: 1; color: var(--ch-dim); transition: none; }
[data-reveal-text="chars"].is-in .lf-ch {
  animation: lf-ch-flash 1s var(--ease-out-quart) var(--ch-d, 0ms) forwards,
             lf-ch-in .15s linear var(--ch-d, 0ms);
}

/* Appear – [data-appear]: a block fades in and rises 24 px once it scrolls
   into view; data-appear-delay="ms" staggers it. */
.cr-js [data-appear] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .8s var(--ease-out-quart) var(--appear-delay, 0ms), transform .8s var(--ease-out-quart) var(--appear-delay, 0ms);
}
.cr-js [data-appear].is-in { opacity: 1; transform: none; }

/* Soft background – [data-bg-scroll]: the section stands on --bg-scroll
   (default --ui-soft, #F4F4F4) from the first frame and for good. Until
   26.09 it took the colour only while it held the middle of the window
   and turned white above and below it; Mateusz: the grey must be there at
   once, not appear after some scrolling – so no switching any more (the
   attribute keeps its name, the pages need no change). */
[data-bg-scroll] { background-color: var(--bg-scroll, var(--ui-soft)); }

@media (prefers-reduced-motion: reduce) {
  .cr-js [data-appear] { opacity: 1; transform: none; transition: none; }
  .lf-rl__in { transform: none; transition: none; }
  .lf-ch { opacity: 1; animation: none; }
  [data-reveal-text="chars"] .lf-ch,
  [data-reveal-text="chars"].is-in .lf-ch { color: inherit; animation: none; }
  [data-reveal-text="sweep"] .lf-rl { animation: none; color: inherit; background: none; }
}

/* ---- UI kit: AI marker ------------------------------------------------------ */
/* span.ai-tag (30.09, Usługi v6 – decision D19 of the copy): right after the
   link of a service that has AI functions, e.g. „aplikacje na abonament
   (SaaS)” + AI. Small, raised like an index and set off from the link (the
   copy's note for Figma: in running text „(SaaS) AI” must not read as part
   of the name), in the heading face like the eyebrows, secondary colour
   (#0A2526 at 70% – 5.9 : 1 on white), no background; outside the word
   count. Markup:
   <span class="ai-tag"><span aria-hidden="true">AI</span><span
   class="lf-sr-only"> (funkcje AI)</span></span> – the reader hears
   „(funkcje AI)”. On a dark ground it takes the text colour at 70%. */
.ai-tag {
  display: inline-block;
  margin-left: .22em;
  font-family: var(--font-heading);
  font-size: max(11px, .55em);           /* 11 px floor: 10 px next to a 17 px line was at the edge of legibility */
  font-weight: 500;
  line-height: 1;
  letter-spacing: .06em;
  vertical-align: .9em;
  color: rgba(10, 37, 38, .7);
  white-space: nowrap;
}
.is-on-dark .ai-tag,
[data-reveal-bg="dark"] .ai-tag { color: rgba(255, 255, 255, .7); }
