/* ==========================================================================
   Moje Atelier — aplikacja klienta
   Kolory wprost z arkusza marki. Biała karta na pudrowym tle, złota
   włoskowata kreska, dużo powietrza. Zero cukierkowego różu.
   ========================================================================== */

/*
 * Barwy siedzą w motywy.css — ten plik dostaje je gotowe i nie wie,
 * który motyw jest włączony. Tutaj zostaje tylko to, co barwą nie jest.
 */
:root {
  --serif: "Cormorant Garamond", Didot, "Playfair Display", Georgia, "Times New Roman", serif;
  --sans:  -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --radius: 16px;
  --gora: env(safe-area-inset-top, 0px);
  --dol:  env(safe-area-inset-bottom, 0px);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.5;
  overscroll-behavior-y: none;
}

/*
 * Zapas na dole strony. Do 09.09.2026 było 84 px — akurat na pasek zakładek.
 * Odkąd nad paskiem stoi pastylka „Podziel się" (dół 70 px, wysokość ~34 px,
 * czyli góra na 104 px), zapas musi ją przepuścić: inaczej po przewinięciu
 * do końca pastylka przykrywała ostatnie wiersze treści przy prawej krawędzi.
 * 116 px = 104 px pastylki + 12 px oddechu. Policzone, nie oszacowane.
 */
body { padding-bottom: calc(116px + var(--dol)); }

h1, h2, h3 { font-family: var(--serif); font-weight: 600; margin: 0; letter-spacing: .01em; }

button, input, select, textarea { font-family: inherit; font-size: inherit; color: inherit; }

/* Mikro-podpis: wersaliki, mocno rozstrzelone. Do etykiet, nie do zdań. */
.label {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}

.zloto { color: var(--gold-dark); }
.cicho { color: var(--muted); }
.srodek { text-align: center; }
.liczby { font-variant-numeric: tabular-nums; }

/* Złota włoskowata linia — jedna kreska robi więcej niż ramka. */
.kreska {
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold-light), var(--gold), var(--gold-light), transparent);
  border: 0;
  margin: 22px 0;
}

.ekran { display: none; }
.ekran.widoczny { display: block; animation: wejscie .45s cubic-bezier(.22,.9,.3,1); }

