/* ==========================================================================
   TOMTOM AUTO GARAGE, v3
   Decyzje i uzasadnienia: DESIGN.md · Fakty: tomtom-auto-garage-context.md

   Reguła koloru, zero wyjątków: biały tekst tylko na --blue i --navy.
   Reguła ruchu: hover to przejazd koloru z lewej do prawej, nigdy przyciemnienie.
   ========================================================================== */

/* ---------- Kroje: hostowane lokalnie, subset do polskiego zakresu ---------- */

@font-face {
  font-family: "Exo 2";
  src: url("fonts/exo2.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2122, U+2190-2199, U+2212, U+2713;
}

@font-face {
  font-family: "Exo 2";
  src: url("fonts/exo2-pl.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0104-0107, U+0118-0119, U+0141-0144, U+015A-015B, U+0179-017C;
}

@font-face {
  font-family: "Archivo";
  src: url("fonts/archivo.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2122, U+2190-2199, U+2212, U+2713;
}

@font-face {
  font-family: "Archivo";
  src: url("fonts/archivo-pl.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0104-0107, U+0118-0119, U+0141-0144, U+015A-015B, U+0179-017C;
}

/* ---------- Tokeny ---------- */

:root {
  --ink: #15181c;
  --ink-soft: #4b535c;
  --rule: #d3d8dd;
  --plate: #eff0ee;
  --paper: #f6f7f8;
  --blue: #0f62c4;
  --navy: #0a3a72;
  --water: #b8d4ee;

  --display: "Exo 2", "Segoe UI", Tahoma, sans-serif;
  --sans: "Archivo", "Helvetica Neue", Arial, sans-serif;

  --shell: 1200px;
  --r: 4px;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --bar: 68px;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--bar) + 1rem);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.6;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

@media (min-width: 48rem) { body { font-size: 1.125rem; } }

p, figure, blockquote, dl, dd { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: var(--blue); }
svg { display: block; }

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 2px;
}

.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.skip {
  position: absolute;
  left: -9999px;
  z-index: 100;
}

.skip:focus {
  left: 1rem;
  top: 1rem;
  background: var(--blue);
  color: #fff;
  padding: 0.75rem 1rem;
  border-radius: var(--r);
  text-decoration: none;
}

/* ---------- Rusztowanie ---------- */

.shell {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 2.5rem);
}

.shell.narrow { max-width: 54rem; }

.band { padding-block: clamp(3.5rem, 8vw, 6.5rem); }

/* Szew między pasmami. Kolory zostały te same, zmieniło się samo przejście:
   plate wchodzi i schodzi gradientem na wysokości mniej więcej jednego
   marginesu sekcji, więc oko nie zaczepia się o twardą kreskę. Wysokość
   przejścia jest w tym samym clampie co padding sekcji, żeby gradient kończył
   się tam, gdzie zaczyna się treść, a nie w jej środku. */
.band.alt {
  background: linear-gradient(to bottom,
    var(--paper),
    var(--plate) clamp(2rem, 5vw, 4rem),
    var(--plate) calc(100% - clamp(2rem, 5vw, 4rem)),
    var(--paper));
}

.head { display: grid; gap: 0.85rem; max-width: 60ch; margin-bottom: clamp(2rem, 4vw, 3rem); }
/* `ch` liczy się od kroju kontenera, nie nagłówka, więc tu jawne rem. */
.head.wide { max-width: 44rem; }
.head.wide .lead { max-width: 54ch; }

/* ---------- Typografia ---------- */

.eyebrow {
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.76rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

h1 {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(2.4rem, 1.1rem + 5.4vw, 4.25rem);
  line-height: 1.02;
  letter-spacing: -0.025em;
  margin: 0 0 1.15rem;
  text-wrap: balance;
}

h2 {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.75rem, 1.1rem + 2.3vw, 2.75rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
}

h3 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.15rem;
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin: 0 0 0.5rem;
}

.lead { color: var(--ink-soft); max-width: 60ch; }
.lead strong { color: var(--ink); font-weight: 600; }

.num { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }

/* ---------- Przyciski: przejazd koloru z lewej ---------- */

.btn {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  min-height: 48px;
  padding: 0.75rem 1.4rem;
  border: 2px solid var(--blue);
  border-radius: var(--r);
  font-family: var(--sans);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.005em;
  text-decoration: none;
  overflow: hidden;
  cursor: pointer;
  transition: color 260ms var(--ease);
}

.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 380ms var(--ease);
}

