/* =========================================================================
   MANOWIECKI.PL — dizajn: ocean/wiatr, ciemny granat + elektryczny cyan,
   duże wyściełane liczby (Bebas Neue) na kontraście z Inter w body.
   Wzorzec ruchu i klas identyczny co sunen-com (data-reveal, data-count),
   nazwy z prefiksem km- zamiast sn-.
   ========================================================================= */

:root {
    --ink:        #0a1930;
    --ink-2:      #0d2340;
    --paper:      #f6f8fb;
    --paper-2:    #eef2f7;
    --text:       #16233a;
    --text-soft:  #566079;
    --cyan:       #1fe4f0;
    --cyan-dark:  #0a97a3;
    --coral:      #ff5a3c;
    --line:       rgba(10, 25, 48, 0.1);
    --line-dark:  rgba(255, 255, 255, 0.14);
    --shadow:     0 20px 50px -20px rgba(10, 25, 48, 0.35);
    --radius:     18px;
    --font-display: 'Bebas Neue', 'Arial Narrow', sans-serif;
    --font-body:  'Inter', system-ui, -apple-system, Segoe UI, sans-serif;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
    margin: 0;
    font-family: var(--font-body);
    color: var(--text);
    background: var(--paper);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    position: relative;
}

/* Ziarno/grain — subtelna tekstura na całej stronie, czysty CSS (SVG noise), zero requestów. */
body::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 150;
    pointer-events: none;
    opacity: .035;
    mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Kursor — znaczek z logo (widok "z góry na wing pływający po wodzie"), obraca się w stronę
   ruchu myszki. Tylko na urządzeniach z myszką (media query niżej wyłącza na dotyku).
   DWIE WARSTWY celowo: .km-cursor (pozycja, ustawiana z JS BEZ transition — inaczej znaczek
   "goni" kursor i czuć opóźnienie) > .km-cursor__spin (obrót + skala na hover, transition
   na transform tutaj daje płynny obrót, niezależny od natychmiastowej pozycji). */
.km-cursor { position: fixed; top: 0; left: 0; z-index: 300; pointer-events: none; transition: opacity .2s; margin: -17px 0 0 -17px; }
.km-cursor__spin { display: block; width: 34px; height: 34px; transform: rotate(var(--cursor-angle, 0deg)) scale(var(--cursor-scale, 1)); transition: transform .18s cubic-bezier(.2,.8,.3,1); }
.km-cursor__arrow { display: block; width: 100%; height: 100%; object-fit: contain; }
.km-cursor.is-hidden { opacity: 0; }
@media (pointer: coarse), (hover: none) { .km-cursor { display: none; } }
@media (pointer: fine) and (hover: hover) { .km-nav__links a, .km-btn, .km-timeline__item, .km-sponsors__item a, .km-gallery__item, .km-langs summary { cursor: none; } }
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3 { font-family: var(--font-display); letter-spacing: .02em; margin: 0; line-height: 1.02; }
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }
ul { list-style: none; margin: 0; padding: 0; }

.no-js [data-reveal] { opacity: 1 !important; transform: none !important; }
[data-reveal] { opacity: 0; transform: translateY(28px); transition: opacity .7s ease, transform .7s ease; transition-delay: calc(var(--d, 0) * 90ms); }
[data-reveal="left"] { transform: translateX(-32px); }
[data-reveal="right"] { transform: translateX(32px); }
[data-reveal="zoom"] { transform: scale(.92); }
[data-reveal].is-in { opacity: 1; transform: none; }

/* ---------- Progress bar + nav ---------- */
.km-progress { position: fixed; top: 0; left: 0; height: 3px; width: 0; background: linear-gradient(90deg, var(--cyan), var(--coral)); z-index: 200; transition: width .1s linear; }