@keyframes wejscie {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

.strona {
  max-width: 560px;
  margin: 0 auto;
  padding: calc(18px + var(--gora)) 18px 18px;
}

/* -------------------------------- karty ---------------------------------- */

.karta {
  background: var(--white);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px;
  margin-bottom: 16px;
}

.karta > h2 { font-size: 24px; margin-bottom: 4px; }

.pasek-sekcji {
  background: var(--pink);
  color: var(--pink-strong);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  padding: 7px 14px;
  border-radius: 999px;
  display: inline-block;
  margin-bottom: 14px;
}

/* ---------------------------- karta klubowa ------------------------------- */
/*
 * Gwiazda całej aplikacji. Klient otwiera telefon przy ladzie i pokazuje
 * właśnie to, więc kod QR musi być duży, jasny i bez niczego dookoła.
 */

/*
 * Tło i obwódka karty niosą KOLOR POZIOMU (patrz „kolory poziomów"
 * w motywy.css). Bez klasy karta zostaje różowa — czyli dokładnie taka,
 * jaka była, zanim poziomy dostały barwy, i taka, jaką widzi klient
 * na najniższym stopniu drabinki.
 */
.klubowa {
  position: relative;
  border-radius: 22px;
  padding: 24px 22px 26px;
  background: var(--poziom-roz-karta);
  box-shadow: var(--shadow-lift);
  overflow: hidden;
  margin-bottom: 18px;
}

.klubowa.poziom-srebro         { background: var(--poziom-srebro-karta); }
.klubowa.poziom-zloto          { background: var(--poziom-zloto-karta); }
.klubowa.poziom-diament { background: var(--poziom-diament-karta); }

/* cienka obwódka — bez niej karta wygląda jak zwykły biały prostokąt */
.klubowa::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 22px;
  padding: 1px;
  background: var(--poziom-roz-ramka);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.klubowa.poziom-srebro::after         { background: var(--poziom-srebro-ramka); }
.klubowa.poziom-zloto::after          { background: var(--poziom-zloto-ramka); }
.klubowa.poziom-diament::after { background: var(--poziom-diament-ramka); }

/*
 * Atrament karty idzie za jej barwą. Różowy numer karty (#AC5163) daje na
 * srebrze 3,99:1, a na złocie 3,2:1 — czyli poniżej progu 4,5:1; to samo
 * dotyczy cichych podpisów. Każda rodzina ma więc własną parę atramentów,
 * policzoną w motywy.css. Poziom różowy wskazuje z powrotem na role motywu,
 * więc jego karta wygląda dokładnie tak, jak wyglądała.
 */
.klubowa .kod-karty { color: var(--poziom-roz-tekst); }
.klubowa .label     { color: var(--poziom-roz-cichy); }

.klubowa.poziom-srebro .kod-karty         { color: var(--poziom-srebro-tekst); }
.klubowa.poziom-srebro .label             { color: var(--poziom-srebro-cichy); }
.klubowa.poziom-zloto .kod-karty          { color: var(--poziom-zloto-tekst); }
.klubowa.poziom-zloto .label              { color: var(--poziom-zloto-cichy); }
/*
 * DIAMENT jest wyjątkiem od reguły „jedna para atramentów": karta idzie
 * po przekątnej z jasnej platyny w czarny diament (1:1 z makiety), więc
 * imię i etykieta u góry (jasna strefa) i numer karty z podpisem u dołu
 * (ciemna strefa, pod kodem QR) potrzebują PRZECIWNYCH atramentów —
 * patrz tabela kontrastów w motywy.css.
 */
.klubowa.poziom-diament .klubowa-imie     { color: var(--poziom-diament-tekst-gora); }
.klubowa.poziom-diament .klubowa-kto .label { color: var(--poziom-diament-cichy-gora); }
.klubowa.poziom-diament .kod-karty        { color: var(--poziom-diament-tekst); }
.klubowa.poziom-diament .label.srodek     { color: var(--poziom-diament-cichy); }

/*
 * Rozbłysk w dolnym prawym rogu — refleks światła na wypolerowanym
 * kamieniu, 1:1 z makiety (diament-propozycje.html, .c-karta::before).
 * Zawężony maską do samego rogu, żeby nie podjeżdżał pod numer karty —
 * ten ma swój kontrast policzony osobno (patrz wyżej). `.klubowa` ma
 * overflow:hidden, więc róg jest przycięty do zaokrąglenia karty bez
 * dodatkowego border-radius tutaj.
 */
.klubowa.poziom-diament::before {
  content: '';
  position: absolute;
  right: 0; bottom: 0;
  width: 46%; height: 34%;
  pointer-events: none;
  background:
    repeating-linear-gradient(118deg, transparent 0 13px, rgba(255,255,255,.20) 13px 15px, transparent 15px 29px, rgba(255,255,255,.10) 29px 31px),
    radial-gradient(80% 80% at 100% 100%, rgba(220,230,239,.80) 0%, rgba(168,181,195,.40) 20%, rgba(104,114,126,.15) 38%, transparent 56%);
  mask-image: radial-gradient(120% 120% at 100% 100%, #000 0%, #000 30%, transparent 66%);
  -webkit-mask-image: radial-gradient(120% 120% at 100% 100%, #000 0%, #000 30%, transparent 66%);
}

/*
 * Sheen — pasek światła po przekątnej, jak na wypolerowanym kamieniu.
 * Element stoi w HTML na KAŻDYM poziomie (pierwsze dziecko karty, zaraz
 * po otwierającym div.klubowa), ale bez tła jest niewidoczny; tylko
 * diament dokłada mu gradient. Kolejność w DOM (przed resztą karty)
 * trzyma go POD numerem, kodem QR i pastylką bez dopisywania z-index
 * gdziekolwiek indziej.
 */
.klubowa .sheen {
  position: absolute;
  inset: -30% -50%;
  transform: rotate(-8deg);
  pointer-events: none;
}
.klubowa.poziom-diament .sheen {
  background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,.42) 46%, rgba(255,255,255,.12) 51%, transparent 66%);
}

/*
 * Iskry scyntylacji — siedem sztuk, 1:1 z makiety co do barw/animacji.
 * Markup dokłada `rysujIskry()` w app.js WYŁĄCZNIE gdy poziom = diament
 * (patrz komentarz tam) — inne poziomy nie mają tych elementów w DOM
 * wcale, więc nie potrzebują tu żadnego przełącznika widoczności.
 */
.klubowa.poziom-diament .iskra {
  position: absolute;
  z-index: 2;
  pointer-events: none;
  color: #2E6690;
  filter: drop-shadow(0 0 1.5px #FFFFFF) drop-shadow(0 0 4px rgba(46,102,144,.65));
  animation: iskra-mig 3.2s ease-in-out infinite;
}
.klubowa.poziom-diament .iskra.iskra-grafit {
  color: #F6F7F9;
  filter: drop-shadow(0 0 1.5px rgba(255,255,255,.9)) drop-shadow(0 0 4px rgba(200,212,224,.55));
}
@keyframes iskra-mig {
  0%, 100% { opacity: .28; transform: scale(.74); }
  50%      { opacity: 1;   transform: scale(1.18); }
}
@media (prefers-reduced-motion: reduce) {
  .klubowa.poziom-diament .iskra { animation: none; opacity: .9; }
}

.klubowa-gora {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 18px;
}

.klubowa-logo { width: 104px; height: 104px; flex: 0 0 auto; }
.klubowa-logo img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* ---------------------------------- ikony ---------------------------------- */
/*
 * Rysunki kreską zamiast emoji: emoji wyglądają inaczej na iPhonie, Androidzie
 * i w Windowsie, więc rozjeżdżają spójność marki. Kolor bierze się z `color`,
 * dzięki czemu ta sama ikona gra różem w pasku i złotem na kartach.
 */
.ikona {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
}

.ikona.duza { width: 34px; height: 34px; }
.ikona.zlota { color: var(--gold); }

/* Znak marki jako obrazek — tam, gdzie ikoną jest samo logo. */
img.ikona { stroke: none; }

.klubowa-kto { flex: 1; min-width: 0; }
.klubowa-imie {
  font-family: var(--serif);
  font-size: 27px;
  line-height: 1.15;
  margin: 2px 0 3px;
  overflow-wrap: anywhere;
}

/* Plakietka poziomu — jedyne miejsce, gdzie złoto gra dużą płaszczyzną,
   i dlatego tekst na niej jest ciemny, nigdy biały. */
.plakietka {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  background: linear-gradient(135deg, #FBF1DA, var(--gold-light) 45%, #F6E8C6);
  color: var(--gold-dark);
  border: 1px solid rgba(192, 147, 56, .45);
}

/* Pastylka w barwie poziomu. Tło i napis są STAŁE, nie z motywu — sygnał
   dla kasy ma znaczyć to samo na telefonie w różu i w grafitowym. */
.plakietka.poziom-roz {
  background: var(--poziom-roz-pastylka);
  color: var(--poziom-roz-napis);
  border-color: var(--poziom-roz-obwodka);
}

.plakietka.poziom-srebro {
  background: var(--poziom-srebro-pastylka);
  color: var(--poziom-srebro-napis);
  border-color: var(--poziom-srebro-obwodka);
}

.plakietka.poziom-zloto {
  background: var(--poziom-zloto-pastylka);
  color: var(--poziom-zloto-napis);
  border-color: var(--poziom-zloto-obwodka);
}

.plakietka.poziom-diament {
  background: var(--poziom-diament-pastylka);
  color: var(--poziom-diament-napis);
  border-color: var(--poziom-diament-obwodka);
}

/*
 * Pastylka poziomu przy kodzie QR — ta, którą kasjerka czyta z drugiej strony
 * lady. Dlatego jest duża (20 px, wersaliki, gruba kreska), a nie dyskretna
 * jak plakietki w listach. Stoi POD kodem, w osi wzroku: kod → poziom → numer.
 */
.poziom-pas {
  display: flex;
  justify-content: center;
  margin: 0 0 12px;
}

.plakietka-duza {
  font-size: 20px;
  line-height: 1.1;
  padding: 10px 22px;
  letter-spacing: .18em;
  border-width: 2px;
  max-width: 100%;
  text-align: center;
  overflow-wrap: anywhere;
}

.qr-pudelko {
  position: relative;
  background: var(--white);
  border-radius: 18px;
  padding: 14px;
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
  margin: 0 auto 16px;
  width: min(300px, 78vw);
  aspect-ratio: 1;
}

.qr-pudelko img, .qr-pudelko svg { width: 100%; height: 100%; display: block; }

/* Logo siedzi w środku kodu QR po stronie serwera — nakładka w przeglądarce
   nigdy nie trafiłaby w wycięty otwór co do piksela i zasłaniałaby moduły. */

.kod-karty {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 19px;
  letter-spacing: .12em;
  font-weight: 700;
  color: var(--pink-strong);
  text-align: center;
  margin-bottom: 2px;
}

/* --------------------------- postęp do poziomu ---------------------------- */

.postep-tor {
  height: 8px;
  background: var(--pink-soft);
  border-radius: 999px;
  overflow: hidden;
  margin: 10px 0 8px;
}

.postep-wypelnienie {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--pink-accent), var(--pink-strong));
  width: 0;
  transition: width 1.1s cubic-bezier(.22,.9,.3,1);
}

/* -------------------------------- pieczątki -------------------------------- */

.pieczatki {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(38px, 1fr));
  gap: 10px;
  margin-top: 4px;
}

.pieczatka {
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1.5px dashed var(--line);
  display: grid;
  place-items: center;
  font-size: 12px;
  color: var(--muted);
  background: #FFFCFD;
  transition: transform .3s cubic-bezier(.34,1.56,.64,1);
}

/*
 * Przybita pieczątka to znak Atelier Słodyczy — różowe koło z kubeczkiem.
 * Używamy znak.png, a nie pełnego logo: przy tym rozmiarze napis pod
 * kubeczkiem zamieniłby się w szlaczek, o czym wprost mówi księga marki.
 */
.pieczatka.pelna {
  border: 1px solid transparent;
  /* Kadr przybliżony: w pliku znak zajmuje niecałe 40% wysokości, więc
     przy 38 pikselach złota kreska niemal znika. Kadrujemy ciaśniej —
     obcięty róż i tak zastępuje różowe tło kółka. */
  background: url('/img/znak.png') center / 168% no-repeat;
  box-shadow: inset 0 0 0 1px rgba(192, 147, 56, .28);
}

.pieczatka.pelna::before { content: none; }
.pieczatka.swieza { animation: przybicie .5s cubic-bezier(.34,1.56,.64,1); }

@keyframes przybicie {
  0%   { transform: scale(1.9); opacity: 0; }
  60%  { transform: scale(.92); opacity: 1; }
  100% { transform: scale(1); }
}

/* -------------------------------- urodziny --------------------------------- */

.urodziny {
  position: relative;
  overflow: hidden;
  background: var(--urodziny-tlo);
  border: 1px solid var(--gold-light);
}

/* Tort w rogu jako znak wodny — ozdoba, nie treść, więc nie odbiera uwagi liczbom. */
.urodziny-znak {
  position: absolute;
  right: -14px;
  top: -10px;
  width: 108px;
  height: 108px;
  fill: none;
  stroke: currentColor;
  opacity: .16;
  pointer-events: none;
}

.urodziny-liczba {
  font-family: var(--serif);
  font-size: 56px;
  line-height: 1;
  color: var(--pink-strong);
  font-variant-numeric: tabular-nums;
}