.btn .ico { width: 17px; height: 17px; flex: none; }

.btn.lg { min-height: 56px; padding: 0.9rem 1.75rem; font-size: 1.1rem; }

/* Ramka jedzie do granatu razem z wypełnieniem, żeby przycisk został jednolity. */
.btn-primary {
  background: var(--blue);
  color: #fff;
  transition: color 260ms var(--ease), border-color 380ms var(--ease);
}
.btn-primary::before { background: var(--navy); }
.btn-primary:hover,
.btn-primary:focus-visible { border-color: var(--navy); }
.btn-primary:hover::before,
.btn-primary:focus-visible::before { transform: scaleX(1); }

.btn-ghost { background: transparent; color: var(--blue); }
.btn-ghost::before { background: var(--blue); }
.btn-ghost:hover,
.btn-ghost:focus-visible { color: #fff; }
.btn-ghost:hover::before,
.btn-ghost:focus-visible::before { transform: scaleX(1); }

.btn-nav {
  min-height: 42px;
  padding: 0.45rem 1rem;
  font-size: 0.92rem;
  background: transparent;
  color: var(--blue);
}
.btn-nav .ico { width: 15px; height: 15px; }
.btn-nav::before { background: var(--blue); }
.btn-nav:hover,
.btn-nav:focus-visible { color: #fff; }
.btn-nav:hover::before,
.btn-nav:focus-visible::before { transform: scaleX(1); }

/* ---------- Belka górna ---------- */

/* Tło nieprzezroczyste: przy półprzezroczystym nagłówki przebijały przez belkę. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--paper);
  border-bottom: 1px solid transparent;
  transition: border-color 300ms var(--ease), box-shadow 300ms var(--ease);
}

.topbar.is-stuck {
  border-bottom-color: var(--rule);
  box-shadow: 0 10px 30px -26px rgba(10, 58, 114, 0.7);
}

.topbar-in {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 2.5rem);
  min-height: var(--bar);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.wordmark {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(0.92rem, 0.82rem + 0.45vw, 1.2rem);
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  line-height: 1;
  white-space: nowrap;
}

.wordmark span { color: var(--blue); }

/* Na wąskim ekranie CTA skraca się, zamiast łamać belkę na dwie linie. */
.cta-short { display: none; }

@media (max-width: 30rem) {
  .cta-long { display: none; }
  .cta-short { display: inline; }
}

.scrollbar {
  display: block;
  height: 2px;
  background: var(--blue);
  transform: scaleX(var(--p, 0));
  transform-origin: left center;
  will-change: transform;
}

/* ---------- Hero ---------- */

.hero { padding-block: clamp(2.5rem, 6vw, 5rem) clamp(3rem, 6vw, 5rem); }

/* Hero trzyma się wspólnej siatki 1200 px. Nie dawaj mu własnego, szerszego
   kontenera: mapa ma zyskiwać zasięg (szerszy viewBox, mniejsza skala), a nie
   rozmiar w pikselach. */
.hero-grid { display: grid; gap: clamp(2.5rem, 5vw, 4rem); align-items: center; }

/* Mapa dostaje trochę więcej miejsca niż kolumna tekstu: to ona odpowiada na pytanie
   „czy to daleko ode mnie", które kierowca zadaje jako pierwsze. */
@media (min-width: 60rem) {
  .hero-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr); }
}

.place {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 1.1rem;
}

.place::before { content: ""; width: 30px; height: 2px; background: var(--blue); }

.hero-sub {
  font-size: clamp(1.02rem, 0.95rem + 0.35vw, 1.2rem);
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 44ch;
  margin-bottom: 1.9rem;
}

.hero-cta { display: flex; flex-wrap: wrap; gap: 0.75rem; }

.hero-note { margin-top: 1.25rem; font-size: 0.88rem; color: var(--ink-soft); }
.hero-note b { color: var(--ink); font-weight: 700; }

/* ---------- Mapa ---------- */

.mapbox { position: relative; }
.map { width: 100%; height: auto; }
.map-dist { display: none; }
.map-note { margin-top: 0.6rem; font-size: 0.8rem; color: var(--ink-soft); }

