/* Giełda Żeglarska — client-side marketplace SPA (served from zeglarski.info)
   Portal-style navbar (#6699ff masthead + #004488 category bar), Archivo/Inter/Bricolage.
   Trzy kroje, nie cztery: Signika wypadla razem z regula w .mainnav i nie ma jej
   juz w linku do Google Fonts w index.html. */
:root{
  --navy:#0a2540; --navy-deep:#071c33; --navy-soft:#143656;
  --accent:#1773d6; --accent-dark:#1160b8; --blue:#2f6cb0; --blue-soft:#eaf1f9;
  --mast:#6699ff; --bar:#004488; --bar-d:#003a75;
  /* greys — every tier that carries information clears WCAG AA on #fff AND on
     --canvas. --faint was #94a1b0 (2.63:1) and failed on every card meta line,
     every timestamp and the whole footer bar; #63707e is 5.06:1 / 4.72:1. */
  --ink:#16202c; --muted:#5d6b7a; --faint:#63707e; --line:#e4e8ee; --canvas:#f5f7fa;
  --hair:#eef1f5;                              /* inside-object divider, one step above --line */
  --green:#0e7a3f; --green-bg:#e8f5ee; --green-bd:#c7e7d3; --red:#c11f12; --red-bg:#fdeceb;
  /* one amber family: promotion, offer notices, stars. #b07a10 on #fdf3dd was
     3.38:1; --amber is 5.78:1. --star is a graphic, so it only owes 3:1 (3.73:1). */
  --amber:#8a5c0b; --amber-bg:#fdf3dd; --amber-bd:#f3e2b3; --star:#b8760a;
  /* SHAPE LOCK — exactly two radii in the whole product.
     Documented radius scale. The home and results pass introduced 10px surfaces
     while every subpage was still on the old 3px, so the product was running two
     shape systems at once. One scale now, three steps:
       --r-lg  10px = SURFACES you can point at: card, box, panel, media, sheet.
       --r      8px = CONTROLS you operate: input, select, button, chip.
       999px        = things that are semantically a pill: badges, dots, sort pills. */
  --r:8px; --r-lg:10px;
  --ease:cubic-bezier(.2,.7,.3,1); --t:.16s;
}
/* FOCUS — one ring, drawn the same way everywhere, always paired with the hover
   design so the keyboard path is never a lesser design than the mouse path. */
