/* ──────────────────────────────────────────────────────────────────────────
   sekcja „course_comparsion" — „MaturalneSOS vs alternatywy".

   Tło ciepłe (canvas-warm), bez slaba: sekcja stoi na końcu landingu i cały
   jej kontrast bierze się z jednej wyróżnionej kolumny, nie z płyty pod spodem.
   Chrom współdzielony (typografia .text-*, marker .hl-marker, przycisk
   .btn-solar, container) pochodzi z design-system.css — tu żyje wyłącznie
   komponent tabeli porównawczej, którego DS jeszcze nie ma zbudowanego.

   Jedno świadome odstępstwo od opisu `.tbl` w DESIGN-SYSTEM.md → „Tabela
   porównawcza", wymuszone projektem tej sekcji: BRAK przewijania poziomego
   i sticky pierwszej kolumny. Cztery kolumny (opis + my + dwie konkurencji)
   mieszczą się na 360px, bo szerokości kolumn są stałe (--ccp-col-us /
   --ccp-col-alt), a opis bierze resztę. Porównanie, którego nie widać
   w całości bez przewijania, nie sprzedaje.
   Wszystkie pięć wzmocnień wyróżnionej kolumny z DS zostaje bez zmian —
   łącznie z <tfoot> z przyciskiem Solar w tej kolumnie (CTA stoi w tabeli,
   nie pod nią, zgodnie z opisem DS).

   Gęstość: opis wiersza ma na mobile 12px, a etykiety kolumn 8px — poniżej
   progu 15px z CLAUDE.md (reguła 9). To odstępstwo świadome i wpisane
   w projekt: przy 14 wierszach i czterech kolumnach bez przewijania nie ma
   innego sposobu zmieścić treści. Od 768px typografia wraca do normy
   (14px → 16px). Do decyzji Tomka, czy tak zostaje.

   Animacje wyłącznie na opacity/transform (reveal), czasy i krzywe z tokenów.
   ────────────────────────────────────────────────────────────────────────── */
.ccp {
  /* Szerokości kolumn — jedyne miejsce do regulacji gęstości tabeli.
     --ccp-gutter musi być równy padding-inline .container-ms, bo tabela
     wychodzi z containera ujemnym marginesem i sama odtwarza jego światło. */
  /* Kolumna własnej oferty poszerzona z 74px: plakietka „Polecane" musi się
     w niej zmieścić (stopień 13px wynika z kontrastu, nie z układu), a przycisk
     "Wybieram!" w <tfoot> (16px, twarde minimum z CLAUDE.md) potrzebuje kilku
     pikseli odstępu od ramy kolumny, żeby nie wyglądał jak blok wypełniający
     kolumnę od krawędzi do krawędzi. Bilans na 360px: kolumny konkurencji
     dostały po 62px (były 56 — przy ręcznie łamanych „KORE-/PETYCJE/1:1"
     to widoczna różnica), a te 12px przyszły z kolumny własnej oferty (98px)
     i z kolumny opisu (138px). Przy 98px przycisk „Wybieram!" (16px, twarde
     minimum) mieści się tylko dzięki ściętemu paddingowi komórki i przycisku
     — niżej z kolumną już nie zejdziemy bez skrócenia etykiety CTA. */
  --ccp-col-us: 98px;
  --ccp-col-alt: 62px;
  --ccp-gutter: var(--ds-space-4);
  /* Hairline wewnątrz wyróżnionej kolumny — success-ink rozcieńczony do siły
     zwykłego hairline'u; na zielonym tincie ciepły --ds-color-hairline
     wyglądałby jak brud. */
  --ccp-rail-line: rgba(8, 94, 65, 0.14);

  /* Tło ciepłe (nie białe .ds-color-canvas) i pełnej szerokości ekranu —
     sekcja ma się wizualnie oddzielić od białej course_forwho nad nią.
     Sama .ccp jest sekcją bez ograniczenia szerokości (żadny przodek w
     kurs/matematyka-rozszerzona.php nie ma max-width), więc tło samo
     rozciąga się do krawędzi bez dodatkowego markupu. */
  background-color: var(--ds-color-canvas-warm);
  padding: var(--ds-space-10) 0 var(--ds-space-12);
}
/* Bez własnego max-width — zawartość bierze szerokość .container-ms
   (1320px), tak jak reszta sekcji na stronie, nie węższy, customowy limit. */