@media (max-width: 45.99rem) {
  .map-dist {
    display: block;
    margin-top: 0.7rem;
    font-family: var(--sans);
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--ink);
  }
  .map-note { margin-top: 0.35rem; }
}

.r-motorway { fill: none; stroke: #eab308; stroke-width: 3.4; stroke-linecap: round; stroke-linejoin: round; }
.r-express { fill: none; stroke: #cfa63f; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.r-main { fill: none; stroke: #aeb6bd; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.r-water { fill: none; stroke: var(--water); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }

.town { fill: #79828a; }

/* Obwódka w kolorze tła: podpisy zostają czytelne, gdy leżą na drodze. */
.map text {
  paint-order: stroke fill;
  stroke: var(--paper);
  stroke-width: 3px;
  stroke-linejoin: round;
}

.t-label { font-family: var(--sans); font-weight: 600; font-size: 9px; letter-spacing: 0.05em; fill: var(--ink-soft); }
.t-label.lg { font-size: 11px; letter-spacing: 0.07em; }
.t-dist { font-family: var(--sans); font-weight: 700; font-size: 8px; letter-spacing: 0.03em; fill: var(--blue); }
.r-shield { font-family: var(--sans); font-weight: 800; font-size: 8px; letter-spacing: 0.07em; fill: #7d6412; }
.r-shield.dk { fill: #6e767e; }
.w-label { font-family: var(--sans); font-weight: 600; font-style: italic; font-size: 8px; letter-spacing: 0.08em; fill: #6f9ec6; }

.here-name { font-family: var(--display); font-weight: 700; font-size: 19px; letter-spacing: -0.02em; fill: var(--ink); stroke-width: 4px; }

/* Telefon: mapa schodzi do jakichś 350 px przy kadrze 532 jednostek, więc jednostka
   viewBox to dwie trzecie piksela. Oznaczenia dróg drugorzędnych znikają, a to, co
   zostaje, rośnie tak, żeby dało się to przeczytać. Podpisy mają tu wyjść na te same
   ~10 px co na desktopie. Skala geograficzna się nie zmienia. */
@media (max-width: 45.99rem) {
  .map .t-dist,
  .map .min { display: none; }
  .map .t-label.lg { font-size: 16px; letter-spacing: 0.05em; }
  .map .r-shield { font-size: 12.5px; }
  .map .town { r: 4; }
  .here-name { font-size: 28px; stroke-width: 6px; transform: translateY(-5px); }
  .pin-core { r: 10; }
  .pin-ring { r: 11; }
  .pin-dot { r: 3.9; }

  /* Trzy auta zamiast czterech: przy tej szerokości dwa pasy A2 zlewają się w jeden. */
  .mcar { transform: scale(1.45); }
  .mcar-a2w { display: none; }
}
/* Auta. Grafit, nie granat: niebieski zostaje zarezerwowany dla pinezki
   i kilometrów. Szyba jest półprzezroczysta, żeby auto czytało się jako
   bryła, a nie jako plamka, przy 5 px wysokości. */
.mcar-body { fill: #39424c; }
.mcar-glass { fill: rgba(255, 255, 255, 0.62); }
.mcar { transform-box: fill-box; transform-origin: 50% 50%; }

.pin-core { fill: var(--blue); }
.pin-ring { fill: none; stroke: var(--blue); stroke-width: 1.4; opacity: 0; }

/* ---------- Dlaczego tutaj: zestawienie zamiast kafelków ---------- */

.versus { display: grid; gap: clamp(1.75rem, 4vw, 3rem); }

@media (min-width: 46rem) {
  .versus { grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 4.5rem); }
}

.vs { display: grid; gap: 0; align-content: start; }

.vs-title {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.76rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding-bottom: 0.7rem;
  border-bottom: 2px solid var(--rule);
}

.vs-them .vs-title { color: var(--ink-soft); }
.vs-us .vs-title { color: var(--blue); border-bottom-color: var(--blue); }

.vs-list { counter-reset: vs; }

.vs-list li {
  counter-increment: vs;
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  gap: 0.5rem;
  align-items: baseline;
  padding: 0.95rem 0;
  border-bottom: 1px solid var(--rule);
  font-size: clamp(1rem, 0.95rem + 0.35vw, 1.15rem);
  line-height: 1.4;
}

.vs-list li::before {
  content: counter(vs, decimal-leading-zero);
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
}

.vs-them .vs-list li { color: var(--ink-soft); }
.vs-them .vs-list li::before { color: #99a2aa; }

.vs-us .vs-list li { color: var(--ink); font-weight: 500; }
.vs-us .vs-list li::before { color: var(--blue); }

/* ---------- Oferta: trzy grupy zamiast jednej długiej listy ---------- */

.groups { display: grid; gap: clamp(2rem, 4vw, 3rem); }

@media (min-width: 46rem) {
  .groups { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1.75rem, 3.5vw, 3rem); }
}

/* Trzy wiersze o stałych rolach, żeby szare podsumowania stały w jednej linii. */
.group { display: grid; grid-template-rows: auto 1fr auto; gap: 0; align-content: start; }

.group-title {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.15rem, 1rem + 0.6vw, 1.4rem);
  letter-spacing: -0.015em;
  padding-bottom: 0.8rem;
  border-bottom: 2px solid var(--ink);
  margin-bottom: 0.25rem;
}

.group-list li {
  position: relative;
  padding: 0.7rem 0 0.7rem 1.5rem;
  border-bottom: 1px solid var(--rule);
  font-size: 1.02rem;
  line-height: 1.35;
}

.group-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.28rem;
  width: 9px;
  height: 2px;
  background: var(--blue);
}

.group-what {
  margin-top: 0.9rem;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.sym-note {
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  color: var(--ink-soft);
  max-width: 56ch;
  font-size: 0.98rem;
}

/* ---------- Cennik ---------- */

.prices { margin-top: clamp(2.5rem, 5vw, 3.5rem); }

/* Ujemny margines o wartości wewnętrznego paddingu komórek: tekst tabeli stoi
   dokładnie w tej samej pionowej linii co reszta sekcji, a podświetlenie wiersza
   wychodzi o te 0,7 rem poza nią z obu stron. */
.table-scroll { overflow-x: auto; margin-inline: -0.7rem; }

table { border-collapse: collapse; width: 100%; min-width: 23.4rem; }

/* Zastrzeżenie o cenniku jest tytułem tabeli, a nie przypisem pod nią. */
caption {
  text-align: left;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.02rem, 0.94rem + 0.4vw, 1.2rem);
  line-height: 1.35;
  color: var(--ink);
  padding-bottom: 1rem;
}

thead th {
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: left;
  padding: 0 0.7rem 0.7rem;
  border-bottom: 2px solid var(--ink);
}

thead th:last-child { text-align: right; }

caption { padding-inline: 0.7rem; }

tbody th {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 1rem;
  text-align: left;
  padding: 0.8rem 1rem 0.8rem 0.7rem;
  border-bottom: 1px solid var(--rule);
}

tbody td {
  padding: 0.8rem 0.7rem 0.8rem 0;
  border-bottom: 1px solid var(--rule);
  text-align: right;
  font-size: 1rem;
}

tbody tr:last-child th,
tbody tr:last-child td { border-bottom: none; }

/* Delikatne podświetlenie wiersza: sekcja stoi na var(--plate), więc biel wystarczy,
   żeby oko trzymało się jednej usługi i jej ceny przez całą szerokość tabeli. */
tbody tr { transition: background-color 200ms var(--ease); }
tbody tr:hover { background: #fff; }
tbody tr:hover td { color: var(--navy); }

@media (prefers-reduced-motion: reduce) {
  tbody tr { transition: none; }
}

/* ---------- Proces: slalom ---------- */

/* Ogon trasy wychodzi poza ostatnią kartę, a ujemny margines wsuwa go pod kolejną
   sekcję. Warsztat jest pozycjonowany z wyższym z-index, więc zamalowuje auto:
   dzięki temu auto wjeżdża pod sekcję i tam znika, zamiast zatrzymać się na krawędzi. */
.route { position: relative; padding-bottom: 12rem; margin-bottom: -5rem; }

#proces { padding-bottom: 0; }
#warsztat { position: relative; z-index: 1; }

.route-lane {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Warstwa przejechana, przycięta od dołu dokładnie na wysokości auta. */
.route-lane.is-done { clip-path: inset(0 0 var(--cut, 100%) 0); }

.lane { fill: none; stroke: var(--rule); stroke-width: 3; stroke-linecap: round; }
.lane-done { fill: none; stroke: var(--blue); stroke-width: 3; stroke-linecap: round; }

@media (max-width: 45.99rem) {
  .route-lane { right: auto; width: 58px; }
}

.car {
  position: absolute;
  top: 0;
  left: 0;
  width: 62px;
  margin: -13.65px 0 0 -31px;
  /* Granat, nie błękit: auto jedzie po niebieskiej linii i musi się od niej odciąć. */
  color: var(--navy);
  pointer-events: none;
  will-change: transform;
  filter: drop-shadow(0 3px 6px rgba(10, 58, 114, 0.35));
}

.car svg { width: 62px; height: 27.3px; }

.steps { position: relative; display: grid; gap: clamp(1.75rem, 5vw, 3.5rem); }

.step {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 1.15rem;
  align-items: start;
  background: #fff;
  border-radius: var(--r);
  border-top: 2px solid var(--rule);
  padding: 1.3rem 1.6rem 1.45rem;
  max-width: 24rem;
  box-shadow: 0 2px 10px -8px rgba(21, 24, 28, 0.35);
  transition: border-color 420ms var(--ease), box-shadow 420ms var(--ease),
              transform 420ms var(--ease);
}

.step-n {
  grid-row: 1 / 3;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(2.1rem, 1.7rem + 1.4vw, 2.8rem);
  line-height: 0.82;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--rule);
  transition: color 420ms var(--ease);
}

.step h3 {
  grid-column: 2;
  font-size: clamp(1.3rem, 1.1rem + 0.7vw, 1.55rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  font-weight: 700;
  margin: 0 0 0.25rem;
}

.step p { grid-column: 2; color: var(--ink-soft); font-size: 0.97rem; line-height: 1.45; }

.step.is-on {
  border-top-color: var(--blue);
  box-shadow: 0 16px 32px -24px rgba(10, 58, 114, 0.8);
  transform: translateY(-3px);
}

.step.is-on .step-n { color: var(--blue); }

@media (min-width: 46rem) {
  .step:nth-child(odd) { justify-self: start; }
  .step:nth-child(even) { justify-self: end; }
}

@media (max-width: 45.99rem) {
  .steps { padding-left: 4.75rem; }
  .step { max-width: none; }
}

/* ---------- Warsztat: zdjęcie + nagłówek ---------- */

.who { display: grid; gap: clamp(1.75rem, 4vw, 3rem); align-items: start; margin-bottom: clamp(2.5rem, 5vw, 3.5rem); }

@media (min-width: 52rem) {
  .who { grid-template-columns: minmax(0, 18rem) minmax(0, 1fr); gap: clamp(2rem, 5vw, 4rem); }
}

.who .head { margin-bottom: 0; }

/* Kadr jest szerszy niż wysoki, żeby kolumna ze zdjęciem kończyła się mniej więcej
   tam, gdzie kolumna z tekstem, a nie zwisała pod nią o pół ekranu. */
.photo { display: grid; gap: 0.6rem; max-width: 18rem; }

/* Proporcje kadru (580:525) trzyma sam plik. aspect-ratio rezerwuje miejsce,
   zanim obrazek się wczyta, żeby nic nie skakało. */
.photo-img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 580 / 525;
  object-fit: cover;
  border-radius: var(--r);
  background: var(--paper);
}

.photo figcaption { font-size: 0.82rem; color: var(--ink-soft); }

/* ---------- Staż ---------- */

/* Z paska czterech liczb została jedna. Kreska nad nią ma szerokość samej treści,
   nie całej kolumny: to ma być stwierdzony fakt, nie kolejny kafelek. */
.who-since {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  width: fit-content;
  margin-top: 0.4rem;
  padding-top: 0.9rem;
  border-top: 2px solid var(--ink);
  font-size: 0.92rem;
  line-height: 1.4;
  color: var(--ink-soft);
}

.who-since .count {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(2.3rem, 1.8rem + 1.9vw, 3.1rem);
  line-height: 0.9;
  letter-spacing: -0.03em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* ---------- Opinie ---------- */

.reviews { display: grid; gap: 1.25rem; }
@media (min-width: 52rem) { .reviews { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* Trzy wiersze o stałych rolach: gwiazdki, cytat, podpis. Cytat rozpycha się
   do wysokości najdłuższego, więc gwiazdki i nazwiska stoją w równych liniach.

   Karta mówi tym samym językiem co krok procesu: biel, twarda kreska u góry,
   ten sam cień. Ramka dookoła wypadła, bo dawała kafelek zamiast karty. */
.review {
  background: #fff;
  border-radius: var(--r);
  border-top: 2px solid var(--rule);
  padding: 1.3rem 1.5rem 1.4rem;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 0.85rem;
  box-shadow: 0 2px 10px -8px rgba(21, 24, 28, 0.35);
  transition: border-color 420ms var(--ease), box-shadow 420ms var(--ease),
              transform 420ms var(--ease);
}

.review:hover {
  border-top-color: var(--blue);
  box-shadow: 0 12px 26px -18px rgba(10, 58, 114, 0.55);
  transform: translateY(-3px);
}

.stars { display: flex; gap: 0.18rem; }
/* Ciemniejsze złoto: gwiazdki niosą ocenę, więc muszą przejść 3:1 (WCAG 1.4.11).
   Jasne #eab308 dawało 1,92:1 na białej karcie. */
.stars svg { width: 16px; height: 16px; color: #b58900; }

.review .quote { font-size: 1rem; line-height: 1.6; }
.review .quote::before { content: "\201E"; }
.review .quote::after { content: "\201D"; }

/* Włoskowa kreska oddziela cudzy głos od tego, kto go wypowiedział i skąd go mamy. */
.review footer {
  display: grid;
  gap: 0.4rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rule);
}

.review cite {
  font-style: normal;
  font-weight: 700;
  font-size: 0.95rem;
}

.src {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--blue);
  text-decoration: none;
  width: fit-content;
  border-bottom: 1px solid transparent;
  transition: border-color 220ms var(--ease);
}

.src:hover { border-bottom-color: var(--blue); }

.ico-out { width: 12px; height: 12px; flex: none; }

/* ---------- FAQ ---------- */

.faq { display: grid; gap: 0.6rem; }

.qa {
  background: #fff;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  overflow: hidden;
  transition: border-color 300ms var(--ease);
}

.qa[open], .qa:hover { border-color: var(--blue); }

.qa summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.1rem 1.35rem;
  min-height: 56px;
  cursor: pointer;
  list-style: none;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: -0.005em;
}

.qa summary::-webkit-details-marker { display: none; }

.chev {
  flex: none;
  width: 12px;
  height: 12px;
  border-right: 2px solid var(--blue);
  border-bottom: 2px solid var(--blue);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 320ms var(--ease);
}

.qa[open] .chev { transform: rotate(225deg) translate(-3px, -3px); }

.qa-body { padding: 0 1.35rem 1.25rem; }
.qa-body p { color: var(--ink-soft); max-width: 60ch; }

/* ---------- Kontakt ---------- */

/* Dół zostaje pełny: pod nim jest granatowa kreska stopki i to ona ma być
   ostrym zamknięciem strony. Gaśnie tylko górna krawędź. */
.contact {
  background: linear-gradient(to bottom,
    var(--paper),
    var(--plate) clamp(2rem, 5vw, 4rem),
    var(--plate));
}

.contact-grid { display: grid; gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
@media (min-width: 56rem) { .contact-grid { grid-template-columns: 1.15fr 1fr; } }

.contact .head { margin-bottom: 0; }
.contact .hero-cta { margin-top: 0.75rem; }

/* Kolumnowy układ: adres nad godzinami, dane firmy nad telefonem. grid-auto-flow
   robi to bez zmiany kolejności w kodzie, więc czytnik ekranu i wąski ekran
   dostają tę samą, logiczną sekwencję. */
.details { display: grid; gap: 1.5rem 2rem; }

@media (min-width: 34rem) {
  .details {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: auto auto;
    grid-auto-flow: column;
    align-content: start;
  }
}

.details dt {
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 600;
  margin-bottom: 0.35rem;
}

.details dd { font-size: 1rem; line-height: 1.5; }

/* ---------- Stopka ---------- */

/* Stopka to jedna belka. Dane firmy stoją wyłącznie w sekcji Kontakt. */
.foot { border-top: 2px solid var(--ink); padding-block: 1.6rem 2rem; }

.foot-mark { font-size: clamp(1.1rem, 0.95rem + 0.6vw, 1.35rem); }

.foot-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem 1.5rem;
  justify-content: space-between;
  align-items: baseline;
}

/* Prawa strona belki: nota o prawach i podpis wykonawcy jako jedna grupa,
   rozdzielona pionową włoskową kreską. Na wąskim ekranie kreska znika
   i oba zdania stają jedno pod drugim. */
.foot-right {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 1.1rem;
  margin-left: auto;
}

.foot-right .credit {
  padding-left: 1.1rem;
  border-left: 1px solid var(--rule);
}

@media (max-width: 40rem) {
  .foot-right .credit { padding-left: 0; border-left: none; }
}

.foot .fine { font-size: 0.82rem; color: var(--ink-soft); }

.credit a {
  font-weight: 700;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 220ms var(--ease);
}

.credit a:hover { border-bottom-color: var(--blue); }

/* ==========================================================================
   RUCH, wszystko poniżej jest dodatkiem. Bez JS treść jest widoczna i pełna.
   ========================================================================== */

.js [data-anim] { opacity: 0; transform: translateY(22px); }

.js.is-ready [data-anim] {
  opacity: 1;
  transform: none;
  transition: opacity 800ms var(--ease) var(--d, 0ms),
              transform 800ms var(--ease) var(--d, 0ms);
}

[data-anim="1"] { --d: 0ms; }
[data-anim="2"] { --d: 90ms; }
[data-anim="3"] { --d: 200ms; }
[data-anim="4"] { --d: 310ms; }
[data-anim="5"] { --d: 420ms; }

.js [data-reveal]:not([data-stagger]) {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 700ms var(--ease), transform 700ms var(--ease);
}

.js [data-reveal].in:not([data-stagger]) { opacity: 1; transform: none; }

.js [data-stagger] > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 620ms var(--ease), transform 620ms var(--ease);
  transition-delay: calc(var(--i, 0) * 90ms);
}

.js [data-stagger].in > * { opacity: 1; transform: none; }

/* ---------- Nagłówki: słowo po słowie ----------

   Podziału na słowa nie ma w HTML, robi go skrypt. Bez JS w dokumencie stoi
   zwykły <h2> i nic się nie zmienia. Maska siedzi na .word, ruch na jego
   dziecku, więc słowo wychodzi zza krawędzi wiersza zamiast po prostu blednąć.

   padding-bottom razem z ujemnym marginesem to miejsce na ogonki ą, ę, j.
   Bez tego overflow ucinałby je w polskim tekście. */

.js .word {
  display: inline-block;
  overflow: hidden;
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
  vertical-align: bottom;
}

.js .word > span {
  display: inline-block;
  transform: translateY(112%);
  transition: transform 780ms var(--ease) calc(var(--wi, 0) * 55ms);
}

.js [data-reveal].in .word > span,
.js.is-ready [data-anim] .word > span { transform: none; }

/* Kiedy ruch niosą słowa, kontener nie rusza się drugi raz. Inaczej nagłówek
   jedzie w dwóch warstwach naraz i robi się z tego szarpnięcie. */
.js [data-reveal].has-words:not([data-stagger]),
.js [data-anim].has-words { transform: none; }

/* ---------- Parallaksa ----------

   Dwa elementy, mapa w hero i zdjęcie w sekcji Warsztat, płyną wolniej niż
   reszta strony. Przesunięcie liczy skrypt i wpisuje je w --py; tu jest tylko
   sposób, w jaki się je nakłada. Zakres to kilkanaście pikseli, ma być
   wyczuwalne jako głębia, a nie widoczne jako efekt. */

.js [data-parallax] {
  transform: translate3d(0, var(--py, 0px), 0);
  will-change: transform;
}

/* Drogi na mapie rysują się kaskadą */
.js .road { stroke-dasharray: 1400; stroke-dashoffset: 1400; }

.js.is-ready .road { animation: draw 2200ms var(--ease) forwards; }
.js.is-ready .d1 { animation-delay: 350ms; }
.js.is-ready .d2 { animation-delay: 750ms; }
.js.is-ready .d3 { animation-delay: 1100ms; }
.js.is-ready .d4 { animation-delay: 1350ms; }

@keyframes draw { to { stroke-dashoffset: 0; } }

.js .towns { opacity: 0; }
.js.is-ready .towns { animation: fadein 700ms ease forwards 1700ms; }
@keyframes fadein { to { opacity: 1; } }

.js.is-ready .pin-ring {
  transform-origin: 300px 200px;
  animation: ring 3400ms ease-out infinite 2200ms;
}

@keyframes ring {
  0% { transform: scale(0.4); opacity: 0.75; }
  70% { transform: scale(2.7); opacity: 0; }
  100% { transform: scale(2.7); opacity: 0; }
}

/* ---------- Ruch drogowy na mapie (.traffic / .mcar) ----------

   Cztery auta na dwóch korytarzach, którymi ludzie faktycznie tu przyjeżdżają.
   Każde dostaje własną ścieżkę pokrywającą się z narysowaną drogą, a ścieżki
   zaczynają się i kończą poza kadrem (viewBox to 34 30 532 361, ścieżki chodzą
   od 0 do 600). Dlatego pętla nie ma szwu: auto nie znika w środku mapy, tylko
   wyjeżdża za ramkę i po chwili wjeżdża z drugiej strony.

   Czasy są dobrane pod stałą prędkość, jakieś 22 jednostki na sekundę, więc
   auto na dłuższej trasie jedzie dłużej, a nie szybciej. Długości są względnie
   pierwsze, żeby czwórka nigdy nie ustawiła się w powtarzalny rytm.

   Opóźnienia są liczone tak, żeby auto wjechało w kadr chwilę PO tym, jak jego
   droga skończy się rysować (A2 kończy rysowanie w 2,55 s). Do krawędzi kadru
   auto ma jakieś 34 jednostki, czyli półtorej sekundy, i to jest już wliczone.

   Bez JS i przy braku offset-path auta zostają przezroczyste, mapa jest wtedy
   zwykłym statycznym schematem. */

.mcar { opacity: 0; }

@supports (offset-path: path("M0 0 L1 1")) {
  .js.is-ready .mcar {
    opacity: 1;
    offset-rotate: auto;
    animation-name: drive;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  }

  /* A2, dwa pasy rozsunięte o 2,2 jednostki od osi drogi, inaczej auta
     przenikałyby się przy mijaniu. */
  .js.is-ready .mcar-a2e {
    offset-path: path("M0 197.2 L100 202.2 L205 207.2 L259 210.2 L300 216.2 L349 224.2 L418 236.2 L503 256.2 L600 272.2");
    animation-duration: 27s;
    animation-delay: 1.2s;
  }

  .js.is-ready .mcar-a2w {
    offset-path: path("M600 267.8 L503 251.8 L418 231.8 L349 219.8 L300 211.8 L259 205.8 L205 202.8 L100 197.8 L0 192.8");
    animation-duration: 30s;
    animation-delay: 2.6s;
  }

  /* DK92, czyli droga pod samym warsztatem. To auto przejeżdża obok pinezki. */
  .js.is-ready .mcar-dk92 {
    offset-path: path("M600 279 L560 268 L503 252 L410 227 L335 211 L300 200 L253 184 L218 177 L179 179 L120 182 L20 187");
    animation-duration: 34s;
    animation-delay: 2.2s;
  }

  .js.is-ready .mcar-s11 {
    offset-path: path("M154.8 0 L167.8 142 L175.8 202 L211.8 246 L248.8 301 L279.8 400");
    animation-duration: 21s;
    animation-delay: 2.6s;
  }
}

@keyframes drive {
  from { offset-distance: 0%; }
  to { offset-distance: 100%; }
}

/* ---------- Wyłącznik ---------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .js [data-anim],
  .js [data-reveal],
  .js [data-stagger] > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  .js .road { stroke-dasharray: none; stroke-dashoffset: 0; }
  .js .towns { opacity: 1; }

  .js .word > span { transform: none !important; }
  .js [data-parallax] { transform: none !important; will-change: auto; }

  .js.is-ready .road,
  .js.is-ready .towns,
  .js.is-ready .pin-ring { animation: none; }

  .js.is-ready .pin-ring { opacity: 0; }

  /* Auta to czysty ruch, bez treści. Przy reduced-motion po prostu ich nie ma. */
  .traffic { display: none; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