.km-nav { position: fixed; top: 0; left: 0; right: 0; z-index: 100; transition: background .3s ease, box-shadow .3s ease, padding .3s ease; }
.km-nav__inner { max-width: 1240px; margin: 0 auto; padding: 22px 28px; display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.km-nav.is-stuck, .km-nav--solid { background: rgba(10, 25, 48, 0.92); backdrop-filter: blur(10px); box-shadow: 0 8px 30px -12px rgba(0,0,0,.4); }
.km-nav.is-stuck .km-nav__inner, .km-nav--solid .km-nav__inner { padding: 14px 28px; }

.km-nav__logo { display: flex; align-items: center; gap: 12px; color: #fff; font-family: var(--font-display); font-size: 28px; letter-spacing: .03em; transition: transform .3s ease; }
.km-nav__logo:hover { transform: scale(1.04); }
.km-nav__logo img { border-radius: 50%; width: 52px; height: 52px; transition: width .3s ease, height .3s ease; }
.km-nav.is-stuck .km-nav__logo img, .km-nav--solid .km-nav__logo img { width: 42px; height: 42px; }
.km-nav__logo em { font-style: normal; color: var(--cyan); }

.km-nav__links { display: flex; gap: 28px; }
.km-nav__links a { color: rgba(255,255,255,.85); font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; transition: color .2s; }
.km-nav__links a:hover { color: var(--cyan); }

.km-nav__right { display: flex; align-items: center; gap: 18px; }
.km-nav__social { color: #fff; opacity: .85; transition: opacity .2s, color .2s; }
.km-nav__social:hover { opacity: 1; color: var(--cyan); }

/* Przełącznik języka — CZŁONEK tego samego rzędu co O MNIE/OSIĄGNIĘCIA/…, ta sama
   typografia (Michał 24.08: ma być wyrównany z resztą menu, nie osobną plakietką). */
.km-langs { position: relative; display: flex; align-items: center; }
.km-langs summary {
    list-style: none; cursor: pointer; display: flex; align-items: center; gap: 5px;
    color: rgba(255,255,255,.85); font-size: 14px; font-weight: 600; text-transform: uppercase;
    letter-spacing: .05em; transition: color .2s;
}
.km-langs summary::-webkit-details-marker { display: none; }
.km-langs summary::after { content: ''; width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); }
.km-langs:hover summary, .km-langs[open] summary { color: var(--cyan); }

/* Rozwinięta lista: siatka, WSZYSTKIE języki widoczne naraz, bez scrolla (wzorzec: glovii.com).
   PEŁNE nazwy własne (endonimy) na desktopie/tablecie — skróty (2 litery) tylko < 560px,
   gdzie 4 kolumny pełnych nazw by się nie zmieściły (Michał 24.08).
   ⚠ Selektor .km-langs__list .km-langs__opt (nie goły .km-langs__opt) CELOWO — od kiedy
   przełącznik siedzi w .km-nav__links, goła klasa (0,1,0) przegrywała specificity z
   `.km-nav__links a` (0,1,1) i cały tekst poza aktywnym językiem wychodził biały-na-białym,
   czyli niewidoczny. Zgłoszenie Michała 24.08 — literówka specificity, nie literówka koloru. */
.km-langs__list { position: absolute; right: 0; top: calc(100% + 12px); background: #fff; border-radius: 12px; box-shadow: var(--shadow); padding: 12px; display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px 10px; width: 560px; }
.km-langs__list .km-langs__opt { display: block; padding: 8px 10px; border-radius: 8px; font-size: 13px; font-weight: 600; color: var(--text); text-align: left; text-transform: none; letter-spacing: 0; white-space: nowrap; }
.km-langs__list .km-langs__opt:hover, .km-langs__list .km-langs__opt.is-current { background: var(--paper-2); color: var(--cyan-dark); }
.km-langs__opt-short { display: none; }
@media (max-width: 560px) {
    .km-langs__list { grid-template-columns: repeat(4, 1fr); width: 220px; gap: 2px; }
    .km-langs__list .km-langs__opt { text-align: center; padding: 6px 4px; }
    .km-langs__opt-full { display: none; }
    .km-langs__opt-short { display: block; }
}

/* ---------- Hero ---------- */
.km-hero { position: relative; min-height: 100svh; display: flex; align-items: flex-end; overflow: hidden; color: #fff; }

/* KAMERA SCHODZĄCA W DÓŁ — jedno zdjęcie, prawdziwa głębia 3D przez perspective+rotateX+translateZ.
   .km-hero__stage NIESIE perspective (musi siedzieć na RODZICU transformowanego elementu, nie na
   nim samym — inaczej przeglądarka nie ma względem czego liczyć 3D). .km-hero__bg dostaje transform
   od site.js przy scrollu: lekki rotateX + translateY + zoom, jakby kamera pochylała się i schodziła
   niżej w kadr. Start delikatnie przechylony "w górę" (patrz --tilt-start), przy scrollu się prostuje —
   stąd wrażenie ruchu kamery, nie tylko przesuwania warstwy. */
.km-hero__stage { position: absolute; inset: 0; perspective: 1200px; overflow: hidden; }
.km-hero__bg {
    position: absolute; inset: -12% -6% -6% -6%;
    background: url('/assets/img/photos/comeback-turkey-2026.jpg') center 22%/cover no-repeat;
    transform: rotateX(6deg) scale(1.18);
    transform-origin: center 30%;
    will-change: transform;
    filter: saturate(1.4) contrast(1.1) brightness(.97);
}
.km-hero__bg::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(6,18,36,.15) 0%, rgba(8,20,38,.35) 45%, rgba(6,14,26,.97) 100%); }
.km-hero__bg::before {
    content: ''; position: absolute; inset: -20%; opacity: .55; mix-blend-mode: screen; pointer-events: none;
    background:
        radial-gradient(38vw 38vw at 18% 22%, rgba(20,200,212,.35), transparent 62%),
        radial-gradient(30vw 30vw at 82% 68%, rgba(255,90,60,.28), transparent 60%);
    animation: km-blob-drift 22s ease-in-out infinite alternate;
}
@keyframes km-blob-drift { 0% { transform: translate(0,0) scale(1); } 100% { transform: translate(4%, -3%) scale(1.08); } }

/* Kursor-spotlight w hero: dokłada delikatną poświatę pod wskaźnikiem myszy. */
.km-spotlight { position: relative; }
.km-spotlight::before {
    content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: 0; transition: opacity .5s ease;
    background: radial-gradient(480px circle at var(--mx, 50%) var(--my, 50%), rgba(20,200,212,.16), transparent 60%);
}
.km-spotlight.is-active::before { opacity: 1; }
.km-hero__grain { position: absolute; inset: 0; z-index: 2; pointer-events: none; }

.km-hero__inner { position: relative; z-index: 3; max-width: 1240px; margin: 0 auto; padding: 0 28px 90px; width: 100%; }
.km-hero__eyebrow {
    display: inline-block; text-transform: uppercase; letter-spacing: .16em; font-size: 13px; font-weight: 800;
    color: var(--ink); background: var(--cyan); padding: 8px 18px; border-radius: 30px; margin: 0 0 18px;
    box-shadow: 0 8px 24px -8px rgba(20,200,212,.7);
}

/* Skala liczy się z SZEROKOŚCI *i* WYSOKOŚCI ekranu (min(vw,vh)), nie samej szerokości —
   na typowym laptopie (1366x768) 12vw dawało 148px (maks.), czyli same litery zjadały
   302px z 768px wysokości hero. Zgłoszenie Michała 25.08 ("masakra" na mniejszych
   rozdzielczościach) — 9vw i 13vh razem trzymają tytuł w ryzach na niskich, szerokich
   ekranach laptopów, a na wysokich telefonach/dużych monitorach nadal rośnie sensownie. */
.km-hero__title { font-size: clamp(40px, min(9vw, 13vh), 132px); text-transform: uppercase; margin: 0 0 18px; }
.km-word { display: block; overflow: hidden; }
.km-word__in { display: block; transform: translateY(112%) rotate(3deg); transform-origin: left bottom; animation: km-word-in 1s cubic-bezier(.16,1,.3,1) forwards; animation-delay: calc(var(--i, 0) * 130ms); }
@keyframes km-word-in { to { transform: translateY(0) rotate(0); } }
.km-hero__sub { max-width: 560px; font-size: 17px; color: rgba(255,255,255,.85); margin-bottom: 30px; }


/* Bardzo NISKI viewport — powiększenie przeglądarki (np. 200%) albo krótkie okno.
   Zgłoszenie Michała 25.08: przy 200% eyebrow+tytuł nachodziły na stały pasek nawigacji,
   bo cała treść hero jest przyklejona do DOŁU (align-items:flex-end) i przy niskim oknie
   po prostu nie mieściła się nad paskiem. Poniżej: dużo mniejsze odstępy/czcionki
   i wyśrodkowanie zamiast przyklejenia do dołu — content trzyma bezpieczny odstęp od navu
   z OBU stron zamiast piąć się od dołu aż pod pasek.

   🐞 Próg 700px → 650px (Michał 25.08, druga runda — zmierzone liczby, nie zgadywanie):
   Chromebook Michała bez F12, więc zamiast kolejnej próby na ślepo dodałem tymczasowy licznik
   `innerWidth x innerHeight` na stronie (usunięty niżej w tym samym commicie). Zmierzone:
   100% = 1536×695, 90% = 1707×772, 110% = 1396×632. Przy progu 700px WSZYSTKIE TRZY 100%/110%
   (695 i 632) łapały się tej reguły (695≤700 i 632≤700), a 90% (772) nie — i to 100% wyglądało
   gorzej, bo tytuł na 100% brał czcionkę WYŁĄCZNIE z tej reguły (clamp do 64px, width=1536>1400
   więc reguła @media max-width:1400px w ogóle się nie odpala), a na 110% (width=1396≤1400) TA SAMA
   właściwość dostawała jeszcze nadpisanie z reguły max-width:1400px (clamp do 96px — większy tytuł),
   bo w pliku stoi NIŻEJ niż ten blok i wygrywa przy takiej samej specyficzności. Obniżenie progu do
   650px wypycha 695 z tej reguły (100% dostaje pełne rozmiary jak 90%, żadna z dwóch reguł się nie
   odpala), 632 zostaje bez zmian (110% wygląda dokładnie tak jak wcześniej — nie dotknięte). */
@media (max-height: 650px) {
    .km-hero { align-items: center; }
    .km-hero__inner { padding-bottom: 30px; }
    .km-hero__eyebrow { font-size: 11px; padding: 5px 12px; margin-bottom: 10px; }
    .km-hero__title { font-size: clamp(28px, min(7vw, 8vh), 64px); margin-bottom: 10px; }
    .km-hero__sub { font-size: 14px; margin-bottom: 16px; }
}
/* Ekstremalny przypadek (400–500px wysokości — bardzo duży zoom, np. 300%+, albo bardzo
   niskie okno): nav TEŻ się kurczy, bo jego stałe 96px samo w sobie zjada ćwierć ekranu. */
@media (max-height: 480px) {
    .km-nav__inner { padding: 10px 28px; }
    .km-nav__logo img { width: 34px; height: 34px; }
    .km-hero__inner { padding-bottom: 12px; }
    .km-hero__eyebrow { font-size: 10px; padding: 4px 10px; margin-bottom: 6px; }
    .km-hero__title { font-size: clamp(20px, min(6vw, 6vh), 36px); margin-bottom: 6px; }
    .km-hero__sub { font-size: 12px; margin-bottom: 10px; }
}
.km-scroll { position: absolute; left: 50%; bottom: 26px; width: 22px; height: 36px; border: 2px solid rgba(255,255,255,.6); border-radius: 12px; transform: translateX(-50%); z-index: 4; }
.km-scroll::before { content: ''; position: absolute; top: 6px; left: 50%; width: 3px; height: 8px; background: #fff; border-radius: 2px; transform: translateX(-50%); animation: km-scroll-dot 1.8s ease infinite; }
@keyframes km-scroll-dot { 0% { opacity: 1; transform: translate(-50%, 0); } 70% { opacity: 0; transform: translate(-50%, 10px); } 100% { opacity: 0; } }

.km-rise { opacity: 0; transform: translateY(20px); animation: km-rise .8s ease forwards; animation-delay: calc(var(--i, 0) * 140ms); }
@keyframes km-rise { to { opacity: 1; transform: none; } }

.km-btn { position: relative; display: inline-flex; align-items: center; gap: 8px; background: var(--coral); color: #fff; font-weight: 700; font-size: 14px; text-transform: uppercase; letter-spacing: .05em; padding: 15px 30px; border-radius: 50px; border: none; cursor: pointer; transition: transform .35s cubic-bezier(.16,1,.3,1), box-shadow .2s ease, background .2s ease; box-shadow: 0 14px 30px -10px rgba(255,90,60,.55); will-change: transform; }
.km-btn:hover { box-shadow: 0 18px 40px -10px rgba(255,90,60,.65); }
.km-btn--ghost { background: transparent; border: 2px solid rgba(255,255,255,.5); box-shadow: none; }
.km-btn--ghost:hover { border-color: var(--cyan); color: var(--cyan); }
.km-btn span { position: relative; z-index: 1; }

/* ---------- Stats ---------- */
.km-stats { position: relative; background: var(--ink); color: #fff; overflow: hidden; }
.km-stats::before {
    content: ''; position: absolute; inset: -20% -5%; z-index: 0; pointer-events: none;
    background: radial-gradient(26vw 26vw at 50% 50%, rgba(20,200,212,.14), transparent 65%);
}
.km-stats__inner { position: relative; z-index: 1; max-width: 1000px; margin: 0 auto; padding: 60px 28px; display: grid; grid-template-columns: repeat(3, 1fr); text-align: center; gap: 20px; }
.km-stats__n { font-family: var(--font-display); font-size: clamp(44px, 6vw, 72px); color: var(--cyan); text-shadow: 0 0 34px rgba(20,200,212,.45); }
.km-stats__l { text-transform: uppercase; letter-spacing: .08em; font-size: 12px; font-weight: 700; color: rgba(255,255,255,.7); margin-top: 4px; }

/* ---------- Sections ---------- */
.km-section { position: relative; padding: 100px 28px; overflow: hidden; }
.km-section--alt { background: var(--paper-2); }
.km-section--dark { background: var(--ink); color: #fff; }
.km-section--dark .km-prose { color: rgba(255,255,255,.75); }
.km-section--dark::before {
    content: ''; position: absolute; inset: -10%; z-index: 0; pointer-events: none; opacity: .5;
    background: radial-gradient(32vw 32vw at 14% 20%, rgba(20,200,212,.16), transparent 62%),
                radial-gradient(28vw 28vw at 86% 82%, rgba(255,90,60,.14), transparent 60%);
    animation: km-blob-drift 26s ease-in-out infinite alternate;
}
.km-section--dark > * { position: relative; z-index: 1; }
.km-section__inner { max-width: 1240px; margin: 0 auto; position: relative; z-index: 1; }
.km-center { text-align: center; }

.km-eyebrow { text-transform: uppercase; letter-spacing: .14em; font-size: 12px; font-weight: 800; color: var(--cyan-dark); margin: 0 0 12px; }
.km-title { font-size: clamp(34px, 5vw, 54px); text-transform: uppercase; margin-bottom: 22px; }
.km-title.km-center { margin-left: auto; margin-right: auto; }
.km-prose { max-width: 640px; color: var(--text-soft); font-size: 16px; }
.km-prose.km-center { margin-left: auto; margin-right: auto; }
.km-prose p { margin-bottom: 1em; }

.km-split { display: grid; grid-template-columns: .85fr 1.15fr; gap: 64px; align-items: center; }
.km-split__media img { border-radius: var(--radius); box-shadow: var(--shadow); width: 100%; height: auto; aspect-ratio: 4/5; object-fit: cover; }

.km-quote { margin: 26px 0 0; padding: 20px 24px; border-left: 4px solid var(--coral); background: #fff; border-radius: 0 12px 12px 0; font-size: 16px; font-style: italic; color: var(--text); box-shadow: var(--shadow); }

/* ---------- Cytaty jako przerywniki między sekcjami (4x, życzenie Michała 25.08) ---------- */
.km-quote-banner { position: relative; padding: 45px 28px; background: var(--ink); overflow: hidden; }
.km-quote-banner::before {
    content: '\201C'; position: absolute; top: -0.15em; left: 50%; transform: translateX(-50%);
    font-family: var(--font-display); font-size: 340px; line-height: 1; color: rgba(255,255,255,.05); pointer-events: none;
}
.km-quote-banner__inner { position: relative; z-index: 1; max-width: 860px; margin: 0 auto; text-align: center; }
.km-quote-banner blockquote {
    margin: 0; color: #fff; font-family: var(--font-display); text-transform: none;
    font-size: clamp(24px, 3.6vw, 42px); line-height: 1.3; letter-spacing: .01em;
}
.km-quote-banner__mark { color: var(--cyan); }

/* ---------- Achievements — karty w karuzeli (coverflow), patrz .km-carousel niżej ----------
   27.08 (Michał): "zamiast wielu kafli jeden obok drugiego, karuzelę... pierwsze powiększone,
   poprzednie/następne pomniejszone po bokach". Bento-grid (span 2x2 na pierwszej karcie) i
   przypięty do karty tilt-3D (data-tilt) USUNIĘTE — środkowa karta jest teraz "duża" DYNAMICZNIE
   (skalowanie w JS wg pozycji w karuzeli), a tilt na hover biłby się o tę samą właściwość
   transform z inline transform karuzeli. Stały rozmiar karty narzuca .km-carousel__item. */
.km-timeline__item {
    position: relative;
    height: 100%;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--ink);
    box-shadow: var(--shadow);
    isolation: isolate;
}

/* Glow-border animowany gradientem, wpuszczony pod kartę, widoczny na hover */
.km-timeline__item::before {
    content: '';
    position: absolute; inset: -1px; z-index: -1; border-radius: inherit;
    background: conic-gradient(from var(--ang, 0deg), var(--cyan), var(--coral), var(--cyan));
    opacity: 0; transition: opacity .35s ease;
    animation: km-spin 4s linear infinite;
    animation-play-state: paused; /* kręci się TYLKO pod kursorem — 13 kart w tle nie grzeje GPU za darmo */
}
.km-timeline__item:hover::before { opacity: .9; animation-play-state: running; }
@keyframes km-spin { to { --ang: 360deg; } }
@property --ang { syntax: '<angle>'; inherits: false; initial-value: 0deg; }

.km-timeline__ghost {
    position: absolute; top: -0.12em; right: 10px; z-index: 0;
    font-family: var(--font-display); font-size: clamp(64px, 11vw, 130px); line-height: 1;
    color: rgba(255,255,255,.07); pointer-events: none; user-select: none;
}

.km-timeline__img { position: absolute; inset: 0; z-index: 0; overflow: hidden; background: var(--paper-2); }
.km-timeline__img img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s cubic-bezier(.16,1,.3,1), filter .4s ease; filter: saturate(1.05); }
.km-timeline__item:hover .km-timeline__img img { transform: scale(1.1) translateZ(0); }
.km-timeline__img::after {
    content: ''; position: absolute; inset: 0;
    background: linear-gradient(180deg, rgba(10,25,48,0) 30%, rgba(6,14,26,.94) 100%);
}

.km-timeline__body { position: relative; z-index: 2; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; padding: 18px 20px 20px; color: #fff; }
.km-timeline__year { display: inline-block; font-family: var(--font-display); font-size: 22px; color: var(--cyan); margin-bottom: 4px; letter-spacing: .02em; }
.km-timeline__title { font-family: var(--font-body); font-weight: 700; font-size: 15px; text-transform: none; letter-spacing: 0; margin-bottom: 4px; color: #fff; }
.km-timeline__desc { font-size: 12.5px; color: rgba(255,255,255,.72); margin: 0; max-width: 34ch; }

/* Sweep światła po przekątnej na hover — jednorazowy „shine" */
.km-timeline__shine {
    position: absolute; inset: 0; z-index: 3; pointer-events: none;
    background: linear-gradient(115deg, transparent 40%, rgba(255,255,255,.28) 50%, transparent 60%);
    transform: translateX(-120%);
}
.km-timeline__item:hover .km-timeline__shine { transition: transform .85s ease; transform: translateX(120%); }

/* ---------- Karuzela (coverflow) — WSPÓLNY mechanizm Osiągnięć i Galerii (27.08, Michał) ----------
   Struktura: .km-carousel (ramka+strzałki) > .km-carousel__viewport (overflow-x:auto +
   scroll-snap, CZYSTY scroll — dotyk/trackpad/kółko myszy działają za darmo, bez JS-a do
   przeciągania) > .km-carousel__track (flex row) > .km-carousel__item (stały rozmiar, karta
   treści w środku). JS (kmInitCarousel w site.js) dolicza WYŁĄCZNIE transform:scale()/opacity
   per karta wg odległości od środka viewportu przy scrollu — struktura/scroll to czyste CSS.
   Padding boczny toru = calc(50% - połowa szerokości karty), żeby PIERWSZA i OSTATNIA karta
   mogły dojechać do samego środka (inaczej sztywny brzeg toru zatrzymywałby scroll za wcześnie). */
.km-carousel { position: relative; margin-top: 50px; max-width: 1340px; margin-left: auto; margin-right: auto; }
.km-carousel__viewport {
    overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory;
    scrollbar-width: none; -ms-overflow-style: none; padding: 44px 0;
}
.km-carousel__viewport::-webkit-scrollbar { display: none; height: 0; }
.km-carousel__track {
    display: flex; align-items: center; gap: 24px; list-style: none; margin: 0;
    padding: 0 calc(50% - 150px); width: max-content;
}
.km-carousel__item {
    flex: 0 0 300px; width: 300px; height: 380px;
    scroll-snap-align: center; cursor: pointer;
    transition: transform .35s cubic-bezier(.16,1,.3,1), opacity .35s ease;
    will-change: transform, opacity;
}
.km-carousel__nav {
    position: absolute; top: 50%; transform: translateY(-50%); z-index: 5;
    width: 52px; height: 52px; border-radius: 50%; border: none; cursor: pointer;
    background: var(--ink); color: #fff; font-size: 26px; line-height: 1;
    display: flex; align-items: center; justify-content: center;
    box-shadow: var(--shadow); transition: background .2s ease, transform .2s ease;
}
.km-carousel__nav:hover { background: var(--coral); transform: translateY(-50%) scale(1.08); }
.km-carousel__nav:disabled { opacity: .35; cursor: default; }
.km-carousel__nav:disabled:hover { background: var(--ink); transform: translateY(-50%); }
.km-carousel__nav--prev { left: -6px; }
.km-carousel__nav--next { right: -6px; }
@media (max-width: 900px) {
    /* Pod strzałkami nie ma już miejsca obok kart — chowają się, przewijanie zostaje
       dotykiem/trackpadem/scroll-snap (naturalne na telefonie i tak). */
    .km-carousel__nav { display: none; }
    .km-carousel__item { flex-basis: 240px; width: 240px; height: 310px; }
    .km-carousel__track { padding: 0 calc(50% - 120px); gap: 18px; }
}

/* ---------- Sponsors — WSZYSCY naraz w siatce (życzenie Michała: nie karuzela) ----------
   Logotypy 2x większe (58px -> 116px, życzenie Michała) — 4 kolumny zamiast 5, żeby kafle
   miały gdzie je pomieścić bez ciasnoty (5 kolumn na 116px logo byłoby stłoczone).
   27.08 (Michał): "na mobile i przy skalowaniu zachowaj układ 4 kafli w rzędzie, skaluj w dół
   wielkość logo i tekstu" — WCZEŚNIEJ węższe ekrany dostawały 2, potem 1 kolumnę (przełamanie
   układu), TERAZ zawsze 4 kolumny, a rozmiar (padding/gap/logo/tekst promo) płynnie maleje
   przez clamp() zamiast skokowych wartości na sztywnych progach — jeden spójny mechanizm
   zamiast osobnych przypadków na 980px/560px. */
.km-sponsors { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(6px, 1.8vw, 18px); margin-top: 46px; align-items: stretch; }
.km-sponsors__item { background: #fff; border-radius: clamp(6px, 1.4vw, 14px); padding: clamp(6px, 2.2vw, 24px); display: flex; align-items: center; justify-content: center; aspect-ratio: 1.35/1; overflow: hidden; box-shadow: 0 8px 24px -14px rgba(10,25,48,.25); transition: transform .3s ease, box-shadow .3s ease; }
.km-sponsors__item:hover { transform: translateY(-4px); box-shadow: 0 16px 34px -14px rgba(10,25,48,.35); }
.km-sponsors__item a { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: clamp(2px, .8vw, 8px); width: 100%; height: 100%; text-decoration: none; }
.km-sponsors__item img { max-height: clamp(26px, 10vw, 150px); max-width: 100%; width: auto; object-fit: contain; }
/* Kafelek z podpisem promocyjnym (np. Glovii) — logo mniejsze, żeby zostało miejsce na tekst
   bez rozsadzania stałego aspect-ratio kafelka (życzenie Michała: siatka równa dla wszystkich). */
.km-sponsors__item:has(.km-sponsors__promo) img { max-height: clamp(18px, 7vw, 100px); }
.km-sponsors__promo { font-size: clamp(7px, 2vw, 13px); font-weight: 700; line-height: 1.25; text-align: center; color: var(--coral); }

/* ---------- Galeria — karty w karuzeli (coverflow), patrz .km-carousel niżej ----------
   27.08 (Michał): "identyczny mechanizm dla galerii zdjęć" — masonry przez CSS columns
   (różne proporcje zdjęć, ręcznie wyrównywane góra-dół) ZASTĄPIONE stałym rozmiarem karty
   (.km-carousel__item) + object-fit:cover, jak karty Osiągnięć. Kolejność zdjęć przestaje
   mieć znaczenie dla balansu kolumn (nie ma już kolumn) — $galleryImages w index.php nadal
   ustala kolejność, teraz tylko jako kolejność przewijania. */
.km-gallery__item { position: relative; display: block; height: 100%; border-radius: 14px; overflow: hidden; box-shadow: var(--shadow); }
.km-gallery__item img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .5s cubic-bezier(.16,1,.3,1); }
.km-gallery__item:hover img { transform: scale(1.06); }
.km-gallery__zoom {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #fff;
    background: rgba(10,25,48,0); opacity: 0; transition: background .3s ease, opacity .3s ease;
}
.km-gallery__item:hover .km-gallery__zoom { background: rgba(10,25,48,.35); opacity: 1; }

.km-lightbox { position: fixed; inset: 0; z-index: 400; display: flex; align-items: center; justify-content: center; padding: 5vh 5vw; background: rgba(6,14,26,.92); backdrop-filter: blur(6px); animation: km-lb-in .25s ease; }
@keyframes km-lb-in { from { opacity: 0; } to { opacity: 1; } }
.km-lightbox img { max-width: 100%; max-height: 90vh; border-radius: 12px; box-shadow: 0 40px 80px -20px rgba(0,0,0,.6); }
.km-lightbox__close { position: absolute; top: 22px; right: 28px; width: 44px; height: 44px; border-radius: 50%; border: none; background: rgba(255,255,255,.12); color: #fff; font-size: 22px; cursor: pointer; transition: background .2s ease; }
.km-lightbox__close:hover { background: rgba(255,255,255,.25); }
.km-lightbox__nav {
    position: absolute; top: 50%; transform: translateY(-50%); width: 52px; height: 52px; border-radius: 50%;
    border: none; background: rgba(255,255,255,.12); color: #fff; font-size: 30px; line-height: 1; cursor: pointer;
    display: flex; align-items: center; justify-content: center; transition: background .2s ease;
}
.km-lightbox__nav:hover { background: rgba(255,255,255,.25); }
.km-lightbox__nav--prev { left: 16px; }
.km-lightbox__nav--next { right: 16px; }
@media (max-width: 560px) { .km-lightbox__nav { width: 44px; height: 44px; font-size: 24px; } .km-lightbox__nav--prev { left: 6px; } .km-lightbox__nav--next { right: 6px; } }

/* Aktualności — import z Instagrama (etap 3, patrz includes/instagram.php). Karty jak
   .km-sponsors (białe tło, cień), nie kolumnowa masonka jak .km-gallery — tu jest tekst
   (podpis+data) pod zdjęciem, nie sam obraz. */
.km-news { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 46px; text-align: left; }
.km-news__item { position: relative; background: #c7cfd9; border-radius: 14px; overflow: hidden; box-shadow: var(--shadow); display: block; text-decoration: none; color: var(--text); transition: transform .3s ease, box-shadow .3s ease; }
.km-news__item:hover { transform: translateY(-4px); box-shadow: 0 16px 34px -14px rgba(10,25,48,.35); }
.km-news__item img { width: 100%; aspect-ratio: 1/1; object-fit: cover; display: block; }
.km-news__play, .km-news-strip__play {
    position: absolute; top: 10px; right: 10px; width: 32px; height: 32px; border-radius: 50%;
    background: rgba(6,14,26,.55); color: #fff; display: flex; align-items: center; justify-content: center;
}
.km-news-strip__play { width: 24px; height: 24px; }
.km-news__body { padding: 16px 18px; }
.km-news__caption { font-size: 14px; line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.km-news__date { display: block; margin-top: 8px; font-size: 12px; letter-spacing: .04em; text-transform: uppercase; color: rgba(10,25,48,.5); }
@media (max-width: 980px) { .km-news { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .km-news { grid-template-columns: 1fr; } }

/* Pasek starszych postów (4.+) — poziome przewijanie zamiast dokładania kolejnych rzędów do
   siatki, inaczej sekcja rośnie w nieskończoność z każdym zaimportowanym postem (Michał 26.08:
   "3 najnowsze, reszta przewijana"). Zwykły overflow-x, bez biblioteki karuzeli — "prosta gra"
   zasada obowiązuje też tutaj. */
.km-news-strip { display: flex; gap: 14px; margin-top: 22px; overflow-x: auto; scroll-snap-type: x proximity; padding-bottom: 6px; }
.km-news-strip__item { flex: 0 0 auto; scroll-snap-align: start; width: 140px; border-radius: 12px; overflow: hidden; box-shadow: var(--shadow); text-decoration: none; position: relative; display: block; transition: transform .25s ease; }
.km-news-strip__item:hover { transform: translateY(-3px); }
.km-news-strip__item img { width: 100%; aspect-ratio: 1/1; object-fit: cover; display: block; }
.km-news-strip__date {
    position: absolute; left: 0; right: 0; bottom: 0; padding: 6px 8px;
    font-size: 11px; letter-spacing: .03em; color: #fff;
    background: linear-gradient(to top, rgba(6,14,26,.75), transparent);
}
@media (max-width: 560px) { .km-news-strip__item { width: 110px; } }

/* ---------- Contact ---------- */
.km-contact-info { display: flex; flex-direction: column; gap: 12px; margin-top: 20px; font-size: 16px; color: var(--text-soft); }
.km-contact-info a:hover { color: var(--cyan-dark); }

.km-contact-form { background: #fff; border-radius: var(--radius); padding: 34px; box-shadow: var(--shadow); }
.km-form { display: flex; flex-direction: column; gap: 6px; }
.km-form label { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--text-soft); margin-top: 12px; }
.km-form input, .km-form textarea { font-family: var(--font-body); font-size: 15px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px; background: var(--paper); color: var(--text); }
.km-form input:focus, .km-form textarea:focus { outline: none; border-color: var(--cyan); }
.km-form .km-btn { margin-top: 20px; align-self: flex-start; }
.km-form__opt { text-transform: none; font-weight: 400; }
.km-form__ok { color: #1c8a53; font-weight: 600; }
.km-form__err { color: var(--coral); font-weight: 600; }
.km-form__note { color: var(--cyan-dark); font-weight: 600; }

.km-cta-row { margin-top: 26px; }

/* ---------- Współpraca — zdjęcie celebracyjne, jeśli Michał je wgra (patrz index.php) ----------
   Zdjęcie MUSI dotykać dołu sekcji (Michał 24.08 — "wisiało w powietrzu" przy wyśrodkowaniu):
   #wspolpraca traci dolny padding, a kolumna ze zdjęciem łapie się dna gridu (align-items: end),
   zamiast wisieć na środku wysokości rzędu. */
.km-section--flush-bottom { padding-bottom: 0; }
/* Zdjęcie łapie się dna (align-self:end na samym sobie), ale tekst/przycisk zostają
   wyśrodkowane WZGLĘDEM WYSOKOŚCI ZDJĘCIA (align-items:center na rzędzie) — inaczej
   "Napisz do mnie" też lądował na granicy sekcji, zgłoszenie Michała 24.08. */
.km-split--collab { align-items: center; }
.km-collab__photo { display: flex; justify-content: center; align-self: end; }
.km-collab__photo img {
    /* Źródłowy plik ma dużo przezroczystej przestrzeni po prawej (Kamil zajmuje tylko lewą
       część kadru 1920×1000) — object-fit:cover + object-position:left kadruje na sztywno
       do sylwetki, zamiast pokazywać ramkę wypełnioną w połowie pustką. */
    width: 100%; max-width: 380px; aspect-ratio: 3/4; object-fit: cover; object-position: left center;
    filter: drop-shadow(0 30px 40px rgba(0,0,0,.5));
    display: block;
    transition: transform .4s cubic-bezier(.2,.8,.3,1);
}
.km-collab__photo img:hover {
    transform: scale(1.08);
}

/* ---------- Footer ---------- */
.km-footer { background: var(--ink); color: rgba(255,255,255,.7); padding: 40px 28px; }
.km-footer__inner { max-width: 1240px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 18px; }
.km-footer__brand { display: flex; align-items: center; gap: 10px; font-weight: 700; color: #fff; }
.km-footer__brand img { border-radius: 50%; }
.km-footer__contact, .km-footer__links { display: flex; gap: 20px; font-size: 14px; }
.km-footer__contact a:hover, .km-footer__links a:hover { color: var(--cyan); }

.km-legal { max-width: 820px; margin: 0 auto; }
.km-legal .km-prose { max-width: none; color: var(--text); }

/* ---------- Responsive (reszta — timeline/galeria mają własne breakpointy wyżej) ---------- */

/* Wersja POŚREDNIA (Michał 25.08): za wąsko, żeby zmieściły się ikona + napis "Kamil Manowiecki"
   + wszystkie linki menu w jednym rzędzie (kolizja tekstu), ale wciąż za szeroko na pełne
   chowanie menu (@media 980px niżej). Znika sam napis przy logo (zostaje ikona) — to
   uwalnia miejsce menu, bez skakania od razu do wersji mobilnej.
   Hero: tytuł/akapit skurczone i węższe, żeby tekst nie sięgał tam, gdzie na zdjęciu jest
   twarz Kamila (zgłoszenie Michała — na tej szerokości akapit "najeżdżał" na twarz). */
@media (max-width: 1400px) {
    .km-nav__logo span { display: none; }
    .km-hero__title { font-size: clamp(36px, min(7vw, 10vh), 96px); }
    .km-hero__sub { max-width: 440px; font-size: 15px; margin-bottom: 22px; }
    /* Blok tekstu jest przyklejony do DOŁU (align-items:flex-end) — sposób na to, żeby
       zjechał niżej (dalej od twarzy na zdjęciu, która siedzi mniej więcej w środku kadru),
       to pokazać MNIEJ zdjęcia u góry, czyli efektywnie "dociągnąć" kadr niżej. Tło i tak
       wypełnia całość przez cover, więc twarz proporcjonalnie "cofa się" wyżej w kadrze.
       125svh dobrane tak, żeby zjazd był wyraźnie większy niż wysokość liter w tytule —
       Michał 25.08: "co najmniej o wysokość liter w KAMIL MANOWIECKI niżej".

       🐞 27.08 POPRAWKA: PIERWOTNIE to była `.km-hero { min-height: 125svh; }` — czyli
       nadmuchany był CAŁY .km-hero, razem z .km-hero__inner (flex align-items:flex-end).
       To pchało w dół TAKŻE przycisk "Zobacz osiągnięcia" (ostatni element tego samego
       bloku) — przy pewnych kombinacjach zoom/rozdzielczości (Michał 27.08, zrzuty
       175/150/125%) przycisk lądował POD dolną krawędzią ekranu i znikał całkowicie, nie
       tylko wymagał doscrollowania ("miał zawsze być widoczny od dołu, w stałej odległości,
       chyba że to mobile"). Naprawione u ŹRÓDŁA, nie łatką na samym przycisku: nadmuchana
       jest teraz WYŁĄCZNIE warstwa tła (.km-hero__stage, position:absolute — nie uczestniczy
       w layoucie fleksa), a .km-hero zostaje na normalnych 100svh. .km-hero__stage bazowo ma
       inset:0 (czyli też 100% wysokości .km-hero) — tu nadpisane na height:125svh z top:0,
       czyli rozciąga się on 25svh NIŻEJ niż .km-hero (obcięte przez overflow:hidden, poza
       ekranem) zamiast wcześniej być NADMUCHANE JAKO CAŁOŚĆ .km-hero. .km-hero__bg (właściwe
       tło, background:cover) liczy swój rozmiar względem .km-hero__stage jako %, więc przy
       IDENTYCZNYCH wymiarach stage (ta sama szerokość, ta sama wysokość 125svh) wychodzi
       BAJT W BAJT ten sam crop/zoom zdjęcia co wcześniej — jedyna różnica to że .km-hero__inner
       (tekst + przycisk) już nie jedzie w dół razem z tą sztuczką, bo nie jest już członkiem
       nadmuchanego kontenera. Zweryfikowane w przeglądarce (getBoundingClientRect) na kilku
       szerokościach/wysokościach z tego bracketu: przycisk zawsze w normalnym przepływie,
       zawsze pod tekstem, nigdy poza ekranem bardziej niż wcześniej sam tekst. */
    .km-hero__stage { top: 0; bottom: auto; height: 125svh; }
}

@media (max-width: 980px) {
    /* Linki tekstowe znikają (brak jeszcze menu mobilnego/hamburgera — osobny temat),
       ale przełącznik języka MUSI zostać widoczny — stąd chowamy tylko <a>, nie cały .km-nav__links. */
    .km-nav__links > a { display: none; }
    .km-nav__links { gap: 0; }
    .km-split { grid-template-columns: 1fr; gap: 36px; }
    .km-section { padding: 70px 20px; }
}
@media (max-width: 560px) {
    .km-stats__inner { grid-template-columns: 1fr; gap: 34px; }
    .km-contact-form { padding: 22px; }
}

/* prefers-reduced-motion — wyłącza ozdobniki ruchu, treść zostaje w pełni czytelna bez nich */
@media (prefers-reduced-motion: reduce) {
    .km-timeline__item::before,
    .km-hero__bg::before { animation: none; }
    .km-hero__bg { transform: none !important; }
    .km-word__in { animation: none; transform: none; }
    .km-btn { transition: none; }
}