.ccp-inner { width: 100%; }

/* Szerokości kolumn na tablecie i desktopie ustawia blok @media niżej w pliku
   (patrz „Tablet" i sekcja desktopowa) — kolejność w pliku jest tu jedynym
   rozstrzygnięciem, bo oba selektory mają tę samą specyficzność. */
@media (min-width: 1024px) {
  .ccp { --ccp-gutter: var(--ds-space-5); padding: var(--ds-space-16) 0; }
}

/* ── Nagłówek ─────────────────────────────────────────────────────────────
   Jedna kolumna na wszystkich szerokościach, wyśrodkowana — tekst → tabela.
   Karty punktacji i legenda glifów zostały usunięte (na życzenie Tomka);
   nad tabelą stoi tylko H2 i lead. */
/* Sztywne złamanie H2 tylko na mobile — od 1024px nagłówek ma dość miejsca
   i łamie się sam (spacja po <br> zostaje w markupie, żeby wyrazy się nie
   skleiły po jego wygaszeniu). */
.ccp-title-break { display: inline; }

.ccp-head { text-align: center; }
.ccp-title { margin: 0 0 var(--ds-space-2); text-wrap: pretty; }
/* margin-inline:auto centruje sam blok, nie tylko tekst w nim — potrzebne,
   bo od 1024px lead dostaje węższy max-width niż kontener. */
.ccp-lead { margin: 0 auto var(--ds-space-4); color: var(--ds-color-ink-secondary); text-wrap: pretty; }

@media (min-width: 1024px) {
  .ccp-title-break { display: none; }
  .ccp-title { margin-bottom: var(--ds-space-3); }
  .ccp-lead { max-width: 34em; margin-bottom: 0; }
}

/* ── Zdanie pod tabelą ────────────────────────────────────────────────────
   Domyka porównanie ceną, w wadze 400, bo to całe zdanie, a nie nagłówek.
   Stopień --ds-text-body-lg (16/17px, na życzenie zmniejszony z
   --ds-text-h2/19-23px — na tamtym stopniu tekst wyglądał za ciężko na
   desktopie) — nadal wyraźnie nad podłogą czytelności (15px, CLAUDE.md
   reguła 10), ale bez wagi nagłówka. Wyśrodkowane jak nagłówek, z miarą
   czytelności — bez niej wiersz na desktopie ma ponad 100 znaków. */
.ccp-note {
  margin: var(--ds-space-6) auto 0;
  max-width: 28em;
  font-family: var(--ds-font-body);
  font-size: var(--ds-text-body-lg);
  font-weight: 400;
  line-height: 1.5;
  text-align: center;
  color: var(--ds-color-ink);
  text-wrap: pretty;
}
@media (min-width: 1024px) {
  .ccp-note { margin-top: var(--ds-space-8); max-width: 34em; }
}

/* ── Glify ────────────────────────────────────────────────────────────────
   Kolor nigdy nie jest jedynym nośnikiem znaczenia: „jest" to ptaszek,
   „nie ma" krzyżyk, „zależy od oferty" oba glify naraz w jednej komórce
   (.ccp-mark-both) — jeden dostawca z kategorii nie reprezentuje wszystkich.
   W wyróżnionej kolumnie ptaszek jest wypełniony i ma własny cień — to jedno
   z pięciu wzmocnień z DESIGN-SYSTEM.md. */
.ccp-mark { display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: var(--ds-radius-full); }
/* „Jest" w obu rodzajach kolumn ma ten sam, intensywny zielony — różni je
   wielkość i cień, nie kolor (hierarchia zostaje, sygnał jest jednoznaczny).
   Ptaszek to grafika z ukrytą etykietą tekstową, nie litera, więc biel na żywym
   --ds-color-success jest tu dozwolona (CLAUDE.md, reguła 12). */