.rabat-duzy {
  font-family: var(--serif);
  font-size: 44px;
  line-height: 1;
  color: var(--gold-dark);
}

/* --------------------------------- kupony ---------------------------------- */

.kupon {
  position: relative;
  display: flex;
  align-items: center;
  gap: 16px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 15px 16px;
  margin-bottom: 10px;
  overflow: hidden;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  transition: transform .12s ease, box-shadow .2s ease;
}

.kupon:active { transform: scale(.99); }
.kupon:hover { box-shadow: 0 6px 18px rgba(172, 81, 99, .12); }

/* Strzałka mówiąca „to się otwiera" — bez niej rabat wygląda na zwykły wiersz listy. */
.kupon .strzalka {
  flex: 0 0 auto;
  color: var(--pink-accent);
  font-size: 22px;
  line-height: 1;
}

/* pionowa złota kreska — sygnał „to jest wartość", nie zwykły wiersz listy */
.kupon::before {
  content: '';
  position: absolute;
  left: 0; top: 10px; bottom: 10px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: linear-gradient(180deg, var(--gold-light), var(--gold));
}

.kupon-wartosc {
  font-family: var(--serif);
  font-size: 30px;
  line-height: 1;
  color: var(--pink-strong);
  flex: 0 0 auto;
  min-width: 62px;
  text-align: center;
}

.kupon-gratis { font-size: 26px; }
.kupon-tresc { flex: 1; min-width: 0; }
.kupon-nazwa { font-weight: 600; margin-bottom: 2px; }

.kupon-kod {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 13px;
  letter-spacing: .1em;
  color: var(--gold-dark);
  font-weight: 700;
}

/* --------------------------------- promocja --------------------------------- */

.promocja {
  background: var(--promocja-tlo);
  border: 1px solid var(--line);
  cursor: pointer;
}

/*
 * Kicker karty promocji — wariant A „kapitalik i kreska" (wybór Karola
 * 14.09.2026, makieta Oferta/materialy/karty-promocji-warianty.html):
 * żadnego tła ani pastylki — rozstrzelone wersaliki serifem w ciemnym
 * złocie i krótka złota kreska pod słowem, przycięta do szerokości podpisu,
 * nie karty. Font z --serif, czyli ta sama rodzina co nagłówki aplikacji
 * (z systemowym zapasem) — zero nowych webfontów. Tekst kickera liczy
 * `kickerPromocji` w akordeon.js: nazywa termin, nie zawsze „dzisiaj".
 */
.promocja-kicker {
  display: inline-block;
  position: relative;
  font-family: var(--serif);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--gold-dark);
  padding-bottom: 9px;
  margin-bottom: 13px;
}

.promocja-kicker::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 30px;
  height: 1px;
  background: linear-gradient(90deg, var(--gold), transparent);
}

/*
 * Kafel jest domyślnie ZWINIĘTY: tytuł + miejsce. Szczegóły (podtytuł,
 * treść, procent) pokazuje dopiero klasa `rozwinieta`, którą nadaje
 * akordeon w app.js (logika w akordeon.js, najwyżej dwa kafle naraz).
 */
.promocja:not(.rozwinieta) .promocja-procent,
.promocja:not(.rozwinieta) .promocja-szczegoly {
  display: none;
}

/*
 * Obwódka = SIŁA promocji (kolumna `promotions.sila`, 1..3). Kolory wprost
 * z marki Atelier Słodyczy (skill atelier-slodyczy-brand) i STAŁE, nie
 * z motywu — jak przy pastylce miejsca: siła ma znaczyć to samo w każdym
 * motywie. Wszystkie trzy czytelne na jasnym tle kart:
 *   1 — róż z logo #FAC7CE (delikatna, codzienna),
 *   2 — róż mocny/burgund #AC5163 (mocna),
 *   3 — złoto #C09338, grubsza kreska (HIT).
 */