:where(a,button,input,select,textarea,[tabindex]):focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r)}
:where(.site-header,.drawer) :where(a,button,input):focus-visible{outline-color:#fff;outline-offset:3px}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
/* Allegro's defining move: the PAGE is grey and every surface that holds
   content is a white card on top of it. Borders become unnecessary. */
body{margin:0;min-height:100vh;display:flex;flex-direction:column;font-family:"Inter",system-ui,-apple-system,sans-serif;color:var(--ink);background:#f1f3f5;line-height:1.55;-webkit-font-smoothing:antialiased}
main{flex:1 0 auto;width:100%}
/* .glow ma teraz treść — definicja na końcu arkusza, przy poświacie tła. */
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%}
button{font-family:inherit;cursor:pointer}
h1,h2,h3,h4{font-family:"Archivo",sans-serif;margin:0}
.wrap{max-width:1280px;margin:0 auto;padding:0 24px}
.disp{font-family:"Archivo",sans-serif}
.hide{display:none!important}

/* ── Header — floating photo-card navbar (mirrors the zeglarski.info masthead) ── */
/* --nb-img jest rysowane przez .site-header::before z filter:blur(--nb-blur), a
   blur ma 16 px, wiec kazdy detal drobniejszy niz ~3 px i tak ginie. Zrodlo
   mialo 1600 px / 139 898 B; zostalo 480 px / 10 713 B i po rozmyciu render jest
   nie do odroznienia. Gdyby --nb-blur kiedys zjechal ponizej ~6 px, trzeba
   wrocic po wiekszy plik. */
:root{--nb-radius-bot:23px; --nb-blur:16px; --nb-a:.70; --nb-img:url('nb-hero.jpg');}
/* #hdr is the sticky wrapper — sticky on .site-header itself would stick inside
   the wrapper's own height (it's the only child) and never pin to the viewport */
#hdr{position:sticky;top:0;z-index:50}
/* The nav dropdowns have to escape downward, so overflow-y must be visible; it
   used to be `hidden`, which silently made every dropdown invisible.
   overflow-x stays CLIPPED, and that half matters just as much: ::before bleeds
   60px on every side for the blur, and its clip-path hides it visually WITHOUT
   removing it from scroll overflow, so a plain `visible` here pushed the page
   44px wide (1393 + 16 + 60 = 1469 against a 1425 viewport). clip rather than
   hidden, because hidden on one axis forces the other axis to auto. */
.site-header{position:relative;isolation:isolate;overflow-x:clip;overflow-y:visible;width:min(1400px,calc(100% - 32px));margin:0 auto;border-radius:0 0 var(--nb-radius-bot) var(--nb-radius-bot);box-shadow:0 28px 64px -26px rgba(8,24,48,.6),0 3px 12px rgba(8,24,48,.22)}
.site-header::before{content:"";position:absolute;inset:-60px;z-index:-2;background:#0a2540 var(--nb-img) center/cover no-repeat;filter:blur(var(--nb-blur)) saturate(1.18) brightness(1.02);clip-path:inset(60px round 0 0 var(--nb-radius-bot) var(--nb-radius-bot))}
.site-header::after{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;background:linear-gradient(118deg,rgba(6,22,46,var(--nb-a)),rgba(7,26,52,calc(var(--nb-a) - .22)) 52%,rgba(12,44,84,var(--nb-a)))}
/* Naglowek trzyma DOKLADNIE te sama kolumne co tresc pod nim: 1280 px i 24 px
   marginesu bocznego, tak jak .wrap. Wczesniej bylo tu 1240/26, wiec cala gora
   serwisu - logo, wyszukiwarka, pasek kategorii - stala wsunieta o 22 px wzgledem
   kazdego rzedu kart, hero i stopki. Roznica jest dokladnie taka, ze nie czyta
   sie jako decyzja, tylko jako niedbalstwo: krawedzie prawie sie zgadzaja. */
.site-header .wrap{padding-left:24px;padding-right:24px;max-width:1280px}
.masthead{background:transparent}
.masthead__top{display:flex;align-items:center;gap:24px;padding-top:15px;padding-bottom:13px}
/* Stala szerokosc, nie auto: globalne img{max-width:100%} razem z kurczliwym
   flexem zgniatalo boks logo grubo ponizej jego proporcji. 235x44 to dokladny
   stosunek viewBoksu, ten sam co w portalu. */
.logo img{height:44px;width:235px;object-fit:contain;filter:drop-shadow(0 2px 8px rgba(4,14,30,.5))}
/* subtitle as HTML (not SVG <text>) — fonts inside an <img> SVG never load, so
   the tagline is typeset here with the page's real fonts, over the wordmark's
   empty bottom-right strip (where "portal żeglarski" sits in the original) */
.logo{position:relative;flex:0 0 auto;min-width:0}
.logo__tag{position:absolute;left:42.5%;bottom:1px;font-size:11px;font-weight:500;letter-spacing:.05em;line-height:1;color:#fff;opacity:.95;white-space:nowrap;text-shadow:0 1px 6px rgba(4,14,30,.6);pointer-events:none}
@media(max-width:600px){.logo img{height:29px}.logo__tag{font-size:7.5px}}
/* navbar search — solid white pill on the photo tile (sits where the topmenu was) */
.nbsearch{flex:1 1 auto;min-width:140px;max-width:640px;margin:0 auto;display:flex;align-items:center;gap:6px;height:42px;padding:0 5px 0 16px;border-radius:999px;background:#fff;box-shadow:0 6px 18px -10px rgba(4,14,30,.6)}
.nbsearch input{flex:1;min-width:0;border:0;outline:none;background:none;height:100%;font-family:inherit;font-size:14px;color:var(--ink)}
.nbsearch input::placeholder{color:var(--faint)}
.nbsearch input::-webkit-search-cancel-button{cursor:pointer}
.nbsearch__go{flex:none;width:34px;height:34px;display:grid;place-items:center;border:0;border-radius:999px;background:var(--navy);color:#fff;cursor:pointer;transition:background .15s}
.nbsearch__go:hover{background:var(--navy-soft)}
.acts{display:flex;align-items:center;gap:2px;margin-left:auto}
.acts--d{display:flex;align-items:center;gap:14px}
.acts__ic{display:flex;align-items:center;gap:6px}
/* Serce i koperta stoja w jednym rzedzie z "Zaloguj sie" i "Dodaj ogloszenie",
   ale byly z zupelnie innego materialu: tamte to oszronione pigulki z bialym
   pierscieniem, te dwa - gole glify bez tla i bez obrysu. Kolko pojawialo sie
   dopiero pod kursorem, wiec w spoczynku nie bylo widac, ze to w ogole przyciski;
   do tego 40px przy 42px sasiadow rozjezdzalo rzad o piksel u gory i u dolu.
   Ten sam material i ta sama wysokosc co reszta rzedu: cztery elementy, jedna
   linia optyczna. */
.act{position:relative;display:inline-flex;align-items:center;justify-content:center;width:42px;height:42px;border-radius:999px;color:#fff;border:0;
  background:rgba(255,255,255,.14);-webkit-backdrop-filter:blur(10px) saturate(1.3);backdrop-filter:blur(10px) saturate(1.3);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.35);transition:background .15s,box-shadow .15s}
.act:hover{background:rgba(255,255,255,.26);box-shadow:inset 0 0 0 1px rgba(255,255,255,.58),inset 0 1px 0 rgba(255,255,255,.42)}
/* Plakietka byla granatowa NA GRANATOWYM pasku, a jej obramowanie tez granatowe,
   wiec biala cyfra wisiala bez zadnego tla i zlewala sie z ikona pod spodem.
   Akcent daje kontrast z paskiem, a obramowanie w kolorze paska odcina ja od
   samej ikony. Ten sam uklad ma juz plakietka w dolnym pasku skrotow (.ab__n),
   wiec przy okazji obie zaczynaja wygladac tak samo.
   -6px wypychalo ja poza obrys przycisku i optycznie za wysoko; -3px trzyma ja
   przy ikonie, a nie nad nia. */
/* 17px przy pismie 10px starczalo na jedna cyfre i to ledwo: przy dwoch cyfrach
   padding rozciagal kolko w waski owal, a cyfry siedzialy scisniete przy samym
   obrysie. 21px z pismem 11px trzyma kolo dla jednej cyfry i daje spokojna
   pigulke dla dwoch, bez zmiany wysokosci - rzad ikon zostaje na swojej linii.
   Wypelnienie to teraz gradient, a nie plaski akcent: jasniejszy blekit u gory,
   glebszy u dolu, plus wewnetrzny rozblysk pod samym obrysem. To on daje polysk;
   sam ciemniejszy kolor dalby tylko ciemniejsza plame. Blekit mocniejszy niz
   --accent, zeby plakietka trzymala sie na tle rozmytego zdjecia w pasku. */
.act .bdg{position:absolute;top:-4px;right:-4px;min-width:21px;height:21px;padding:0 5px;display:grid;place-items:center;border-radius:999px;
  /* Bez koloru. Plakietka jest z tego samego szkla co przycisk pod nia, tylko
     odrobine ciemniejsza - tyle, zeby cyfra miala sie na czym oprzec, i nie
     wiecej. Kolorowa kropka w rogu przyciagala wzrok mocniej niz cokolwiek
     innego w pasku, a niesie najmniej: liczbe obserwowanych. */
  background:rgba(6,24,48,.34);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  color:#fff;font-size:11px;font-weight:700;line-height:1;letter-spacing:.01em;
  border:0;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.34),inset 0 1px 0 rgba(255,255,255,.22),0 1px 3px rgba(4,20,48,.35)}
.pill{display:inline-flex;align-items:center;gap:8px;height:42px;padding:0 16px;border-radius:999px;font-size:13.5px;font-weight:600;border:0;white-space:nowrap;transition:background .15s,box-shadow .15s}
.pill--w{background:rgba(255,255,255,.15);color:#fff;font-weight:700;-webkit-backdrop-filter:blur(10px) saturate(1.3);backdrop-filter:blur(10px) saturate(1.3);box-shadow:inset 0 0 0 1px rgba(255,255,255,.42),inset 0 1px 0 rgba(255,255,255,.3),0 6px 18px -10px rgba(4,14,30,.6)}
.pill--w:hover{background:rgba(255,255,255,.26);box-shadow:inset 0 0 0 1px rgba(255,255,255,.58),inset 0 1px 0 rgba(255,255,255,.42),0 9px 24px -10px rgba(4,14,30,.72)}
/* Same material as the account button next to it: frosted translucent white over
   the header photo, not a blue fill. The two sat side by side in one row wearing
   two different treatments. */
.pill--n{background:rgba(255,255,255,.14);color:#fff;font-weight:700;-webkit-backdrop-filter:blur(10px) saturate(1.3);backdrop-filter:blur(10px) saturate(1.3);box-shadow:inset 0 0 0 1px rgba(255,255,255,.35)}
.pill--n:hover{background:rgba(255,255,255,.26);box-shadow:inset 0 0 0 1px rgba(255,255,255,.58),inset 0 1px 0 rgba(255,255,255,.42),0 9px 24px -10px rgba(4,14,30,.72)}
/* 42, nie 40: dokladnie tyle ma .act, czyli serce, czat i dzwonek stojace obok.
   Dwa piksele roznicy w rzedzie okraglych przyciskow widac od razu jako
   "ten jest inny" - i wlasnie tak wygladalo na zrzucie. */
.acct{display:inline-flex;align-items:center;gap:6px;height:42px;padding:0 8px 0 4px;border-radius:999px;background:rgba(255,255,255,.14);border:0;-webkit-backdrop-filter:blur(10px) saturate(1.3);backdrop-filter:blur(10px) saturate(1.3);box-shadow:inset 0 0 0 1px rgba(255,255,255,.35)}
.acct:hover{background:rgba(255,255,255,.24)}
.avt{width:34px;height:34px;border-radius:999px;display:grid;place-items:center;background:var(--navy);color:#fff;font-size:12px;font-weight:800}
.acct .nm{color:#fff;font-size:13.5px;font-weight:600}
/* Daszek, a nie "kazdy svg w przycisku". Odkad w kolku siedzi znak zeglarski,
   regula bez ograniczenia do dziecka bezposredniego obracala TAKZE logo przy
   otwieraniu menu - zagiel robil piruet, choc nic nie zapowiadal.
   `>` wystarczy: daszek jest bezposrednim dzieckiem przycisku, a logo siedzi
   wewnatrz .avt. */
.acct>svg{color:#fff;transition:transform .15s}
.acct.open>svg{transform:rotate(180deg)}
.menu{position:fixed;right:24px;top:100px;width:232px;background:#fff;border:1px solid var(--line);border-radius:var(--r);box-shadow:0 14px 34px -12px rgba(10,37,64,.5);padding:6px 0;z-index:75;animation:menuIn .14s ease}
@keyframes menuIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}
.menu .mh{padding:6px 16px 8px;border-bottom:1px solid var(--line);margin-bottom:4px}
.menu .mh small{font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--faint);font-weight:700}
.menu .mh b{display:block;font-size:13.5px;color:var(--navy)}
.menu a,.menu button{display:block;width:100%;text-align:left;padding:8px 16px;font-size:13.5px;font-weight:600;color:var(--ink);background:none;border:0}
.menu a:hover{background:var(--canvas);color:var(--blue)}
.menu .lg{color:var(--red)}
.menu .lg:hover{background:var(--red-bg)}
.menu .sep{height:1px;background:var(--line);margin:6px 0}
.burger{width:40px;height:40px;display:grid;place-items:center;border-radius:999px;color:#fff;background:none;border:0}
.burger:hover{background:rgba(255,255,255,.15)}

/* second row — category nav (mirrors zeglarski's .mainnav) */
/* ── main navigation: four groups with dropdowns, not ten flat links ────────
   Sits on the navy masthead, so triggers are white-on-dark and the menus drop as
   the same white 10px cards the rest of the product uses. overflow must stay
   visible or the menus are clipped by the header. */
.mainnav{background:transparent;border-top:1px solid rgba(255,255,255,.16);overflow:visible}
/* one family for the whole bar, triggers and menus alike. The old rule set a
   third typeface here (Signika), so the nav was the only place in the product
   using it; everything below inherits this rather than declaring its own. */
.mainnav__list{position:relative;overflow:visible;padding:4px 24px;
  font-family:"Inter",system-ui,sans-serif}
/* Pasek przewija sie na KAZDEJ szerokosci: dwanascie dzialow z ikonami zajmuje
   ~1390 px, wiec na 1440 miesci sie w calosci, a nizej trzeba przesunac. Ukryty
   pasek przewijania, bo to nawigacja, nie tabela. */
.mainnav__scroll{display:flex;align-items:center;gap:1px;flex-wrap:nowrap;
  overflow-x:auto;overflow-y:visible;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.mainnav__scroll::-webkit-scrollbar{display:none}
/* Dzialy WYPELNIAJA szerokosc paska. `1 0 auto`, nie `1`: rosna od swojej
   naturalnej szerokosci i nigdy nie kurcza sie ponizej niej. Roznica jest cala
   funkcja tej reguly - przy `flex:1` dziewiec pozycji dostaje po rowno, wiec
   "Rejsy" ma tyle samo miejsca co "Bezpieczenstwo" i albo jedno plywa w pustce,
   albo drugie sie lamie. Przy `1 0 auto` proporcje zostaja, nadmiar rozklada sie
   miedzy pozycje, a gdy miejsca zabraknie, pasek wraca do przewijania zamiast
   sciskac etykiety. */
.mainnav__scroll>.nvg{flex:1 0 auto}
.mainnav__scroll>.nvg>.nvg__i{width:100%;justify-content:center}
/* 8px zamiast 11 i 13px zamiast 13,5: kazda pozycja niesie teraz ikone, wiec
   szerokosc trzeba bylo znalezc gdzie indziej. Same liczby sa zmierzone, nie
   dobrane na oko - przy poprzednich wartosciach tresc paska miala 1539 px. */
.nvg__i{position:relative;display:inline-flex;align-items:center;gap:6px;height:34px;padding:0 8px;
  border-radius:var(--r);white-space:nowrap;cursor:pointer;text-decoration:none;
  font-size:13px;font-weight:600;letter-spacing:0;text-transform:none;
  color:rgba(255,255,255,.92);text-shadow:0 1px 7px rgba(4,14,30,.45);
  transition:background-color var(--t) var(--ease),color var(--t) var(--ease)}
.nvg__i:hover{background:rgba(255,255,255,.14);color:#fff}
.nvg__i.on{background:rgba(255,255,255,.18);color:#fff}
/* the intent pair reads as one control, so it gets pills rather than tabs */
.nvg__seg{display:flex;align-items:center;gap:5px;flex:none}
.nvg__i--sm{height:28px;padding:0 12px;border-radius:999px;font-size:12.5px;
  border:1px solid rgba(255,255,255,.34);text-shadow:none}
.nvg__i--sm:hover{background:rgba(255,255,255,.16)}
.nvg__i--sm.on{background:#fff;border-color:#fff;color:var(--navy)}
.nvg__sep{width:1px;height:22px;background:rgba(255,255,255,.24);margin:0 8px 0 4px;flex:none}
.nvg{display:flex;align-items:center;flex:none}
/* Ikona dzialu. Lekko przygaszona wzgledem tekstu: ma pomagac znalezc pozycje
   wzrokiem, a nie konkurowac z jej nazwa. */
.nvg__ic{display:inline-flex;flex:none;opacity:.72}
.nvg__i--has:hover .nvg__ic,.nvg:hover>.nvg__i .nvg__ic,.nvg__i.on .nvg__ic{opacity:1}
.nvg__chev{width:6px;height:6px;flex:none;opacity:.6;
  border-right:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:rotate(45deg) translateY(-2px)}
.nvg:hover>.nvg__i,.nvg:focus-within>.nvg__i{background:rgba(255,255,255,.16);color:#fff}
/* .nvg__i--last odeszla razem z pozycja "Wszystkie". */
/* Strzalki paska kategorii. Bialy krazek z granatowym znakiem - ten sam jezyk co
   strzalki karuzeli, bo obie robia to samo na ciemnym tle. Domyslnie ich nie ma:
   pokazuje je dopiero klasa, ktora navHint ustawia po zmierzeniu. */
.mnar{position:absolute;top:50%;transform:translateY(-50%);z-index:4;
  width:30px;height:30px;border:0;border-radius:999px;display:grid;place-items:center;
  background:#fff;color:var(--navy);cursor:pointer;
  box-shadow:0 2px 10px rgba(4,14,30,.35);
  opacity:0;pointer-events:none;transition:opacity var(--t) var(--ease)}
.mnar--l{left:8px}
.mnar--r{right:8px}
.mainnav__list.ma-l .mnar--l,.mainnav__list.ma-r .mnar--r{opacity:1;pointer-events:auto}
/* Dotyk przewija palcem, wiec krazek bylby tam tylko przeszkoda nad trescia. */
@media(hover:none){.mnar{display:none}}
@media(prefers-reduced-motion:reduce){.mnar{transition:none}}
.nvg__menu{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:70;min-width:0;
  background:#fff;border-radius:var(--r-lg);padding:7px;
  box-shadow:0 20px 46px -18px rgba(4,14,30,.5),0 0 0 1px rgba(10,37,64,.07);
  opacity:0;visibility:hidden;transform:translateY(-4px);
  transition:opacity var(--t) var(--ease),transform var(--t) var(--ease),visibility 0s linear var(--t)}
.nvg:hover>.nvg__menu,.nvg:focus-within>.nvg__menu{opacity:1;visibility:visible;transform:none;transition-delay:0s}
/* Hover bridge. The panel hangs off .mainnav__list, so it opens ~8px below the
   trigger it belongs to, and a pointer travelling down from the label crosses
   dead space — .nvg:hover goes false and the menu shuts under the cursor. This
   invisible strip is a child of the panel (so a descendant of .nvg) and keeps
   the chain alive across the gap. It inherits visibility, so a closed panel's
   bridge is inert and cannot swallow clicks on the page underneath. */
.nvg__menu::before{content:"";position:absolute;left:0;right:0;top:-10px;height:10px}
/* mega panel: a grid of cards rather than a list of links. Each card carries the
   category's own ink in its icon tile and the live count of what it returns, so
   the menu is a small directory instead of a set of guesses. */
.nvg__menu--mega{padding:12px}
/* one shelf of cards for every group: uniform column width is what makes the
   panels feel like the same object being refilled rather than five menus */
/* One box, refilled. Every panel is the same height whichever group you hover,
   so the menu stops resizing under the cursor — the discipline Etsy's category
   mega menu uses. The height is the tallest group's natural height, so nothing
   is ever clipped and no panel has to grow. */
/* 221px is the tallest group's natural content height (a full three-item rail),
   so pinning to it makes every panel exactly the same box without ever clipping
   or stretching one. Groups with a shorter rail keep the slack rather than
   letting the menu jump as the cursor crosses the bar. */
.nvm__in{display:flex;align-items:flex-start;gap:14px;min-height:221px}
.nvm__main{flex:1;min-width:0}
/* Two columns, not three: the groups hold 2, 6, 2, 2 and 2 cards, so a 3-column
   grid left a ragged empty cell in four panels out of five. At two columns every
   group fills its rows exactly (2 -> one row, 6 -> three). The cap keeps a card
   near its old 302px instead of stretching it across half the bar. */
.nvc-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;max-width:660px}
/* Panel dzieli sie na pol: lewa polowa to kupno, prawa sprzedaz. Kreska miedzy
   nimi jest granica dwoch pytan, nie ozdoba, wiec biegnie przez cala wysokosc
   panelu (align-items:stretch), a nie tylko obok wyzszej kolumny.
   Siatka kart wewnatrz polowy schodzi do JEDNEJ kolumny: polowa panelu ma okolo
   320px, a karta jest projektowana na ~302px, wiec dwie obok siebie zwezilyby ja
   do polowy i opis pod tytulem zawijalby sie po jednym slowie. */
.nvm__sides{display:grid;grid-template-columns:1fr 1fr;align-items:stretch;min-width:0}
.nvm__side{min-width:0;padding:0 13px}
.nvm__side:first-child{padding-left:0;border-right:1px solid var(--line)}
.nvm__side:last-child{padding-right:0}
.nvm__side .nvc-grid{grid-template-columns:minmax(0,1fr);max-width:none}
/* Polowa bez ogloszen. Kreskowana ramka czytala sie jak pole "upusc tu plik",
   wiec zamiast niej jest wlasna kompozycja: kafel z ikona dzialu w jego kolorze,
   jedno zdanie i akcja. Nie wyszarzamy jej na sile - to nie blad, tylko stan
   przejsciowy, a przygaszona kolumna obok pelnej wyglada jak wylaczona funkcja. */
/* Stan wylaczony. Kafel zachowuje uklad i kolor dzialu, traci zaproszenie: bez
   tla pod kursorem, bez podniesienia, z wyblakla ikona i zerem w miejscu liczby.
   Tlo zostaje biale - szare pole na bialym panelu czytaloby sie jak zaladowanie
   w toku, a to jest wynik koncowy. */
.nvc--zero{cursor:default;background:#fff;box-shadow:inset 0 0 0 1px var(--hair)}
.nvc--zero .nvc__ic{opacity:.38}
.nvc--zero .nvc__tx b{color:var(--muted);font-weight:650}
.nvc--zero .nvc__d{color:#a8b2bd}
.nvc--zero .nvc__n{color:#a8b2bd;background:var(--canvas);box-shadow:none}
.nvc--pusto{background:color-mix(in srgb,var(--ic) 5%,#fff);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ic) 14%,transparent)}
.nvc--pusto:hover{background:color-mix(in srgb,var(--ic) 9%,#fff)}
.nvc--pusto .nvc__tx b{color:var(--muted);font-weight:650}
.nvc--pusto .nvc__ic{opacity:.5}

/* Naglowek polowy. Tytul normalna wielkoscia liter, nie kapitalikami: to nazwa
   sekcji, a nie etykieta systemowa, a przy kapitalikach obie polowy wygladaly
   identycznie. Liczba obok tytulu jest informacja - mowi, ile tam jest, zanim
   ktokolwiek przesunie wzrok na karty. Podpis odjezdza na prawo, zeby tytul i
   liczba stali razem jako jedna calosc. */
.nvm__st{display:flex;align-items:baseline;gap:8px;padding:1px 0 9px;line-height:1.2}
.nvm__st b{font-size:13px;font-weight:750;letter-spacing:-.01em;color:var(--navy)}
.nvm__st i{font-style:normal;font-size:11.5px;font-weight:700;font-variant-numeric:tabular-nums;
  color:var(--side-ink);background:color-mix(in srgb,var(--side-ink) 12%,#fff);
  border-radius:999px;padding:1px 7px}
.nvm__st span{margin-left:auto;font-size:11px;font-weight:500;color:var(--faint);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}

/* Kolor strony jako zmienna, nie jako trzypikselowa kreska. Kupno prowadzi do
   ofert, sprzedaz do ludzi, ktorzy szukaja: ten sam podzial, ktory na karcie
   niesie kolor wstazki. Polowa sprzedazowa dostaje jeszcze wlasne, bardzo lekkie
   tlo - dwie identyczne kolumny obok siebie nie czytaly sie jako dwa rozne
   pytania, a sam znacznik przy naglowku byl na to za slaby. */
.nvm__side--kup{--side-ink:var(--accent)}
.nvm__side--sprz{--side-ink:#6b3fa0;border-radius:var(--r);
  background:linear-gradient(180deg,color-mix(in srgb,#6b3fa0 4%,transparent),transparent 62%)}
.nvm__rail{flex:none;width:284px;border-left:1px solid var(--line);padding-left:14px;align-self:stretch}
/* Ten sam rytm co naglowki polowek: trzy naglowki w jednym panelu musza byc
   jednym systemem, a nie dwoma kapitalikami i jednym tytulem. */
.nvm__rt{font-size:13px;font-weight:750;letter-spacing:-.01em;color:var(--navy);
  padding:1px 0 9px;line-height:1.2}
.nvr{display:flex;align-items:center;gap:10px;padding:6px;border-radius:var(--r);
  text-decoration:none;text-shadow:none;transition:background-color var(--t) var(--ease)}
.nvr:hover{background:var(--canvas)}
.nvr__m{flex:none;width:46px;height:46px;border-radius:var(--r);overflow:hidden}
.nvr__m img{width:100%;height:100%;object-fit:cover;display:block}
.nvr__m .nvr__tx{flex:1;min-width:0}
.nvr__tx b{display:block;font-size:12.5px;font-weight:600;color:var(--navy);line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.nvr__p{display:block;font-size:12px;font-weight:700;color:var(--ink);margin-top:2px;
  font-variant-numeric:tabular-nums}
/* Under ~1140px the 284px rail starves the cards — three of them drop to 180px,
   which is not enough for "Części i pokład" plus its count. The cards are the
   navigation and the rail is garnish, so the rail goes first. */
/* Rail hidden here, so the tallest panel is the six-card grid instead of the
   rail. Re-pin to that height, otherwise every panel carries 100px of slack the
   rail is no longer there to fill. */
@media (max-width:1139px){.nvm__rail{display:none}.nvm__in{min-height:192px}}
.nvc{--ic:var(--faint);display:flex;align-items:center;gap:11px;padding:10px 11px;
  border-radius:var(--r);text-decoration:none;text-shadow:none;
  transition:background-color var(--t) var(--ease)}
/* Pelny cykl stanow, nie sama zmiana tla. Dotad karta reagowala wylacznie
   tlem, a klawiatura nie dostawala NICZEGO - przejscie tabem po panelu bylo
   niewidoczne. Wcisniecie daje mikroprzesuniecie, zeby klikniecie mialo
   fizyczna odpowiedz. */
.nvc{transition:background-color var(--t) var(--ease),box-shadow var(--t) var(--ease),
  transform .09s var(--ease)}
.nvc:hover{background:var(--canvas);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ic) 16%,transparent)}
.nvc:focus-visible{outline:none;background:var(--canvas);
  box-shadow:0 0 0 2px #fff,0 0 0 4px var(--accent)}
.nvc:active{transform:translateY(1px)}
.nvc__ic{transition:background-color var(--t) var(--ease)}
.nvc:hover .nvc__ic{background:color-mix(in srgb,var(--ic) 18%,#fff)}
.nvc__ic{flex:none;width:38px;height:38px;display:grid;place-items:center;border-radius:var(--r);
  color:var(--ic);background:color-mix(in srgb,var(--ic) 11%,#fff)}
.nvc__tx{flex:1;min-width:0}
.nvc__tx b{display:block;font-size:13px;font-weight:700;color:var(--navy);letter-spacing:0;line-height:1.25}
.nvc__d{display:block;font-size:11.5px;font-weight:500;color:var(--faint);margin-top:1px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nvc__n{flex:none;min-width:22px;text-align:center;font-size:11.5px;font-weight:700;
  font-variant-numeric:tabular-nums;color:var(--muted);background:var(--canvas);
  border-radius:999px;padding:3px 8px}
.nvc__n{transition:background-color var(--t) var(--ease),color var(--t) var(--ease)}
.nvc:hover .nvc__n{background:#fff;color:var(--navy)}
/* a post card leads to the form, not a list, so it says so instead of counting */
.nvc--post .nvc__n--post{color:var(--accent-dark);background:var(--blue-soft)}
/* nothing listed yet: still clickable (the results page has a real empty state),
   just not shouting a zero at the reader */
.nvc--empty .nvc__ic{opacity:.45}
.nvc--empty .nvc__tx b{color:var(--muted);font-weight:600}
.nvg__menu .nvg__all{display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-top:7px;padding:10px 11px 4px;border-top:1px solid var(--line);border-radius:0;
  font-size:12.5px;font-weight:700;color:var(--accent-dark);text-decoration:none;text-shadow:none}
.nvg__menu .nvg__all:hover{color:var(--accent)}
.nvg__menu .nvg__all i{font-style:normal;font-weight:600;color:var(--faint);font-variant-numeric:tabular-nums}
/* the last groups would push a left-aligned panel off the right edge */
.nvg__i:focus-visible{outline:2px solid #fff;outline-offset:2px}
.nvg:focus-visible{outline:2px solid #fff;outline-offset:2px;border-radius:var(--r)}
/* below the desktop breakpoint the whole bar becomes a scroll rail and the
   dropdowns open on tap via :focus-within, which touch gives us for free */
/* 24 px, nie 16: ponizej 1080 px tresc strony dalej ma 24 px marginesu, wiec
   16 px w pasku odsuwaloby kategorie od kolumny kart o osiem pikseli - dokladnie
   tyle, zeby bylo widac, i za malo, zeby wygladalo celowo. */
@media(max-width:1080px){
  .mainnav__list{padding:4px 24px}
}
@media(prefers-reduced-motion:reduce){.nvg__menu,.nvg__i{transition:none}}

/* mobile drawer */
.backdrop{position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:60}
.drawer{position:fixed;top:0;right:0;height:100%;width:310px;max-width:86vw;background:#fff;z-index:70;box-shadow:-12px 0 40px -12px rgba(8,28,64,.45);display:flex;flex-direction:column;overflow-y:auto}
/* fixed-height children of the drawer's flex column must never be squashed */
.drawer .btn,.drawer__h{flex:none}
.drawer__h{height:60px;display:flex;align-items:center;justify-content:space-between;padding:0 20px;background:var(--mast)}
.drawer__h img{height:28px}
.drawer__x{width:36px;height:36px;display:grid;place-items:center;border-radius:999px;color:#fff;background:none;border:0}
.drawer__acct{padding:16px 20px;border-bottom:1px solid var(--line)}
.drawer__row{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;font-size:15px;font-weight:600;color:var(--navy)}
.drawer__row:hover{background:var(--canvas)}
.drawer__lbl{padding:10px 20px 4px;font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--faint);font-weight:700}
/* flex, not block: the row carries a count on the right like .drawer__row */
.drawer a.cat{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 20px;font-size:14px;color:var(--ink)}
.drawer a.cat:hover{background:var(--canvas);color:var(--blue)}
.drawer a.cat .cnt{margin-left:0;flex:none}
.cnt--go{color:var(--accent-dark);background:transparent;padding-right:0}
.drawer a.cat--empty{color:var(--faint)}
.drawer a.cat--all{margin-top:6px;border-top:1px solid var(--line);padding-top:14px;font-weight:700;color:var(--navy)}

/* ── Buttons ── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:46px;padding:0 20px;border-radius:var(--r);font-weight:700;font-size:15px;line-height:1;border:0;white-space:nowrap;transition:background-color var(--t) var(--ease),border-color var(--t) var(--ease),color var(--t) var(--ease),transform .09s var(--ease)}
.btn:active{transform:translateY(1px)}
/* in-flight submit: visibly inert so a second tap is obviously a no-op */
.btn:disabled{opacity:.6;cursor:default;pointer-events:none}
.btn .ic{flex:none}
.btn--p{background:var(--bar);color:#fff}.btn--p:hover{background:var(--bar-d)}
.btn--o{background:#fff;color:var(--navy);border:1.5px solid var(--navy)}.btn--o:hover{background:var(--canvas)}
.btn--n{background:var(--navy);color:#fff}.btn--n:hover{background:var(--navy-soft)}
.btn--g{background:var(--green);color:#fff}.btn--g:hover{background:#0b6334}
/* toggled outline button (obserwujesz / w porównaniu): the same object, filled in */
.btn--o.onmark{background:var(--blue-soft);border-color:var(--accent);color:var(--accent-dark)}
.btn--o.onmark:hover{background:#dceaf8}
@media(prefers-reduced-motion:reduce){.btn{transition:background-color var(--t) linear}.btn:active{transform:none}}

/* detail-panel helpers */
.dt-kick{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--faint)}
/* The phone action bar. It had NO rules at all, so it rendered as a plain
   static block on EVERY width: a second, unstyled copy of the price and both
   buttons, sitting a little below the identical pair in the rail. The markup
   comment always claimed it was "pinned" and "hidden above 860" but the CSS to
   do either was never written. It only earns its place where the rail has
   scrolled out of view, so above 860 it is simply not rendered. */
.dtbar{display:none}
@media(max-width:860px){
  /* .ab (dolny pasek skrotow) stoi na 0..62px z z-index 59, a .dtbar mial
     bottom:0 i z-index 20, wiec cena i przycisk "Napisz" byly zakryte w calosci
     na kazdym telefonie: elementFromPoint w srodku CTA zwracal nav#appbar.
     .cmpbar dostal juz taka korekte, .dtbar nie. */
  .dtbar{position:sticky;bottom:calc(62px + env(safe-area-inset-bottom,0px));z-index:20;display:flex;align-items:center;
    justify-content:space-between;gap:12px;margin-top:14px;padding:10px 12px;
    background:#fff;border-radius:var(--r-lg);
    box-shadow:0 -8px 20px -14px rgba(8,28,64,.45),0 0 0 1px var(--line)}
  .dtbar__p{font-family:"Archivo",sans-serif;font-size:17px;font-weight:800;
    color:var(--navy);white-space:nowrap}
  .dtbar__a{display:flex;gap:8px;min-width:0}
  /* .cmpbar is position:fixed bottom:0 z-index:55, so on a phone the two bottom
     bars would stack on top of each other. One bottom bar at a time: comparing
     listings and acting on this one are different jobs. :has is already used
     elsewhere in this file, so this is an existing pattern. */
  body:has(.cmpbar) .dtbar{display:none}
  .dtbar__a .btn{height:42px;padding:0 14px;font-size:13.5px}
}
.dt-acts{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.dt-acts .btn{height:42px;padding:0 8px;font-size:13.5px;min-width:0}
.proact{display:flex;align-items:center;justify-content:center;gap:6px;font-size:13px;font-weight:800;color:var(--amber);background:var(--amber-bg);border:1px solid var(--amber-bd);border-radius:var(--r);padding:10px 12px;margin-bottom:8px}

/* ── Headings — four levels, each identified by the weight of its own rule ──
   .rg__h  display, no rule      (home register only)
   .phead  page title, 2px navy rule
   .sec-h  section, 1px hairline + the 42px accent tab this site already owns
   .box__h inside a box, 1px hairline, no tab
   All sentence case: the register set the voice, the rest follows it. */
.sec{margin-top:40px}

/* ── Allegro benefits strip: five white cards, each a coloured round badge and
   one short promise. It is the first thing under the banner, so it takes the
   tighter 22px the first element gets rather than the 40px section rhythm. ── */
.benes{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-top:22px}
.bene{display:flex;align-items:center;gap:12px;background:#fff;border-radius:12px;padding:14px 16px}
.bene__ic{
  flex:none;width:38px;height:38px;border-radius:50%;display:grid;place-items:center;
  color:var(--bc);background:color-mix(in srgb,var(--bc) 13%,#fff);
}
@supports not (background:color-mix(in srgb,red 10%,#fff)){.bene__ic{background:var(--blue-soft)}}
.bene__tx{min-width:0;display:flex;flex-direction:column}
.bene__tx b{font-size:13px;font-weight:700;color:var(--navy);line-height:1.25}
.bene__tx span{font-size:11.5px;color:var(--faint);line-height:1.3}
@media(max-width:1080px){.benes{grid-template-columns:repeat(3,1fr)}.bene:nth-child(n+4){display:none}}
@media(max-width:760px){.benes{grid-template-columns:repeat(2,1fr);gap:8px}.bene:nth-child(n+3){display:none}}
@media(max-width:480px){.bene{padding:12px}.bene__tx span{display:none}}

/* on a phone the trail would push the real inventory several screens down, so it
   is trimmed to a single row of two. Targets .sec--recent directly now: it used
   to ride on .sec--first, which no longer exists since the benefits strip took
   that slot — and whichever section happened to be first would have inherited a
   trim meant only for the recently-viewed row. */
@media(max-width:560px){.sec--recent .grid .card:nth-child(n+3){display:none}}
.sec-h{position:relative;font-family:"Archivo",sans-serif;color:var(--navy);font-weight:800;font-size:20px;letter-spacing:-.02em;padding-bottom:0;margin-bottom:14px;display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:6px 14px}

.sec-h .more,.phead .more{font-family:"Inter",sans-serif;font-weight:700;font-size:13px;color:var(--accent-dark);letter-spacing:0}
.sec-h .more:hover,.phead .more:hover{text-decoration:underline}
.phead{font-family:"Archivo",sans-serif;font-size:clamp(23px,3vw,31px);font-weight:800;letter-spacing:-.026em;line-height:1.12;color:var(--navy);margin:26px 0 20px;padding-bottom:13px;border-bottom:2px solid var(--navy);display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:6px 16px}
.phead .cnt{align-self:center}
/* ── Category chips (used by the results page filters). A 3px rule in the category's own ink at chip scale; empty ones are
   dashed "open berths" (the .empty border idiom) rather than a wall of zeros. ── */
.rg__arr{transition:transform .16s ease}
.rg__c{--cc:var(--line);display:inline-flex;align-items:center;gap:10px;height:34px;padding:0 12px 0 15px;background:#fff;border:1px solid var(--line);border-radius:var(--r);box-shadow:inset 3px 0 0 var(--cc);transition:background-color .16s ease,border-color .16s ease,box-shadow .16s ease}
.rg__c b{font-size:13.5px;font-weight:600;color:var(--navy)}
.rg__c span{font-size:12.5px;font-weight:700;color:var(--muted)}
.rg__c:hover,.rg__c:focus-visible{background:var(--canvas);border-color:var(--accent);box-shadow:inset 5px 0 0 var(--cc)}
.rg__c:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.rg__c--o{border-style:dashed}
.rg__c--o b{font-weight:500;color:var(--muted)}
.rg__c--o .rg__p{display:grid;place-items:center;color:var(--muted)}
.rg__c--o:hover,.rg__c--o:focus-visible{border-style:solid}
.rg__c--o:hover b,.rg__c--o:focus-visible b{color:var(--navy)}
.rg__c--o:hover .rg__p,.rg__c--o:focus-visible .rg__p{color:var(--accent-dark)}
/* the buyer's target: the .btn--n recipe at chip scale, closing the rail */
.rg__c--all{gap:8px;padding:0 14px;background:var(--navy);border-color:var(--navy);box-shadow:none;color:#fff;font-size:13.5px;font-weight:700}
.rg__c--all:hover,.rg__c--all:focus-visible{background:var(--navy-soft);border-color:var(--navy-soft);box-shadow:none}
.rg__c--all:hover .rg__arr,.rg__c--all:focus-visible .rg__arr{transform:translateX(4px)}
@media(prefers-reduced-motion:reduce){.rg__c,.rg__arr{transition:none}.rg__c--all:hover .rg__arr,.rg__c--all:focus-visible .rg__arr{transform:none}}

/* ── HERO "Żywa woda" (gw-). The WebGL light-on-water surface (engine in app.js)
   with Bricolage Grotesque display type on it, one primary CTA, and the three
   posting intents as a functional bar on the hero's bottom edge. ── */
.gw{
  position:relative;
  isolation:isolate;
  overflow:hidden;
  border-radius:18px;
  margin:10px 0 6px;
  background:var(--blue-soft);            /* holds the color until WebGL is up */
  min-height:clamp(520px,66vh,640px);
  display:flex;flex-direction:column;
  --gw-pad:clamp(22px,4vw,56px);
  --gw-lead-ink:#3f4d5d;                  /* 7.0:1 on the darkest water tile */
  --gw-amber-aa:#8a5a15;                  /* AA-safe amber for text (5.9:1 on white) */
}
.gw__fx{position:absolute;inset:0;z-index:-2;width:100%;height:100%;display:block}

/* No-WebGL fallback (or failed compile): a static but designed surface
   in the same palette. */
.gw--nogl .gw__fx{display:none}
.gw--nogl{
  background:
    radial-gradient(120% 90% at 82% 18%, rgba(242,225,191,.5) 0%, rgba(242,225,191,0) 42%),
    radial-gradient(90% 120% at 70% 80%, rgba(102,153,255,.22) 0%, rgba(102,153,255,0) 55%),
    radial-gradient(140% 100% at 12% 30%, #fdfeff 0%, rgba(253,254,255,0) 60%),
    linear-gradient(160deg,#f7fafd 0%, var(--blue-soft) 55%, #dfeaf7 100%);
}

/* Fade into the page color at the hero's bottom edge: the chip rail below
   "surfaces" out of the same water. Above canvas (-1), below content. */
.gw::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:90px;z-index:-1;
  background:linear-gradient(to bottom, rgba(245,247,250,0), var(--canvas));
  pointer-events:none;
}

.gw__in{
  flex:1;display:flex;flex-direction:column;justify-content:center;
  padding:56px var(--gw-pad) 34px;
}
.gw__kick{
  font-size:12px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:var(--accent-dark);
  margin:0 0 20px;
}
.gw__h{
  font-family:"Bricolage Grotesque","Archivo",sans-serif;
  font-size:clamp(40px,6.4vw,86px);
  font-weight:500;
  letter-spacing:-.033em;
  line-height:1.02;
  color:var(--navy);
  margin:0 0 22px;
}
.gw__lead{
  font-size:clamp(15.5px,1.3vw,18px);
  line-height:1.55;
  color:var(--gw-lead-ink);
  max-width:46ch;
  margin:0 0 30px;
}
.gw__cta{display:flex;align-items:center;gap:26px;flex-wrap:wrap}

/* Primary pill: resting --accent-dark (6.2:1), hover --accent (4.7:1, AA).
   Do not shrink 15.5px/600: that closes the hover state's AA margin. */
.gw__btn{
  display:inline-flex;align-items:center;gap:10px;
  background:var(--accent-dark);color:#fff;
  font-size:15.5px;font-weight:600;letter-spacing:-.01em;
  padding:15px 30px;border-radius:999px;text-decoration:none;
  box-shadow:0 8px 24px rgba(17,96,184,.26);
  transition:background .25s ease, transform .25s ease, box-shadow .25s ease;
}
.gw__btn:hover{background:var(--accent);transform:translateY(-1px);box-shadow:0 12px 28px rgba(23,115,214,.32)}
.gw__btn:active{transform:translateY(0) scale(.98)}
.gw__btn .rg__arr{color:#fff}
.gw__roll{display:block;position:relative;overflow:hidden;height:1.35em}
.gw__roll i{
  display:block;font-style:normal;height:1.35em;line-height:1.35em;
  transition:transform .34s cubic-bezier(.16,1,.3,1);
}
.gw__btn:hover .gw__roll i{transform:translateY(-1.35em)}
.gw__btn svg{flex:none;transition:transform .34s cubic-bezier(.16,1,.3,1)}
.gw__btn:hover svg{transform:translateX(3px)}

.gw__browse{
  display:inline-flex;align-items:center;gap:7px;
  font-size:15px;font-weight:600;color:var(--accent-dark);text-decoration:none;
  border-bottom:1.5px solid rgba(17,96,184,.30);
  padding-bottom:2px;
  transition:border-color .2s ease;
}
.gw__browse:hover{border-color:var(--accent-dark)}
.gw__browse svg{flex:none;transition:transform .25s cubic-bezier(.16,1,.3,1)}
.gw__browse:hover svg{transform:translateX(3px)}

/* Visually-hidden label for screen readers (single CTA name next to the
   aria-hidden roll). */
.gw-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* Focus: outline only, NO border-radius mutation (outline follows the element
   radius; the pill never deforms on keyboard focus). */
.gw a:focus-visible{outline:2px solid var(--accent-dark);outline-offset:2px}

/* Content entrance: once, short, transform/opacity only, and only without a
   reduced-motion preference. */
@media (prefers-reduced-motion: no-preference){
  .gw__kick,.gw__h,.gw__lead,.gw__cta{animation:gw-in .7s cubic-bezier(.16,1,.3,1) both}
  .gw__h{animation-delay:.06s}
  .gw__lead{animation-delay:.12s}
  .gw__cta{animation-delay:.18s}
  @keyframes gw-in{
    from{opacity:0;transform:translateY(14px)}
    to{opacity:1;transform:none}
  }
}
@media (prefers-reduced-motion: reduce){
  .gw__btn,.gw__btn svg,.gw__roll i,.gw__browse,.gw__browse svg{transition:none}
  .gw__btn:hover .gw__roll i{transform:none}
  .gw__btn:hover,.gw__btn:hover svg,.gw__browse:hover svg{transform:none}
  /* The static water frame is drawn by JS (t=14); the loop never starts. */
}

@media (max-width:1080px){
  .gw__h{font-size:clamp(40px,7.2vw,72px)}
}
@media (max-width:860px){
}
@media (max-width:760px){
  .gw{border-radius:14px}
}
@media (max-width:560px){
  /* --gw-navh is set by startHeroFx() from the real navbar height;
     190px is only the fallback. */
  .gw{min-height:min(560px, calc(100svh - var(--gw-navh,190px)))}
  .gw__in{padding-top:40px;padding-bottom:26px}
  .gw__h{font-size:clamp(38px,11vw,46px)}
  .gw__cta{gap:18px}
  .gw__btn{padding:14px 26px;font-size:15px}
}

/* ── Video hero (vhx-). A contained rounded card in the page flow (the site's
   card language), sailing video inside with the proposition on it. The navbar
   stays normal: the hide-and-reveal trick belonged to the full-screen variant. ── */
.vhx{
  position:relative;isolation:isolate;overflow:hidden;
  display:flex;flex-direction:column;
  /* eBay proportions: the banner is a strip, not a stage. Short enough that
     real inventory clears the fold on a laptop. */
  min-height:clamp(300px,38vh,380px);
  margin:28px 0 0;                        /* clear air between the navbar card and the banner */
  border-radius:18px;
  background:var(--navy-deep);
  --gw-pad:clamp(22px,4vw,56px);
}
/* object-position pushes the crop down: the source frame's top third is flat
   horizon haze, the water below it is the part worth showing. The grade lifts
   the Baltic teal that the fog washes out. */
.vhx__vid{
  position:absolute;inset:0;z-index:-2;width:100%;height:100%;
  object-fit:cover;object-position:center 50%;
  filter:saturate(1.14) contrast(1.07);
}
.vhs--novid .vhx__vid{display:none}
/* Plakat jest tlem KAZDEGO slajdu wideo (adres wstawia app.js, bo nosi ?v=).
   Dzieki temu jedno nieudane pobranie gasi jedno ujecie, a nie cala karuzele -
   i nie ma czarnej klatki miedzy pokazaniem slajdu a startem odtwarzania. */
.vhs--vid{background-color:#0a2540;background-position:center;background-size:cover;background-repeat:no-repeat}

/* ── carousel ───────────────────────────────────────────────────────────────
   Slides are stacked, not tracked: a crossfade needs no width arithmetic and
   cannot drift out of alignment when the hero is resized. The container keeps
   its own height because every slide is absolutely positioned except the
   active one, which stays in flow and therefore sets the height. */
/* isolation:isolate is load-bearing, not decoration. .vhx__img sits at
   z-index:-2, so it needs its OWN slide to be a stacking context; otherwise it
   escapes to .vhx (which isolates) and paints beneath every slide background,
   and .vhs--b/--c carry opaque gradients. While a slide fades, opacity is
   between 0 and 1, which creates a stacking context on its own and the photo
   shows. The moment the transition lands on exactly 1 that context disappears,
   the gradient covers the photo, and the picture "loads and then turns back
   into a placeholder". Isolating here makes the slide a stacking context at
   every opacity, so the photo stays put. */
.vhs{position:absolute;inset:0;isolation:isolate;display:flex;flex-direction:column;opacity:0;visibility:hidden;
     transition:opacity .5s var(--ease),visibility 0s linear .5s}
/* flex:1 0 auto, or the banner grows a dark stripe along its bottom edge.
   .vhx carries min-height:clamp(300px,38vh,380px) while a slide's own content is
   shorter (310px against 342px at a 1280px viewport). The inactive slides are
   absolute with inset:0 so they always fill; the ACTIVE one is the only in-flow
   child, and with the default flex:0 1 auto it stopped at its content height and
   left the remainder showing --navy-deep. The dots sit at bottom:16px of the
   banner, so they landed inside that empty strip and it read as a bar under the
   carousel rather than as an overlay on it. */
.vhs.on{position:relative;flex:1 0 auto;opacity:1;visibility:visible;transition:opacity .5s var(--ease)}
/* .vhs--b i .vhs--c odeszly razem ze slajdami zdjeciowymi: karuzela ma teraz piec
   ujec wideo, a tlem kazdego z nich jest wlasny plakat (.vhs--vid). .vhx__img
   zostaje, bo markup nadal umie narysowac slajd ze zdjecia - wystarczy wpisac
   `img` zamiast `vid`. */
.vhx__img{position:absolute;inset:0;z-index:-2;width:100%;height:100%;object-fit:cover;object-position:center 42%}
/* these frames are busier than the open water of the video, so the scrim over
   the copy column is heavier: white 15.5px/600 needs to clear AA against sails
   and hulls, not just sea */
/* .vhs--jasny to ujecie prawie biale (detal olinowania w pelnym sloncu). Bez
   mocniejszej przyslony biala typografia siada na jasnym zaglu i przestaje sie
   odcinac - to ten sam problem co na zdjeciach, wiec i to samo rozwiazanie. */
/* Przyslona mocniejsza nad ujeciem bardzo jasnym (detal olinowania w pelnym
   sloncu): biala typografia siada tam na jasnym zaglu i przestaje sie odcinac. */
.vhs--jasny .vhx__scrim{background:
  linear-gradient(100deg,rgba(4,15,30,.88) 0%,rgba(4,15,30,.66) 44%,rgba(5,20,42,.3) 74%,rgba(5,20,42,.36) 100%),
  linear-gradient(to top,rgba(4,15,30,.5) 0%,rgba(4,15,30,0) 30%)}
/* arrows: only on hover, and never on touch where they would sit over content */
.vhx__nav{position:absolute;top:50%;transform:translateY(-50%);z-index:3;
  width:38px;height:38px;border:0;border-radius:999px;display:grid;place-items:center;
  background:rgba(255,255,255,.9);color:var(--navy);cursor:pointer;
  opacity:0;transition:opacity var(--t) var(--ease),background-color var(--t) var(--ease)}
.vhx__nav--p{left:14px}
.vhx__nav--n{right:14px}
.vhx:hover .vhx__nav,.vhx:focus-within .vhx__nav{opacity:1}
.vhx__nav:hover{background:#fff}
.vhx__nav:focus-visible{opacity:1;outline:2px solid #fff;outline-offset:2px}
@media(hover:none){.vhx__nav{display:none}}
/* dots sit in the corner the copy does not use */
.vhx__dots{position:absolute;z-index:3;right:calc(var(--gw-pad) - 4px);bottom:16px;display:flex;gap:7px}
.vhx__dot{width:9px;height:9px;padding:0;border:0;border-radius:999px;cursor:pointer;
  background:rgba(255,255,255,.42);transition:background-color var(--t) var(--ease),width var(--t) var(--ease)}
.vhx__dot:hover{background:rgba(255,255,255,.72)}
.vhx__dot.on{width:22px;background:#fff}
.vhx__dot:focus-visible{outline:2px solid #fff;outline-offset:3px}
.vhx__live{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
@media(prefers-reduced-motion:reduce){
  .vhs,.vhs.on{transition:none}
  .vhx__dot{transition:none}
}
@media(max-width:560px){
  .vhx__dots{right:auto;left:var(--gw-pad);bottom:12px}
}
/* scrim: strong over the text zone (left), open over the boat (right), plus a
   bottom band under the intent bar. White 15.5px/600 lead over the .85 stop
   computes 5.0:1; the 92px headline is large text at 3:1 with margin to spare. */
.vhx__scrim{
  position:absolute;inset:0;z-index:-1;
  background:
    linear-gradient(100deg, rgba(5,18,36,.85) 0%, rgba(5,18,36,.62) 42%, rgba(6,22,46,.28) 70%, rgba(6,22,46,.34) 100%),
    linear-gradient(to top, rgba(5,18,36,.55) 0%, rgba(5,18,36,0) 32%);
}

.vhx__in{
  flex:1;display:flex;flex-direction:column;justify-content:center;
  width:100%;max-width:1280px;margin:0 auto;
  padding:34px var(--gw-pad);
}
.vhx__kick{
  font-size:12px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:#9cc4ff;margin:0 0 12px;
}
.vhx__h{
  font-family:"Bricolage Grotesque","Archivo",sans-serif;
  font-size:clamp(32px,3.9vw,52px);
  font-weight:500;letter-spacing:-.03em;line-height:1.05;
  color:#fff;margin:0 0 14px;
  text-shadow:0 2px 26px rgba(4,14,30,.45);
}
.vhx__lead{
  font-size:clamp(15px,1.15vw,16.5px);line-height:1.5;font-weight:600;
  color:rgba(255,255,255,.94);max-width:44ch;margin:0 0 20px;
  text-shadow:0 1px 14px rgba(4,14,30,.5);
}
.vhx__browse{
  display:inline-flex;align-items:center;gap:7px;
  font-size:15px;font-weight:600;color:#fff;text-decoration:none;
  border-bottom:1.5px solid rgba(255,255,255,.45);
  padding-bottom:2px;
  text-shadow:0 1px 12px rgba(4,14,30,.5);
  transition:border-color .2s ease;
}
.vhx__browse:hover{border-color:#fff}
.vhx__browse svg{flex:none;transition:transform .25s cubic-bezier(.16,1,.3,1)}
.vhx__browse:hover svg{transform:translateX(3px)}
.vhx a:focus-visible{outline:2px solid #fff;outline-offset:2px}

@media (prefers-reduced-motion: no-preference){
  .vhx__kick,.vhx__h,.vhx__lead,.vhx .gw__cta{animation:gw-in .7s cubic-bezier(.16,1,.3,1) both}
  .vhx__h{animation-delay:.06s}
  .vhx__lead{animation-delay:.12s}
  .vhx .gw__cta{animation-delay:.18s}
}
@media (max-width:760px){
  .vhx{border-radius:14px}
}
@media (max-width:560px){
  .vhx{min-height:min(360px,52svh)}
  .vhx__in{padding:26px var(--gw-pad)}
  .vhx__h{font-size:clamp(28px,7.6vw,36px)}
  .vhx__lead{font-size:14.5px;margin-bottom:16px}
}

/* section-level voids sit under a .sec-h that already carries the rule */
.sec .void{border-top:0;padding-top:4px}

/* carousel + grids */
.row{position:relative}
.row__track{display:flex;gap:14px;overflow-x:auto;scroll-behavior:smooth;padding-bottom:6px;scrollbar-width:none;scroll-snap-type:x proximity}
.row__track::-webkit-scrollbar{display:none}
/* matches the grid exactly. A five-up grid inside the 1232px content column
   computes to 232px per card and cannot reach 246, so the rail comes to the
   grid rather than the other way round: one card size everywhere on the page. */
/* Derived, not hardcoded. 232px happened to match the grid at a 1280px viewport
   and drifted everywhere else (235 vs 232 at 1028px), so the rail's cards sat a
   few pixels off the grid's above them. Same column count, same gap, same width. */
.row__track .card{width:calc((100% - (var(--cards,5) - 1) * 14px) / var(--cards,5));flex:0 0 auto;scroll-snap-align:start}
.row__nav{position:absolute;top:36%;transform:translateY(-50%);width:40px;height:40px;display:grid;place-items:center;border-radius:999px;background:#fff;border:1px solid var(--line);box-shadow:0 4px 14px -4px rgba(10,37,64,.4);color:var(--navy);z-index:2;transition:opacity var(--t) var(--ease),background-color var(--t) var(--ease)}
.row__nav:hover:not(:disabled){background:var(--canvas)}
.row__nav:disabled{opacity:.3;cursor:default}
.row--static .row__nav{display:none}
.row__nav--l{left:-12px}.row__nav--r{right:-12px}
@media(max-width:860px){.row__nav{display:none}.row__track{scroll-snap-type:none}}
@media(prefers-reduced-motion:reduce){.row__track{scroll-behavior:auto}}
/* Retail density. One card size serves both layouts: the full-width home grid is
   1232px (8 × 145px) and the results column beside the 248px sidebar is 952px
   (6 × 150px). The column count is a variable so the ladder below only has to
   restate a number, never the whole template. */
/* 5 across, not 6. The Okazje rail sets the house card size at 246px
   (.row__track .card), and at six columns every other homepage section drew
   the same card ~50px narrower, so one shelf looked like a different product
   from the one above it. Five columns lands at ~235px in a 1280 viewport,
   which reads as the same card. The ladder below shifts down to match. */
.grid{display:grid;grid-template-columns:repeat(var(--cards,5),minmax(0,1fr));gap:14px}
/* .grid.grid--3, not .grid--3: the narrow variant must outrank every plain .grid
   rule in the ladder below, otherwise a later equal-specificity breakpoint wins and
   the sidebar column silently inherits the full-width column count. */
.grid.grid--3{--cards:4}
/* The ladder holds the card near 195-230px the whole way down rather than letting
   it inflate: below 860px the sidebar is gone, so .grid--3 gets the full width and
   the two grids converge. Phones keep two columns; one column at this card size
   would waste half the screen. */
/* Breakpoints derived from the 232px card, not guessed: a column count is kept
   until its card would fall under ~200px, NOT until it stops being exactly
   232px. Switching at the equality point dropped the grid to 3 columns at
   1000px and drew a 303px card beside the rail's 232px; four columns there is
   227px, which reads the same. 5 cols to 1104px, 4 to 890px, 3 to 676px. */
/* ── Polka strony glownej ────────────────────────────────────────────────────
   Polka dostaje z JS zawsze dziesiec kart, a ile z nich widac, decyduje arkusz -
   bo tylko arkusz wie, ile jest akurat kolumn. Zasada jest jedna: rzad ma byc
   PELNY. Dziesiec kart w czterech kolumnach to dwa rzedy i dwie sieroty, wiec
   przy czterech kolumnach polka konczy sie na osmiu.
   Progi nie zachodza na siebie (min-width + max-width), bo nakladajace sie
   zakresy wymagaja potem odkrecania display:none regula wyzej w kaskadzie. */
@media(min-width:890px) and (max-width:1103px){.grid--home>.card:nth-child(n+9){display:none}}
@media(min-width:676px) and (max-width:889px){.grid--home>.card:nth-child(n+10){display:none}}
/* Telefon: cztery ogloszenia i guzik. Dwie kolumny po dwa rzedy - tyle, ile
   miesci sie na ekranie bez przewijania przez cala kategorie w drodze do
   nastepnej. */
@media(max-width:675px){.grid--home>.card:nth-child(n+5){display:none}}
.secmore{display:none}
@media(max-width:675px){
  .secmore{display:flex;align-items:center;justify-content:center;gap:7px;
    margin-top:12px;padding:11px 14px;border-radius:var(--r);
    border:1.5px solid var(--line);background:#fff;
    font-size:13.5px;font-weight:700;color:var(--navy);text-decoration:none}
  .secmore:active{background:var(--canvas)}
  /* Adres w naglowku i guzik pod siatka to ten sam link. Na telefonie zostaje
     guzik, bo jest wiekszy i stoi tam, gdzie konczy sie czytanie polki. */
  .sec-h .more{display:none}
}

/* ── Baner przebijajacy polki ────────────────────────────────────────────────
   Na cala szerokosc kolumny tresci, ale niski: ma przerwac rytm polek, a nie
   zajac ekran. Kolor akcentu wchodzi zmienna, wiec kolejny baner to jeden wpis
   w HOME_PROMO, a nie nowa regula. */
.bnr{--bi:var(--accent);display:flex;align-items:center;gap:18px;flex-wrap:wrap;
  margin-top:40px;padding:18px 22px;border-radius:var(--r-lg);
  background:linear-gradient(100deg,color-mix(in srgb,var(--bi) 12%,#fff),#fff 68%);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--bi) 22%,transparent)}
@supports not (background:color-mix(in srgb,red 10%,#fff)){
  .bnr{background:var(--blue-soft);box-shadow:inset 0 0 0 1px var(--line)}
}
.bnr__tx{flex:1;min-width:210px;display:flex;flex-direction:column;gap:3px}
.bnr__tx b{font-family:"Archivo",sans-serif;font-size:17px;font-weight:800;
  letter-spacing:-.02em;color:var(--navy);line-height:1.25}
.bnr__tx span{font-size:13px;line-height:1.5;color:var(--muted)}
.bnr__a{flex:none;display:inline-flex;align-items:center;gap:7px;
  padding:10px 16px;border-radius:var(--r);background:var(--bi);color:#fff;
  font-size:13.5px;font-weight:700;text-decoration:none;
  transition:filter var(--t) var(--ease)}
.bnr__a:hover{filter:brightness(1.08)}
.bnr__a:focus-visible{outline:2px solid var(--navy);outline-offset:2px}
/* Zapowiedz nie ma przycisku, bo nie ma dokad prowadzic. Zamiast niego stoi
   etykieta stanu - wyglada inaczej niz przycisk, wiec nikt jej nie klika.
   Kolor akcentu marki, nie fiolet: fiolet byl jedynym miejscem w calym serwisie,
   gdzie ta barwa sie pojawiala, wiec czytal sie jak wstawka z innego produktu. */
.bnr--soon{--bi:var(--accent)}
.bnr__soon{flex:none;padding:9px 14px;border-radius:var(--r);
  background:color-mix(in srgb,var(--bi) 10%,#fff);color:var(--bi);
  font-size:12.5px;font-weight:700;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--bi) 26%,transparent)}
@media(max-width:600px){
  .bnr{gap:12px;padding:16px}
  .bnr__tx b{font-size:15.5px}
  .bnr__a,.bnr__soon{width:100%;justify-content:center;text-align:center}
}

@media(max-width:1103px){:root{--cards:4}}
@media(max-width:889px){:root{--cards:3}.grid.grid--3{--cards:3}}
@media(max-width:860px){.grid.grid--3{--cards:3}}
/* .grid--3 ustawia --cards na SAMYM elemencie, wiec wygrywa z wartoscia z :root
   niezaleznie od kolejnosci regul. Bez tej linii siatka wynikow zostawala przy
   trzech kolumnach az do 375px, gdzie kafel ma niecale 110px i tytul lamie sie
   po dwoch slowach. */
@media(max-width:675px){:root{--cards:2}.grid.grid--3{--cards:2}}
@media(max-width:600px){:root{--cards:2}.grid,.grid.grid--3{gap:10px}}

/* ── card — Allegro's dense retail card ─────────────────────────────────────
   Row order is theirs: badge strip → PRICE → accent line → title → small print
   → green delivery line. The price leads because on a grid of eight columns the
   number is what the eye hunts for, and the title is deliberately quiet.
   No border and no resting shadow: the white card is the figure, the grey page
   is the ground, and the shadow appears only on hover.
   Structure: a <div> holding a stretched <a>, so the ♥ and ⇄ controls are real
   siblings of the link rather than <button>s nested inside an <a> (invalid HTML,
   and it put two unrelated controls inside one tab stop). */
.card{--ic:var(--faint);position:relative;display:flex;flex-direction:column;border:0;border-radius:var(--r-lg);background:#fff;transition:box-shadow var(--t) var(--ease)}
.card__link::after{content:"";position:absolute;inset:0;z-index:1;border-radius:inherit}
.card:hover,.card:focus-within{box-shadow:0 4px 16px -4px rgba(10,37,64,.2)}
/* the link IS the card, so its focus ring outlines the card. :focus-within is
   only the fallback for browsers without :has(); where :has() exists the ring
   fires on :focus-visible alone, so a mouse click never paints a keyboard ring. */
.card:focus-within{outline:2px solid var(--accent);outline-offset:-1px}
@supports selector(:has(*)){
  .card:focus-within{outline:none}
  .card:has(.card__link:focus-visible){outline:2px solid var(--accent);outline-offset:-1px}
  .cact:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
}
.card__link:focus-visible{outline:none}
.card__t{transition:color var(--t) var(--ease)}
.card:hover .card__t,.card:focus-within .card__t{color:var(--navy)}

/* media — square, contained, on white: retail product framing, so a mast and a
   winch handle sit at the same optical size instead of one being cropped away.
   The plate underneath is the real fallback: broken or missing art degrades to a
   designed field in the category ink instead of a torn-image glyph. */
.card__media{position:relative;aspect-ratio:1/1;overflow:hidden;border-radius:var(--r-lg) var(--r-lg) 0 0;background:#fff}
/* cover, edge to edge, no padding and no radius: these are photographs, not
   studio cut-outs, so filling the square beats letterboxing it. Costs about a
   quarter of a 4:3 frame to the crop, which is the OLX/Vinted/eBay trade. */
.card__media img{position:relative;z-index:1;width:100%;height:100%;object-fit:cover}
.card__media.noimg img{display:none}
/* The plate is the MISSING-image state, not a backdrop. Seed photos are 4:3 in a
   square tile, so contain leaves a quarter of every card empty — and painting
   that quarter in category ink, with a 1px frame drawn around the whole box,
   read as a coloured panel isolating the picture. It now shows only when there
   is genuinely nothing to display, which is what it was always for. */
/* the plate is absolutely positioned against its host, so the host must BE a
   containing block. plated() emits a bare <span class="… plated">, and only
   .card__media, .gal__main and .thead__m happened to declare position:relative;
   .lr-m, .cmpc__m, .cmpbar__m and .gal__th did not, so a failed image resolved
   inset:0 against the page and painted a category plate across the whole view. */
.plated{position:relative;display:block}
/* Zastepcze zdjecie, JEDNO dla calego serwisu (patrz plate() w app.js).
   Tlo w kolorze dzialu zostaje POD obrazkiem z dwoch powodow: przy najmniejszych
   kafelkach obrazek jest przyciety tak mocno, ze widac z niego sam granat, a
   gdyby sie nie wczytal, kafel nadal ma swoj kolor zamiast bialej dziury. */
.plate{position:absolute;inset:0;display:none;align-items:center;justify-content:center;
  background:color-mix(in srgb,var(--ic) 9%,#fff);color:var(--ic);overflow:hidden}
.plate>img{width:100%;height:100%;object-fit:cover;display:block}
.plated.noimg .plate{display:flex}
/* only .card__media, .gal__main and .thead__m had a rule hiding the broken img;
   the compare cells, compare bar and promo row showed a torn-image glyph on top
   of their own fallback. One selector covers every .plated surface. */
.plated.noimg img{display:none}
.plate::after{content:"";position:absolute;inset:0;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ic) 18%,transparent)}
/* the ink is mixed toward --navy before it is set as text: several category
   inks (the slate #3f5168, the teal #0f7c8c) do not clear AA against their own
   9% tint, and the plate label has to be readable, not just decorative */
/* sold — the one state allowed to cover the art, because it invalidates the card */
/* the scrim is opaque enough that the white label clears AA over any photo:
   at .62 the darkest the backdrop can be is rgb(97,105,116) → 4.6:1 on white */
/* pointer-events:none or the veil eats the click: it spans the whole photo at
   z-index:2, directly over the stretched .card__link::after at z-index:1, so a
   sold card's entire image was dead to clicks while its text stayed live. */
.card__sold{position:absolute;inset:0;z-index:2;pointer-events:none;display:grid;place-items:center;background:rgba(12,28,48,.62)}
.card__sold b{font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:#fff;border:1.5px solid rgba(255,255,255,.9);border-radius:var(--r);padding:5px 12px}

/* card actions — Allegro floats one white disc over the photo. The heart is
   always present; compare only materialises on hover, because two discs on a
   145px card is clutter. Touch devices have no hover, so there both stay put —
   and an active comparison stays visible either way. */
/* Offsety liczone sa od .card, a nie od zdjecia, wiec po dodaniu 5px paddingu
   serduszko zostalo tylko 3px od krawedzi fotografii. 8+5 utrzymuje ten sam
   wizualny odstep od zdjecia, co przed ramka. */
.cacts{position:absolute;z-index:2;top:14px;right:14px;display:flex;gap:5px}
/* the disc is fully opaque now: it sits on a cropped photograph rather than on
   white padding, so a translucent white would tint whatever is behind it */
.cact{width:30px;height:30px;border:0;border-radius:999px;display:grid;place-items:center;color:var(--muted);background:#fff;box-shadow:0 1px 5px rgba(10,37,64,.22);transition:color var(--t) var(--ease),background-color var(--t) var(--ease),opacity var(--t) var(--ease),transform var(--t) var(--ease)}
.cact:hover{color:var(--navy);background:#fff;transform:translateY(-1px)}
.cact:active{transform:translateY(0)}
.cact.on{background:var(--accent);color:#fff}
.cact.on:hover{background:var(--accent-dark)}
@media(hover:hover){
  .cact--cmp{opacity:0;transform:scale(.86)}
  .card:hover .cact--cmp,.card:focus-within .cact--cmp,.cact--cmp.on{opacity:1;transform:none}
}

/* body — Amazon's order: NAME, category, price, date. Five things counting the
   photo and the heart, and nothing else on the card. */
.card__b{display:flex;flex-direction:column;flex:1;padding:11px 12px 13px}
.card__link{display:block;color:inherit}
/* the name leads, the way it does on Amazon: regular weight, near-black, two
   lines and then an ellipsis. min-height reserves both lines so the price below
   sits on one baseline across the row even when a title only runs to one line.
   overflow-wrap breaks a long unbroken word instead of letting it widen the box. */
.card__t{font-size:14.5px;font-weight:400;color:var(--ink);line-height:1.35;margin:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere;min-height:40px}
/* category sits where Amazon puts the star rating: quiet, one line, never wraps */
.card__cat{margin-top:5px;font-size:12px;font-weight:500;color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* price — the loudest thing on the card. tabular-nums so a column of prices down
   the grid reads as a column; nowrap+ellipsis so "1 250 000 zł" can never wrap to
   a second line and shove the date out of alignment. */
.card__p{margin-top:6px;font-family:"Archivo",sans-serif;font-size:21px;font-weight:800;letter-spacing:-.02em;color:var(--ink);line-height:1.15;min-height:25px;font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* min-height above, not on the variant: "Do ustalenia" sets 13px and would
   otherwise sit 6px higher than the numeric prices either side of it, breaking
   the one horizontal line the eye follows across a row of eight. */
.card__p--txt{font-family:"Inter",sans-serif;font-size:15px;font-weight:700;color:var(--muted);letter-spacing:0;display:flex;align-items:center}
/* the unit reads as a unit, not as de-emphasis: same ink, just smaller */
.card__p small{font-family:"Inter",sans-serif;font-size:14px;font-weight:700;letter-spacing:0;color:inherit}
/* date of posting — Amazon's delivery-line slot. margin-top:auto pins it to the
   bottom so every card in a row shares one closing baseline. */
.card__when{margin-top:auto;padding-top:6px;font-size:12px;font-weight:500;color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.deliv{display:inline-block;font-size:9.5px;font-weight:800;color:var(--green);background:var(--green-bg);border:1px solid var(--green-bd);border-radius:999px;padding:1px 6px;margin-left:6px;vertical-align:1px}
@media(prefers-reduced-motion:reduce){.card,.cact,.card__t{transition:none}.cact:hover{transform:none}}

/* results layout. Breadcrumbs are gone; .wrap--top carries the top space they
   used to contribute, so the first block does not butt against the masthead. */
.wrap--top{padding-top:22px}
/* 228, nie 248. Kolumna filtrow byla najgrubszym elementem strony przy
   najmniejszej tresci: same selecty i checkboxy, ktore i tak nie potrzebuja
   szerokosci. Dwadziescia pikseli wraca do listy wynikow, gdzie tytul
   ogloszenia zawija sie o jedno slowo pozniej. */
.layout{display:grid;grid-template-columns:228px minmax(0,1fr);gap:28px;align-items:start;padding-bottom:32px}
/* Kolejnosc nalezy do UKLADU WYNIKOW, nie do klasy .side. Bez tego zawezenia
   regula lapala takze panel uzytkownika, ktory uzywa tej samej klasy na swojej
   szufladzie (<aside class="side pside">) i nie ma zadnego .res: aside dostawal
   order:1, sekcja zostawala na 0, wiec szuflada renderowala sie DRUGA - czyli
   ladowala w kolumnie 1fr, a tresc panelu w kolumnie 232 px. Panel wygladal jak
   odwrocony i zgnieciony, i tak wygladal do dzis. */
.layout>.side{order:1}
.layout>.res{order:2;min-width:0}
/* Allegro's filter rail: not one ruled index but a stack of white cards on the
   grey page. Each group owns its own panel, so the boundary between "type" and
   "price" is a gap rather than a hairline, and the rail reads as separate
   decisions instead of one long list. */
.side{background:none;border:0;padding:0;display:grid;gap:10px;align-content:start}
.fpanel{background:#fff;border-radius:10px;padding:13px 14px 11px}
.fpanel--end{display:grid;gap:9px;padding-top:14px}
/* the rail follows you down a long results page instead of scrolling away.
   Desktop only: below 860px .side becomes the mobile filter sheet, where sticky
   and a max-height would fight the sheet's own positioning. */
@media(min-width:861px){
  /* 118px, measured: the sticky masthead's bottom edge sits at 110px, so a
     smaller offset slides the rail underneath it */
  /* Szyna ma 874px tresci, a przy oknie 800px do dyspozycji bylo 647px, wiec
     przyklejona szyna musiala miec wlasny pasek przewijania — inaczej przycisk
     "Pokaz wyniki" i polowa parametrow bylyby nieosiagalne. Skoro wewnetrzne
     przewijanie odpada, odpada tez przyklejanie: szyna jedzie razem ze strona,
     tak jak w panelach filtrow OLX i Amazona. Nic sie nie tnie i nic nie drga,
     bo nie ma juz progu, na ktorym cos mialoby sie zatrzymac. */
  .side{align-self:start}
}
.side h3,.fset__h{font-size:11.5px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--navy);margin:0 0 8px;padding:0;border:0}
.side a.cl{display:flex;justify-content:space-between;align-items:baseline;gap:10px;padding:6px 8px 6px 0;font-size:13.5px;color:var(--ink);border-radius:var(--r);transition:color var(--t) var(--ease),background-color var(--t) var(--ease)}
.side a.cl:hover{background:var(--canvas);color:var(--navy);padding-left:8px}
/* active: a filled tint across the whole row rather than a 2px bar on its edge.
   On a white panel the bar was easy to miss; the fill reads as "this one is on"
   from across the rail and matches the pill the price bands use. */
.side a.cl.on{background:var(--blue-soft);color:var(--accent-dark);font-weight:700;box-shadow:none;padding-left:8px}
.side a.cl.on:hover{background:#dceafa}
.side a.cl .c{flex:none;font-size:11.5px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--faint)}
.side a.cl.on .c{color:var(--accent-dark)}
.side a.cl--0{color:var(--faint)}
.side a.cl--0:hover{color:var(--muted)}
.fset{margin-top:0;padding-top:0;border-top:0;display:grid;gap:8px}
.fset label{display:block;font-size:11.5px;font-weight:700;letter-spacing:.02em;color:var(--navy);margin-bottom:6px}
.fset input,.fset select{width:100%;height:35px;border:1.5px solid var(--line);border-radius:var(--r);padding:0 10px;font-size:13px;outline:none;font-family:inherit;background:#fff;color:var(--ink);transition:border-color var(--t) var(--ease),box-shadow var(--t) var(--ease)}
.fset input::placeholder{color:var(--faint)}
.fset input:hover,.fset select:hover{border-color:#ccd5e0}
.fset input:focus,.fset select:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(23,115,214,.14);outline:none}
.fset label.chk{display:flex;align-items:center;gap:9px;text-transform:none;font-size:13.5px;font-weight:600;color:var(--ink);margin-bottom:0;padding:3px 0;cursor:pointer}
.fset label.chk:hover{color:var(--navy)}

/* ── filter groups ──────────────────────────────────────────────────────────
   Collapsible sections so a rail carrying type, price, condition, location and
   per-category parameters stays scannable. <details> does the state, so there is
   no JS and the open/closed choice survives a re-render for free. */
.fgrp{background:#fff;border:0;border-radius:10px;padding:13px 14px 10px}
.fgrp>summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:11.5px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--navy);padding:0 0 8px}
.fgrp>summary::-webkit-details-marker{display:none}
.fgrp>summary::after{content:"";flex:none;width:7px;height:7px;border-right:2px solid var(--faint);border-bottom:2px solid var(--faint);transform:rotate(45deg) translateY(-2px);transition:transform var(--t) var(--ease)}
.fgrp[open]>summary::after{transform:rotate(-135deg) translateY(0)}
.fgrp>summary:hover{color:var(--accent-dark)}
.fgrp>summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r)}
/* facet rows — same ruled-index grammar as the category list above, so the two
   halves of the rail read as one thing. The count is the whole point: no option
   is a blind click, and a zero is information, not a dead end. */
.frows{display:grid;gap:1px;padding-bottom:5px}
.fset .frow{display:flex;align-items:baseline;gap:8px;margin:0;padding:4px 8px 4px 0;font-size:13.5px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--ink);border-radius:var(--r);cursor:pointer;transition:color var(--t) var(--ease),background-color var(--t) var(--ease),padding-left var(--t) var(--ease)}
.fset .frow:hover{background:var(--canvas);color:var(--navy);padding-left:8px}
.fset .frow.on{background:var(--blue-soft);color:var(--accent-dark);font-weight:700;box-shadow:none;padding-left:8px}
.fset .frow.on:hover{background:#dceafa}
/* Wyposazenie uzywa tych samych wierszy co pozostale fasety, tylko z checkboxem:
   to nadal jest lista opcji z licznikiem, wiec nie ma powodu, zeby wygladala jak
   inny komponent. Rozni sie jedna rzecza: wyborow moze byc kilka naraz. */
.fset .frow input[type=radio],.fset .frow input[type=checkbox]{width:auto;height:auto;flex:none;margin:0;accent-color:var(--accent)}
.frow__l{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fset .frow .c{flex:none;font-size:11.5px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--faint)}
.fset .frow.on .c{color:var(--accent-dark)}
.fset .frow--0{color:var(--faint)}
.fset .frow--0:hover{color:var(--muted)}
/* Reszta dlugiej listy wyposazenia. Zwiniecie jest tu po to, zeby czternascie
   pozycji nie spychalo lokalizacji i ceny pod krawedz ekranu; podsumowanie mowi,
   ile jeszcze zostalo, wiec nikt nie musi zgadywac, czy warto klikac. */
.eqmore{margin:-2px 0 6px}
.eqmore>summary{cursor:pointer;list-style:none;font-size:12.5px;font-weight:700;color:var(--muted);padding:4px 0}
.eqmore>summary::-webkit-details-marker{display:none}
.eqmore>summary::after{content:"";display:inline-block;width:6px;height:6px;margin-left:7px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:translateY(-2px) rotate(45deg);transition:transform var(--t) var(--ease)}
.eqmore[open]>summary::after{transform:translateY(1px) rotate(-135deg)}
.eqmore>summary:hover{color:var(--accent-dark)}
.eqmore>summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r)}
/* price: two fields and the unit, nothing else */
.prange{display:flex;align-items:center;gap:8px;padding-bottom:3px}
.prange input{flex:1;min-width:0;text-align:center}
.prange small{flex:none;color:var(--faint);font-size:12.5px;font-weight:600}
.fclear--blk{display:block;text-align:center;font-size:13px;font-weight:700;color:var(--muted);text-decoration:none;padding:6px;border-radius:var(--r)}
.fclear--blk:hover{color:var(--red);background:var(--red-bg)}
/* active-filter chips: each one is a thing you can take off again, so the ✕ is
   the affordance and the whole chip is the hit area */
.fchips{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:10px}
.fchip{display:inline-flex;align-items:center;gap:7px;background:var(--blue-soft);color:var(--accent-dark);border:1px solid #cfe0f3;border-radius:999px;padding:4px 6px 4px 12px;font-size:12.5px;font-weight:600;text-decoration:none;transition:background-color var(--t) var(--ease),border-color var(--t) var(--ease)}
/* .16 dropped the ✕ to 4.45:1 against --accent-dark; .12 puts it at 4.69:1 */
.fchip span{display:grid;place-items:center;width:17px;height:17px;border-radius:999px;background:rgba(23,115,214,.12);font-size:13px;line-height:1;transition:background-color var(--t) var(--ease),color var(--t) var(--ease)}
.fchip:hover{background:#dceaf8;border-color:#b9d4ef}.fchip:hover span{background:var(--red);color:#fff}
.fclear{font-size:12.5px;font-weight:700;color:var(--muted);text-decoration:none;margin-left:2px}
.fclear:hover{color:var(--red);text-decoration:underline}
/* custom dropdown (enhances native <select> for a nicer open state) */
.nsel{position:relative}
.nsel select{position:absolute;inset:0;width:100%;height:100%;opacity:0;pointer-events:none;margin:0}
.nsel__btn{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;height:46px;padding:0 12px;border:1.5px solid var(--line);border-radius:var(--r);background:#fff;font-family:inherit;font-size:14px;color:var(--ink);text-align:left;cursor:pointer;transition:border-color .15s,box-shadow .15s}
.nsel__btn:hover{border-color:#c3ccd8}
.nsel.open .nsel__btn{border-color:var(--accent);box-shadow:0 0 0 3px rgba(23,115,214,.15)}
.nsel__lbl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nsel__chev{flex:none;color:var(--faint);transition:transform .18s,color .18s}
.nsel.open .nsel__chev{transform:rotate(180deg);color:var(--accent)}
/* Zamkniete menu mialo tylko opacity:0, wiec jego przyciski zostawaly w kolejnosci
   tabulacji: formularz mial 110 przystankow Tab przy 14 widocznych kontrolkach,
   z czego 73 chowaly sie pod jednym polem Lokalizacja. visibility wyjmuje je z
   drzewa dostepnosci, a przejscie na visibility pozwala zachowac animacje. */
.nsel__menu{visibility:hidden;position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:60;background:#fff;border:1px solid #dbe2ea;border-radius:var(--r);box-shadow:0 14px 34px -10px rgba(8,28,64,.34);padding:6px;max-height:300px;overflow:auto;opacity:0;transform:translateY(-6px) scale(.99);transform-origin:top;pointer-events:none;transition:opacity .15s ease,transform .15s ease}
.nsel.open .nsel__menu{visibility:visible;opacity:1;transform:translateY(0) scale(1);pointer-events:auto}
.nsel__opt{display:flex;align-items:center;width:100%;text-align:left;padding:9px 12px;border:0;border-radius:var(--r);background:transparent;font-family:inherit;font-size:14px;color:var(--ink);cursor:pointer;transition:background .12s}
.nsel__opt:hover{background:var(--blue-soft)}
.nsel__opt.on{background:var(--blue-soft);color:var(--accent-dark);font-weight:700}
.nsel__opt.on::after{content:"✓";margin-left:auto;padding-left:12px;color:var(--accent)}
/* ── Wybor wielokrotny ──────────────────────────────────────────────────
   Kupujacy rzadko ma jeden port: pyta o Trojmiasto ALBO Mazury. Pozycja
   zaznaczona dostaje kwadrat z ptaszkiem zamiast haczyka na koncu wiersza,
   bo ptaszek po prawej czyta sie jak "wybrane teraz", a kwadrat po lewej jak
   "mozesz zaznaczyc kilka" - i to jest cala roznica, ktora trzeba pokazac
   ZANIM ktos kliknie. */
.nsel--multi .nsel__opt.on::after{content:none}
.nsel__box{flex:none;width:16px;height:16px;margin-right:10px;border-radius:4px;border:1.5px solid #c3ccd8;background:#fff;position:relative;transition:background .12s,border-color .12s}
.nsel--multi .nsel__opt.on .nsel__box{background:var(--accent);border-color:var(--accent)}
.nsel--multi .nsel__opt.on .nsel__box::after{content:"";position:absolute;left:4.5px;top:1px;width:4px;height:8px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(42deg)}
/* Pole z wyborem daje sygnal takze wtedy, gdy menu jest zamkniete. */
.nsel--multi.has .nsel__btn{border-color:var(--accent);color:var(--accent-dark);font-weight:600}
/* Szukajka przykleja sie do gory listy: przy 73 lokalizacjach zjezdza razem z
   trescia i po dwoch obrotach kolka nie ma juz czym filtrowac. */
.nsel__q{position:sticky;top:0;z-index:1;width:100%;margin-bottom:4px;padding:8px 10px;border:1.5px solid var(--line);border-radius:var(--r);background:#fff;font-family:inherit;font-size:13.5px;color:var(--ink)}
.nsel__q:focus{outline:0;border-color:var(--accent);box-shadow:0 0 0 3px rgba(23,115,214,.15)}
.nsel__none{padding:10px 12px;font-size:13px;color:var(--faint)}
.fset .nsel__btn{height:38px;font-size:13px;padding:0 10px;border-radius:var(--r);border-width:1.5px}
.fset .nsel__menu{font-size:13px}
.fset .nsel__opt{font-size:13px;padding:8px 11px}
/* results head — title + tally on the left, instruments on the right, closed by
   the same 2px navy rule that opens the filter rail */
/* the heading and its controls sit in their own white card, the same object the
   filter rail is made of: on a grey page a bare row under a hairline read as a
   loose caption, not as the header of the results beneath it. 10px gap matches
   the gap between panels in the rail, so the two columns share one rhythm. */
.res-h{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px 20px;background:#fff;border:0;border-radius:10px;padding:12px 16px;margin-bottom:10px}
.res-h h1{font-size:clamp(19px,2vw,23px);font-weight:800;letter-spacing:-.02em;line-height:1.2;color:var(--navy)}
.res-h__tools{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.cnt{display:inline-block;margin-left:10px;font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--accent-dark);background:var(--blue-soft);border-radius:999px;padding:1px 10px;vertical-align:2px}
.sort{display:flex;gap:8px;align-items:center;font-size:12.5px;color:var(--faint)}
/* separate pills rather than one welded segment: --r is 3px, so the old control
   read as a hard-edged bar next to the pill-shaped Filtry button */
/* Sortowanie jest kontrolka paska narzedzi, nie polem formularza: domyslne
   46px z .nsel__btn rozpychaloby rzad z przyciskiem "Filtry". */
.sort .nsel{min-width:168px}
.sort .nsel__btn{height:34px;padding:0 11px;border-width:1px;font-size:12.5px;font-weight:600;color:var(--navy)}
.sort .nsel__chev{width:14px;height:14px}

/* ── empty states — one object, used everywhere ─────────────────────────────
   A new marketplace lives here. Left-ruled like every other entry in the
   register, never a centred dashed box apologising for itself. */
.void{border-top:2px solid var(--navy);padding:30px 0 34px;max-width:640px}
.void__k{font-size:11px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--faint);margin-bottom:10px}
.void__h{font-family:"Archivo",sans-serif;font-size:clamp(20px,2.4vw,26px);font-weight:800;letter-spacing:-.022em;line-height:1.15;color:var(--navy);margin-bottom:9px}
.void p{font-size:14.5px;line-height:1.6;color:var(--muted);max-width:56ch}
.void p+p{margin-top:8px}
.void__cta{display:flex;flex-wrap:wrap;gap:10px;margin-top:18px}
/* the recovery rail: each row drops exactly one constraint and says what that
   is worth, so a dead end always has a measured way out */
.void__fix{margin-top:22px;border-top:1px solid var(--line)}
.void__fix b{display:block;padding:14px 0 2px;font-family:"Inter",sans-serif;font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--faint)}
.vfix{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:11px 10px 11px 13px;border-top:1px solid var(--hair);box-shadow:inset 3px 0 0 var(--accent);transition:background-color var(--t) var(--ease),box-shadow var(--t) var(--ease)}
.vfix:first-of-type{border-top:0}
.vfix:hover,.vfix:focus-visible{background:var(--canvas);box-shadow:inset 5px 0 0 var(--accent)}
.vfix span{font-size:14px;font-weight:600;color:var(--navy)}
.vfix em{flex:none;font-style:normal;font-size:12.5px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--accent-dark)}
.vfix:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
/* legacy .empty kept as an alias so no surface loses its state while migrating */
.empty{border-top:2px solid var(--navy);padding:30px 0 34px;max-width:640px;color:var(--muted);font-size:14.5px;line-height:1.6}
.empty h2{font-family:"Archivo",sans-serif;font-size:clamp(20px,2.4vw,26px);font-weight:800;letter-spacing:-.022em;color:var(--navy);margin-bottom:9px}
.empty p+p{margin-top:8px}

/* ── skeletons — the shape of what is coming, not a spinner ── */
.sk{display:grid;gap:16px}
.sk__card{border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.sk__b{padding:12px}
.skl{background:var(--hair);border-radius:var(--r);height:11px}
.sk__card .skl--m{height:0;padding-bottom:66.6%;border-radius:0}
.skl--t{height:13px;margin:11px 0 6px}.skl--t2{width:72%}
.skl--p{height:19px;width:46%;margin-top:12px}
.skl--f{height:10px;width:58%;margin-top:14px}
.sk-h{padding:26px 0 20px;margin-bottom:20px;border-bottom:2px solid var(--navy)}
.sk-say{margin-top:22px;font-size:13px;font-weight:600;color:var(--faint)}
@media(prefers-reduced-motion:no-preference){
  .skl{background:linear-gradient(90deg,var(--hair) 0%,#f7f9fb 42%,var(--hair) 84%);background-size:280% 100%;animation:skw 1.3s var(--ease) infinite}
  @keyframes skw{from{background-position:180% 0}to{background-position:-80% 0}}
}

/* detail */
/* the aside is first in the DOM for heading order and tab order; `order` puts it
   back on the right at desktop, and it leads on mobile where price-first is the
   correct reading order for a classified anyway */
/* grid-template-rows jest tu konieczne: "main" rozpina sie na oba wiersze, wiec
   bez tego przegladarka rozdziela jego wysokosc (ponad 1100px) miedzy wiersz 1
   i 2. Wiersz 1 puchl do polowy tej wartosci, .dt-head wypelnial go tylko w
   czesci, a align-items:start zostawial reszte jako pustke — stad ponad 140px
   dziury miedzy cena a karta sprzedajacego. auto 1fr daje wierszowi 1 wysokosc
   jego wlasnej tresci, a cala nadwyzke oddaje wierszowi 2. */
.dt{display:grid;grid-template-columns:minmax(0,1fr) 366px;grid-template-rows:auto 1fr;grid-template-areas:"main head" "main side";gap:16px 32px;align-items:start;padding:8px 0 32px}
.dt-head{grid-area:head}
/* the card gap lives here, not in inline margin-top strings on two of the three
   children. .dt-side said 14px while .dt and the inline overrides said 16px, and
   the two columns sit side by side, so the 2px was directly comparable. */
.dt-main{grid-area:main;min-width:0;display:grid;gap:16px;align-content:start}
/* min-width:0 tak samo jak w .dt-main. Bez tego element siatki nie moze zwezic
   sie ponizej swojej szerokosci minimalnej i - przy sztywnym torze 366px -
   zamiast sie zmiescic, WYCHODZI poza kolumne i poza maksymalna szerokosc
   strony. Wywolala to nazwa serwisu w przycisku: "Zobacz w serwisie
   ogloszenia.trojmiasto.pl" przy .btn{white-space:nowrap} ma szerokosc
   minimalna wieksza niz caly tor. */
.dt-side{grid-area:side;display:grid;gap:16px;min-width:0}
/* the shared subpage surface. Borderless like the cards and filter panels on
   home and results: on a grey page the white fill already draws the edge, and
   the hairline made subpages read as a different, older product. */
.box{background:#fff;border:0;border-radius:var(--r-lg);padding:20px}
.box__h{font-family:"Archivo",sans-serif;font-size:15px;font-weight:800;letter-spacing:-.01em;color:var(--navy);margin:0 0 12px;padding-bottom:10px;border-bottom:1px solid var(--line)}
.gal{position:relative}
/* --r-lg: this is media on a surface, and the SAME photo on the results card
   (.card__media) already uses --r-lg. 8px here made one object change shape
   between the grid you clicked and the page you landed on. */
.gal__main{position:relative;aspect-ratio:16/11;border-radius:var(--r-lg);overflow:hidden;background:var(--canvas)}
.gal__main img{position:relative;z-index:1;width:100%;height:100%;object-fit:cover}
.gal__main.noimg img{display:none}
.gal__main .gal__nav{position:absolute;z-index:2;top:50%;transform:translateY(-50%);width:38px;height:38px;display:grid;place-items:center;border-radius:999px;background:rgba(255,255,255,.94);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);color:var(--navy);border:0;box-shadow:0 2px 8px -2px rgba(10,37,64,.45);transition:background-color var(--t) var(--ease)}
.gal__nav:hover{background:#fff}
.gal__nav--l{left:10px}.gal__nav--r{right:10px}
.gal__cnt{position:absolute;z-index:2;bottom:10px;left:10px;background:rgba(7,20,36,.8);color:#fff;font-size:11.5px;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:.03em;padding:3px 9px;border-radius:999px}
.gal__th{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap}
.gal__th button{width:74px;height:55px;border-radius:var(--r);overflow:hidden;border:0;box-shadow:inset 0 0 0 1px var(--line);background:var(--canvas);padding:0;transition:box-shadow var(--t) var(--ease)}
.gal__th button:hover{box-shadow:inset 0 0 0 1px var(--accent)}
.gal__th button.on{box-shadow:inset 0 0 0 2px var(--accent)}
.gal__th img{width:100%;height:100%;object-fit:cover}

/* trade head — title, then the number, then the facts. The number is the anchor
   and it is set in weight, not in --accent. */
.dt h1{font-size:clamp(20px,2.4vw,25px);font-weight:800;letter-spacing:-.022em;color:var(--navy);line-height:1.22;margin:12px 0 12px}
.dt .price{display:flex;align-items:baseline;flex-wrap:wrap;gap:0 8px;font-size:clamp(29px,3.6vw,37px);font-weight:800;letter-spacing:-.03em;line-height:1;font-variant-numeric:tabular-nums;color:var(--navy);font-family:"Archivo",sans-serif;margin-bottom:12px}
.dt .price small{font-size:13px;color:var(--muted);font-weight:600;letter-spacing:0;font-family:"Inter",sans-serif}
.metas{display:flex;flex-wrap:wrap;gap:7px;font-size:12px;color:var(--muted);margin-bottom:14px}
.pillm{background:var(--canvas);border:1px solid var(--line);border-radius:999px;padding:2px 10px;font-weight:600}
.pillm--g{color:var(--green);background:var(--green-bg);border-color:var(--green-bd)}
.specs div{display:flex;justify-content:space-between;align-items:baseline;gap:16px;font-size:13.5px;padding:10px 0;border-bottom:1px solid var(--hair)}
.specs div:last-child{border-bottom:0}
.specs span{color:var(--muted);flex:none}
.specs b{color:var(--ink);font-weight:600;text-align:right}
/* Wyposazenie zajmuje caly wiersz, bo jest lista, a nie jedna wartoscia. Prawa
   kolumna tabelki miesci "7,30 m", nie trzynastu pozycji. */
.specs .specs__eq{display:block;padding:12px 0}
.eql{list-style:none;margin:8px 0 0;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(165px,1fr));gap:6px 16px}
.eql li{display:flex;align-items:baseline;gap:7px;font-size:13.5px;font-weight:600;color:var(--ink)}
.eql .ic{flex:none;color:var(--green);transform:translateY(1px)}
/* min-width:0 na dziecku flexa z ta sama motywacja co przy .dt-side: nazwa
   sprzedajacego bywa adresem serwisu (ogloszenia.trojmiasto.pl), a taki ciag nie
   ma gdzie sie zlamac i rozpycha karte. Awatar zostaje na flex:none. */
.seller{display:flex;align-items:center;gap:12px;margin-bottom:14px;min-width:0}
.seller>div{min-width:0}
.seller__n,.seller__meta{overflow-wrap:anywhere}
.seller .a{flex:none;width:46px;height:46px;border-radius:999px;background:var(--navy);color:#fff;display:grid;place-items:center;font-weight:800;font-size:18px;font-family:"Archivo",sans-serif}
/* The seller name was inline font-weight:800 on Inter, but Inter is loaded at
   400;500;600;700 only, so the browser synthesised a faux bold on the largest
   body text of the page. Archivo 800 is a real cut and is what .box__h uses, so
   the seller name and the card titles finally agree. */
.seller .a{text-decoration:none}
.seller .a:hover{background:var(--accent-dark)}
.seller__n{font-family:"Archivo",sans-serif;font-size:15px;font-weight:800;letter-spacing:-.01em;color:var(--navy)}
.seller__n a{color:inherit;text-decoration:none}
.seller__n a:hover{color:var(--accent-dark)}
.seller__rate{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;font-weight:700;color:var(--navy);text-decoration:none}
.seller__meta{font-size:12px;color:var(--muted);margin-top:2px}
.seller__meta a{color:var(--accent-dark);font-weight:600;text-decoration:none}
.seller__meta a:hover{text-decoration:underline}

/* ── the negotiation panel ──────────────────────────────────────────────────
   Built-in price negotiation is what this giełda has and OLX does not, so it is
   the one place allowed to be the loudest object on the page. It states the
   asking price, offers three pre-computed openings so nobody has to be the first
   to say a number out loud, and explains the mechanic at the point of use. */
.deal{border:1.5px solid var(--navy);border-radius:var(--r);overflow:hidden;margin-bottom:14px}
.deal__h{display:flex;align-items:baseline;justify-content:space-between;gap:10px;padding:10px 14px;background:var(--navy);color:#fff}
.deal__h b{font-family:"Archivo",sans-serif;font-size:13.5px;font-weight:800;letter-spacing:.01em}
.deal__h span{font-size:11.5px;font-weight:600;color:rgba(255,255,255,.82);font-variant-numeric:tabular-nums}
.deal__b{padding:13px 14px 14px}
.deal__q{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:11px}
.deal__q button{flex:1 1 0;min-width:72px;height:34px;padding:0 8px;border:1px solid var(--line);border-radius:var(--r);background:#fff;font-family:"Archivo",sans-serif;font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--navy);cursor:pointer;transition:border-color var(--t) var(--ease),background-color var(--t) var(--ease),color var(--t) var(--ease)}
.deal__q button:hover{border-color:var(--accent);background:var(--blue-soft);color:var(--accent-dark)}
.deal__q button:active{transform:translateY(1px)}
.deal__q button.on{border-color:var(--navy);background:var(--navy);color:#fff}
.deal__row{display:flex;gap:8px}
.deal__in{position:relative;flex:1;min-width:0}
.deal__in input{width:100%;height:46px;border:1.5px solid var(--line);border-radius:var(--r);padding:0 34px 0 12px;font-family:"Archivo",sans-serif;font-size:16px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--navy);outline:none;background:#fff;transition:border-color var(--t) var(--ease),box-shadow var(--t) var(--ease)}
.deal__in input::placeholder{font-weight:600;color:var(--faint)}
.deal__in input:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(23,115,214,.14)}
.deal__cur{position:absolute;right:12px;top:50%;transform:translateY(-50%);font-size:13px;font-weight:700;color:var(--faint);pointer-events:none}
.deal__note{margin-top:10px;font-size:11.5px;line-height:1.5;color:var(--muted)}
/* the ask/counter ledger — a negotiation is a sequence of numbers, so show the
   sequence. Same ruled grammar as everything else. */
.led{margin:0 0 14px;border-top:1px solid var(--line)}
.led__r{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding:9px 0 9px 12px;border-bottom:1px solid var(--hair);box-shadow:inset 3px 0 0 var(--line)}
.led__r--me{box-shadow:inset 3px 0 0 var(--accent)}
.led__r--live{box-shadow:inset 3px 0 0 var(--navy)}
.led__r--done{box-shadow:inset 3px 0 0 var(--green)}
.led__l{font-size:12px;font-weight:600;color:var(--muted)}
.led__v{font-family:"Archivo",sans-serif;font-size:15px;font-weight:800;font-variant-numeric:tabular-nums;color:var(--navy)}
.led__r--done .led__v{color:var(--green)}
.led__r--old .led__v{color:var(--faint);text-decoration:line-through;text-decoration-thickness:1px}
@media(prefers-reduced-motion:reduce){.deal__q button,.deal__in input,.gal__nav,.gal__th button{transition:none}.deal__q button:active{transform:none}}
/* `align-content:start` jest tu obowiazkowe, nie kosmetyczne. Pole stoi czesto w
   `.two`, gdzie obie kolumny sa rozciagane do wysokosci wyzszej z nich - a siatka
   bez tej deklaracji rozdziela nadmiar miedzy WSZYSTKIE swoje wiersze auto.
   Krotsza kolumna rozpychala sie wtedy od srodka: etykieta "Cena (zl)" rosla z 19
   do 70 px, przelacznik z 35 do 86, a samo pole ceny ladowalo 51 px nizej niz
   sasiednie pole lokalizacji. Nadmiar ma sie zbierac na dole kolumny. */
.fld{display:grid;gap:6px;align-content:start}
.fld label{font-size:12.5px;font-weight:700;letter-spacing:.005em;color:var(--navy)}
.flab-o{font-weight:500;color:var(--faint)}
.fld input,.fld select,.fld textarea{width:100%;border:1.5px solid var(--line);border-radius:var(--r);padding:0 12px;height:46px;font-size:14.5px;color:var(--ink);outline:none;font-family:inherit;background:#fff;transition:border-color var(--t) var(--ease),box-shadow var(--t) var(--ease)}
.fld input::placeholder,.fld textarea::placeholder{color:var(--faint)}
.fld textarea{height:auto;min-height:104px;padding:10px 12px;resize:vertical;line-height:1.55}
.fld input:hover,.fld select:hover,.fld textarea:hover{border-color:#ccd5e0}
.fld input:focus,.fld select:focus,.fld textarea:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(23,115,214,.14);outline:none}
.fld input:disabled{background:var(--canvas);color:var(--faint);border-color:var(--hair)}
.fhint{font-size:12px;line-height:1.45;color:var(--muted)}
.fhint--ok{color:var(--green)}
.fhint--warn{color:var(--amber)}
.two{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.chk{display:flex;align-items:center;gap:9px;font-size:13.5px;font-weight:600;color:var(--ink);cursor:pointer}
.chk input{width:17px;height:17px;flex:none;accent-color:var(--accent)}
.chk:hover{color:var(--navy)}
/* ── lista wyposazenia w formularzu ───────────────────────────────────────────
   Grupa idzie przez cala szerokosc sekcji: w kolumnie o polowie szerokosci
   "Przyczepa podłodziowa" zawija sie na dwie linie i lista przestaje wygladac
   jak lista. Kolumny same dobieraja liczbe do szerokosci okna, wiec na telefonie
   zostaje jedna, a nie scisniete dwie. */
.eqf{grid-column:1/-1}
.eqg{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:2px 14px;margin-top:2px}
/* `label.eqo`, nie `.eqo`. Kazda pozycja wyposazenia siedzi wewnatrz
   `<div class="fld eqf">`, wiec regula `.fld label` (0,1,1) bila `.eqo` (0,1,0)
   NIEZALEZNIE od kolejnosci w pliku - i wygrywala kompletem: 12,5px zamiast 13,5,
   waga 700 zamiast 500, kolor granatowy zamiast atramentowego. Zmierzone.
   Skutek nie byl kosmetyczny. `.eqo:has(input:checked)` dokłada `font-weight:700`
   jako DRUGI sygnal zaznaczenia, obok tla - ale skoro NIEZAZNACZONE pozycje juz
   byly 700, ten sygnal nie istnial. Do tego cala lista 91 opcji miala te sama
   typografie co naglowki grup, wiec czytala sie jak lista naglowkow.
   `label.eqo` to (0,1,1), czyli remis rozstrzygniety kolejnoscia - a `.eqo`
   stoi nizej. Klasa nie wystepuje nigdzie poza `<label>`. */
label.eqo{display:flex;align-items:center;gap:9px;padding:6px 8px 6px 6px;margin-left:-6px;border-radius:var(--r);font-size:13.5px;font-weight:500;color:var(--ink);cursor:pointer;transition:background-color var(--t) var(--ease),color var(--t) var(--ease)}
.eqo:hover{background:var(--canvas);color:var(--navy)}
.eqo input{width:17px;height:17px;flex:none;margin:0;accent-color:var(--accent)}
.eqo span{min-width:0}
/* Zaznaczone ma byc widac bez czytania kwadracikow: to jest odpowiedz na pytanie
   "co ta lodz ma", a nie lista pytan. */
.eqo:has(input:checked){background:var(--blue-soft);color:var(--accent-dark);font-weight:700}

/* ── post form — the register's gutter, scaled to a document you fill in ──── */
.pform-wrap{max-width:768px}
.backlink{display:inline-flex;align-items:center;gap:5px;margin:22px 0 20px;font-size:13px;font-weight:700;color:var(--accent-dark)}
.backlink:hover{text-decoration:underline}
.pform-h{font-family:"Archivo",sans-serif;font-size:clamp(25px,3.4vw,36px);font-weight:800;letter-spacing:-.025em;line-height:1.08;color:var(--navy)}
.pform-lead{margin:9px 0 4px;max-width:52ch;font-size:14.5px;line-height:1.55;color:var(--muted)}
/* each step is a card on the grey page, matching the filter panels and the
   results header. The hairline-separated gutter layout it replaces belonged to
   the pre-Allegro visual language and was the last place still using it. */
.pfs{background:#fff;border:0;border-radius:var(--r-lg);padding:18px 20px 20px;margin-bottom:10px}
.pfs:first-of-type{margin-top:20px}
.pfs__h{font-family:"Archivo",sans-serif;font-size:18px;font-weight:800;letter-spacing:-.018em;color:var(--navy)}
.pfs__d{margin:5px 0 18px;max-width:52ch;font-size:13px;line-height:1.55;color:var(--muted)}
.pfs__f{display:grid;gap:17px}
.opts{display:grid;gap:11px;padding:14px 16px;background:var(--canvas);border-radius:var(--r);box-shadow:inset 3px 0 0 var(--line)}
/* Sticky, so the publish button and the error that belongs to it are on screen
   at every scroll position instead of only at the very bottom of a long form. */
/* Zwykla karta na koncu formularza, nie pasek przyklejony do dolu okna.
   Przyklejony zabieral pas ekranu przez cale wypelnianie, na telefonie wchodzil
   pod pasek skrotow, a cien pod nim sugerowal, ze nizej jest jeszcze tresc.
   Przycisk stoi tam, gdzie formularz sie konczy. */
.pform-go{display:grid;gap:10px;justify-items:start;background:#fff;border:0;border-radius:var(--r-lg);padding:18px 20px;box-shadow:inset 0 0 0 1px var(--line)}
.pform-go #adderr:empty{display:none}
.pform-go .btn{min-width:230px}
@media(max-width:640px){
  .pfs{padding:15px 16px 17px}
  .two{grid-template-columns:1fr}
  .pform-go .btn{min-width:0;width:100%}
}
.err{background:var(--red-bg);border:1px solid #f3cdc9;border-left:3px solid var(--red);color:var(--red);font-size:13px;font-weight:700;border-radius:var(--r);padding:10px 12px}
/* visually-hidden label — keeps inputs named for screen readers where the design
   carries the label some other way (the deal panel's own header) */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.dt-ds{font-size:14.5px;line-height:1.65;color:var(--ink);white-space:pre-line}
.dt-safe{font-size:11.5px;line-height:1.5;color:var(--muted);text-align:center;margin-top:11px}
.dt-own{font-size:13px;line-height:1.55;color:var(--muted);margin-bottom:12px}
/* .dt-fix had NO rule, so this one-line note rendered at the browser default
   16px/--ink: larger and darker than the card headings above it. Same recipe as
   .dt-own, which is the same object doing the same job. */
.dt-fix{font-size:13px;line-height:1.55;color:var(--muted);margin:0 0 12px}
.dt-sold{text-align:center;font-weight:700;color:var(--muted);background:var(--canvas);border:1px solid var(--line);border-radius:var(--r);padding:14px}

/* auth */
.auth{max-width:436px;margin:40px auto 56px;padding:0 24px}
/* the auth surface is the same white card as everything else. It used to carry a
   hairline, a 2px navy cap and a 50px drop shadow, three decorations no other
   surface in the product has: it read as a modal borrowed from another site. */
.auth .card2{border:0;border-radius:var(--r-lg);padding:26px;background:#fff}
.auth h1{font-family:"Archivo",sans-serif;font-size:25px;font-weight:800;letter-spacing:-.025em;color:var(--navy);margin:16px 0 4px}
.auth .sub{font-size:13.5px;line-height:1.55;color:var(--muted);margin-bottom:18px}
.auth .sw{text-align:center;font-size:13px;color:var(--muted);margin-top:14px}
.auth .sw a{color:var(--accent-dark);font-weight:700;cursor:pointer}
.auth .sw a:hover{text-decoration:underline}
.pw{position:relative}.pw button{position:absolute;right:6px;top:50%;transform:translateY(-50%);width:34px;height:34px;display:grid;place-items:center;border-radius:999px;background:none;border:0;color:var(--faint);transition:color var(--t) var(--ease),background-color var(--t) var(--ease)}
.pw button:hover{color:var(--navy);background:var(--canvas)}

/* chat */
/* Rozmowa to tresc strony, wiec nalezy jej sie ta sama biala plyta co reszcie:
   lista rozmow obok siedzi w .box, a watek lezal wprost na szarym tle. */
.thread{max-width:760px;margin:0 auto;padding:22px 24px 40px;background:#fff;border-radius:var(--r-lg)}
/* W ukladzie dwukolumnowym watek wypelnia prawa kolumne — wlasne centrowanie
   zostawialoby puste marginesy wewnatrz i tak juz waskiej kolumny. */
.msg__pane .thread{max-width:none;margin:0}
/* Powyzej 700px lista rozmow stoi obok, wiec link "Wiadomosci" prowadzilby tam,
   gdzie uzytkownik juz patrzy, a jego marginesy odsuwaly karte watku od gory.
   Ponizej 700px kolumny sie skladaja i link zostaje jedyna droga powrotna. */
@media(min-width:701px){.msg__pane .backlink{display:none}}
.tmsg{max-width:78%;display:flex;flex-direction:column;gap:3px;margin-bottom:11px}
.tmsg.me{align-self:flex-end;align-items:flex-end;margin-left:auto}
.tbub{padding:9px 14px;font-size:14px;border-radius:var(--r);line-height:1.5}
.tmsg.me .tbub{background:var(--navy);color:#fff}
.tmsg.them .tbub{background:var(--canvas);box-shadow:inset 0 0 0 1px var(--line),inset 3px 0 0 var(--line)}
.tbub.off{font-family:"Archivo",sans-serif;font-weight:800;font-variant-numeric:tabular-nums}
.tbub small{display:block;font-family:"Inter",sans-serif;font-size:10px;text-transform:uppercase;letter-spacing:.06em;opacity:.72;font-weight:700;margin-bottom:2px}
.tmeta{font-size:10.5px;font-weight:500;color:var(--faint);padding:0 3px}
.sys{align-self:center;max-width:92%;text-align:center;font-size:12px;line-height:1.5;color:var(--muted);background:var(--canvas);border:1px solid var(--line);border-radius:999px;padding:5px 14px;margin-bottom:11px}
.composer{display:flex;gap:8px;align-items:flex-end;margin-top:18px;padding-top:16px;border-top:1px solid var(--line)}
.composer textarea{flex:1;min-width:0;border:1.5px solid var(--line);border-radius:var(--r);padding:9px 12px;font-size:14px;line-height:1.5;outline:none;resize:none;font-family:inherit;color:var(--ink);background:#fff;transition:border-color var(--t) var(--ease),box-shadow var(--t) var(--ease)}
.composer textarea::placeholder{color:var(--faint)}
.composer textarea:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(23,115,214,.14)}

/* ── the offer panel — the negotiation made legible ────────────────────────
   The differentiator is that two people move a number until they agree, so the
   panel shows the number moving: asking price, every offer, the live one. */
.offerp{background:#fff;border:1.5px solid var(--navy);border-radius:var(--r);overflow:hidden;margin:18px 0}
.offerp__h{display:flex;align-items:baseline;justify-content:space-between;gap:10px;padding:9px 14px;background:var(--navy);color:#fff}
.offerp__h b{font-family:"Archivo",sans-serif;font-size:13px;font-weight:800;letter-spacing:.01em}
/* demoted by size and weight, never by opacity: white at .72 clears AA on the
   navy head but only reaches 3.6:1 on the green one */
.offerp__h span{font-size:11.5px;font-weight:600;color:#fff}
.offerp__b{padding:14px}
.offerp__say{font-size:13.5px;line-height:1.55;color:var(--ink);margin-bottom:12px}
.offerp__act{display:flex;gap:8px;flex-wrap:wrap}
.offerp__act .btn{height:42px;font-size:14px}
.offerp__cf{display:flex;gap:8px;margin-top:12px;padding-top:12px;border-top:1px solid var(--line)}
.offerp__cf input{flex:1;min-width:0;height:42px;border:1.5px solid var(--line);border-radius:var(--r);padding:0 12px;font-family:"Archivo",sans-serif;font-size:15px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--navy);outline:none;transition:border-color var(--t) var(--ease),box-shadow var(--t) var(--ease)}
.offerp__cf input::placeholder{font-family:"Inter",sans-serif;font-size:13.5px;font-weight:500;color:var(--faint)}
.offerp__cf input:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(23,115,214,.14)}
.offerp--done{border-color:var(--green)}
.offerp--done .offerp__h{background:var(--green)}
.offerp--wait{border-color:var(--line)}
.offerp--wait .offerp__h{background:var(--canvas);color:var(--navy)}
.offerp--wait .offerp__h span{color:var(--muted)}

.list-row{display:flex;align-items:center;gap:14px;padding:14px;border-bottom:1px solid var(--hair);cursor:pointer;transition:background-color var(--t) var(--ease),box-shadow var(--t) var(--ease)}
.list-row:hover{background:var(--canvas)}
.list-row:last-child{border-bottom:0}
/* the box moves to the .plated wrapper, not the child <img>: .plated.noimg img
   sets display:none on failure, and if the wrapper carried no size the row
   collapsed to 0px and jumped. Sizing the wrapper keeps the layout stable and
   puts the radius and clipping where the plate can inherit them. */
.lr-m{flex:none;width:58px;height:48px;border-radius:var(--r);overflow:hidden;background:var(--canvas)}
.lr-m img{width:100%;height:100%;object-fit:cover;border-radius:0}
.lr-m .lr-unread{flex:none;min-width:20px;height:20px;padding:0 6px;display:grid;place-items:center;border-radius:999px;background:var(--accent);color:#fff;font-size:11px;font-weight:700}
/* thread header: which listing, at what price, with whom */
.thead{display:flex;align-items:center;gap:14px;padding:12px;border:1px solid var(--line);border-radius:var(--r);box-shadow:inset 3px 0 0 var(--line);transition:background-color var(--t) var(--ease),box-shadow var(--t) var(--ease)}
.thead:hover{background:var(--canvas);box-shadow:inset 5px 0 0 var(--accent)}
.thead__m{position:relative;flex:none;width:64px;height:50px;border-radius:var(--r);overflow:hidden;background:var(--canvas)}
.thead__m img{position:relative;z-index:1;width:100%;height:100%;object-fit:cover}
.thead__m.noimg img{display:none}
.thead__m .plate{--ic:var(--faint)}
.thead__m .thead__b{flex:1;min-width:0}
.thead__b b{display:block;font-size:14.5px;font-weight:700;color:var(--navy);line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.thead__p{display:block;margin-top:2px;font-family:"Archivo",sans-serif;font-size:14px;font-weight:800;font-variant-numeric:tabular-nums;color:var(--navy)}
.thead__w{flex:none;text-align:right;font-size:11.5px;line-height:1.4;color:var(--muted)}
.thead__w b{display:block;font-size:13px;color:var(--navy)}
.tstream{display:flex;flex-direction:column;margin-top:18px}
@media(max-width:560px){.thead__w{display:none}}

/* footer — mirrors zeglarski.info's .footer exactly: light gradient over a
   sailing photo, dark navy headings, muted body text (not a dark navy panel). */
/* To zdjecie laduje sie na KAZDEJ podstronie, lacznie z /regulamin i 404, i jest
   przykryte gradientem o kryciu 0,90-0,96 - widac z niego jakies 5%. Zrodlo
   mialo 2000 px i 604 944 B; po przeskalowaniu do 960 px i q55 zostalo 73 587 B,
   a roznicy pod welonem nie widac (porownanie renderu przed/po w raporcie).
   Telefon dostaje jeszcze mniejszy plik - to jest odpowiednik srcset dla tla,
   bo dla background-image nie ma atrybutu sizes. */
footer{margin-top:64px;border-top:1px solid var(--line);background:linear-gradient(180deg,rgba(245,247,250,.96) 0%,rgba(245,247,250,.9) 100%),url('footer-sailing.jpg') center/cover no-repeat;color:var(--muted)}
@media (max-width:760px){
  footer{background-image:linear-gradient(180deg,rgba(245,247,250,.96) 0%,rgba(245,247,250,.9) 100%),url('footer-sailing-480.jpg')}
}
/* ── Strony informacyjne (Dla sprzedających, Jak to działa) ──────────────────
   Te strony sa dluzsze niz reszta serwisu i skladaja sie z blokow, nie z listy
   kart. Rytm trzyma jeden odstep miedzy blokami i jeden krok wielkosci naglowka;
   wszystko inne dziedziczy po .step i .box, ktore juz tu byly. */
.sprz__lead{font-size:16px;line-height:1.65;color:var(--muted);margin-bottom:24px;max-width:62ch}
.sprz__h2{font-family:"Archivo",sans-serif;font-size:20px;font-weight:800;letter-spacing:-.02em;
  color:var(--navy);margin:34px 0 10px}
.sprz__p{font-size:14.5px;line-height:1.65;color:var(--muted);margin-bottom:14px;max-width:66ch}
.sprz__p b{color:var(--navy)}
.sprz__ptr{font-size:13px;line-height:1.6;color:var(--faint);margin:10px 0 0;max-width:62ch}

/* Cztery zera. Liczba jest tu komunikatem, wiec dostaje wielkosc naglowka, a
   zdanie pod spodem tlumaczy, czego dotyczy - bez tego "0 zl" jest sloganem. */
.cenn{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px;margin:22px 0 0}
.cenn__i{background:#fff;border-radius:var(--r-lg);padding:16px 16px 18px;
  box-shadow:inset 0 0 0 1px var(--line)}
.cenn__i b{display:block;font-family:"Archivo",sans-serif;font-size:30px;font-weight:800;
  letter-spacing:-.03em;color:var(--green,#0e7a3f);line-height:1}
.cenn__i span{display:block;font-size:12.5px;font-weight:700;color:var(--navy);margin:6px 0 6px}
.cenn__i i{display:block;font-style:normal;font-size:12.5px;line-height:1.5;color:var(--muted)}
@media(max-width:760px){.cenn{grid-template-columns:repeat(2,1fr)}}
@media(max-width:420px){.cenn{grid-template-columns:1fr}}

/* Pasek zdjec. Stale proporcje, zeby trzy rozne kadry ulozyly sie w jeden rzad
   bez skakania wysokosci. */
.fotos{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin:26px 0 4px}
.fotos__i{margin:0}
.fotos__i img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover;
  border-radius:var(--r-lg);background:var(--canvas)}
.fotos__i figcaption{font-size:12px;color:var(--faint);padding:7px 2px 0}
@media(max-width:600px){.fotos{grid-template-columns:1fr 1fr;gap:8px}.fotos__i:nth-child(3){display:none}}

/* Chipy kategorii na stronach informacyjnych. Liczba w srodku, nie obok: pigulka
   ma byc jednym obiektem, a nie linkiem z doklejonym licznikiem. */
.chps{display:flex;flex-wrap:wrap;gap:8px;margin:4px 0 6px}
.chp{display:inline-flex;align-items:center;gap:7px;padding:8px 13px;border-radius:999px;
  background:#fff;box-shadow:inset 0 0 0 1px var(--line);
  font-size:13px;font-weight:700;color:var(--navy);text-decoration:none;
  transition:box-shadow var(--t) var(--ease),background-color var(--t) var(--ease)}
.chp:hover{background:var(--blue-soft);box-shadow:inset 0 0 0 1px var(--accent)}
.chp i{font-style:normal;font-size:11.5px;font-weight:700;font-variant-numeric:tabular-nums;
  color:var(--accent-dark);background:var(--blue-soft);border-radius:999px;padding:1px 7px}
.chp--new{color:#0e7a3f;box-shadow:inset 0 0 0 1px color-mix(in srgb,#0e7a3f 30%,transparent)}
.chp--new:hover{background:color-mix(in srgb,#0e7a3f 8%,#fff);box-shadow:inset 0 0 0 1px #0e7a3f}
@supports not (background:color-mix(in srgb,red 10%,#fff)){
  .chp--new{box-shadow:inset 0 0 0 1px var(--line)}
}
.sprz__first{margin:18px 0 0;border-left:3px solid #0e7a3f}

/* Dwie kolumny "Kupujesz / Sprzedajesz". Na waskim ekranie jedna pod druga -
   to sa dwie odpowiedzi na to samo pytanie, wiec kolejnosc wystarczy. */
.dwie{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:28px 0 4px}
.dwie__k{background:#fff;border-radius:var(--r-lg);padding:18px 20px;
  box-shadow:inset 0 0 0 1px var(--line)}
.dwie__k h2{font-family:"Archivo",sans-serif;font-size:16px;font-weight:800;letter-spacing:-.02em;
  color:var(--navy);margin-bottom:8px}
.dwie__k p{font-size:13.5px;line-height:1.6;color:var(--muted);margin-bottom:9px}
.dwie__k p:last-child{margin-bottom:0}
@media(max-width:700px){.dwie{grid-template-columns:1fr}}

/* Grupa pol technicznych. Naglowek grupy odroznia sie od etykiety pola, bo
   inaczej "Silnik" jako nazwa sekcji i "Silnik" jako nazwa pola wygladalyby
   identycznie - a w profilu motorowym stoja jedno pod drugim. */
.spgrp{margin-top:18px}
/* Wyjatek dotyczy PIERWSZEJ grupy sekcji technicznej, a nie kazdej grupy, ktora
   akurat jest pierwszym dzieckiem swojego rodzica. Przy kategoriach z data
   wyplyniecia (DEP_CATS: rejsy) przed `#spwrap` stoi jeszcze pole daty, wiec
   naglowek grupy dostawal margines 0 i stykal sie z tym polem na styk.
   `#spwrap:first-child` sprawdza dokladnie ten warunek: sekcja techniczna zaczyna
   sekcje formularza. */
#spwrap:first-child>.spgrp:first-child{margin-top:0}
.spgrp>label{display:block;padding-bottom:7px;margin-bottom:11px;border-bottom:1px solid var(--hair)}
/* Przelacznik logiczny w siatce pol technicznych: zajmuje caly wiersz, bo w
   polowie szerokosci "Wersja z kabina wlasciciela" zawija sie po jednym slowie. */
.sw--sp{grid-column:1/-1}
/* Gwiazdka pola wymaganego. Kolor ostrzegawczy, ale bez tla - to znacznik, nie
   komunikat o bledzie. */
.req{color:var(--red);font-weight:800}
/* Pozycja wygaszona po osiagnieciu limitu zaznaczen. Nie znika, bo znikajace
   opcje wygladaja na awarie - przestaje byc klikalna i to widac. */
.eqo--off{opacity:.42;cursor:not-allowed}
.eqo--off input{cursor:not-allowed}

/* ── Zapowiedz wyroznienia w formularzu ──────────────────────────────────────
   Wyglada jak informacja, nie jak oferta: bez przycisku i bez ceny, bo obu
   jeszcze nie ma. Bursztyn zamiast akcentu, zeby nie udawal glownej akcji
   sekcji, ktora stoi tuz pod spodem. */
.wyrz{display:flex;align-items:flex-start;gap:13px;flex-wrap:wrap;
  padding:14px 16px;border-radius:var(--r-lg);
  background:#fffaf0;box-shadow:inset 0 0 0 1.5px #e6c67a}
.wyrz__ic{flex:none;display:grid;place-items:center;width:34px;height:34px;border-radius:999px;
  background:#b7791f;color:#fff}
.wyrz__tx{flex:1;min-width:200px;display:flex;flex-direction:column;gap:3px}
.wyrz__tx b{font-size:14px;font-weight:800;color:#7a4f10}
.wyrz__tx span{font-size:13px;line-height:1.55;color:var(--muted)}
.wyrz__st{flex:none;align-self:center;padding:7px 13px;border-radius:var(--r);
  background:#fff;box-shadow:inset 0 0 0 1px #e6c67a;
  font-size:12.5px;font-weight:700;color:#7a4f10}
@media(max-width:560px){.wyrz__st{width:100%;text-align:center}}

/* ── Dopisywanie wlasnej cechy ───────────────────────────────────────────────
   Wiersz pod lista, nie kolejna pozycja w niej: dopisanie to inna czynnosc niz
   zaznaczanie i nie ma udawać jednej z opcji. */
.eqadd{display:flex;gap:8px;margin-top:9px}
/* Ta sama pulapka co wyzej: `.fld input` (0,1,1) bilo `.eqadd__i` (0,1,0), wiec
   CALA ta deklaracja byla martwa - pole dostawalo 46px wysokosci z reguly pola
   formularza i stalo o 10px wyzej niz przycisk "Dodaj" obok, mimo ze oba mialy
   w arkuszu wpisane 36px. `.eqadd input.eqadd__i` to (0,2,1) i wygrywa. */
.eqadd input.eqadd__i{flex:1;min-width:0;height:36px;padding:0 11px;border-radius:var(--r);
  border:1.5px solid var(--line);background:#fff;font-size:13px;color:var(--navy)}
.eqadd input.eqadd__i:focus{outline:none;border-color:var(--accent)}
.eqadd__b{flex:none;height:36px;padding:0 15px;border-radius:var(--r);
  border:1.5px solid var(--accent);background:var(--blue-soft);
  font-size:13px;font-weight:700;color:var(--accent-dark);cursor:pointer;
  transition:background-color var(--t) var(--ease)}
.eqadd__b:hover{background:#fff}
.eqadd__b:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* Pozycja dopisana recznie. Rozni sie od listowej, bo za nia odpowiada
   sprzedajacy - i po edycji ma byc widac, ktore cechy sa jego. */
.eqo--wl{box-shadow:inset 0 0 0 1px var(--accent)}
.eqo--blysk{animation:eqblysk .9s var(--ease)}
@keyframes eqblysk{0%,100%{background:transparent}30%{background:var(--blue-soft)}}
@media(prefers-reduced-motion:reduce){.eqo--blysk{animation:none}}

/* ── Stan weryfikacji firmy ──────────────────────────────────────────────────
   Cztery stany, cztery kolory, ale JEDEN uklad: tytul stanu i zdanie o tym, co
   dalej. Bez tego drugiego zdania pasek mowi tylko "czekaj", a firma nie wie,
   ile i na co. */
.kycb{--kc:var(--faint);display:flex;flex-direction:column;gap:3px;
  padding:12px 14px;border-radius:var(--r-lg);
  background:var(--canvas);box-shadow:inset 0 0 0 1px var(--line);
  border-left:3px solid var(--kc)}
.kycb b{font-size:13.5px;font-weight:800;color:var(--navy)}
.kycb span{font-size:13px;line-height:1.55;color:var(--muted)}
.kycb--wait{--kc:#b7791f;background:#fffaf0;box-shadow:inset 0 0 0 1px #f0dfb8}
.kycb--ok{--kc:#0e7a3f;background:#f2fbf5;box-shadow:inset 0 0 0 1px #bfe4cd}
.kycb--no{--kc:var(--red);background:#fef4f4;box-shadow:inset 0 0 0 1px #f3cccc}

/* ── Kafle pulpitu ───────────────────────────────────────────────────────────
   Liczba jest trescia kafla, wiec ma wielkosc naglowka; etykieta schodzi pod nia
   drobnym drukiem. Zero traci akcent - "0 nieprzeczytanych" to dobra wiadomosc. */
.pstat{display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto auto;
  gap:2px 11px;align-items:center;background:#fff;padding:15px 16px 14px;
  transition:background-color var(--t) var(--ease),box-shadow var(--t) var(--ease)}
/* `1 / -1`, nie `1 / 3`. Kafel ma dwa wiersze albo trzy, zaleznie od tego, czy
   pokazuje zdanie o zerze - przy trzech ikona spieta na sztywno do drugiego
   wiersza zostawala u gory i wygladala jak osobny element nad liczba, zamiast
   stac obok calego bloku. */
.pstat__ic{grid-row:1/-1;align-self:center;display:grid;place-items:center;
  width:40px;height:40px;flex:none;
  border-radius:999px;background:var(--blue-soft);color:var(--accent-dark)}
.pstat__n{font-family:"Archivo",sans-serif;font-size:24px;font-weight:800;
  letter-spacing:-.03em;line-height:1;color:var(--navy);font-variant-numeric:tabular-nums}
.pstat__l{font-size:12.5px;font-weight:600;color:var(--muted);line-height:1.3}
.pstat__z{grid-column:2;font-size:11.5px;color:var(--faint)}
/* Zero traci AKCENT, ale nie etykiete. Chowanie etykiety przy zerze zostawialo
   kafel, ktory mowi "0 / skrzynka na czysto" i nie zdradza, czego dotyczy -
   zdanie pocieszenia zastepowalo informacje, zamiast ja uzupelniac. */
.pstat--0 .pstat__ic{background:var(--canvas);color:var(--faint)}
.pstat--0 .pstat__n{color:var(--faint)}
.pstat--0 .pstat__l{color:var(--faint);font-weight:600}

/* ── Moje ogloszenie: stan i akcje ───────────────────────────────────────────
   Gorny wiersz to STAN (wyroznienie, termin, sprzedane), dolny AKCJE. Usuwanie
   siedzi na prawym skraju jako sama ikona - jedyna nieodwracalna pozycja nie ma
   stac obok tej, ktora klika sie najczesciej. */
.mycard__st{display:flex;flex-wrap:wrap;gap:5px;padding:8px 9px 0;
  border:1px solid var(--line);border-top:0;border-bottom:0;background:var(--canvas)}
.myst{display:inline-flex;align-items:center;gap:4px;padding:3px 8px;border-radius:999px;
  background:#fff;box-shadow:inset 0 0 0 1px var(--line);
  font-size:11px;font-weight:700;color:var(--muted)}
.myst--pro{color:#7a4f10;box-shadow:inset 0 0 0 1px #e6c67a;background:#fffaf0}
.myst--sold{color:var(--navy)}
.mycard__a--del{flex:0 0 40px;display:grid;place-items:center}

/* ── Lista rozmow ────────────────────────────────────────────────────────────
   Kolumna wierszy ze zdjeciami i nazwiskami nie mowila o sobie nic. */
/* Naglowek jest PIERWSZYM WIERSZEM karty, wiec ma jej padding i kreske pod
   spodem. Nad karta wisial jako samotny tekst na szarym tle i czytal sie jak
   podpis niczyj - lista zaczynala sie dopiero nizej. */
.msg__lh{display:flex;align-items:center;gap:8px;
  font-family:"Archivo",sans-serif;font-size:14px;font-weight:800;letter-spacing:-.02em;
  color:var(--navy);padding:13px 14px;border-bottom:1px solid var(--line);
  background:var(--canvas)}

/* ── Wiersz rozmowy ──────────────────────────────────────────────────────────
   Trzy linie w stalej hierarchii: OGLOSZENIE (o czym), osoba i rola (z kim),
   ostatnia wiadomosc (na czym stanelo). Rozmowe prowadzi sie w sprawie
   przedmiotu, a nie z osoba: przy trzech watkach z ta sama osoba o trzy rozne
   silniki lista nazwisk nie pozwala wybrac wlasciwego. */
.mrow{display:flex;align-items:center;gap:11px;padding:11px 14px;
  border-bottom:1px solid var(--hair);text-decoration:none;
  transition:background-color var(--t) var(--ease)}
.mrow:last-child{border-bottom:0}
.mrow:hover{background:var(--canvas)}
.mrow.on{background:var(--blue-soft);box-shadow:inset 3px 0 0 var(--accent)}
.mrow__m{flex:none;width:48px;height:48px;border-radius:var(--r);overflow:hidden}
.mrow__m img{width:100%;height:100%;object-fit:cover;display:block}
.mrow__b{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.mrow__t{font-size:13.5px;font-weight:700;color:var(--navy);line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mrow__kto{font-size:12px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mrow__kto i{font-style:normal;color:var(--faint)}
.mrow__last{font-size:12.5px;color:var(--faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mrow__last.is-new{color:var(--navy);font-weight:600}
.mrow__n{flex:none;min-width:20px;height:20px;padding:0 6px;border-radius:999px;
  background:var(--red);color:#fff;font-size:11px;font-weight:700;
  display:grid;place-items:center;font-variant-numeric:tabular-nums}
@media(prefers-reduced-motion:reduce){.mrow{transition:none}}
.msg__lc{font-family:"Inter",sans-serif;font-size:11.5px;font-weight:700;
  font-variant-numeric:tabular-nums;color:#fff;background:var(--red);
  border-radius:999px;padding:1px 7px}
/* Temat rozmowy. Etykieta nad karta ogloszenia, bo bez niej karta ze zdjeciem
   i cena czyta sie jak pierwsza wiadomosc watku, a nie jak jego temat. */
.thead__k{font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
  color:var(--faint);margin:2px 0 6px}

/* ── Zwijana grupa wyposazenia ───────────────────────────────────────────────
   Wyglada jak naglowek grupy obok, tylko klikalny: ten sam rytm, ta sama kreska
   pod spodem. Licznik po prawej mowi, ile juz zaznaczono, wiec nie trzeba
   otwierac, zeby to sprawdzic. */
.spgrp--zw{margin-top:18px}
.spgrp--zw>summary{display:flex;align-items:center;gap:9px;cursor:pointer;list-style:none;
  padding-bottom:7px;margin-bottom:0;border-bottom:1px solid var(--hair);
  font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--navy)}
.spgrp--zw>summary::-webkit-details-marker{display:none}
/* Znacznik rysowany sami, bo natywny trojkat siedzi w innym miejscu w kazdej
   przegladarce i lamie rytm etykiet. */
.spgrp--zw>summary::before{content:"";width:6px;height:6px;flex:none;margin-right:1px;
  border-right:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:rotate(-45deg) translate(-1px,1px);opacity:.6;
  transition:transform var(--t) var(--ease)}
.spgrp--zw[open]>summary::before{transform:rotate(45deg) translate(-2px,-2px)}
.spgrp--zw>summary:hover{color:var(--accent-dark)}
.spgrp--zw>summary:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.spgrp__n{margin-left:auto;font-size:11px;font-weight:700;letter-spacing:0;
  font-variant-numeric:tabular-nums;color:var(--accent-dark);
  background:var(--blue-soft);border-radius:999px;padding:1px 8px}
.spgrp--zw>.two{margin-top:11px}
@media(prefers-reduced-motion:reduce){.spgrp--zw>summary::before{transition:none}}

/* ── Dane firmy w rejestracji ────────────────────────────────────────────────
   Wydzielone tlem, bo to nie sa kolejne pola tego samego formularza, tylko drugi
   komplet, ktory dotyczy polowy zakladajacych konto. */
.regf{background:var(--canvas);border-radius:var(--r-lg);padding:14px 15px;
  display:grid;gap:13px;box-shadow:inset 0 0 0 1px var(--line)}
.regf__h{font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
  color:var(--navy);margin:0}
.regf__d{font-size:12.5px;line-height:1.5;color:var(--muted);margin:-7px 0 0}

/* Wiersz "Haslo" w ustawieniach: opis po lewej, akcja po prawej. */
/* Wiersz stoi POD formularzem danych osobowych, wewnatrz tej samej karty, wiec
   potrzebuje wlasnego oddechu z obu stron - inaczej przycisk "Zmien haslo" cisnie
   sie do przycisku "Zapisz zmiany" nad nim i wygladaja jak para. */
.ustpwd{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  margin-top:20px;padding-top:18px;border-top:1px solid var(--hair)}
.ustpwd b{display:block;font-size:13.5px;font-weight:700;color:var(--navy)}
.ustpwd span{display:block;font-size:12.5px;color:var(--muted);margin-top:2px}
.ustpwd .btn{flex:none}
@media(max-width:520px){.ustpwd .btn{width:100%}}

/* ── Trzy klasy, ktore nigdy nie mialy regul ─────────────────────────────────
   Znalazl je test gielda-css-uzycie, nie oko: renderowaly sie stylem domyslnym
   przegladarki, wiec nie wygladaly na zepsute - po prostu na nijakie. */

/* Podpis przy naglowku polki ("Ogloszenia z oplaconym wyroznieniem"). Stoi w
   jednym wierszu z tytulem, wiec musi byc wyraznie cichszy - inaczej czyta sie
   jak druga czesc naglowka. */
.sec-h__d{font-family:"Inter",sans-serif;font-size:12.5px;font-weight:500;
  letter-spacing:0;color:var(--faint);margin-left:2px}
@media(max-width:600px){.sec-h__d{display:none}}

/* Wejscie w panel z szuflady mobilnej. Link pod nazwiskiem, wiec dostaje
   akcentowy kolor i strzalke wyrownana do tekstu. */
.drawer__me{display:inline-flex;align-items:center;gap:5px;margin-top:2px;
  font-size:12.5px;font-weight:700;color:var(--accent-dark);text-decoration:none}
.drawer__me:hover{text-decoration:underline}
.drawer__me .ic{flex:none}

/* Stopka panelu negocjacji: zdanie o tym, co jeszcze mozna zrobic, po tym jak
   akcje sie skonczyly. Ton jak przypis, nie jak kolejna akcja. */
.offerp__foot{margin:10px 0 0;font-size:12.5px;line-height:1.55;color:var(--muted)}
.offerp__foot a{color:var(--accent-dark);font-weight:600}
.offerp__foot a:hover{text-decoration:underline}

/* Skrot nad dokumentem prawnym. */
.lgtl{background:var(--blue-soft);border-radius:var(--r-lg);padding:18px 20px;margin:0 0 22px}
.lgtl>b{display:block;font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:var(--accent-dark);margin-bottom:7px}
.lgtl>p{font-size:14.5px;line-height:1.6;color:var(--navy);margin:0 0 14px;max-width:62ch}
.lgtl__g{display:flex;flex-wrap:wrap;gap:8px}
.lgtl__i{display:inline-flex;align-items:baseline;gap:7px;background:#fff;border-radius:999px;
  padding:7px 14px;font-size:12.5px;color:var(--muted)}
.lgtl__i b{font-family:"Archivo",sans-serif;font-size:13.5px;font-weight:800;color:var(--navy)}

.foot{max-width:1280px;margin:0 auto;padding:52px 24px 40px;display:grid;gap:40px 36px;grid-template-columns:1.6fr 1fr 1fr 1fr}
.foot h4{font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.1em;color:var(--navy);padding-bottom:9px;margin-bottom:5px;border-bottom:1px solid var(--line)}
.foot a{display:block;font-size:14px;color:var(--muted);padding:6px 0;transition:color var(--t) var(--ease)}
.foot a:hover{color:var(--accent-dark);text-decoration:underline}
.foot__brand img{height:40px;margin-bottom:14px}
.foot__brand p{font-size:14px;line-height:1.65;color:var(--muted);max-width:330px}
.foot__bar{border-top:1px solid var(--line)}
.foot__bar div{max-width:1280px;margin:0 auto;padding:16px 24px;display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px;font-size:12.5px;color:var(--faint)}

/* toast */
.toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%) translateY(120%);background:var(--navy);color:#fff;font-size:13.5px;font-weight:600;padding:11px 18px;border-radius:var(--r);box-shadow:0 10px 30px rgba(8,28,64,.4);z-index:90;opacity:0;transition:transform .25s,opacity .25s;max-width:90vw;text-align:center}
.toast.show{transform:translateX(-50%) translateY(0);opacity:1}

/* responsive */
@media(max-width:860px){
  /* Uklad jak w aplikacji portalu: logo fizycznie na srodku ekranu, szukajka po
     lewej, jedna okragla akcja po prawej. Grid 1fr auto 1fr trzyma logo w osi
     niezaleznie od tego, jak szerocy sa sasiedzi; flex z margin-left:auto tego
     nie potrafi, bo srodek zalezy wtedy od szerokosci obu stron. */
  .masthead__top{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:12px;padding-bottom:14px}
  .logo{grid-column:2;justify-self:center}
  .logo img{height:29px;width:155px}
  .logo__tag{font-size:8.5px;left:41%;letter-spacing:.04em}
  .nbsearch{grid-column:1;justify-self:start;flex:0 0 auto;width:176px;max-width:100%;margin:0}
  /* Ponizej 16px iOS Safari sam przybliza strone przy wejsciu w pole. */
  .nbsearch input{font-size:16px}
  .acts{grid-column:3;justify-self:end;margin-left:0}
  /* Prawa strona nie znika w calosci jak dotad: zostaje jeden okragly przycisk
     konta albo logowania, reszta ikon ma swoje wejscia w dolnym pasku. */
  .acts--d{display:flex;align-items:center;gap:8px}
  .acts--d .acts__ic{display:none}
  .acts--d .pill--n{display:none}
  .pill--w{padding:0;width:42px;justify-content:center}
  .pill--w span{display:none}
  .acct{padding:0;width:42px;height:42px;justify-content:center}
  /* Na waskim ekranie chowamy sam daszek, nie wszystko: `.acct svg` zabieralo
     razem z nim logo z kolka i zostawialo pusty granatowy krazek. */
  .acct>svg{display:none}
  /* Hamburger i szuflada dublowaly teraz arkusz "Wiecej" z dolnego paska. */
  .burger{display:none}
  .mainnav{display:none}
  .site-header{width:100%;border-radius:0}
  /* clip-path na ::before ma wpisany na sztywno promien dolnych rogow, wiec przy
     border-radius:0 rozjezdzal sie z ::after, ktory dziedziczy 0: kwadratowy
     gradient wystawal poza zaokraglone zdjecie i w dolnych rogach paska widac
     bylo krawedzie tla. Na telefonie wycinek tez musi byc kwadratowy. */
  .site-header::before{clip-path:inset(60px)}
  .layout{grid-template-columns:1fr;gap:20px}
  .side{display:none}
  /* single column, and the head leads: title, price and the two actions before
     the gallery, which is the order a classified is actually read on a phone */
  .dt{grid-template-columns:1fr;grid-template-areas:"head" "main" "side";gap:16px}
  .foot{grid-template-columns:1fr 1fr}
}
@media(min-width:861px){.burger{display:none}}
@media(max-width:760px){
  .res-h{align-items:flex-start}
  .res-h__tools{width:100%;justify-content:space-between}
  .sort span{display:none}
  .thread{padding:18px 16px 36px}
  .pstats{grid-template-columns:1fr 1fr}
  .pstat:nth-child(3){border-left:0}
  .pstat:nth-child(n+3){border-top:1px solid var(--line)}
}
@media(max-width:560px){
  .foot{grid-template-columns:1fr}
  /* a scroll rail, not a wrapping block: flex:1 on four pills inside a wrapping
     container stacked them two-deep and made the header card 221px tall, a
     quarter of the screen before the first listing */
  /* min-width:0 the whole way down, or the scroll rail sizes to its content and
     pushes the page wide instead of scrolling inside itself: a flex item's
     default min-width:auto refuses to shrink below min-content */
  .res-h__tools{min-width:0}
  .sort{flex:1;min-width:0}
  /* Poziome przewijanie ratowalo rzad czterech pigulek; select miesci sie sam. */
  .sort .nsel{flex:1;min-width:0;width:100%}
  .dt-acts{grid-template-columns:1fr}
  .void__cta .btn,.pform-go .btn{width:100%}
  .vfix{flex-wrap:wrap;gap:4px}
}

/* ── brand ── */
.logo{display:inline-flex;align-items:center;gap:10px}

/* ── onboarding — the same left-rule idiom as every other advisory object ── */
.welc,.pubok{position:relative;border-radius:var(--r);padding:17px 46px 17px 20px;margin-top:22px}
.welc{background:var(--blue-soft);box-shadow:inset 3px 0 0 var(--accent)}
.pubok{background:var(--green-bg);box-shadow:inset 3px 0 0 var(--green);margin:22px 0 0}
/* Zwykla biala karta (.box daje tlo, promien i padding), a tutaj tylko to, co
   dodaje sam kafelek rad: miejsce na przycisk zamkniecia po prawej i odstep
   od formularza pod spodem. Niebieskie tlo i akcentowa kreska z boku odpadly:
   byl to jedyny taki element na stronie i czytal sie jak komunikat systemu. */
.hintbox{position:relative;padding-right:46px;margin:22px 0 18px}
.welc b,.pubok b{display:block;font-family:"Archivo",sans-serif;font-size:16px;letter-spacing:-.015em;color:var(--navy);margin-bottom:5px}
.welc p,.pubok p{font-size:13.5px;color:var(--ink);line-height:1.6;max-width:70ch}
.hintbox ul{margin:0 0 0 18px;font-size:13.5px;color:var(--ink);line-height:1.65}
.hintbox .box__h{margin-bottom:12px}
.welc__cta{display:flex;flex-wrap:wrap;gap:10px;margin-top:12px}
.welc__cta .btn{height:38px;font-size:13.5px;padding:0 14px}
.welc__x{position:absolute;top:8px;right:8px;width:30px;height:30px;display:grid;place-items:center;border:0;border-radius:999px;background:none;font-size:20px;line-height:1;color:var(--muted);cursor:pointer;transition:background-color var(--t) var(--ease),color var(--t) var(--ease)}
.welc__x:hover{color:var(--red);background:rgba(193,31,18,.09)}
.startm{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:90;width:min(460px,calc(100vw - 32px));background:#fff;border-radius:var(--r);box-shadow:0 24px 60px -12px rgba(8,28,64,.5);padding:24px}
.startm>b{display:block;font-family:"Archivo",sans-serif;font-size:19px;color:var(--navy)}
.startm>p{font-size:13.5px;color:var(--muted);margin:4px 0 14px}
.startm__t{display:block;border:1.5px solid var(--line);border-radius:var(--r);padding:12px 14px;margin-bottom:9px;transition:border-color .15s,background .15s}
.startm__t:hover{border-color:var(--bar);background:var(--blue-soft)}
.startm__t b{display:block;font-size:14.5px;color:var(--navy)}
.startm__t span{font-size:12.5px;color:var(--muted)}
.startm__skip{display:block;width:100%;border:0;background:none;font-size:13px;font-weight:600;color:var(--muted);padding:8px 0 0;cursor:pointer}
.startm__skip:hover{color:var(--navy)}
.retnote{background:var(--green-bg);border:1px solid var(--green-bd);border-radius:var(--r);font-size:12.5px;color:var(--green);font-weight:600;padding:8px 12px;margin-bottom:12px}
.rodo{font-size:11.5px;color:var(--faint);text-align:center;line-height:1.5}
.rodo a{color:var(--accent)}

/* ── trust / detail meta ── */
/* .safe rides on .box now, so the surface rule that used to repeat .box is gone
   and the heading is a real <h2 class="box__h"> like every other card. What is
   left here is only what is genuinely particular to this card. */
/* A checklist, not a bulleted paragraph: the marker is a check in the brand
   green and the text hangs in its own column, so three rules read as three
   rules. list-style is dropped because the glyph IS the marker. */
.safe__l{list-style:none;margin:0;padding:0;display:grid;gap:9px}
.safe__l li{display:flex;align-items:flex-start;gap:9px;font-size:13px;line-height:1.5;color:var(--muted)}
.safe__l svg{flex:none;margin-top:1px;color:var(--green)}
/* the card's one action, on its own row under a hairline rather than trailing
   the list as a muted underline */
.safe__rep{display:flex;align-items:center;gap:8px;margin-top:14px;padding-top:13px;
  border-top:1px solid var(--line);font-size:12.5px;font-weight:700;
  color:var(--muted);text-decoration:none}
.safe__rep svg{flex:none;color:var(--faint)}
.safe__rep:hover{color:var(--red)}
.safe__rep:hover svg{color:var(--red)}
.vbadge{display:inline-flex;align-items:center;gap:3px;font-size:10.5px;font-weight:800;text-transform:uppercase;letter-spacing:.03em;color:var(--green);background:var(--green-bg);border:1px solid var(--green-bd);border-radius:999px;padding:1px 7px;vertical-align:2px;margin-left:4px}
.dtmeta{font-size:11.5px;color:var(--faint);margin:10px 0 12px;padding-top:10px;border-top:1px solid var(--line)}

/* ── numbered process steps — ruled entries, not stacked boxes ── */
/* KROKI JAKO KARTY, nie jako lista wierszy rozdzielonych kreskami.
   Wczesniej piec krokow bylo piecioma akapitami jeden pod drugim w waskiej
   kolumnie - czytalo sie to jak ciagly tekst i nie dawalo omiesc wzrokiem, a
   to jest strona, po ktorej sie skacze. Karta z numerem w kolku odklada kazdy
   krok osobno i pozwala ustawic je w dwa albo trzy rzedy. */
.steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(270px,1fr));gap:12px;margin:6px 0 4px}
.step{display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:14px;align-items:start;
  background:#fff;border-radius:var(--r-lg);padding:17px 18px 18px;
  box-shadow:inset 0 0 0 1px var(--line);
  transition:box-shadow var(--t) var(--ease)}
.step:hover{box-shadow:inset 0 0 0 1px var(--accent)}
.step__n{display:grid;place-items:center;width:30px;height:30px;border-radius:999px;
  background:var(--blue-soft);color:var(--accent-dark);
  font-family:"Archivo",sans-serif;font-size:14px;font-weight:800;line-height:1;
  font-variant-numeric:tabular-nums}
.step__b b{display:block;font-family:"Archivo",sans-serif;font-size:15.5px;font-weight:800;letter-spacing:-.018em;color:var(--navy);line-height:1.3;padding-top:5px}
.step__b p{margin-top:6px;font-size:13.5px;line-height:1.6;color:var(--muted)}
@media(max-width:560px){.steps{grid-template-columns:1fr}}

/* ── legal pages ── */
.lgwrap{font-size:14px;line-height:1.65;color:var(--ink)}
.lg-h2{font-size:15.5px;font-weight:800;color:var(--navy);margin:22px 0 8px}
.lgwrap ol.lg,.lgwrap ul.lg{margin:0 0 4px 20px;display:grid;gap:7px}
.lg-p{margin-bottom:4px}
.lgwrap a{color:var(--accent-dark);font-weight:600}
.lgwrap a:hover{text-decoration:underline}
.lgnav{display:flex;flex-wrap:wrap;align-items:center;gap:0 6px;margin:30px 0 8px;padding-top:16px;border-top:1px solid var(--line);font-size:13px}
.lgnav .backlink{margin:0 10px 0 0}
.lgnav span{color:var(--faint)}
.authback{text-align:center;margin-top:16px}
.authback .backlink{margin:0;color:var(--muted);font-weight:600}
.authback .backlink:hover{color:var(--navy)}

/* ── mobile filter sheet ── */
.fbtn{display:none;align-items:center;gap:7px;height:36px;padding:0 14px;border:1.5px solid var(--navy);border-radius:999px;background:#fff;color:var(--navy);font-size:13px;font-weight:700;font-family:inherit;cursor:pointer}
.side__x{display:none;position:absolute;top:14px;right:14px;width:38px;height:38px;border:0;border-radius:999px;background:var(--canvas);color:var(--navy);cursor:pointer;place-items:center}
@media(max-width:860px){
  .fbtn{display:inline-flex}
  .side.open{display:block;position:fixed;inset:0;z-index:85;overflow:auto;background:#fff;padding:20px 20px 40px;border:0}
  .side.open .side__x{display:grid}
}

/* ── user panel ── */
/* `minmax(0,1fr)`, nie `1fr`. Samo `1fr` znaczy `minmax(auto,1fr)`, czyli tor NIE
   zwezi sie ponizej min-content swojej zawartosci - a kolumna tresci panelu miala
   min-content 353 px. Przy oknie 360 px rozpychalo to caly dokument do 377 px i
   panel jako jedyny widok jechal bokiem. */
.playout{display:grid;grid-template-columns:232px minmax(0,1fr);gap:28px;margin-top:24px;align-items:start}
/* Odstep od naglowka liczony ze ZMIENNEJ, nie wpisany z palca. Naglowek ma
   ~115px i rosnie, gdy etykiety w pasku kategorii sie zawijaja; sztywne 130px
   dzialalo dopoki nie urosl, a potem pasek konta wchodzil pod niego. */
/* Kolumna to teraz stos kart, nie jedna plansza z kreska u gory. */
.pside{padding:0;border:0;background:none;border-top:0;
  position:sticky;top:calc(var(--gw-navh,115px) + 18px);
  display:grid;gap:10px;align-content:start}
.pcard{padding:0;overflow:hidden}
/* Karta tozsamosci. Nazwa, adres i typ konta jedno pod drugim - typ jest tu
   informacja, nie ozdoba: od niego zalezy, czy kupujacego chroni rekojmia. */
.pside__me{display:flex;align-items:center;gap:12px;padding:14px}
.pside__id{min-width:0;display:flex;flex-direction:column;gap:1px}
.pside__id b{font-size:14px;font-weight:700;color:var(--navy);line-height:1.25;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pside__mail{font-size:12px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pside__typ{margin-top:4px;align-self:flex-start;padding:1px 8px;border-radius:999px;
  font-size:10.5px;font-weight:700;letter-spacing:.02em;
  background:var(--canvas);color:var(--muted);box-shadow:inset 0 0 0 1px var(--line)}
.pside__typ.is-firma{background:var(--blue-soft);color:var(--accent-dark);
  box-shadow:inset 0 0 0 1px var(--accent)}

/* Karta nawigacji: pozycje na calej szerokosci karty, przycisk na dole oddzielony
   kreska - jest akcja, a nie kolejnym miejscem, do ktorego sie przechodzi. */
.pcard--nav{padding:6px}
.pnav__add{margin:8px 0 2px;width:100%;height:40px;font-size:13.5px}
.pnav{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:var(--r);font-size:14px;font-weight:600;color:var(--ink);transition:background-color var(--t) var(--ease),color var(--t) var(--ease),box-shadow var(--t) var(--ease)}
.pnav svg{color:var(--faint);flex:none;transition:color var(--t) var(--ease)}
.pnav:hover{background:var(--canvas);color:var(--navy)}
.pnav:hover svg{color:var(--muted)}
/* one active recipe across the product: filled tint, accent text, weight 700,
   no inset edge bar. The results rail migrated already (.side a.cl.on,
   .fset .frow.on); these were the surfaces left behind. */
.pnav.on{background:var(--blue-soft);color:var(--accent-dark);font-weight:700;box-shadow:none}
.pnav.on:hover{background:#dceafa}
.pnav.on svg{color:var(--accent)}
.pnav__c{margin-left:auto;min-width:20px;height:20px;padding:0 6px;display:grid;place-items:center;border-radius:999px;background:var(--canvas);color:var(--muted);font-size:11px;font-weight:700;font-variant-numeric:tabular-nums}
.pnav.on .pnav__c{background:var(--accent);color:#fff}
.ph1{font-family:"Archivo",sans-serif;font-size:clamp(22px,2.8vw,28px);font-weight:800;letter-spacing:-.024em;line-height:1.14;color:var(--navy);margin-bottom:4px}
.ph2{font-family:"Archivo",sans-serif;font-size:16px;font-weight:800;letter-spacing:-.015em;color:var(--navy);margin:30px 0 12px;padding-bottom:9px;border-bottom:1px solid var(--line)}
.psub{font-size:14px;color:var(--muted);margin-bottom:20px;max-width:56ch}
/* the four counters read as one instrument row: hairline-divided, numbers set in
   Archivo tabular so they line up down the row */
/* Tyle kolumn, ile kafli - nie cztery na sztywno. Kafli sa trzy, wiec czwarta
   kolumna zostawala pusta i rzad konczyl sie w trzech czwartych szerokosci.
   auto-fit z minimum 150 px zwija je tez sam na waskim ekranie. */
.pstats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:0;border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
/* Ostatni slad po definicji kafla sprzed przebudowy na siatke. Stala TU, czyli
   nizej niz nowa, wiec `display:block` wygrywalo z `display:grid`, `.pstat span`
   trafialo takze w kolko ikony, a `.pstat b` bilo `.pstat__n` - kafel skladal sie
   w slupek zamiast stanac w dwie kolumny. Wyglad kafla jest teraz w JEDNYM
   miejscu, przy `.pstat__ic`; tutaj zostaja tylko te dwie reguly, ktore mowia o
   kaflu jako calosci i nie maja odpowiednika wyzej. */
.pstat+.pstat{border-left:1px solid var(--line)}
.pstat:hover{background:var(--canvas);box-shadow:inset 3px 0 0 var(--accent)}
/* my-listing card: the action bar is the same object continued, so the card's
   bottom corners open into it rather than the bar being bolted underneath */
.mycard{display:flex;flex-direction:column}
.mycard .card{flex:1;border-radius:var(--r-lg) var(--r-lg) 0 0}
.mycard__bar{display:flex;border:1px solid var(--line);border-top:0;border-radius:0 0 var(--r) var(--r);background:var(--canvas);overflow:hidden}
.mycard__a{flex:1;border:0;background:none;padding:10px 6px;font-size:12px;font-weight:700;color:var(--navy);cursor:pointer;transition:background-color var(--t) var(--ease),color var(--t) var(--ease)}
.mycard__a+.mycard__a{border-left:1px solid var(--line)}
.mycard__a:hover{background:#fff;color:var(--accent-dark)}
.mycard__a--del{color:var(--red)}
.mycard__a--del:hover{color:var(--red);background:var(--red-bg)}
@media(max-width:860px){
  .playout{grid-template-columns:minmax(0,1fr);gap:16px}
  .pside{position:static;display:block}
  .pstats{grid-template-columns:1fr 1fr}
}

/* ── photo picker ── */
.ph{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
.ph__t{position:relative;aspect-ratio:4/3;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:var(--canvas)}
.ph__t img{width:100%;height:100%;object-fit:cover}
.ph__cov{position:absolute;left:0;bottom:0;background:rgba(8,28,64,.78);color:#fff;font-size:10px;font-weight:700;padding:2px 7px;border-top-right-radius:var(--r)}
.ph__x{position:absolute;top:5px;right:5px;width:28px;height:28px;border:0;border-radius:999px;background:rgba(8,28,64,.72);color:#fff;font-size:15px;line-height:1;display:grid;place-items:center;cursor:pointer;transition:background-color var(--t) var(--ease)}
/* Wylaczony krzyzyk: zdjecie jest juz na serwerze, a API nie ma jeszcze koncewki
   do kasowania. Zostaje widoczny, zeby uklad kafelka sie nie zmienial, ale nie
   udaje klikalnego - kursor i przezroczystosc mowia to samo, co atrybut. */
.ph__x--off{opacity:.4;cursor:not-allowed}
.ph__x--off:hover{background:rgba(8,28,64,.55)}
.ph__x:hover{background:var(--red)}
.ph__add{aspect-ratio:4/3;border:1.5px dashed #c3ccd8;border-radius:var(--r);background:var(--canvas);color:var(--muted);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;font-size:12px;font-weight:700;cursor:pointer;transition:border-color .15s,color .15s}
.ph__add:hover{border-color:var(--accent);color:var(--accent)}
@media(max-width:520px){.ph{grid-template-columns:repeat(2,1fr)}}

/* ── notifications ── */
.ntf{position:fixed;right:24px;top:100px;width:340px;max-width:calc(100vw - 24px);background:#fff;border:1px solid var(--line);border-radius:var(--r);box-shadow:0 16px 40px -12px rgba(10,37,64,.5);padding:6px;z-index:75;animation:menuIn .14s ease}
.ntf__h{display:flex;align-items:center;justify-content:space-between;padding:8px 12px 8px;border-bottom:1px solid var(--line);margin-bottom:4px}
.ntf__h b{font-family:"Archivo",sans-serif;font-size:14px;color:var(--navy)}
.ntf__h button{border:0;background:none;font-size:12px;font-weight:700;color:var(--muted);cursor:pointer}
.ntf__h button:hover{color:var(--red)}
.ntf__row{display:flex;gap:10px;align-items:flex-start;padding:9px 10px;border-radius:var(--r)}
.ntf__row:hover{background:var(--canvas)}
.ntf__row--new{background:var(--blue-soft)}
.ntf__row--new:hover{background:#dceaf8}
.ntf__ic{flex:none;width:28px;height:28px;border-radius:999px;display:grid;place-items:center;margin-top:1px}
.ntf__ic--offer{background:var(--amber-bg);color:var(--amber)}
.ntf__ic--msg{background:var(--blue-soft);color:var(--accent)}
.ntf__ic--price{background:var(--green-bg);color:var(--green)}
.ntf__ic--sys{background:var(--canvas);color:var(--muted)}
.ntf__b{min-width:0}
.ntf__t{display:block;font-size:12.5px;font-weight:600;color:var(--ink);line-height:1.4}
.ntf__b small{font-size:11px;color:var(--faint)}
.ntf__empty{padding:18px 12px;text-align:center;font-size:13px;color:var(--faint)}
.ntf__all{display:block;text-align:center;padding:9px;font-size:12.5px;font-weight:700;color:var(--accent);border-top:1px solid var(--line);margin-top:4px}

/* ── saved searches + seller page ── */
.ssbtn{display:inline-flex;align-items:center;gap:7px;height:36px;padding:0 14px;border:1.5px solid var(--accent);border-radius:999px;background:#fff;color:var(--accent);font-size:13px;font-weight:700;font-family:inherit;cursor:pointer;transition:background .15s,color .15s}
.ssbtn:hover{background:var(--blue-soft)}
.ssbtn.on{background:var(--accent);color:#fff}
.ssrow{display:flex;align-items:center;gap:8px;padding:4px 6px}
.ssrow a{flex:1;display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:var(--r);font-size:13.5px;font-weight:600;color:var(--ink);min-width:0}
.ssrow a svg{color:var(--faint);flex:none}
.ssrow a span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ssrow a:hover{background:var(--canvas);color:var(--accent-dark)}
.ssrow button{flex:none;width:30px;height:30px;border:0;border-radius:999px;background:none;color:var(--faint);font-size:17px;line-height:1;cursor:pointer;transition:background-color var(--t) var(--ease),color var(--t) var(--ease)}
.ssrow button:hover{background:var(--red-bg);color:var(--red)}
.ntf__ic--search{background:var(--blue-soft);color:var(--accent)}
.sellhead{display:flex;align-items:center;gap:16px;margin-top:14px}

/* ── reviews / stars ── */
.stars{position:relative;display:inline-block;line-height:0}
.stars svg{display:inline-block;vertical-align:top}
.stars__bg{color:#dfe4ea}
.stars__bg svg,.stars__fg svg{fill:currentColor}
.stars__fg{position:absolute;left:0;top:0;overflow:hidden;white-space:nowrap;color:var(--star)}
.stars--in{display:flex;gap:2px;margin:8px 0 10px}
.stars--in button{border:0;background:none;padding:0;color:#dfe4ea;cursor:pointer}
.stars--in button svg{fill:currentColor}
.stars--in button.on{color:var(--star)}
.ratebox{margin-top:14px;padding-top:14px;border-top:1px solid var(--line)}
.ratebox b{display:block;font-family:"Archivo",sans-serif;font-size:14px;color:var(--navy);margin-bottom:2px}
.ratebox textarea{width:100%;border:1.5px solid var(--line);border-radius:var(--r);padding:8px 12px;font-size:13.5px;font-family:inherit;outline:none;resize:none;margin-bottom:10px}
.ratebox textarea:focus{border-color:var(--accent)}
.revrow{padding:12px;border-bottom:1px solid var(--hair)}
.revrow:last-child{border-bottom:0}
.revrow__h{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--navy)}
.revrow__h small{color:var(--faint);font-size:11.5px}
.revrow p{font-size:13px;color:var(--muted);margin-top:4px}
.ntf__ic--star{background:var(--amber-bg);color:var(--amber)}

/* ── promotions ── */
.promos{display:grid;gap:10px;margin-bottom:14px}
.promo{display:flex;align-items:center;gap:12px;border:1.5px solid var(--line);border-radius:var(--r);padding:13px 15px;cursor:pointer;transition:border-color .15s,background .15s}
.promo:hover{border-color:#c3ccd8}
.promo:has(input:checked){border-color:var(--bar);background:var(--blue-soft)}
.promo input{accent-color:var(--bar);width:16px;height:16px;flex:none}
.promo__b{flex:1;min-width:0}
.promo__b b{display:block;font-family:"Archivo",sans-serif;font-size:14.5px;color:var(--navy)}
.promo__b span{font-size:12.5px;color:var(--muted)}
.promo__p{flex:none;font-family:"Archivo",sans-serif;font-weight:800;font-size:16px;font-variant-numeric:tabular-nums;color:var(--bar)}
/* Wariant do obejrzenia, nie do kupienia: karta zachowuje uklad i cene, traci
   kursor i podswietlenie. Tlo zostaje biale - szare czytaloby sie jak ladowanie. */
.promo--off{cursor:default;border-style:dashed}
.promo--off:hover{border-color:var(--line);background:#fff}
.promo--off .promo__p{color:var(--faint)}
.paybox{border:1px dashed #c3ccd8;border-radius:var(--r);padding:13px 15px;background:var(--canvas)}
.paybox b{font-family:"Archivo",sans-serif;font-size:13px;color:var(--navy)}
.paybox__grid{display:flex;gap:8px;margin:8px 0}
.paybox__grid input{flex:1;height:36px;border:1px solid var(--line);border-radius:var(--r);padding:0 10px;font-size:13px;color:var(--muted);background:#fff;font-family:inherit}
.paybox p{font-size:11.5px;color:var(--faint)}
.mycard__a--pro{color:var(--amber)}
.mycard__a--pro:hover{background:var(--amber-bg);color:var(--amber)}

/* ── comparison ── */
.cmpbar{position:fixed;left:0;right:0;bottom:0;z-index:55;background:var(--navy);box-shadow:0 -6px 20px -8px rgba(8,28,64,.5)}
.cmpbar__in{max-width:1280px;margin:0 auto;padding:9px 24px;display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.cmpbar__items{display:flex;gap:8px;flex:1;min-width:0}
.cmpbar__t{position:relative;flex:none}
.cmpbar__m{width:56px;height:42px;border-radius:var(--r);overflow:hidden;border:2px solid rgba(255,255,255,.25);background:var(--navy-soft)}
.cmpbar__m img{width:100%;height:100%;object-fit:cover;border-radius:0}
.cmpbar__t button{position:absolute;top:-7px;right:-7px;width:24px;height:24px;border:1.5px solid var(--navy);border-radius:999px;background:var(--red);color:#fff;font-size:13px;line-height:1;display:grid;place-items:center;cursor:pointer}
.cmpbar__hint{font-size:12.5px;color:rgba(255,255,255,.75);font-weight:600}
.cmpbar__clr{border:0;background:none;color:rgba(255,255,255,.65);font-size:12.5px;font-weight:700;cursor:pointer}
.cmpbar__clr:hover{color:#fff}
body:has(.cmpbar) footer{padding-bottom:64px}
.cmpwrap{overflow-x:auto;border:1px solid var(--line);background:#fff}
.cmptable{border-collapse:collapse;width:100%;min-width:560px;font-size:13.5px}
.cmptable th,.cmptable td{padding:11px 14px;border-bottom:1px solid var(--hair);text-align:left;vertical-align:top}
.cmptable thead th,.cmptable thead td{border-bottom:1px solid var(--line);background:var(--canvas)}
.cmptable tbody th{position:sticky;left:0;background:#fff;font-size:11.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--faint);font-weight:700;white-space:nowrap;width:1%}
.cmptable td{min-width:150px}
.cmptable td.best b{color:var(--green)}
.cmptable td.best{background:var(--green-bg)}
.cmptable td.best b{color:var(--green);font-weight:800}
.cmpc{position:relative}
.cmpc__m{width:130px;height:88px;margin-bottom:6px;border-radius:var(--r);overflow:hidden;background:var(--canvas)}
.cmpc__m img{width:100%;height:100%;object-fit:cover;border-radius:0}
.cmpc b{display:block;font-size:13px;color:var(--navy);line-height:1.3;max-width:180px}
.cmpc a:hover b{color:var(--accent)}
.cmpc__x{position:absolute;top:4px;right:4px;width:28px;height:28px;border:0;border-radius:999px;background:#fff;color:var(--muted);font-size:15px;line-height:1;display:grid;place-items:center;cursor:pointer;box-shadow:0 1px 4px rgba(10,37,64,.25);transition:color var(--t) var(--ease),background-color var(--t) var(--ease)}
.cmpc__x:hover{color:var(--red)}

/* ── reduced motion — global backstop ──────────────────────────────────────
   Every component already degrades individually; this catches anything added
   later, plus html{scroll-behavior:smooth} and the two keyframe animations,
   which were the only motion in the file not covered by a local rule. */
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important;
  }
}

/* compare table: a missing spec is stated, not left as an unreadable dash */
.cmp-na{font-size:12.5px;font-style:italic;color:var(--faint)}

/* ── Messages: two columns ────────────────────────────────────────────────────
   Conversations left, the open thread right, the way OLX and every mail client
   do it. Both panes were full-width pages before, so opening a second thread
   meant navigating back to a list that was no longer on screen. The thread
   views still emit their own .wrap, so it is neutralised here rather than
   rewriting four view functions. */
.msg-wrap{max-width:1180px}
/* 300px, nie 340: lista rozmow siedzi teraz w kolumnie tresci konta, a nie na
   pelnej szerokosci strony, wiec przed nia stoi jeszcze pasek nawigacyjny. */
.msg{display:grid;grid-template-columns:300px minmax(0,1fr);gap:16px;align-items:start}
/* Trzy kolumny mieszcza sie do 1180px; nizej watek schodzi pod liste. */
@media(max-width:1180px){.msg{grid-template-columns:1fr}.msg__list{position:static;max-height:none}}
.msg__list{min-width:0;position:sticky;top:96px;max-height:calc(100vh - 120px);overflow:auto}
/* Wiersze maja kwadratowe rogi i wlasne tlo, a .box nie przycinal zawartosci,
   wiec przy jednej rozmowie aktywny wiersz zamalowywal cala biala plyte i jego
   kanty wystawaly poza jej promien — lista przestawala wygladac na karte. */
.msg__list .box{overflow:hidden}
/* Otwarta rozmowa zostaje zwyklą białą kartą: niebieskie tło i pasek akcentu
   robily z niej inny obiekt niz reszta powierzchni w serwisie. Ktora rozmowa
   jest otwarta, widac po watku obok. */
.msg__list .list-row.on{background:#fff}
.msg__pane{min-width:0}
.msg__pane>.wrap{max-width:none;padding:0}
.msg__none{background:#fff;border-radius:var(--r-lg);padding:48px 24px}
/* .void is shared with a dozen views and brings a 2px navy rule with it. On a
   surface of its own that rule is a stray line across the pane, so it is
   neutralised here exactly as it is on the empty watchlist card. */
.msg__none .void{border-top:0;padding:0;max-width:56ch;margin:0 auto}
@media(max-width:1040px){
  /* the pane gets cramped before the layout actually breaks, so the list gives
     up width first rather than disappearing */
  .msg{grid-template-columns:270px minmax(0,1fr)}
}
@media(max-width:700px){
  /* only now is there genuinely no room for two columns: the open thread wins
     and the list returns when none is open */
  .msg{grid-template-columns:minmax(0,1fr)}
  .msg__list{position:static;max-height:none}
  .msg--open .msg__list{display:none}
}

/* ── Obserwowane ──────────────────────────────────────────────────────────────
   Sold entries keep their place on the list but stop competing with the ones
   still for sale: same card, dimmed, under a quieter heading. */
.favgone{margin-top:26px}
.favgone .sec-h{color:var(--muted)}
.favgone .card{opacity:.62;transition:opacity var(--t) var(--ease)}
.favgone .card:hover,.favgone .card:focus-within{opacity:1}
.favss{padding:6px}
.favnote{font-size:13px;color:var(--faint);margin-top:26px;max-width:65ch}
/* The empty watchlist is a card like everything else on the page. .void is shared
   with a dozen other views, so it is neutralised here instead of restyled: no top
   rule and no double padding when it sits on a surface of its own. */
.favempty{padding:28px 24px 26px}
.favempty .void{border-top:0;padding:0;max-width:56ch}
.favnote--in{margin-top:18px;padding-top:16px;border-top:1px solid var(--line)}

/* ── Cena: tryb, negocjacje, dostawa ─────────────────────────────────────
   Trzy jednakowe checkboxy w jednym szarym pudełku sugerowały trzy równorzędne,
   niezależne pytania. Tylko jedno z nich takie było. Podanie kwoty i „cena do
   ustalenia" wykluczają się, więc dostają segment: forma kontrolki mówi, że
   wybiera się jedno z dwóch, zanim ktokolwiek przeczyta etykiety. */
/* justify-self, bo ciało sekcji formularza to grid — sam inline-flex rozciąga
   się tam na całą kolumnę i segment przestaje wyglądać jak przełącznik. */
.pmode{display:inline-flex;justify-self:start;gap:3px;padding:3px;margin-bottom:4px;background:var(--canvas);border:1px solid var(--line);border-radius:999px}
.pmode__b{appearance:none;-webkit-appearance:none;border:0;background:none;font:inherit;font-size:13px;font-weight:650;color:var(--muted);padding:7px 16px;border-radius:999px;cursor:pointer;transition:color .12s,background .12s,box-shadow .12s}
.pmode__b:hover{color:var(--navy)}
.pmode__b.on{background:#fff;color:var(--navy);box-shadow:0 1px 2px rgba(10,37,64,.14)}
.pmode__b:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* Przełącznik, nie checkbox: to ustawienie ogłoszenia, a nie pozycja listy do
   odhaczenia. Zbudowany na natywnym input[type=checkbox] przez appearance:none,
   więc Tab, Spacja i czytniki ekranu działają bez dokładania ARIA. */
.sw{display:flex;align-items:flex-start;gap:11px;margin-top:6px;cursor:pointer}
.sw input{appearance:none;-webkit-appearance:none;flex:none;width:36px;height:21px;margin:1px 0 0;border-radius:999px;background:#ccd5e0;position:relative;cursor:pointer;transition:background .16s}
.sw input::after{content:'';position:absolute;top:2px;left:2px;width:17px;height:17px;border-radius:50%;background:#fff;box-shadow:0 1px 2px rgba(10,37,64,.3);transition:transform .16s}
.sw input:checked{background:var(--accent)}
.sw input:checked::after{transform:translateX(15px)}
.sw input:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.sw b{display:block;font-size:13.5px;font-weight:650;color:var(--ink);line-height:1.3}
.sw i{display:block;font-style:normal;font-size:12.5px;color:var(--faint);line-height:1.35;margin-top:1px}
.sw:hover b{color:var(--navy)}
.poanote{margin:0;font-size:13px;line-height:1.45;color:var(--muted)}
@media (prefers-reduced-motion:reduce){.sw input,.sw input::after,.pmode__b{transition:none}}

/* Nagłówek grupy w podmienionym selectcie — 73 lokalizacje bez podziału na akweny
   są listą, a nie wyborem. */
.nsel__grp{padding:9px 13px 4px;font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--faint)}
.nsel__grp:first-child{padding-top:5px}
.nsel__opt--off{opacity:.55;cursor:default}

/* ── Poświata tła ────────────────────────────────────────────────────────
   Ta sama ambientowa poświata, co na zeglarski.info (zeglarski/styles.css:43),
   przeniesiona 1:1 razem z mocniejszym wariantem na telefony. Działa mimo
   szarego body, bo <html> nie ma własnego tła: kolor body propaguje się na
   kanwę dokumentu, a pseudoelement z z-index:-1 ląduje NAD kanwą i POD treścią.
   Przypięta do viewportu (position:fixed), więc nie przewija się razem ze stroną. */
.glow{
  display:block;position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(120% 80% at 50% -12%, rgba(102,153,255,.38) 0%, rgba(102,153,255,0) 60%);
}
@media (max-width:860px){
  .glow{background:radial-gradient(160% 92% at 50% -10%, rgba(102,153,255,.58) 0%, rgba(102,153,255,0) 66%);}
}

/* ── Mobilny pasek skrotow ───────────────────────────────────────────────
   Wzorowany na appbarze z zeglarski.info. Pokazywany tam, gdzie pozioma
   nawigacja i tak sie nie miesci (<=860px), czyli dokladnie tam, gdzie do tej
   pory jedyna droga byl hamburger. */
.ab,.ab__scrim{display:none}
@media(max-width:860px){
  body{padding-bottom:calc(62px + env(safe-area-inset-bottom,0px))}
  .ab__scrim{display:block;position:fixed;inset:0;z-index:58;background:rgba(7,22,40,.45);opacity:0;pointer-events:none;transition:opacity .2s ease}
  .ab__scrim.on{opacity:1;pointer-events:auto}
  .ab{display:block;position:fixed;left:0;right:0;bottom:0;z-index:59;
      background:linear-gradient(180deg,rgba(13,42,74,.95),rgba(7,26,52,.97));
      -webkit-backdrop-filter:blur(14px) saturate(1.25);backdrop-filter:blur(14px) saturate(1.25);
      box-shadow:0 -1px 0 rgba(255,255,255,.09),0 -8px 24px rgba(7,22,40,.24);
      padding-bottom:env(safe-area-inset-bottom,0px)}
  .ab__row{display:flex;max-width:620px;margin:0 auto}
  .ab__b{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
         min-width:0;height:62px;padding:0 2px;border:0;background:none;font:inherit;font-size:10.5px;font-weight:600;
         color:rgba(255,255,255,.72);text-align:center;cursor:pointer;transition:color .14s}
  .ab__b span:last-child{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ab__b:hover,.ab__b:focus-visible{color:#fff}
  .ab__b.on{color:#fff}
  .ab__i{position:relative;display:grid;place-items:center;width:26px;height:26px}
  .ab__i svg{width:22px;height:22px}
  /* Aktywna pozycja dostaje podswietlona plamke pod ikona, a nie inne tlo:
     pasek ma zostac jednym paskiem, nie rzedem przyciskow. */
  .ab__b.on .ab__i::before{content:"";position:absolute;inset:-5px -9px;border-radius:999px;background:rgba(255,255,255,.15)}
  /* Ten sam material co plakietka w gornym pasku - obie znacza to samo i nie ma
     powodu, zeby na telefonie byla plaska, a na dużym ekranie polyskliwa. */
  .ab__n{position:absolute;top:-5px;right:-8px;min-width:17px;height:17px;padding:0 4px;border-radius:999px;
         background:linear-gradient(180deg,#3585dd 0%,var(--accent) 45%,#1058a6 100%);
         box-shadow:inset 0 1px 0 rgba(255,255,255,.55),0 1px 3px rgba(4,20,48,.45);
         color:#fff;font-size:10.5px;font-weight:700;line-height:17px;text-align:center}
  /* Arkusz "Wiecej" wysuwa sie nad paskiem, wiec siedzi w tym samym elemencie. */
  .ab__more{max-width:620px;margin:0 auto;padding:14px 14px 6px;border-bottom:1px solid rgba(255,255,255,.1)}
  .ab__mh{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px;color:#fff}
  .ab__mh b{font-family:"Archivo",sans-serif;font-size:14px;font-weight:700}
  .ab__x{border:0;background:none;color:rgba(255,255,255,.75);font-size:24px;line-height:1;cursor:pointer;padding:0 4px}
  .ab__ml{display:block;margin:10px 0 4px;font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:rgba(255,255,255,.5)}
  .ab__mg{display:grid;grid-template-columns:repeat(4,1fr);gap:2px}
  .ab__mg .ab__b{height:66px;font-size:10px}
  /* Pasek porownywarki tez jest przyklejony do dolu — bez tego siedzialby pod. */
  .cmpbar{bottom:calc(62px + env(safe-area-inset-bottom,0px))}
  @media (prefers-reduced-motion:reduce){.ab__scrim{transition:none}}
}

/* ── Szukajka na stronie wynikow + chowanie paska ────────────────────────
   Na desktopie szukajka siedzi w pasku, wiec ta na stronie wynikow byłaby
   drugim identycznym polem. Pokazujemy ja dokladnie tam, gdzie pasek swoja
   chowa, czyli ponizej 561px. */
.res-q{display:none}
@media(max-width:560px){
  /* Ponizej tego progu gorny pasek zostawia samo logo, tak jak aplikacja
     portalu: szukanie i konto maja swoje wejscia w dolnym pasku skrotow. */
  .nbsearch{display:none}
  .acts--d{display:none}
  .res-q{display:flex;align-items:center;gap:6px;height:44px;margin-bottom:14px;
         padding:0 5px 0 14px;border-radius:999px;background:#fff;
         box-shadow:0 0 0 1px var(--line),0 6px 18px -14px rgba(8,28,64,.5)}
  .res-q input{flex:1;min-width:0;height:100%;border:0;background:none;outline:none;
               font:inherit;font-size:16px;color:var(--ink)}
  .res-q input::placeholder{color:var(--faint)}
  .res-q button{flex:none;width:34px;height:34px;display:grid;place-items:center;
                border:0;border-radius:999px;background:var(--accent);color:#fff;cursor:pointer}
  .res-q button:hover{background:var(--accent-dark)}
}
@media(max-width:860px){
  /* transform tylko w stanie ukrytym: stala transformacja zrobilaby z paska blok
     zawierajacy dla position:fixed w jego wnetrzu. Zapas 40px na cien. */
  #hdr .site-header{transition:transform .28s ease}
  #hdr.is-hidden .site-header{transform:translateY(calc(-100% - 40px));pointer-events:none}
}
@media (prefers-reduced-motion:reduce){#hdr .site-header{transition:none}}

/* ── Zdjecie w ramce ─────────────────────────────────────────────────────
   Karta dostaje wlasny margines wewnetrzny, a zdjecie zamiast dwoch gornych
   rogow ma zaokraglone wszystkie cztery, wiec biale tlo karty obchodzi je
   dookola jak passe-partout. Promien wewnetrzny = zewnetrzny minus padding
   (10 - 6), inaczej rogi nie sa wspolsrodkowe i ramka optycznie "plywa". */
.card{padding:6px}
.card__media{border-radius:4px}
.card__b{padding:9px 7px 8px}

/* ── Karta lokalizacji ───────────────────────────────────────────────────
   Uklad jak na OLX: nazwa miejscowosci i wojewodztwo po lewej, mala mapka po
   prawej. Mapka jest statyczna (kafle OSM jako zwykle <img>), wiec nie ma tu
   zadnego JavaScriptu do przewijania ani biblioteki do zaladowania. */
.dt-loc__in{display:flex;align-items:center;justify-content:space-between;gap:14px}
.dt-loc__t{display:flex;align-items:flex-start;gap:9px;min-width:0}
.dt-loc__t svg{flex:none;margin-top:1px;color:var(--navy)}
.dt-loc__t b{display:block;font-size:14.5px;font-weight:700;color:var(--navy);line-height:1.3}
.dt-loc__t i{display:block;font-style:normal;font-size:13px;color:var(--muted);margin-top:1px}
.locmap{position:relative;flex:none;overflow:hidden;border-radius:var(--r);background:#e8edf2;
        box-shadow:inset 0 0 0 1px var(--line)}
.locmap img{max-width:none}   /* globalne img{max-width:100%} zgnioloby kafle */
.locmap__a{position:absolute;right:2px;bottom:1px;font-size:8.5px;line-height:1.3;color:#4a5866;
           background:rgba(255,255,255,.78);padding:0 3px;border-radius:3px;pointer-events:none}
@media(max-width:520px){
  /* Kazdy kafel ma wyliczony wlasny left, wiec mapki nie da sie rozciagnac
     CSS-em bez rozsypania mozaiki. Na waskim ekranie schodzi pod tekst i
     zostaje wysrodkowana w swojej naturalnej szerokosci. */
  .dt-loc__in{flex-direction:column;align-items:flex-start;gap:12px}
  .locmap{align-self:center}
}

/* ── Filtry jako pionowa lista pol ───────────────────────────────────────
   Kazdy filtr to etykieta i jedna kontrolka, jeden pod drugim. Wczesniej byly
   to rozwijane <details> z listami radiobuttonow: zeby zobaczyc, co jest
   wybrane, trzeba bylo najpierw rozwinac grupe, a piec grup nie miescilo sie
   w szynie. Select pokazuje biezaca wartosc bez klikania. */
.ffield{display:grid;gap:5px;margin-bottom:13px}
.ffield > label{font-size:12.5px;font-weight:700;color:var(--navy);letter-spacing:.005em}
.fset .ffield select{width:100%}
/* Opcja bez ani jednego wyniku zostaje widoczna, ale nieklikalna: znika pytanie
   "czemu tego nie ma na liscie", a nie da sie wejsc w puste wyniki. */
.fset .ffield option:disabled{color:var(--faint)}
.prange{display:flex;gap:8px}
.prange input{width:100%;min-width:0}

/* Karta z jednym filtrem: margines pod polem jest po to, zeby oddzielic je od
   nastepnego, wiec przy ostatnim (a w kartach jednopolowych: jedynym) tworzy
   tylko martwy pas nad krawedzia karty. */
.fpanel .ffield:last-child{margin-bottom:0}
.fpanel > h3 + .ffield{margin-top:2px}

/* Prawa konsumenta: informacja, nie ostrzezenie, wiec bez czerwieni i bez ikony
   alarmu. Ton ustawia sam fakt, ze blok jest osobny i nazwany. */
.rights p{margin:0;font-size:13.5px;line-height:1.55;color:var(--muted)}


/* ── Telefon: pola nie moga miec mniej niz 16px ───────────────────────────
   Ponizej tego progu iOS Safari sam przybliza strone przy wejsciu w pole i NIE
   oddala po wyjsciu, wiec uzytkownik zostaje na powiekszonej stronie do konca
   wizyty. Arkusz znal juz te regule i stosowal ja do dwoch szukajek; obowiazuje
   wszystkie pola. Rozmiar podnosimy tylko na telefonie, zeby nie ruszac desktopu. */
@media(max-width:860px){
  /* .fld musi byc wymieniony wprost: reguly .fld input maja specyficznosc (0,1,1),
     wiec samo "input" (0,0,1) ich nie przebija, niezaleznie od kolejnosci w pliku.
     .fset to formularz FILTROW, a nie dodawania ogloszenia — to dwa rozne miejsca. */
  input,select,textarea,
  .fld input,.fld select,.fld textarea,
  .fset input,.fset select,.fset textarea,
  .nsel__btn,.res-q input,.prange input,.ffield input,.ffield select{font-size:16px}
}
/* Toast lezal na dolnym pasku skrotow i przez 2,4s przechwytywal dotkniecia
   przycisku "Dodaj": elementFromPoint zwracal DIV.toast. Powiadomienie nie ma
   prawa blokowac nawigacji. */
.toast{pointer-events:none}

/* ── Oferta ze strony trzeciej ───────────────────────────────────────────
   Wyroznienie ma byc czytelne, ale nie krzykliwe: to nie ostrzezenie, tylko
   informacja o tym, dokad prowadzi klikniecie. */
/* Chip na zdjeciu. Niebieski, bo to informacja, nie ostrzezenie - ale pelny
   kontrast bieli na granacie marki, zeby dzialal takze na jasnym kadrze. Stoi
   POD warstwa "Sprzedane" (z-index 2), wiec sprzedana oferta nadal czyta sie
   przede wszystkim jako sprzedana. */
.chipz{position:absolute;top:8px;left:8px;z-index:1;max-width:calc(100% - 16px);
  padding:3px 8px;border-radius:999px;
  background:var(--accent);color:#fff;
  font-size:10.5px;font-weight:700;letter-spacing:.01em;line-height:1.35;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  box-shadow:0 1px 6px rgba(4,14,30,.28)}
@media(max-width:600px){.chipz{top:6px;left:6px;padding:2px 7px;font-size:9.5px}}
.ext{display:grid;gap:10px}
.ext__k{display:flex;align-items:center;gap:6px;font-size:11px;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.ext__p{margin:0;font-size:13.5px;line-height:1.55;color:var(--muted)}
.ext__p b{color:var(--navy)}
.ext .btn svg{margin-left:7px;flex:none}
/* Nazwa serwisu w etykiecie potrafi byc dowolnie dluga (ogloszenia.trojmiasto.pl
   to 24 znaki), a .btn ma nowrap dla wszystkich pozostalych przyciskow w
   serwisie i tak ma zostac. Tutaj pozwalamy zawinac: przycisk rosnie w dol,
   czyli w kierunku, w ktorym jest miejsce, zamiast rozpychac kolumne w bok.
   height:auto, bo staly 46px scinalby druga linie. */
.ext .btn{white-space:normal;overflow-wrap:anywhere;height:auto;min-height:46px;padding:12px 18px;line-height:1.3;text-align:center}
/* To samo dla nazwy serwisu w prozie i w naglowku karty sprzedajacego: dlugi
   adres bez spacji nie ma gdzie sie zlamac i wypycha kontener. */
.ext__p b,.ext__d{overflow-wrap:anywhere}
.ext__d{margin:0;font-size:12px;color:var(--faint)}

/* Termin waznosci w panelu wlasciciela. Trzy stany, trzy wagi: wygasle wola,
   konczace sie przypomina, reszta tylko informuje i nie ma byc klikalna. */
.mycard__a--exp{background:var(--red,#c0392b);color:#fff;font-weight:700}
.mycard__a--soon{background:#fff4e2;color:var(--amber,#8a5c0b);font-weight:700}
.mycard__a--info{color:var(--faint);cursor:default}
.mycard__a--info:hover{background:none}

/* Doladowywanie wynikow. Licznik pod przyciskiem, bo "Pokazano 48 z 682" jest
   odpowiedzia na pytanie, ktore uzytkownik zadaje PRZED klinieciem, a nie po. */
.more{display:grid;justify-items:center;gap:8px;padding:22px 0 4px}
.more .btn{min-width:200px}
.more__n{margin:0;font-size:13px;color:var(--faint);text-align:center}
p.more__n{padding:18px 0 4px}

/* Logowanie spolecznosciowe, ten sam uklad co na zeglarski.info: przyciski NAD
   formularzem, bo to szybsza droga, a separator "albo" mowi wprost, ze to
   alternatywa dla hasla, a nie dodatkowy krok. */
.authsocial{display:grid;gap:9px;margin-bottom:2px}
.authsocial__btn{display:flex;align-items:center;justify-content:center;gap:10px;height:44px;
  border-radius:var(--r);background:#fff;box-shadow:inset 0 0 0 1.5px var(--line);
  font-size:14.5px;font-weight:650;color:var(--navy);transition:box-shadow .14s,background .14s}
.authsocial__btn:hover{background:var(--canvas);box-shadow:inset 0 0 0 1.5px #ccd5e0}
.authsocial__btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.authsocial__sep{display:flex;align-items:center;gap:12px;margin:4px 0 2px;
  font-size:12.5px;color:var(--faint)}
.authsocial__sep::before,.authsocial__sep::after{content:"";flex:1;height:1px;background:var(--line)}

/* Rozwijak z reszta filtrow parametrycznych. Wyglada jak pozycja listy, a nie jak
   przycisk: to nadal jest filtr, tylko zwiniety, i nie ma konkurowac uwaga z
   trzema, ktore stoja nad nim otwarte. */
.fmore{margin-top:2px}
.fmore>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:6px;
  padding:6px 0;font-size:12.5px;font-weight:700;color:var(--accent)}
.fmore>summary::-webkit-details-marker{display:none}
.fmore>summary::after{content:"";width:7px;height:7px;border-right:2px solid currentColor;
  border-bottom:2px solid currentColor;transform:rotate(45deg) translate(-1px,-1px);
  transition:transform var(--t) var(--ease)}
.fmore[open]>summary::after{transform:rotate(-135deg) translate(-2px,-2px)}
.fmore>summary:hover{color:var(--accent-dark)}
.fmore__in{display:grid;gap:8px;padding-top:4px}

/* Dlugie etykiety filtrow: najwyzej dwa wiersze.
   "Zaswiadczenie o odbycia kursu", "Uprawnienia zawodowe (MCA/RYA)" albo
   "Mieszana (teoria online, praktyka na wodzie)" rozpychaly kolumne filtrow albo
   rozlewaly sie na cztery wiersze, przez co jedna pozycja byla wyzsza niz trzy
   sasiednie razem. Przyciecie do dwoch wierszy trzyma rytm listy; pelna tresc
   zostaje w atrybucie title, wiec nic nie ginie. */
.fset .frow__l{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;overflow-wrap:anywhere;line-height:1.35}
/* Wiersz musi sie wtedy wyrownywac do gory, a nie do linii bazowej pierwszego
   wiersza - inaczej licznik po prawej odjezdza w dol razem z druga linijka. */
.fset .frow{align-items:flex-start}
.fset .frow .c{margin-top:1px}
/* To samo w rozwijanych listach wielokrotnego wyboru. */
.nsel__opt>span:last-child{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;overflow-wrap:anywhere;line-height:1.35}

/* Wejscie panelu. Ruch ma tu jedno zadanie: powiedziec, ze panel PRZYSZEDL z
   paska nad nim, a nie pojawil sie znikad. Dlatego przesuniecie jest male i
   pionowe, a skala ledwie zauwazalna. Nic wiecej sie nie rusza. */
@media (prefers-reduced-motion:no-preference){
  .nvg__menu{transform:translateY(-6px) scale(.994);transform-origin:top center}
  .nvg:hover>.nvg__menu,.nvg:focus-within>.nvg__menu{transform:none}
}
/* Bez ruchu: panel po prostu jest albo go nie ma. Przejscie na widocznosci
   zostaje, bo bez niego menu miga przy kazdym przesunieciu kursora po pasku.
   Tego guardu nie bylo tu wcale, a panel animowal sie od zawsze. */
@media (prefers-reduced-motion:reduce){
  .nvg__menu{transform:none;transition:opacity .01s linear,visibility 0s linear .01s}
  .nvc,.nvc__ic,.nvc__n{transition:none}
  .nvc:active{transform:none}
}

/* ── Puste stany: znak wizualny ─────────────────────────────────────────────
   Osiemnascie pustych stanow w serwisie mialo do tej pory sam tekst na kresce.
   Znak nie jest ilustracja dodana dla ozdoby: to ten sam kafel, ktorym oznaczamy
   brakujace zdjecie (.plate), wiec "brak" ma w calym serwisie jedna forme.
   Kolor bierze z dzialu, gdy stan dotyczy konkretnej kategorii; inaczej z akcentu. */
.void--mark{--ic:var(--accent)}
.void__mark{display:grid;place-items:center;width:52px;height:52px;margin-bottom:16px;
  border-radius:var(--r-lg);color:var(--ic);
  background:color-mix(in srgb,var(--ic) 9%,#fff);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ic) 15%,transparent)}
/* Kicker pod znakiem, nie nad nim: znak jest wejsciem w kompozycje, etykieta
   dopiero go nazywa. Bez tego oba elementy walczyly o pierwsze spojrzenie. */
.void--mark .void__k{margin-bottom:7px}
/* Kreska nad pustym stanem ze znakiem jest zbedna: znak sam otwiera blok, a dwa
   otwarcia jedno nad drugim to szum. */
.void--mark{border-top:0;padding-top:6px}
@media(max-width:640px){
  .void__mark{width:46px;height:46px;margin-bottom:13px}
}

/* ── Rodzaj konta przy rejestracji ──────────────────────────────────────────
   Dwie opcje, obie z konsekwencja wypisana wprost. Nie select i nie przelacznik:
   wybor ma skutek prawny (rekojmia i zwrot w 14 dni), wiec obie mozliwosci musza
   byc widoczne naraz i opisane, a nie schowane pod rozwijana lista. Zadna nie
   jest zaznaczona z gory - domyslna odpowiedz przy takiej konsekwencji byloby
   zgadywaniem za uzytkownika. */
/* acctPICK, nie acct: `.acct` bylo od dawna przyciskiem konta w naglowku
   (inline-flex, rzad), a ta regula stala PONIZEJ w pliku i wygrywala kaskade.
   Skutek: awatar i imie ustawialy sie w kolumnie, wiec przycisk konta wygladal
   na zepsuty. Klasa o nazwie tak ogolnej jak "acct" musi byc jedna w calym
   arkuszu. */
.acctpick{display:grid;gap:8px;border:0;padding:0;margin:0;min-width:0}
.acctpick>legend{padding:0;font-size:11.5px;font-weight:700;letter-spacing:.02em;color:var(--navy);margin-bottom:2px}
.acctpick__o{display:flex;align-items:flex-start;gap:10px;padding:11px 12px;cursor:pointer;
  border:1.5px solid var(--line);border-radius:var(--r);background:#fff;
  transition:border-color var(--t) var(--ease),background-color var(--t) var(--ease),
    box-shadow var(--t) var(--ease)}
.acctpick__o:hover{border-color:#ccd5e0}
.acctpick__o input{flex:none;width:17px;height:17px;margin:1px 0 0;accent-color:var(--accent);cursor:pointer}
.acctpick__t{min-width:0}
.acctpick__t b{display:block;font-size:13.5px;font-weight:700;color:var(--navy);line-height:1.3}
.acctpick__t i{display:block;font-style:normal;font-size:12px;line-height:1.45;color:var(--muted);margin-top:2px}
.acctpick__o:has(input:checked){border-color:var(--accent);background:var(--blue-soft);
  box-shadow:inset 0 0 0 1px var(--accent)}
.acctpick__o:has(input:checked) .acctpick__t i{color:var(--accent-dark)}
.acctpick__o:has(input:focus-visible){outline:2px solid var(--accent);outline-offset:2px}

/* Znak w kolku konta. Wypelnienie zamiast obrysu, bo to logo, nie ikona
   interfejsu - i dlatego ma wlasna regule zamiast dziedziczyc po .act svg. */
.avt--mark{padding:0}
/* Glif jest PIONOWY (viewBox 214x265), wiec o wielkosci decyduje wysokosc, a
   szerokosc idzie za proporcja: 26 x 21. Wczesniej stalo tu kwadratowe 19x19 i
   to byl blad - przy dopasowaniu 'meet' glif rysowal sie jako 15x19, czyli
   zajmowal 45% wysokosci kolka i ginal w granatowym pierscieniu, podczas gdy
   serce, czat i dzwonek obok wypelniaja swoje przyciski w jakichs 55%.
   26 px sprawdzone renderem: przy 28 dolna fala dotyka juz krawedzi. */
.avt__l{width:21px;height:26px;fill:#fff;display:block}