.ccp-mark-yes { background-color: var(--ds-color-success); color: #fff; }
/* Tło „nie ma" jest chłodne (hairline-cool), nie kremowe: krzyżyk ma czytać się
   jako neutralny brak, a nie jako element ciepłej palety sekcji. */
.ccp-mark-no { background-color: var(--ds-color-hairline-cool); color: var(--ds-color-ink-muted); }
.ccp-mark-us {
  width: 23px; height: 23px;
  background-color: var(--ds-color-success);
  color: #fff;
  box-shadow: var(--ds-shadow-mark-yes-hi);
}
/* Dwa glify jednej komórki, ciasno obok siebie — kolumna alt ma na mobile
   tylko 62px, więc gap zostaje minimalny. */
.ccp-mark-both { display: inline-flex; align-items: center; gap: 4px; }
.ccp-glyph { width: 11px; height: 11px; fill: none; stroke: currentColor; stroke-width: 3.4; stroke-linecap: round; stroke-linejoin: round; }
.ccp-mark-us .ccp-glyph { width: 13px; height: 13px; }
/* Ukośna kreska między glifami, nie goły "/" ze zestawu znaków — gradient
   od success (ptaszek) do hairline-cool (krzyżyk) po drodze wiąże kolory obu
   glifów, więc separator sam niesie sens „między tak i nie", nie jest tylko
   ozdobą. Dekoracyjny (aria-hidden), etykieta dostępności zostaje na
   .ccp-mark-both. */
.ccp-mark-sep {
  flex: none;
  width: 2px;
  height: 12px;
  border-radius: var(--ds-radius-full);
  background: linear-gradient(180deg, var(--ds-color-success) 0%, var(--ds-color-hairline-cool) 100%);
  transform: rotate(18deg);
}

@media (min-width: 1024px) {
  .ccp-mark { width: 27px; height: 27px; }
  .ccp-glyph { width: 14px; height: 14px; stroke-width: 3.2; }
  .ccp-mark-both { gap: 6px; }
  .ccp-mark-sep { height: 16px; }
  .ccp-mark-us { width: 32px; height: 32px; }
  .ccp-mark-us .ccp-glyph { width: 17px; height: 17px; }
}

/* ── Tabela ───────────────────────────────────────────────────────────────
   Na mobile tabela wychodzi z .container-ms na pełną szerokość ekranu, żeby
   hairline'y biegły od krawędzi do krawędzi i żeby kolumna opisu dostała
   każdy dostępny piksel. Światło containera odtwarza padding komórki opisu
   (--ccp-gutter), więc tekst nadal stoi w jednej osi z nagłówkiem sekcji. */
/* Zapas na pływającą flagę „Najlepszy wybór": jej środek leży dokładnie na
   górnej krawędzi ciemnej karty, więc górna połowa wychodzi nad tabelę.
   margin-top to osobny odstęp OD LEADU nad tabelą (na życzenie zwiększony) —
   nie myl z padding-top wyżej, który jest zapasem TYLKO na flagę. Musi
   przebić --ds-space-4 z `.ccp-lead` (margin-bottom), inaczej sąsiadujące
   marginesy się zwiną do wspólnego, większego z obu (tu: bez zmiany). */
.ccp-tablewrap { position: relative; margin-top: var(--ds-space-6); margin-inline: calc(-1 * var(--ccp-gutter)); padding-top: 13px; }

/* Flaga stoi nad kolumną własnej oferty i jest wpięta w jej górną krawędź
   (translateY(-50%) na wysokości paddingu wrappera). Szerokość bierze z kolumny
   i centruje w niej treść — pigułka może wyjść o kilka pikseli poza kolumnę,
   bo to wstążka nad kartą, nie element jej siatki.
   ODSTĘPSTWO (decyzja Tomka): pełny --ds-color-cta-solar pod tekstem 11/13px.
   Ciemny tekst na pełnym żółtym ma sufit Lc 75, a próg dla tych stopni to
   90 (CLAUDE.md, reguła 3 — 16px bez wyjątków). Flaga jest `aria-hidden`
   i powtarza to, co niesie nagłówek kolumny, więc czytnik ekranu nic nie traci;
   czytelny wariant tej samej pigułki to `cta-solar-tint` + `cta-solar-ink`
   + obwódka w pełnym solarze. */
.ccp-flag {
  display: flex; align-items: center; justify-content: center;
  position: absolute; top: 13px;
  right: calc(var(--ccp-col-alt) * 2);
  width: var(--ccp-col-us);
  transform: translateY(-50%);
  z-index: 2; pointer-events: none;
}
.ccp-flag > span {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 7px;
  border-radius: var(--ds-radius-full);
  background-color: var(--ds-color-cta-solar);
  color: var(--ds-color-on-cta-solar);
  box-shadow: var(--ds-shadow-cta-solar);
  font-family: var(--ds-font-display);
  /* 9px na mobile (o ~20% mniej niż 11px) — plakietka jest `aria-hidden`
     i tylko powtarza to, co niesie nagłówek kolumny, więc nie stosuje się do
     niej podłoga 13px dla treści; od 1024px wraca do 13px. */
  font-size: 9px; font-weight: 600; letter-spacing: 0.02em;
  white-space: nowrap;
}
/* Puchar tylko od 1024px: na mobile pigułka bez niego jest węższa od kolumny
   i mieści się wyśrodkowana nad kartą, bez nachodzenia na sąsiednią etykietę. */
.ccp-flag-ic { display: none; width: 12px; height: 12px; flex: none; }
.ccp-tbl {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
  font-family: var(--ds-font-body);
}
.ccp-col-us { width: var(--ccp-col-us); }
.ccp-col-alt { width: var(--ccp-col-alt); }

.ccp-head-cell {
  padding: 0 2px 8px;
  vertical-align: bottom; text-align: center;
  border-bottom: 1px solid var(--ds-color-hairline);
  font-family: var(--ds-font-display);
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.02em; text-transform: uppercase;
  color: var(--ds-color-ink);
}
.ccp-tbl thead td { border-bottom: 1px solid var(--ds-color-hairline); }
.ccp-altname { display: block; line-height: 1.25; }
/* Pełna nazwa kolumny jest dla czytnika ekranu, dopóki nie ma dla niej
   miejsca w kolumnie 56px; wersja skrócona (łamana ręcznie) jest dekoracją. */
.ccp-altname-full { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; }

/* Nagłówek wyróżnionej kolumny = góra karty: gradient marki, pierścień 2,5px
   domykający ramę kolumny od góry, plakietka „Polecane" (jedyne żółte miejsce
   w tabeli). */
/* Kolumna własnej oferty jest zielona, nie niebieska. Płaski --ds-color-success-ink,
   nie gradient: biel na nim ma Lc 91 (próg 90 przy 13px), a żywy --ds-color-success
   dałby tylko Lc 66 — za mało na tekst. Gradientu tu nie ma, bo jeden kolor
   wystarcza (CLAUDE.md → „Test na «wygenerowane»"). */
.ccp-head-us {
  padding: 9px var(--ds-space-1) 8px;
  border-bottom: none;
  border-radius: var(--ds-radius-md) var(--ds-radius-md) 0 0;
  background: var(--ds-color-success-ink);
  color: #fff;
  text-transform: none; letter-spacing: normal;
  box-shadow: 0 0 0 2.5px var(--ds-color-success-ink), var(--ds-shadow-md);
}
.ccp-badge {
  display: block; width: fit-content; margin: 0 auto 5px;
  padding: 2px 5px;
  border-radius: var(--ds-radius-full);
  /* Ciemny tekst na PEŁNYM żółtym ma sufit Lc 75 — wystarcza dopiero od 16px
     (patrz etykieta głównego CTA). Flaga jest z natury mała, więc bierze
     jaśniejszy wariant żółtego i ciemniejszy tekst: Lc 82 przy 12px. Nadal
     jedyne ciepłe miejsce w tabeli, tylko o ton spokojniejsze. */
  background-color: var(--ds-color-cta-solar-tint);
  color: var(--ds-color-cta-solar-ink);
  box-shadow: inset 0 0 0 1px var(--ds-color-cta-solar);
  font-size: 13px; font-weight: 600; letter-spacing: 0.03em; text-transform: uppercase;
}
.ccp-brand { display: block; font-size: 13px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.15; }
/* „SOS" nie da się złamać w środku, więc na mobile idzie w osobną linię. */
.ccp-brand i { display: block; font-style: normal; color: var(--ds-color-on-deep-accent); }
.ccp-brandsub { display: none; }

.ccp-label {
  padding: 7px var(--ds-space-2) 7px var(--ccp-gutter);
  text-align: left; font-weight: 400;
  font-size: 13px; line-height: 1.3;
  /* Pełny --ds-color-ink, nie ink-secondary: to główna treść tabeli i przy
     13px na ciepłym tle każdy punkt Lc jest tu na wagę złota (Lc 98). */
  color: var(--ds-color-ink);
  border-bottom: 1px solid var(--ds-color-hairline);
  text-wrap: pretty;
}
.ccp-cell {
  padding: 6px 0;
  text-align: center; vertical-align: middle;
  border-bottom: 1px solid var(--ds-color-hairline);
}
/* Ciągła rama boczna wyróżnionej kolumny — inset box-shadow, bo border
   na komórkach rozpadłby się na 16 odcinków (DS: wymaga border-collapse:separate). */
.ccp-cell-us {
  background-color: var(--ds-color-success-tint);
  border-bottom-color: var(--ccp-rail-line);
  box-shadow: inset 2.5px 0 0 var(--ds-color-success-ink), inset -2.5px 0 0 var(--ds-color-success-ink);
}

/* Podświetlenie wiersza tylko tam, gdzie jest kursor — pomaga śledzić wiersz.
   Wyróżniona kolumna nie zmienia tła: ma zostać jednolitą kartą. Kolor
   podświetlenia to canvas (biały), nie canvas-warm — sekcja stoi teraz na
   cieplejszym tle, więc podświetlenie w tym samym tonie byłoby niewidoczne. */
@media (hover: hover) and (pointer: fine) {
  .ccp-tbl tbody tr:hover .ccp-label,
  .ccp-tbl tbody tr:hover .ccp-cell:not(.ccp-cell-us) { background-color: var(--ds-color-canvas); }
}

/* Wiersz CTA — domyka ramę wyróżnionej kolumny od dołu i niesie przycisk
   zapisu; sąsiednie komórki (opis, konkurencja) zostają puste. */
.ccp-row-cta td { border-bottom: none; }
/* Selektor dwuklasowy, bo ta komórka nosi też .ccp-cell-us, a reguła
   .ccp-cell-us w bloku desktopowym stoi w pliku NIŻEJ i przy równej
   specyficzności wygrywała — dolna krawędź ramy kolumny znikała od 1024px. */
.ccp-cell-us.ccp-cta-cell {
  padding: 8px 4px 10px;
  border-radius: 0 0 var(--ds-radius-md) var(--ds-radius-md);
  box-shadow:
    inset 2.5px 0 0 var(--ds-color-success-ink),
    inset -2.5px 0 0 var(--ds-color-success-ink),
    inset 0 -2.5px 0 var(--ds-color-success-ink);
}
/* Rozmiar niestandardowy (nie .btn-lg/.btn-sm): kolumna wyróżniona ma na
   mobile tylko 104px (patrz --ccp-col-us wyżej — poszerzona właśnie po to,
   żeby przyciskowi zostało kilka pikseli luzu od ramy). Przycisk NIE wypełnia
   kolumny (width:100% wyglądał jak masywny blok w wąskiej kolumnie) — jest
   dopasowany do treści (inline-flex) i wyśrodkowany przez text-align:center
   z .ccp-cell. Stopień etykiety i min-height zostają na twardym minimum
   z CLAUDE.md (reguła 10 i 15) — tylko padding się ściska. */
.ccp-cta-cell-btn {
  display: inline-flex;
  align-items: center; justify-content: center;
  /* 44px zostaje — to podłoga celu dotykowego (CLAUDE.md, reguła 15).
     ODSTĘPSTWO (decyzja Tomka): etykieta ma 14px, a nie 16px. Reguła 10
     wymienia 16px na CTA jako minimum bez wyjątków i robi to z powodu koloru:
     ciemny tekst na PEŁNYM solarze ma sufit Lc 75, a próg dla 14px to 85.
     Ten przycisk stoi na ścieżce zakupu, więc to najdroższe odstępstwo w tej
     sekcji — jeśli kiedyś wróci do normy, przy 98px kolumny trzeba będzie
     skrócić etykietę („Wybieram" bez wykrzyknika daje ~8px).
     Stopień poza skalą DS (najbliższe są --ds-text-btn-sm 15px i 16px), bo
     projekt chce tu wyraźnie mniejszego napisu niż jeden krok w dół. */
  min-height: 44px;
  padding: 6px 3px;
  font-size: 14px;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

@media (min-width: 1024px) {
  .ccp-cell-us.ccp-cta-cell {
    padding: var(--ds-space-4) var(--ds-space-2) var(--ds-space-5);
    border-radius: 0 0 var(--ds-radius-lg) var(--ds-radius-lg);
    box-shadow:
      inset 3px 0 0 var(--ds-color-success-ink),
      inset -3px 0 0 var(--ds-color-success-ink),
      inset 0 -3px 0 var(--ds-color-success-ink);
  }
  .ccp-cta-cell-btn { min-height: 48px; padding: 12px 22px; font-size: var(--ds-text-btn-lg); }
}

/* Tablet: kolumny robią się szerokie na tyle, żeby typografia wróciła do
   normy DS i żeby nazwy kolumn zmieściły się bez ręcznego łamania. */
@media (min-width: 768px) {
  .ccp { --ccp-col-us: 150px; --ccp-col-alt: 120px; }
  .ccp-label { font-size: 14px; line-height: 1.35; padding-top: 10px; padding-bottom: 10px; }
  .ccp-head-cell { font-size: 11.5px; }
  .ccp-altname-short { display: none; }
  .ccp-altname-full { position: static; width: auto; height: auto; overflow: visible; clip: auto; white-space: normal; line-height: 1.3; }
  .ccp-brand { font-size: 14px; }
  .ccp-brand i { display: inline; }
}

@media (min-width: 1024px) {
  .ccp { --ccp-col-us: 216px; --ccp-col-alt: 180px; }

  /* Tabela wraca do containera. Flaga nie jest już wpięta w krawędź karty,
     tylko stoi nad nią (bez translateY), 6px od góry wrappera. */
  .ccp-tablewrap { margin-top: var(--ds-space-3); margin-inline: 0; padding-top: var(--ds-space-6); }
  .ccp-flag { top: 6px; transform: none; }
  .ccp-flag > span { gap: 5px; padding: 4px 10px 4px 9px; font-size: 13px; }
  .ccp-flag-ic { display: block; width: 14px; height: 14px; }

  /* Od 1024px rolę plakietki przejmuje pływające „Najlepszy wybór" wpięte
     w górną krawędź karty — dwie identyczne pigułki Solar dziesięć pikseli od
     siebie czytałyby się jak błąd, a DS chce w tabeli jednego żółtego miejsca. */
  .ccp-badge { display: none; }

  .ccp-head-cell { font-size: 12px; letter-spacing: 0.06em; padding-bottom: 14px; }
  .ccp-head-us {
    padding: 22px var(--ds-space-3) var(--ds-space-4);
    border-radius: var(--ds-radius-lg) var(--ds-radius-lg) 0 0;
    box-shadow: 0 0 0 3px var(--ds-color-success-ink), var(--ds-shadow-md);
  }
  .ccp-brand { font-size: 18px; line-height: 1.1; }
  .ccp-brandsub {
    display: block; margin-top: 5px;
    font-family: var(--ds-font-body);
    font-size: 13px; font-weight: 400; letter-spacing: normal; text-transform: none;
    opacity: 0.82;
  }

  .ccp-label { font-size: 15px; line-height: 1.4; padding: 13px var(--ds-space-6) 13px var(--ds-space-1); }
  .ccp-cell { padding: 11px 0; }
  .ccp-cell-us {
    border-bottom-color: var(--ccp-rail-line);
    box-shadow: inset 3px 0 0 var(--ds-color-success-ink), inset -3px 0 0 var(--ds-color-success-ink);
  }
}

/* ── Reveal na wejściu w kadr ─────────────────────────────────────────────
   Klasę .ccp-reveal dopina JS (assets/js/course_comparsion.js) — bez JS,
   bez IntersectionObserver i przy prefers-reduced-motion treść jest po prostu
   widoczna. Animujemy tylko opacity i transform; stagger przez --i. */
.ccp-reveal {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity var(--ds-duration-slow) var(--ds-ease-out-soft),
    transform var(--ds-duration-slow) var(--ds-ease-out-soft);
  transition-delay: calc(var(--i, 0) * 45ms);
}
.ccp-reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .ccp-reveal { opacity: 1; transform: none; transition: none; }
}