.promocja-sila-1 { border-color: #FAC7CE; }
.promocja-sila-2 { border-color: #AC5163; }
.promocja-sila-3 { border-color: #C09338; border-width: 2px; }

.promocja-procent {
  font-family: var(--serif);
  font-size: 40px;
  line-height: 1;
  color: var(--pink-strong);
}

/* --------------------------------- przyciski -------------------------------- */

.przycisk {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 15px 20px;
  border-radius: 12px;
  border: 0;
  background: var(--pink-strong);
  color: var(--white);
  font-size: 17px;
  font-weight: 600;
  cursor: pointer;
  transition: transform .12s ease, box-shadow .2s ease, opacity .2s;
  box-shadow: 0 6px 18px rgba(172, 81, 99, .28);
}

.przycisk:active { transform: translateY(1px) scale(.995); }
.przycisk[disabled] { opacity: .5; cursor: default; box-shadow: none; }

.przycisk.lekki {
  background: var(--white);
  color: var(--pink-strong);
  border: 1px solid var(--line);
  box-shadow: none;
}

.przycisk.tekstowy {
  background: none;
  color: var(--muted);
  box-shadow: none;
  font-weight: 500;
  font-size: 15px;
  padding: 12px;
  width: auto;
}

/* przycisk operacji nieodwracalnej — ekran usuwania karty (#ekran-usun) */
.przycisk.groza { background: var(--blad); box-shadow: none; }

/* ---------------------------------- formularz -------------------------------- */

.pole { margin-bottom: 16px; }

.pole label {
  display: block;
  font-size: 13px;
  font-weight: 700;
  color: var(--pink-strong);
  margin-bottom: 6px;
  letter-spacing: .02em;
}

.pole input, .pole select {
  width: 100%;
  padding: 14px 15px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--white);
  outline: none;
  transition: border-color .2s, box-shadow .2s;
}

.pole input:focus, .pole select:focus {
  border-color: var(--pink-accent);
  box-shadow: 0 0 0 4px rgba(233, 163, 175, .18);
}

.pole .podpowiedz { font-size: 13px; color: var(--muted); margin-top: 6px; }

/* Data urodzin: trzy listy (dzień / miesiąc / rok) — powód w app.js.
   Miesiąc dostaje najwięcej miejsca („październik" jest długi). */
.wybor-daty { display: flex; gap: 8px; }
.wybor-daty select { flex: 1 1 0; min-width: 0; padding-left: 10px; padding-right: 10px; }
.wybor-daty select:nth-child(2) { flex: 1.6 1 0; }
.wybor-daty select:disabled { opacity: .55; }

.zgoda {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 13px;
  border-radius: 12px;
  background: var(--pink-soft);
  margin-bottom: 10px;
  cursor: pointer;
  font-size: 14px;
  line-height: 1.45;
}

.zgoda input { width: 21px; height: 21px; flex: 0 0 auto; margin: 1px 0 0; accent-color: var(--pink-strong); }

/* odnośnik w zdaniu — m.in. link do regulaminu przy zakładaniu karty */
.odnosnik {
  color: var(--pink-strong);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ----------------------------------- pasek dolny ------------------------------ */

.pasek-dolny {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  display: none;
  background: rgba(255, 255, 255, .93);
  backdrop-filter: blur(14px);
  border-top: 1px solid var(--line);
  padding: 8px 8px calc(8px + var(--dol));
  z-index: 40;
}

.pasek-dolny.widoczny { display: flex; }

.pasek-dolny button {
  flex: 1;
  border: 0;
  background: none;
  padding: 8px 4px 6px;
  border-radius: 12px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
  display: grid;
  gap: 3px;
  justify-items: center;
}

.pasek-dolny button.aktywna { color: var(--pink-strong); background: var(--pink-soft); }

/* ------------------------- rabat na pełnym ekranie -------------------------- */
/*
 * Klient naciska rabat i dostaje kod karty na cały ekran. Jasne tło i duży
 * kod to nie estetyka, tylko warunek odczytu: skaner przy ladzie dostaje
 * wtedy najwięcej kontrastu, także przy przyciemnionym ekranie telefonu.
 */
.zaslona {
  position: fixed;
  inset: 0;
  background: rgba(26, 23, 24, .55);
  display: none;
  place-items: center;
  padding: 16px;
  z-index: 70;
}

.zaslona.widoczna { display: grid; }

.okno-rabat {
  background: var(--white);
  border-radius: 22px;
  padding: 26px 22px;
  max-width: 420px;
  width: 100%;
  max-height: 92vh;
  overflow-y: auto;
  box-shadow: var(--shadow-lift);
  animation: wejscie .3s cubic-bezier(.22,.9,.3,1);
}

.rabat-naglowek {
  font-family: var(--serif);
  font-size: 62px;
  line-height: 1;
  color: var(--pink-strong);
  text-align: center;
  margin: 6px 0 4px;
}

/*
 * Powitanie po zatwierdzeniu karty. Biała karta, złota włoskowata linia
 * i róż jako jedyny mocny akcent — złoto zostaje przy detalu, nie robi tła.
 */
.powitanie-znak { width: 78px; height: 78px; display: block; margin: 2px auto 12px; }

.powitanie-tytul {
  font-family: var(--serif);
  font-size: 30px;
  line-height: 1.15;
  margin: 4px 0 0;
  color: var(--pink-strong);
}

.powitanie-kupon {
  border: 1px solid var(--gold-light);
  border-radius: 16px;
  background: var(--pink-soft);
  padding: 10px 14px 14px;
  margin: 16px 0 14px;
}

.powitanie-kupon .rabat-naglowek { font-size: 48px; margin: 0; }

/* ------------------------------------ drobiazgi -------------------------------- */

/*
 * Krótki komunikat na dole. Od 09.09.2026 stoi WYŻEJ (96 → 120 px): pod nim
 * siedzi teraz pastylka „Podziel się" i przy szerokości 375 px jedno
 * nachodziło na drugie — zmierzone, nie oszacowane.
 */
.powiadomienie {
  position: fixed;
  left: 50%;
  bottom: calc(120px + var(--dol));
  transform: translate(-50%, 20px);
  background: var(--ink);
  color: var(--white);
  padding: 13px 20px;
  border-radius: 12px;
  font-size: 15px;
  max-width: min(420px, calc(100vw - 32px));
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s, transform .25s;
  z-index: 60;
}

.powiadomienie.widoczne { opacity: 1; transform: translate(-50%, 0); }
.powiadomienie.zle { background: #8E2A22; }

.wiersz { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }

/* Kropkowany łącznik — nazwa po lewej, liczba po prawej, oko trafia bez błądzenia. */
.wiersz .lacznik {
  flex: 1;
  border-bottom: 1px dotted var(--line);
  transform: translateY(-4px);
}

.wiersz .wartosc { font-weight: 700; font-variant-numeric: tabular-nums; }

.ladowanie {
  display: grid;
  place-items: center;
  min-height: 60vh;
  gap: 16px;
  color: var(--muted);
}

.kolo {
  width: 34px; height: 34px;
  border: 2px solid var(--line);
  border-top-color: var(--pink-strong);
  border-radius: 50%;
  animation: obrot .8s linear infinite;
}

@keyframes obrot { to { transform: rotate(360deg); } }

.pusto { text-align: center; color: var(--muted); padding: 26px 10px; font-size: 15px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* „Dziś" zamiast liczby jest szersze — zmniejszamy, żeby nie łamało kolumny. */
.urodziny-liczba.slowo { font-size: 40px; }

/* Znak marki w miejscu wartości kuponu, gdy nagrodą jest wyrób, a nie procent. */
.kupon-gratis-znak { width: 46px; height: 46px; display: block; margin: 0 auto; }

/* -------------------------------- opinia ----------------------------------- */

.opinia {
  background: linear-gradient(135deg, #FFF9EC, var(--powierzchnia) 65%);
  border: 1px solid var(--zloto-jasne);
}

.opinia-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 13px 15px;
  margin-bottom: 8px;
  border-radius: 12px;
  border: 1px solid var(--linia);
  background: var(--powierzchnia);
  color: var(--tekst);
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: transform .12s ease, border-color .2s;
}

.opinia-link:active { transform: scale(.99); }
.opinia-link:hover { border-color: var(--zloto); }

.opinia-link .nazwa { font-weight: 600; }
.opinia-link .opis { font-size: 14px; color: var(--tekst-cichy); }
.opinia-link .strzalka { color: var(--zloto); font-size: 22px; line-height: 1; }

/* --------------------------- historia zakupów ------------------------------ */
/*
 * Lista zakupów i oceny wyrobów. Zasada ta sama, co w reszcie aplikacji:
 * biała karta, złota kreska, dużo powietrza — a wszystko, co się dotyka,
 * ma co najmniej 44 piksele, bo to ekran telefonu trzymanego jedną ręką.
 */

/* Karta, która jest przyciskiem — wejście do historii z ekranu karty. */
.karta-przycisk {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  border: 0;
  text-align: left;
  cursor: pointer;
  transition: transform .12s ease, box-shadow .2s ease;
}

.karta-przycisk:active { transform: scale(.995); }
.karta-przycisk .karta-przycisk-tresc { flex: 1; min-width: 0; display: block; }
.karta-przycisk .karta-przycisk-tytul { font-weight: 600; display: block; }
.karta-przycisk .strzalka { color: var(--gold); font-size: 24px; line-height: 1; }

/* Jeden zakup: nagłówek do dotknięcia, pod nim schowane pozycje paragonu. */
.zakup {
  background: var(--white);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin-bottom: 12px;
  overflow: hidden;
}

.zakup-gora {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 16px 18px;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
}

.zakup-opis { flex: 1; min-width: 0; display: block; }
.zakup-kiedy { display: block; font-weight: 600; }
.zakup-gdzie { display: block; font-size: 14px; }
.zakup-kwota { font-weight: 700; white-space: nowrap; }

.zakup-gora .strzalka {
  color: var(--gold);
  font-size: 22px;
  line-height: 1;
  transition: transform .18s ease;
}

.zakup.otwarty .zakup-gora .strzalka { transform: rotate(90deg); }

.pozycja {
  padding: 14px 18px 16px;
  border-top: 1px solid var(--line);
}

.pozycja-gora {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.pozycja-nazwa { font-weight: 600; }
.pozycja-cena { font-size: 14px; white-space: nowrap; }

/* Gwiazdki. Puste są konturowe, wystawione — pełne, złote. */
.gwiazdki { display: flex; gap: 2px; margin-top: 8px; }

.gwiazdka {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  background: none;
  padding: 0;
  border-radius: 10px;
  color: var(--muted);
  cursor: pointer;
  transition: transform .12s ease, color .15s;
}

.gwiazdka .ikona { width: 26px; height: 26px; }
.gwiazdka:active { transform: scale(.9); }
.gwiazdka.pelna { color: var(--gold-dark); }

.ocena-komentarz { display: flex; gap: 8px; margin-top: 10px; }
/* [hidden] przegrywa z display:flex — pole komentarza ma naprawde znikac */
.ocena-komentarz[hidden] { display: none; }

.ocena-pole {
  flex: 1;
  min-width: 0;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--white);
  font-size: 15px;
}

.ocena-pole:focus { outline: 2px solid var(--pink-strong); outline-offset: 1px; }
.ocena-zapisz { width: auto; padding: 12px 16px; font-size: 15px; white-space: nowrap; }

/* ==========================================================================
   Plansza „Dodaj skrót na ekran główny"
   --------------------------------------------------------------------------
   Pisane pod OSOBĘ STARSZĄ trzymającą telefon w jednej ręce: duże litery,
   jeden krok pod drugim, zero skrótów myślowych. Zasłona jest NIEPRZEZROCZYSTA
   — półprzezroczysta mgła nad aplikacją czyta się jak usterka, a nie jak
   prośba. Wyjścia są na dole i są celowo mniejsze od kroków, ale nie mniejsze
   niż 44 piksele wysokości dotyku.
   ========================================================================== */

.skrot-zaslona {
  position: fixed;
  inset: 0;
  z-index: 90;                 /* nad wszystkim, także nad planszą powiadomień */
  display: flex;
  justify-content: center;
  /*
   * Pionowo srodkujemy przez `safe center`: przy dlugiej planszy zwykle
   * `center` w kontenerze z przewijaniem ucina GORE, czyli tytul i pierwszy
   * krok. Starsza przegladarka pominie te linie i zostanie przy `center`.
   */
  align-items: center;
  align-items: safe center;
  background: var(--bg);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: calc(20px + var(--gora)) 16px calc(20px + var(--dol));
}

.skrot-zaslona[hidden] { display: none; }

/* Pod planszą nie ma co przewijać — strona ma stać w miejscu. */
body.skrot-blokada { overflow: hidden; }

.skrot-plansza {
  width: 100%;
  max-width: 420px;
  text-align: center;
}

.skrot-znak {
  width: 76px;
  height: 76px;
  border-radius: 20px;
  box-shadow: var(--shadow);
  margin-bottom: 14px;
}

.skrot-tytul {
  font-size: 32px;
  line-height: 1.14;
  color: var(--pink-strong);
  margin: 0 0 8px;
}

.skrot-lead {
  font-size: 17px;
  line-height: 1.45;
  color: var(--muted);
  margin: 0 0 20px;
}

/*
 * Uwaga: wlasne `display` bije atrybut `hidden` z przegladarki. Bez reguly
 * nizej wszystkie warianty krokow pokazywalyby sie naraz — sprawdzone na zywo.
 */
.skrot-kroki { display: block; }
.skrot-kroki[hidden] { display: none; }

/* Jeden krok = numer, ikona systemowa, zdanie. Nic więcej się tu nie zmieści. */
.skrot-krok {
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: center;
  gap: 14px;
  text-align: left;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 14px 16px;
  box-shadow: var(--shadow);
}

.skrot-krok.jeden { grid-template-columns: auto 1fr; }

.skrot-numer {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--pink-strong);
  color: var(--white);
  font-size: 19px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.skrot-ikona {
  width: 44px;
  height: 44px;
  color: var(--gold-dark);
  flex: none;
}

.skrot-tekst {
  font-size: 18px;
  line-height: 1.32;
}

.skrot-tekst b { font-weight: 700; color: var(--ink); }

/* Strzałka między krokami — prowadzi wzrok w dół, nie zdobi. */
.skrot-strzalka {
  display: block;
  width: 22px;
  height: 30px;
  margin: 6px auto;
  color: var(--gold-light);
}

.skrot-uwaga {
  font-size: 17px;
  line-height: 1.4;
  text-align: left;
  background: var(--pink-soft);
  border-radius: 16px;
  padding: 14px 16px;
  margin: 0 0 12px;
}

.skrot-duzy {
  font-size: 20px;
  padding: 18px 20px;
  border-radius: 14px;
  margin-top: 14px;
}

.skrot-wyjscia {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin-top: 22px;
}

.skrot-wyjscie {
  text-decoration: underline;
  min-height: 44px;
}

.skrot-kropka { color: var(--muted); }

/* Niskie ekrany (iPhone SE w poziomie, stare Androidy) — zbieramy powietrze. */
@media (max-height: 680px) {
  .skrot-znak { width: 56px; height: 56px; margin-bottom: 8px; }
  .skrot-tytul { font-size: 27px; }
  .skrot-lead { font-size: 16px; margin-bottom: 14px; }
  .skrot-krok { padding: 11px 13px; gap: 11px; }
  .skrot-ikona { width: 38px; height: 38px; }
  .skrot-tekst { font-size: 17px; }
  .skrot-strzalka { height: 22px; margin: 3px auto; }
}


/* --------------------- miejsce, w którym promocja działa ------------------- */
/*
 * Złota pastylka pod tytułem promocji. Klient pyta „gdzie?" zanim zapyta
 * „za ile", a pracownia ma dwa punkty oddalone o pół miasta — promocja bez
 * adresu kończy się rozmową przy ladzie, której nikt nie chce prowadzić.
 *
 * Tło pastylki jest STAŁE, nie z motywu — dokładnie jak przy plakietce
 * poziomu. Dzięki temu złoto zostaje złotem w każdym motywie, także
 * w grafitowym, gdzie złoto z palety robi za akcent i pastylka zlałaby się
 * z przyciskami.
 *
 * Kontrast policzony, nie oceniony okiem: napis #6B4E18 na najciemniejszym
 * końcu gradientu (#EBD8A6) daje 5,46:1 — powyżej progu WCAG 4,5:1.
 * Pinezka #8A6520 na tym samym tle: 3,76:1, powyżej progu 3:1 dla grafiki.
 */
.promocja-miejsce {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: 7px;
  padding: 4px 11px 4px 8px;
  border-radius: 999px;
  background: linear-gradient(135deg, #FDF6E4, #F1E1B6 60%, #EBD8A6);
  border: 1px solid rgba(192, 147, 56, .55);
  color: #6B4E18;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.25;
  max-width: 100%;
}

.promocja-miejsce svg {
  width: 15px;
  height: 15px;
  flex: none;
  color: #8A6520;
}

.promocja-miejsce-nazwa { overflow-wrap: anywhere; }

/* ========================= tabela poziomów w regulaminie =================== */
/*
 * Drabinka poziomów w regulaminie (09.09.2026, korekta Karola). Przedtem był
 * to ciąg zdań; żeby porównać dwa poziomy, trzeba je było czytać. Tabela
 * porównuje się wzrokiem, w pionie — i mieści się na 375 px bez przewijania
 * w bok, bo nagłówki są jednowyrazowe, a liczby idą cyfrą tabelaryczną.
 *
 * `overflow-x: auto` na opakowaniu jest siatką bezpieczeństwa: gdyby ktoś
 * nazwał poziom „Diamentowy Ambasador", tabela ma się przewinąć, a nie
 * rozepchnąć całej strony.
 */
#regulamin-poziomy { overflow-x: auto; }

.tabela-poziomy {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.tabela-poziomy th,
.tabela-poziomy td {
  padding: 9px 6px;
  text-align: left;
  border-bottom: 1px solid var(--linia);
  vertical-align: top;
}

.tabela-poziomy th {
  font-size: 11.5px;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--zloto-ciemne);
  border-bottom: 1px solid var(--zloto-jasne);
}

.tabela-poziomy th:first-child,
.tabela-poziomy td:first-child { padding-left: 0; }

.tabela-poziomy th:last-child,
.tabela-poziomy td:last-child { padding-right: 0; }

.tabela-poziomy td:first-child { font-weight: 700; color: var(--tekst); }

.tabela-poziomy .liczba {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/*
 * Nagłówki MUSZĄ się łamać, komórki NIE. Przy `nowrap` na nagłówkach tabela
 * urosła na 375 px do 352 px w polu szerokim na 299 i ostatnia kolumna
 * uciekała za krawędź (zmierzone na żywo). „Rabat stały" łamie się teraz na
 * dwie linijki, a liczby zostają w jednym kawałku.
 */
.tabela-poziomy th.liczba { white-space: normal; }

.tabela-poziomy tbody tr:last-child th,
.tabela-poziomy tbody tr:last-child td { border-bottom: 0; }

/* ================================= stopka ================================== */
/*
 * Stopka adresowa na końcu ekranu karty i regulaminu — tak jak na stronie
 * www. Do tej pory aplikacja nie mówiła NIGDZIE, gdzie nas szukać i pod jaki
 * numer zadzwonić w sprawie tortu.
 *
 * Dyskretnie: drobny tekst, cicha barwa, złota włoskowata kreska u góry.
 * Ma być na miejscu, gdy ktoś jej szuka, i nie odciągać wzroku od karty.
 * Barwy z ról motywu, więc stopka wygląda swojo w każdym z nich.
 *
 * Wszystko, co się dotyka, ma co najmniej 44 piksele — telefon trzymany
 * jedną ręką, a wśród klubowiczów sporo osób starszych.
 */
.stopka {
  margin: 28px 0 8px;
  padding-top: 18px;
  border-top: 1px solid var(--zloto-jasne);
  font-size: 14px;
  line-height: 1.45;
  color: var(--tekst-cichy);
}

.stopka-nazwa {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--zloto-ciemne);
  margin-bottom: 13px;
}

/*
 * Punkt sprzedaży w stopce jest LINKIEM do Map Google (09.09.2026).
 * Wysokość co najmniej 44 px — pinezka na telefonie musi dać się trafić
 * kciukiem, a wśród klubowiczów jest sporo osób starszych.
 * Barwy zostają dokładnie te co przedtem: adres nie ma nagle wyglądać
 * jak przycisk, ma tylko dać się dotknąć.
 */
/*
 * TELEFON PRZY PUNKCIE (09.09.2026, korekta Karola). Numer stoi obok adresu
 * swojego punktu, a nie w osobnym wersie na dole — bo jeden ogólny numer
 * wysyłał pytania o chleb do kawiarni.
 *
 * Pastylka z numerem leży NA ABSOLUCIE, w wolnym miejscu po prawej od krótkiej
 * nazwy punktu. To nie ozdoba układu, tylko warunek: gdyby numer stał w rzędzie
 * flex, zabrałby adresowi tyle szerokości, że „ul. Reymonta 76, 44-200 Rybnik"
 * łamałoby się na dwie linijki — i stopka zamiast się skrócić, urosłaby.
 * Nazwa punktu dostaje wolny margines po prawej, żeby nie wjechać pod pastylkę.
 *
 * Numer NIE MOŻE być zagnieżdżony w linku do mapy — `<a>` w `<a>` jest
 * nieprawidłowe i przeglądarka i tak by je rozerwała. Stąd wspólny rodzic.
 */
.stopka-punkt-para {
  position: relative;
  margin-bottom: 11px;
}

.stopka-punkt {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin-bottom: 11px;
  min-height: 44px;
  padding: 3px 0;
  color: inherit;
  text-decoration: none;
}

.stopka-punkt-para .stopka-punkt { margin-bottom: 0; }
.stopka-punkt-para .nazwa { padding-right: 118px; }

/*
 * WYSOKOŚĆ PASTYLKI JEST WYMIAREM ROBOCZYM, nie kwestią gustu.
 *
 * Punkt zajmuje dwie linijki: nazwę (u góry) i adres (pod nią). Pastylka wisi
 * przy prawej krawędzi i ma się zmieścić W LINIJCE Z NAZWĄ — nazwa jest krótka,
 * więc miejsca tam jest w bród. Wysoka pastylka schodziła na linijkę z adresem
 * i nachodziła na „Rybnik" w najdłuższym adresie (zmierzone na żywo 09.09.2026:
 * adres kończył się na 239 px, pastylka zaczynała na 232 px).
 *
 * 24 px to wysokość linijki z nazwą — pastylka kończy się dokładnie tam, gdzie
 * zaczyna się adres, więc DŁUGOŚĆ ADRESU PRZESTAJE MIEĆ ZNACZENIE. Pole dotyku
 * dobiera warstwa `::after` niżej, żeby palec dalej miał swoje 44 px.
 */
.stopka-tel {
  position: absolute;
  /* jeden piksel wyżej — dolna krawędź pastylki ma leżeć NAD linijką adresu */
  top: -1px;
  right: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 24px;
  padding: 0 11px;
  border: 1px solid var(--zloto-jasne);
  border-radius: 999px;
  background: var(--powierzchnia);
  color: var(--tekst);
  font-weight: 700;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  white-space: nowrap;
}

/*
 * Pole dotyku sięga 44 px, choć sama pastylka ma 24 — powiększamy je warstwą
 * niewidoczną, bo wyższa pastylka zeszłaby na linijkę z adresem.
 */
.stopka-tel::after { content: ''; position: absolute; inset: -10px -6px; }

.stopka-tel svg { width: 14px; height: 14px; flex: none; color: var(--zloto); }
.stopka-tel:hover { border-color: var(--zloto); }
.stopka-tel:active { opacity: .7; }

.stopka-punkt:hover .nazwa { text-decoration: underline; }
.stopka-punkt:active { opacity: .7; }

.stopka-punkt svg {
  width: 17px;
  height: 17px;
  flex: none;
  margin-top: 2px;
  color: var(--zloto);
}

.stopka-punkt .nazwa {
  display: block;
  font-weight: 600;
  color: var(--tekst);
}

.stopka-linia {
  display: flex;
  align-items: center;
  gap: 9px;
  min-height: 44px;
  color: var(--tekst);
  text-decoration: none;
  font-weight: 600;
}

.stopka-linia svg {
  width: 17px;
  height: 17px;
  flex: none;
  color: var(--zloto);
}

.stopka-linia:hover { text-decoration: underline; }

/*
 * IKONY SOCIAL STOJĄ NA ŚRODKU (korekta Karola 10.09.2026).
 *
 * Cztery kółka dosunięte do lewej krawędzi wyglądały jak niedokończony wiersz
 * listy — reszta stopki to teksty czytane od lewej, a to jest pasek znaków,
 * czyli osobna rzecz. Na środku czyta się jak podpis, nie jak kolejna pozycja.
 *
 * Rachunek na ekranie 375 px: 4 × 44 px kółka + 3 × 10 px przerwy = 206 px.
 * Pas treści ma 375 − 2 × 18 px marginesu strony = 339 px, więc po obu stronach
 * zostaje po (339 − 206) / 2 = 66,5 px. `justify-content` dzieli tę resztę
 * równo — i tak samo podzieli ją, gdy dojdzie piąty znak albo zmieni się
 * szerokość ekranu. Środek odmierzony ręcznie, marginesem, rozjechałby się
 * przy pierwszej takiej zmianie.
 *
 * `flex-wrap` zostaje: na bardzo wąskim telefonie kółka mają zawinąć się
 * do drugiego wiersza, a nie wyjechać poza kadr — i ten drugi wiersz też
 * będzie wyśrodkowany.
 */
.stopka-sociale {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin: 12px 0 15px;
}

.stopka-social {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--linia);
  background: var(--powierzchnia);
  color: var(--zloto-ciemne);
  text-decoration: none;
  transition: border-color .2s, transform .12s ease;
}

.stopka-social svg { width: 21px; height: 21px; }
.stopka-social:hover { border-color: var(--zloto); }
.stopka-social:active { transform: scale(.94); }

.stopka-stopa {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--tekst-cichy);
}

/* --------------------- pociągnij w dół, żeby odświeżyć --------------------- */
/*
 * Wskaźnik odświeżania. Aplikacja z ikony (standalone) nie ma natywnego
 * „pociągnij, odśwież" ani na Androidzie, ani na iOS — robimy własny.
 * Gest obsługuje `public/odswiez.js`; tutaj jest wyłącznie wygląd.
 *
 * `pointer-events: none` jest tu warunkiem koniecznym, nie ozdobą: kółko wisi
 * nad treścią i bez tego przechwytywałoby dotknięcia karty pod sobą.
 */
.odswiez {
  position: fixed;
  top: calc(var(--gora) + 6px);
  left: 50%;
  width: 48px;
  height: 48px;
  z-index: 60;                 /* nad treścią, POD zasłonami (70) i planszą skrótu (90) */
  transform: translate(-50%, -64px) scale(.6);
  opacity: 0;
  pointer-events: none;
  border-radius: 50%;
  background: var(--powierzchnia);
  box-shadow: var(--cien);
  display: grid;
  place-items: center;
}

/* Powrót i dojazd na próg. W czasie ciągnięcia klasy nie ma — kółko ma
   iść za palcem co do piksela, a nie doganiać go z opóźnieniem. */
.odswiez.wraca {
  transition: transform .32s cubic-bezier(.22,.9,.3,1), opacity .28s ease;
}

.odswiez-luk {
  position: absolute;
  inset: 0;
  width: 48px;
  height: 48px;
  transform: rotate(-90deg);   /* łuk zaczyna się u góry, nie z prawej */
}

.odswiez-luk circle {
  fill: none;
  stroke-width: 3;
  stroke-linecap: round;
}

.odswiez-tor { stroke: var(--linia); }

/*
 * Złoty łuk narasta z przeciągnięciem. Obwód koła o promieniu 21 to 131,95 —
 * wpisany wprost, bo `calc()` nie policzy nam liczby pi.
 */
.odswiez-postep {
  stroke: var(--zloto);
  stroke-dasharray: 131.95;
  stroke-dashoffset: calc(131.95 * (1 - var(--odswiez-postep, 0)));
}

/* Próg przekroczony — puszczenie palca odświeży. Ciemniejsze złoto trzyma
   3:1 na powierzchni w każdym motywie, jasne #E2CE9C by tego nie zrobiło. */
.odswiez.gotowy .odswiez-postep { stroke: var(--zloto-ciemne); }

.odswiez-znak {
  width: 22px;
  height: 22px;
  object-fit: contain;
  opacity: .9;
}

/* Kręci się, dopóki dane nie dojdą. */
.odswiez.kreci .odswiez-luk { animation: odswiez-obrot .9s linear infinite; }

@keyframes odswiez-obrot {
  from { transform: rotate(-90deg); }
  to   { transform: rotate(270deg); }
}

@media (prefers-reduced-motion: reduce) {
  .odswiez.wraca { transition: opacity .2s ease; }
  .odswiez.kreci .odswiez-luk { animation-duration: 2.4s; }
}

/* ======================= piętrowiec malowany ============================== */
/*
 * Licznik oszczędności na ekranie Historii (decyzja Karola 09.09.2026).
 *
 * Zasada rysunku jest jedna: WSZYSTKIE etapy są w DOM od początku, a różni je
 * tylko klasa. Bez klasy `namalowany` element jest SZKICEM — kreskowanym
 * konturem bez wypełnienia; z klasą staje się bryłą w barwie. Dzięki temu
 * klient od pierwszego wejścia widzi, co powstanie, a domalowanie kolejnego
 * elementu nie wymaga podmiany rysunku (i nie da się rozjechać z serwerem).
 *
 * Barwy siedzą w motywy.css (`--tort-*`) i wskazują na role motywu, więc tort
 * chodzi za motywem razem z resztą aplikacji.
 */
.oszczednosci { text-align: center; }

.oszczednosci-licznik { margin: 4px 0 2px; }

.oszczednosci-kwota {
  font-size: 38px;
  font-weight: 800;
  line-height: 1.1;
  color: var(--pink-strong);
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}

.tort-plansza {
  display: flex;
  justify-content: center;
  margin: 6px 0 2px;
}

.tort {
  width: 100%;
  max-width: 240px;
  height: auto;
}

/* Warstwa NAMALOWANA: bryła w barwie, obrysowana ciemnym złotem. */
.tort-etap .wypelnienie {
  stroke: var(--tort-kontur);
  stroke-width: 1.3;
  stroke-linejoin: round;
}
.tort-etap .kreska {
  fill: none;
  stroke-width: 1.4;
  stroke-linecap: round;
}

.tort-patera   { fill: var(--tort-patera); }
.tort-biszkopt { fill: var(--tort-biszkopt); }
.tort-krem     { fill: var(--tort-krem); }
.tort-masa     { fill: var(--tort-masa); }
.tort-polewa   { fill: var(--tort-polewa); }
.tort-dekor    { fill: var(--tort-dekor); }
.tort-perla    { fill: var(--tort-perla); }
/* Perełka ma 4 px średnicy — pełny kontur zrobiłby z niej czarną kropkę. */
.tort-etap .tort-perla { stroke-width: .8; }
.tort-wisienka { fill: var(--tort-wisienka); }
.tort-listek   { fill: var(--tort-listek); }
.tort-okruchy  { stroke: var(--tort-kontur); opacity: .45; }
.tort-blysk    { stroke: var(--tort-blysk); opacity: .8; }
/* Połysk wisienki ma własną, czerwoną rolę — biały błysk reszty tortu na
   czerwonej kuli wyglądał jak plama, nie jak światło. */
.tort-wisienka-polysk { stroke: var(--tort-wisienka-polysk); opacity: .8; }
.tort-ogonek   { stroke: var(--tort-kontur); stroke-width: 2.2; }

/*
 * SZKIC — element jeszcze nie namalowany. Kreskowany kontur bez wypełnienia,
 * mocno przygaszony: ma powiedzieć „tu coś będzie", a nie udawać gotowego.
 * Kreski wewnętrzne (okruchy, błyski) w szkicu chowamy — bez bryły wyglądałyby
 * jak przypadkowe zadrapania.
 */
.tort-etap:not(.namalowany) .wypelnienie {
  fill: none;
  stroke: var(--tort-szkic);
  stroke-width: 1;
  stroke-dasharray: 3 3;
  opacity: .42;
}
.tort-etap:not(.namalowany) .kreska { display: none; }

/* Element malowany WŁAŚNIE TERAZ — mocniejszy szkic, żeby było widać, co dalej. */
.tort-etap.nastepny .wypelnienie {
  stroke: var(--gold);
  opacity: .8;
  stroke-dasharray: 4 3;
}

@media (prefers-reduced-motion: no-preference) {
  .tort-etap.nastepny .wypelnienie { animation: tort-czeka 2.4s ease-in-out infinite; }
  @keyframes tort-czeka {
    0%, 100% { opacity: .45; }
    50%      { opacity: .95; }
  }
}

.tort-postep { margin-top: 10px; }

/* --------------------------- półka „Kolekcja” ----------------------------- */
/*
 * Torty już upieczone, każdy z rocznikiem. Półka przewija się w poziomie —
 * po kilku latach w klubie stanie tu ich kilkanaście, a ekran ma 375 px.
 */
.tort-polka {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  padding: 4px 2px 8px;
  scrollbar-width: thin;
}

.tort-mini {
  flex: none;
  width: 78px;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 6px 4px 4px;
  background: var(--pink-soft);
}

.tort-mini .tort { max-width: 62px; }

.tort-rocznik {
  display: block;
  font-size: 13px;
  font-weight: 700;
  color: var(--gold-dark);
  font-variant-numeric: tabular-nums;
}

/* ====================== ekran „Następny poziom" =========================== */
/*
 * Zachęta spod paska punktów. Miniatura karty używa TYCH SAMYCH klas poziomów
 * co prawdziwa karta (`.klubowa` + `poziom-*`), więc srebro, złoto i diamentowa
 * Fuzja wyglądają tu dokładnie tak, jak będą wyglądać w telefonie po awansie.
 * Osobna paleta „na podgląd" rozjechałaby się przy pierwszej zmianie.
 */
.poziom-zacheta { text-align: center; }

.klubowa-mini {
  max-width: 260px;
  margin: 0 auto 4px;
  padding: 18px 18px 20px;
  border-radius: 20px;
}

.klubowa-mini .klubowa-imie { font-size: 21px; }

/*
 * Pastylka poziomu na miniaturze. Na pełnej karcie ma 20 px i luźne
 * rozstrzelenie; na węższej miniaturze "DIAMENTOWY" łamało się na dwie linie
 * i zostawało samotne "Y" w drugim wierszu. Zwężamy rozstrzelenie i pismo,
 * a łamanie wyłączamy wprost — nazwa poziomu ma stać w jednej linii.
 * Sprawdzone na żywo na 375 px.
 */
.klubowa-mini .plakietka-duza {
  font-size: 17px;
  letter-spacing: .1em;
  padding: 9px 18px;
  white-space: nowrap;
  overflow-wrap: normal;
}
.klubowa-mini .poziom-pas { margin-top: 18px; }

.poziom-zacheta .postep-tor { max-width: 260px; margin-inline: auto; }
.poziom-zacheta .karta { text-align: left; }

/* Karta z paskiem punktów jest przyciskiem — pasek musi być blokiem. */
.blok-poziom .postep-tor { display: block; }
.postep-wypelnienie { display: block; }

/*
 * ETYKIETA-ZACHĘTA pod paskiem punktów (09.09.2026, korekta Karola).
 * Sama strzałka po prawej nie wystarczała: pasek otwierał ekran „Następny
 * poziom", ale nic o tym nie mówiło. Pastylka w złotej obwódce wygląda jak
 * rzecz do dotknięcia i pisze wprost, co jest po drugiej stronie.
 *
 * To NIE jest osobny przycisk — cała karta jest już przyciskiem, a przycisk
 * w przycisku jest nieklikalny na iOS i myli czytniki ekranu. Stąd `span`
 * z wyglądem pastylki i `pointer-events: none`, żeby dotknięcie zawsze
 * trafiało w kartę pod spodem.
 */
.poziom-zachetka {
  display: inline-block;
  margin-top: 10px;
  padding: 7px 13px;
  border: 1px solid var(--gold-light);
  border-radius: 999px;
  background: var(--pink-soft);
  color: var(--gold-dark);
  font-size: 13.5px;
  font-weight: 700;
  line-height: 1.25;
  pointer-events: none;
}

.karta-przycisk:active .poziom-zachetka { border-color: var(--gold); }

/* ==========================================================================
   INSTRUKTAŻ — przyciemnienie z wyciętym oknem
   --------------------------------------------------------------------------
   Wycięcie robi JEDEN `box-shadow` o ogromnym rozlaniu: dziura to prostokąt
   `.przewodnik-cien`, a cień maluje całą resztę ekranu. Element pod spodem
   zostaje więc w pełnym kolorze i na swoim miejscu — nie kopiujemy go nigdzie,
   więc nie ma jak się rozjechać z tym, co klient naprawdę widzi.

   Pisane pod OSOBĘ STARSZĄ: 17 px w dymku, tytuł 24 px, przyciski po 48 px.
   `touch-action: none` na zasłonie zatrzymuje przewijanie strony pod spodem
   bez `overflow: hidden` na body — a to jest tu warunek konieczny, bo każdy
   krok sam przewija ekran do swojego elementu (`scrollIntoView`).
   ========================================================================== */

.przewodnik {
  position: fixed;
  inset: 0;
  z-index: 100;                /* nad wszystkim: także nad planszą skrótu (90) */
  touch-action: none;
}

.przewodnik[hidden] { display: none; }

.przewodnik-cien {
  position: fixed;
  border-radius: 18px;
  box-shadow: 0 0 0 9999px rgba(26, 23, 24, .74);
  outline: 2px solid var(--gold);
  pointer-events: none;        /* dotknięcie ma trafić w zasłonę = „pomiń" */
  transition: left .22s ease, top .22s ease, width .22s ease, height .22s ease;
}

/* Pierwszy krok staje od razu na miejscu: nie ma skąd przypłynąć, więc
   płynięcie z rogu ekranu wyglądałoby jak usterka, a nie jak animacja. */
.przewodnik-cien.przewodnik-bez-ruchu { transition: none; }

.przewodnik-dymek {
  position: fixed;
  width: min(340px, calc(100vw - 24px));
  background: var(--white);
  border: 1px solid var(--gold-light);
  border-radius: 18px;
  padding: 16px 18px 14px;
  box-shadow: var(--shadow-lift);
  animation: wejscie .22s cubic-bezier(.22,.9,.3,1);
}

.przewodnik-podpis { color: var(--gold-dark); margin-bottom: 6px; }

.przewodnik-tytul {
  font-family: var(--serif);
  font-size: 24px;
  line-height: 1.15;
  margin: 0 0 6px;
  color: var(--pink-strong);
}

.przewodnik-tresc {
  margin: 0 0 14px;
  font-size: 17px;
  line-height: 1.45;
  color: var(--ink);
}

.przewodnik-przyciski { display: flex; align-items: center; gap: 10px; }

.przewodnik-pomin {
  flex: 0 0 auto;
  min-height: 48px;
  padding: 0 14px;
  border: 0;
  border-radius: 12px;
  background: none;
  color: var(--muted);
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
}

.przewodnik-dalej { flex: 1; min-height: 48px; padding: 12px 18px; }

/* Wskaźnik „pociągnij, żeby odświeżyć" normalnie jest niewidoczny. Na czas
   swojego kroku pokazujemy go — inaczej wycięlibyśmy w cieniu pustą dziurę. */
.odswiez.przewodnik-pokaz {
  opacity: 1;
  transform: translate(-50%, 14px) scale(1);
}

/* Dyskretne wejście do przewodnika pod kartą klubową. Po prawej, małe,
   w złotej kresce — ma być do znalezienia, a nie do omijania wzrokiem. */
.przewodnik-wejscie-pas { display: flex; justify-content: flex-end; margin: -6px 0 14px; }

.przewodnik-wejscie {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--gold-light);
  border-radius: 999px;
  background: none;
  color: var(--gold-dark);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}

.przewodnik-wejscie:active { background: var(--pink-soft); border-color: var(--gold); }
.przewodnik-wejscie .ikona { width: 18px; height: 18px; }

/* ==========================================================================
   PODZIEL SIĘ KARTĄ — pastylka w rogu i nakładka z kodem QR
   --------------------------------------------------------------------------
   HIERARCHIA: ta nakładka jest OSTATNIA. Plansza powiadomień i powitania (70),
   plansza skrótu (90) oraz instruktaż (100) mają ją zasłaniać, nigdy odwrotnie
   — stąd 65 i 50, a nie „gdzieś wysoko".
   ========================================================================== */

.podziel-pastylka {
  position: fixed;
  right: 12px;
  bottom: calc(70px + var(--dol));   /* tuż nad paskiem zakładek, pod komunikatem (120) */
  z-index: 50;                 /* nad treścią, POD wskaźnikiem (60) i zasłonami */
  display: none;               /* przed założeniem karty nie ma czym się dzielić */
  align-items: center;
  gap: 6px;
  padding: 8px 13px 8px 11px;
  border: 1px solid var(--gold-light);
  border-radius: 999px;
  background: var(--white);
  color: var(--gold-dark);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .01em;
  box-shadow: var(--shadow);
  opacity: .82;                /* „delikatnie" — pastylka nie konkuruje z treścią */
  cursor: pointer;
}

.podziel-pastylka.widoczna { display: inline-flex; }
.podziel-pastylka:active { opacity: 1; background: var(--pink-soft); border-color: var(--gold); }
.podziel-pastylka .ikona { width: 17px; height: 17px; }

.podziel-zaslona {
  position: fixed;
  inset: 0;
  z-index: 65;                 /* pod zasłonami (70), skrótem (90) i instruktażem (100) */
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(26, 23, 24, .55);
}

.podziel-zaslona[hidden] { display: none; }

.podziel-okno {
  position: relative;
  width: 100%;
  max-width: 380px;
  max-height: 92vh;
  overflow-y: auto;
  padding: 24px 20px 20px;
  border-radius: 22px;
  background: var(--white);
  box-shadow: var(--shadow-lift);
  animation: wejscie .3s cubic-bezier(.22,.9,.3,1);
}

.podziel-x {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--muted);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
}

.podziel-qr {
  width: min(240px, 62vw);
  aspect-ratio: 1;
  margin: 0 auto 12px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: #FFFFFF;         /* kod QR czyta się z bieli w każdym motywie */
  display: grid;
  place-items: center;
}

.podziel-qr img, .podziel-qr svg { width: 100%; height: 100%; display: block; }

.podziel-adres {
  text-align: center;
  font-size: 15px;
  font-weight: 700;
  color: var(--gold-dark);
  word-break: break-all;
}
