/*
 * jb-home.css — nowa strona główna (port makiety lovable-glowna).
 * Ładowana WYŁĄCZNIE gdy IndexController::isNewHomeLayout() === true
 * (header.tpl, $jb_new_home_layout). Wszystkie reguły są izolowane pod:
 *   - body.jbh-page  (elementy layoutu poza .jbh)
 *   - .jbh           (cała nowa strona główna)
 * Sekcja Bestsellery reużywa kartę produktu .ddc-card z dd-category.css —
 * tokeny kolorów poniżej mają te same wartości co --ddc-* (spójność wizualna),
 * zadeklarowane osobno jako --jbh-*, bo --ddc-* nie są widoczne poza .ddc.
 */

/* ------------------------------------------------------------------ ukrycie starych elementów poza .jbh */
/* Pasek "DARMOWA DOSTAWA / SZYBKA WYSYŁKA / 5000+ KLIENTÓW / 2 LATA GWARANCJI"
   (#advantage, wstrzykiwany przez JS modułu jsox_manyworks — nie da się go
   wyłączyć przez {if} w Smarty, bo nie pochodzi z żadnego szablonu) oraz stary
   pasek logotypów DHL/DPD/PayU (.bottom-logos, ukryty też w footer.tpl warunkiem
   page_name) — na nowej stronie głównej mają swoje odpowiedniki (hero, stopka). */
body.jbh-page #swap_blocks_container,
body.jbh-page #advantage,
body.jbh-page .bottom-logos {
  display: none !important;
}

/* Stara siatka "8 kategorii" (moduł themeconfigurator) i stary hero-slider
   (moduł homeslider) — OBA rejestrują się na hooku displayTopColumn w
   header.tpl (czyli POZA index.tpl) i sprawdzają tylko php_self=='index',
   nie flagę jb_new_home_layout, dlatego trzeba je ukryć tu, a nie warunkiem
   w Smarty. Dubluje nową sekcję "Wybierz rodzaj lampy" / nowy Hero. */
body.jbh-page #htmlcontent_top,
body.jbh-page #homepage-slider {
  display: none !important;
}

/* #left_column/#right_column (header.tpl ok. linii 445, POZA index.tpl — renderowane
   dla każdego kontrolera niezależnie od jb_new_home_layout, więc {if} w Smarty tu nic
   nie da) zawierają m.in. stary widget modułu blocknewsletter (hookDisplayLeftColumn,
   themes/modula/modules/blocknewsletter/blocknewsletter.tpl) z polem id="newsletter-input"
   i starą sztuczką placeholdera przez value+JS zamiast atrybutu placeholder — stąd
   podmieniający się tekst po kliknięciu w NASZE pole newslettera, zanim zmieniliśmy mu
   id na jbh-newsletter-input (duplikat id w DOM = ten sam selektor w dwóch miejscach).
   Ten sam wzorzec ukrycia co #left_column na body.ddc-page w dd-category.css. */
body.jbh-page #left_column,
body.jbh-page #right_column {
  display: none !important;
}
body.jbh-page #center_column {
  width: 100%;
  float: none;
}
body.jbh-page #columns.container {
  padding-left: 10px;
  padding-right: 10px;
}

/* Sticky header — 1:1 odwzorowanie lovable-głowna (src/components/
   SiteHeader.tsx) na JEDNYM, prawdziwym węźle DOM, nie dwóch jak w
   referencji (tam: osobny, zawsze-fixed "duplikat" React nałożony na
   oryginał w normalnym przepływie — u nas zduplikowanie #jb-desktop-nav
   albo #searchbox/koszyka złamałoby ich JS, bo wiążą się po ID zakładającym
   dokładnie jedno wystąpienie). #stickybar ZAWSZE jest position:fixed — JS
   (jb-home.js) co klatkę scrolla liczy, o ile pikseli go "odsunąć w dół"
   transformem, żeby wyglądał dokładnie tak, jakby był w normalnym
   przepływie (to ręczna emulacja position:sticky — natywny sticky nie
   działa w tym motywie: global.css ustawia `body { overflow-x: hidden }`,
   co każe przeglądarce policzyć overflow-y jako auto, psując sticky dla
   potomków). CIĄGŁA funkcja scrolla zamiast dyskretnego przełącznika
   static<->fixed = nie ma momentu przejścia, który mógłby "skoczyć".

   Belka Logo + Wyszukiwarka + Ikony konta w ogóle się nie kurczy — zawsze
   ta sama wielkość, tylko jej POZYCJA jest ciągle dogrywana transformem.

   Pasek kategorii jb_menu (#jb-desktop-nav) chowa/pokazuje się BINARNIE wg
   KIERUNKU scrolla, dokładnie jak w referencji (showCats/delta/past w
   SiteHeader.tsx) — scroll w dół chowa, scroll w górę (o min. 4px, histereza
   przeciw drganiom) pokazuje, i to WYŁĄCZNIE gdy belka jest już "zadokowana"
   (.jbh-header-docked) — przed zadokowaniem pasek zachowuje się zupełnie
   normalnie (widoczny, w naturalnym przepływie), tak jak oryginalny,
   nie-sticky nagłówek w referencji. Celowo BEZ animowania height/max-height
   (CSS nie umie animować do/z "auto") — height/visibility przełączają się
   SKOKIEM w tym samym momencie co opacity:0, więc skok jest niewidoczny pod
   przykrywką niewidzialności; realną, widoczną animację niesie tylko
   opacity+transform. jb_menu's own front.js wyłącza na tej stronie swój
   NIEZALEŻNY auto-hide (initDesktopAutoHide() sprawdza body.jbh-page), żeby
   oba mechanizmy nie biły się o ten sam element. */
@media (min-width: 768px) {
  body.jbh-page #stickybar {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 5003;
    background: #fff;
    border-bottom: none;
  }

  body.jbh-page.jbh-header-docked #stickybar {
    box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
    background-color: rgba(255, 255, 255, .95);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    transition: box-shadow .2s ease, background-color .2s ease;
  }

  body.jbh-page #jb-desktop-nav {
    transition: opacity .2s cubic-bezier(.4, 0, .2, 1), transform .2s cubic-bezier(.4, 0, .2, 1);
  }

  /* Chowa pasek kategorii TYLKO gdy belka jest zadokowana i showCats=false —
     przed zadokowaniem (gdy nagłówek jest jeszcze w swojej "naturalnej"
     pozycji wizualnej) pasek jest zawsze w pełni widoczny, bez tej reguły. */
  body.jbh-page.jbh-header-docked:not(.jbh-cats-visible) #jb-desktop-nav {
    opacity: 0;
    transform: translateY(-4px);
    visibility: hidden;
    height: 0;
    overflow: hidden;
    pointer-events: none;
  }

  /* Stary, współdzielony mechanizm (footer.tpl stickyNav(), niedotknięty —
     nadal działa na całym sklepie) przy aktywnej klasie .sticky na #page
     dokłada sztywne "margin-bottom: 151px" do .header-container (global.css)
     jako WŁASNĄ, osobną rezerwację miejsca dla position:fixed. Tu mamy już
     własny, dynamicznie mierzony .jbh-header-spacer — bez tej neutralizacji
     oba mechanizmy dokładałyby się do siebie. */
  body.jbh-page .sticky .header-container {
    margin-bottom: 0 !important;
  }
}

/* Ten sam problem co wyżej (margin-bottom:151px), tylko mobile: global.css ma
   "@media (max-width:768px) { #header { padding-top: 127px/109px } }" — stała
   rezerwacja miejsca pod zawsze-fixed #stickybar na telefonie, z czasów sprzed
   .jbh-header-spacer (ten drugi liczy się dynamicznie z jb-home.js, patrz
   measure() tam). Współistnienie obu dawało podwójne przerwy nad/pod paskiem
   logo/wyszukiwarki.
   ALE: zerowanie na stałe (bez warunku) zostawiało dziurę DOKŁADNIE odwrotną —
   .jbh-header-spacer nie istnieje w DOM, dopóki jb-home.js (defer) go nie
   wstawi, więc między pierwszym renderem a wykonaniem się tego skryptu nic
   nie rezerwowało miejsca wcale -> stały #stickybar (position:fixed) nachodził
   na górę strony ("obcinany/zasłonięty przez wyszukiwarkę zaraz po
   odpaleniu"). Stąd klasa .jbh-header-ready: dopóki jej nie ma, zostaje
   oryginalna, statyczna rezerwacja ze sklepu (bezpiecznik na pierwszy render);
   jb-home.js dopisuje ją na <body> W TEJ SAMEJ klatce, w której wstawia
   spacer — więc zawsze dokładnie jeden z dwóch mechanizmów jest aktywny,
   nigdy zero, nigdy oba naraz. */
@media (max-width: 768px) {
  body.jbh-page.jbh-header-ready #header {
    padding-top: 0;
  }
}

/* ------------------------------------------------------------------ tokeny */
/* .jbh-footer jest POZA #jbh (footer.tpl to osobny, siostrzany blok w DOM), więc
   tokeny --jbh-* muszą być zadeklarowane też na niej, inaczej byłyby niewidoczne. */
.jbh,
.jbh-footer {
  --jbh-bg: #fefdfb;
  /* #15110d / #625d56 (nie #1c1917 / #6b6660) — dokładne, zmierzone w devtools
     wartości text-foreground / text-muted-foreground z makiety (oklch()
     przeliczone na sRGB), patrz komentarz przy .jbh-newsletter__title. Wcześniej
     tu był własny, zaokrąglony odczyt sprzed tego pomiaru — ustawione teraz
     globalnie (zamiast punktowych nadpisań per-sekcja), żeby nie powtarzać tej
     samej poprawki za każdym razem, gdy ktoś zmierzy kolejny element. */
  --jbh-fg: #15110d;
  --jbh-fg-75: rgba(21, 17, 13, 0.75);
  --jbh-fg-40: rgba(21, 17, 13, 0.4);
  --jbh-muted: #625d56;
  --jbh-card: #fff;
  --jbh-primary: #941114;
  --jbh-primary-hover: #7a0e10;
  --jbh-primary-8: rgba(148, 17, 20, 0.08);
  --jbh-primary-40: rgba(148, 17, 20, 0.4);
  --jbh-beige: #f7f4ee;
  --jbh-product-bg: #f6f2ec;
  --jbh-border: #e5e0d8;
  --jbh-border-soft: rgba(229, 224, 216, 0.6);
  --jbh-radius: 10px;
  --jbh-radius-sm: 6px;
  --jbh-font: "Poppins", ui-sans-serif, system-ui, sans-serif;

  font-family: var(--jbh-font);
  color: var(--jbh-fg);
  background: var(--jbh-bg);
  letter-spacing: 0;
  /* domyślny line-height makiety (Tailwind preflight) — bez tego elementy bez
     własnego jawnego line-height (tytuły sekcji, nazwy kafelków/pomieszczeń...)
     dziedziczyły cokolwiek ustawił sklep na <body>, dające zmierzone rozjazdy
     wysokości linii względem makiety na wielu miejscach naraz. Akapity "lead"/
     "desc" mają własne, jawne 1.625 (leading-relaxed) nadpisujące to tu. */
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
.jbh *,
.jbh *::before,
.jbh *::after,
.jbh-footer *,
.jbh-footer *::before,
.jbh-footer *::after {
  box-sizing: border-box;
}
/* sklep (cv_custom.css) ustawia letter-spacing .8px na wielu elementach — neutralizacja w obrębie widoku */
#jbh
  :where(p, a, span, strong, h1, h2, h3, button, li, label, input, select, div),
.jbh-footer
  :where(
    p,
    a,
    span,
    strong,
    h1,
    h2,
    h3,
    button,
    li,
    label,
    input,
    select,
    div
  ) {
  letter-spacing: 0;
}
.jbh svg,
.jbh-footer svg {
  width: 1em;
  height: 1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}
.jbh button,
.jbh-footer button {
  font-family: inherit;
  cursor: pointer;
  background: none;
  border: 0;
}
.jbh a,
.jbh-footer a {
  text-decoration: none;
  color: inherit;
}
.jbh img,
.jbh-footer img {
  display: block;
  max-width: 100%;
}
.jbh ul,
.jbh-footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.jbh [hidden],
.jbh-footer [hidden] {
  display: none !important;
}

/* 1400px = --nc-container-max z nc-product.css (nowa karta produktu) — ta sama
   szerokość treści na całej nowej stronie głównej, dla spójności z resztą sklepu. */
.jbh-container {
  width: 100%;
  max-width: 1400px;
  margin-inline: auto;
  /* padding-inline: 0 — reszta marginesu na mobile NIE pochodzi z tej reguły,
     patrz #columns/.container sklepu (global.css) i/lub padding na sekcjach
     (.jbh-rooms, .jbh-newsletter itd.) — do zbadania osobno. */
}
@media (min-width: 640px) {
  .jbh-container {
    padding-inline: 1.5rem;
  }
}
@media (min-width: 1024px) {
  .jbh-container {
    padding-inline: 2rem;
  }
}

/* pełna szerokość tła sekcji bez zmiany szerokości treści */
.jbh-hero,
.jbh-rooms {
  box-shadow: 0 0 0 100vmax var(--jbh-beige);
  clip-path: inset(0 -100vmax);
}
.jbh-newsletter {
  box-shadow: 0 0 0 100vmax var(--jbh-beige);
  clip-path: inset(0 -100vmax);
  border-block: 1px solid var(--jbh-border-soft);
}

/* ------------------------------------------------------------------ przyciski */
.jbh-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  height: 48px;
  padding-inline: 1.5rem;
  border-radius: var(--jbh-radius-sm);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  transition: background-color 0.15s ease;
}
.jbh-btn svg {
  width: 16px;
  height: 16px;
}
/* .jbh .jbh-btn--primary (nie samo .jbh-btn--primary) — musi pobić specyficznością
   ".jbh a { color: inherit; }" (klasa+typ = wyższa specyficzność niż sama klasa),
   inaczej biały tekst przycisku przegrywa i wychodzi ciemny/nieczytelny, gdy
   przycisk jest linkiem <a> (jak CTA w Hero). */
.jbh .jbh-btn--primary {
  background: var(--jbh-primary);
  color: #fff;
}
.jbh-btn--primary:hover {
  background: var(--jbh-primary-hover);
}

/* ------------------------------------------------------------------ nagłówek sekcji */
.jbh-heading {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
}
.jbh-heading__text {
  min-width: 0;
}
/* Rozmiar/waga 1:1 z nagłówkami sekcji na nowej karcie produktu (nc-product.css
   FIXUPS v19: .nc-inspiracje-eyebrow/.nc-section-title) — dla spójności wizualnej
   między stroną główną i kartą produktu. Wcześniej 10.5px/600 — zarówno mniejsze,
   jak i cieńsze niż tam (13/14px, waga 700), stąd nagłówki na stronie głównej
   wyglądały zauważalnie drobniej. */
.jbh-heading__eyebrow {
  display: block;
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.18em !important;
  color: var(--jbh-primary);
}
.jbh-heading__title {
  margin: 0.25rem 0 0;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.025em !important;
  color: var(--jbh-fg);
}
.jbh-heading__desc {
  margin: 0.5rem 0 0;
  max-width: 42rem;
  font-size: 13px;
  line-height: 1.625;
  color: var(--jbh-muted);
}
.jbh .jbh-heading__link {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 13px;
  font-weight: 600;
  color: var(--jbh-primary);
  white-space: nowrap;
}
.jbh-heading__link:hover {
  text-decoration: underline;
  text-underline-offset: 4px;
}
.jbh-heading__link svg {
  width: 15px;
  height: 15px;
  transition: transform 0.15s ease;
}
.jbh-heading__link:hover svg {
  transform: translateX(3px);
}
.jbh-link--desktop {
  display: none;
}
.jbh-link-mobile-row {
  display: flex;
  justify-content: center;
  margin-top: 0.875rem;
}
/* "Zobacz wszystkie poradniki" pod Poradnikami — zawsze widoczny (nie tylko mobile),
   w odróżnieniu od jbh-link-mobile-row (dubluje desktopowy link w nagłówku sekcji). */
.jbh-guides__seeall {
  display: flex;
  justify-content: center;
  margin-top: 3rem;
  margin-bottom: 5rem;
}
@media (min-width: 640px) {
  .jbh-heading__eyebrow {
    font-size: 14px;
  }
  .jbh-heading__title {
    font-size: 24px;
  }
  .jbh-heading__desc {
    font-size: 14px;
    margin-top: 0.625rem;
    white-space: nowrap;
  }
  .jbh-link--desktop {
    display: inline-flex;
  }
  .jbh-link-mobile-row {
    display: none;
  }
}

/* ------------------------------------------------------------------ 1. HERO */
.jbh-hero {
  background: var(--jbh-beige);
  border-bottom: 1px solid var(--jbh-border-soft);
}
.jbh-hero .jbh-container {
  padding-block: 1rem;
}
.jbh-hero__grid {
  display: grid;
  gap: 1.25rem;
}
.jbh-hero__main {
  position: relative;
  overflow: hidden;
  border-radius: 16px;
  border: 1px solid var(--jbh-border-soft);
}
.jbh-hero__img {
  width: 100%;
  height: 300px;
  object-fit: cover;
}
.jbh-hero__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to right,
    rgba(28, 25, 23, 0.7),
    rgba(28, 25, 23, 0.35) 55%,
    transparent
  );
}
.jbh-hero__text {
  position: absolute;
  inset-block: 0;
  left: 0;
  display: flex;
  max-width: 560px;
  flex-direction: column;
  justify-content: center;
  padding: 2.25rem;
}
.jbh-hero__eyebrow {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em !important;
  color: rgba(255, 255, 255, 0.85);
}
.jbh-hero__title {
  margin: 0.4rem 0 0;
  font-size: 26px;
  font-weight: 600;
  line-height: 1.15;
  color: #fff;
}
.jbh-hero__break {
  display: none;
}
.jbh-hero__lead {
  margin: 0.5rem 0 0;
  font-size: 13.5px;
  color: rgba(255, 255, 255, 0.85);
}
.jbh-hero__cta {
  margin-top: 1.5rem;
  align-self: flex-start;
  border-radius: 10px;
  padding-inline: 2rem !important;
}
.jbh-hero__side {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
}
.jbh-hero__tile {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: 16px;
  border: 1px solid var(--jbh-border-soft);
}
.jbh-hero__tile-img {
  width: 100%;
  height: 140px;
  object-fit: cover;
}
.jbh-hero__tile-caption {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  padding: 1rem;
  background: linear-gradient(to top, rgba(28, 25, 23, 0.85), transparent);
}
.jbh-hero__tile-title {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: #fff;
}
.jbh-hero__tile-hint {
  display: none;
  margin: 0.15rem 0 0;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.9);
}
@media (min-width: 640px) {
  .jbh-hero__img {
    height: 380px;
  }
  .jbh-hero__text {
    padding: 2rem;
  }
  .jbh-hero__title {
    font-size: 34px;
  }
  .jbh-hero__break {
    display: inline;
  }
  .jbh-hero__lead {
    font-size: 15px;
  }
  .jbh-hero__tile-img {
    height: 170px;
  }
  .jbh-hero__tile-caption {
    padding: 1.25rem;
  }
  .jbh-hero__tile-title {
    font-size: 16px;
  }
  .jbh-hero__tile-hint {
    display: block;
  }
}
@media (min-width: 1024px) {
  .jbh-hero .jbh-container {
    padding-block: 2rem;
  }
  .jbh-hero__grid {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  }
  .jbh-hero__img {
    height: 460px;
  }
  .jbh-hero__text {
    padding: 3rem;
  }
  .jbh-hero__title {
    font-size: 40px;
  }
  .jbh-hero__side {
    grid-template-columns: 1fr;
  }
  .jbh-hero__tile-img {
    height: 224px;
  }
  .jbh-hero__tile-caption {
    padding: 1.5rem;
  }
}

/* ------------------------------------------------------------------ 2. WYBIERZ RODZAJ LAMPY */
.jbh-lamptypes {
  margin-top: 2rem;
  /* Czytane przez fillRgb() w jb-home.js (silnik NCImageCrop, patrz initTileImageCrop) —
     kolor, na jaki przemalowuje się wycięte białe tło zdjęcia, żeby pasował do tła
     kafla (ten sam token co dla bestsellerów, --ddc-product-bg, tylko tu wartość
     dopasowana do tła TYCH kafli, #fbf8f3 — patrz .jbh-tile niżej). */
  --ddc-product-bg: #fbf8f3;
}
.jbh-lamptypes__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1rem;
  margin-top: 1rem;
}
.jbh-tile {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 16px;
  border: 1px solid #f0ede6;
  background: #fbf8f3;
  box-shadow: 0 1px 2px rgba(28, 25, 23, 0.06);
  transition: box-shadow 0.15s ease;
}
/* 1:1 z LampTypes.tsx: "hover:border-primary/40 hover:shadow-sm" — border-color
   zostawało bez zmian (#f0ede6, to samo co base), więc bordowy hover w ogóle nie
   był widoczny, tylko sam cień. */
.jbh-tile:hover {
  box-shadow: 0 6px 16px -8px rgba(0, 0, 0, 0.18);
  border-color: var(--jbh-primary-40) !important;
}
.jbh-tile__media {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: #fbf8f3;
}
.jbh-tile__img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 0.5rem;
  mix-blend-mode: multiply;
}
/* Warstwa z przyciętym (bez białych marginesów) zdjęciem — DOGRYWKA nad oryginałem,
   nie bramka widoczności (ten sam wzorzec co karta produktu/bestsellery, tam świadomie
   WYŁĄCZONY dla wydajności przy 20+ kartach naraz, patrz dd-category.css; tu tylko
   8 kafli, więc koszt pomijalny). Oryginał (.jbh-tile__img, mix-blend-mode:multiply)
   jest widoczny od razu — crop canvasem (initTileImageCrop w jb-home.js, silnik
   nc-image-crop.js) dogrywa się na wierzchu, gdy skończy liczyć, z płynnym fade-in. */
.jbh-tile__media .ddc-card__crop {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 0.5rem;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: multiply;
  transition: opacity 0.15s;
}
.jbh-tile__media .ddc-card__crop.is-ready {
  opacity: 1;
}
.jbh-tile__label {
  margin-top: auto;
  background: #fff;
  border-top: 1px solid #f0ede6;
  padding: 0.875rem 0.75rem;
  text-align: center;
}
/* 1:1 z LampTypes.tsx: text-[13px] font-semibold leading-snug sm:text-[13.5px]
   (było 14.5px/700/#111827 — ani rozmiar, ani grubość, ani kolor się nie zgadzały). */
.jbh-tile__name {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.375;
  color: var(--jbh-fg);
  transition: color 0.15s ease;
}
.jbh-tile:hover .jbh-tile__name {
  color: var(--jbh-primary);
}
@media (min-width: 640px) {
  .jbh-tile__name {
    font-size: 13.5px;
  }
}
@media (min-width: 768px) {
  .jbh-lamptypes__grid {
    grid-template-columns: repeat(4, 1fr);
    gap: 1.25rem;
  }
}

/* ------------------------------------------------------------------ 3. WYBIERZ WEDŁUG POMIESZCZENIA */
.jbh-rooms {
  background: var(--jbh-beige);
  margin-top: 2.5rem;
  padding-block: 2.5rem;
  border-block: 1px solid var(--jbh-border-soft);
}
.jbh-rooms__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1rem;
  margin-top: 1rem;
}
.jbh-room {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: 16px;
  border: none;
}
.jbh-room__media {
  position: relative;
  display: block;
  aspect-ratio: 4 / 5;
  overflow: hidden;
}
.jbh-room__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Warstwa z wyciętym (bez białych pasów z PS ImageType::resize()) zdjęciem —
   DOGRYWKA nad oryginałem, ten sam wzorzec co .jbh-tile__media .ddc-card__crop
   wyżej (initRoomImageCrop w jb-home.js), ale bez mix-blend-mode/padding: to
   zdjęcie wnętrza wypełniające cały kafel (object-fit: cover), nie produkt na
   jednolitym tle. */
.jbh-room__media .ddc-card__crop {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s;
}
.jbh-room__media .ddc-card__crop.is-ready {
  opacity: 1;
}
.jbh-room__caption {
  position: absolute;
  z-index: 2;
  inset-inline: 0;
  bottom: 0;
  padding: 1.25rem 1rem 1rem 1.25rem;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.65) 0%,
    rgba(0, 0, 0, 0.25) 50%,
    transparent 100%
  );
}
.jbh-room__name {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--jbh-bg);
}
.jbh-room__hint {
  display: none;
  margin: 0.2rem 0 0;
  font-size: 12px;
  color: rgba(254, 253, 251, 0.8);
}
.jbh-room__cta {
  display: none;
  align-items: center;
  gap: 0.2rem;
  margin-top: 0.4rem;
  font-size: 12px;
  font-weight: 600;
  color: var(--jbh-bg);
  transition: gap 0.15s ease;
}
.jbh-room__cta svg {
  width: 13px;
  height: 13px;
  transition: transform 0.15s ease;
}
.jbh-room:hover .jbh-room__cta {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.jbh-room:hover .jbh-room__cta svg {
  transform: translateX(3px);
}
@media (min-width: 640px) {
  .jbh-rooms__grid {
    gap: 1.25rem;
  }
  .jbh-room__media {
    aspect-ratio: 4 / 3;
  }
  .jbh-room__caption {
    padding: 1.5rem 1.25rem 1.25rem 1.5rem;
  }
  .jbh-room__name {
    font-size: 17px;
  }
  .jbh-room__hint,
  .jbh-room__cta {
    display: flex;
  }
}
@media (min-width: 1024px) {
  .jbh-rooms {
    padding-block: 3rem;
  }
  .jbh-rooms__grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* ------------------------------------------------------------------ raile (Bestsellery / Prawdziwe wnętrza / Poradniki) */
.jbh-rail {
  margin-top: 4.5rem;
}
.jbh-rail__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.75rem;
}
.jbh-rail__head .jbh-heading {
  flex: 1;
  min-width: 0;
}
.jbh-rail__arrows {
  display: none;
  gap: 0.5rem;
  flex-shrink: 0;
}
/* .jbh .jbh-rail__arrow (nie samo .jbh-rail__arrow) — musi pobić specyficznością
   ".jbh button { background: none; border: 0; }" (klasa+typ = wyższa specyficzność
   niż sama klasa), inaczej ramka i białe tło przycisku znikają (przycisk to <button>). */
.jbh .jbh-rail__arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  border: 1px solid #e5e7eb;
  background: #fff;
  color: #6b7280;
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease,
    color 0.2s ease;
}
.jbh-rail__arrow:hover {
  background: var(--jbh-primary);
  border-color: var(--jbh-primary);
  color: #fff;
}
.jbh-rail__arrow:disabled {
  opacity: 0.4;
  cursor: default;
}
.jbh-rail__arrow:disabled:hover {
  background: #fff;
  border-color: #e5e7eb;
  color: #6b7280;
}
.jbh-rail__arrow svg {
  width: 16px;
  height: 16px;
}
@media (min-width: 768px) {
  .jbh-rail__arrows {
    display: flex;
  }
}

.jbh-rail__track {
  display: flex;
  gap: 0.75rem;
  margin-top: 1rem;
  overflow-x: auto;
  scrollbar-width: none;
  scroll-behavior: smooth;
}
.jbh-rail__track::-webkit-scrollbar {
  display: none;
}
/* chwytanie myszką i przeciąganie na desktopie (initDragScrollTrack w jb-home.js) —
   tylko gdy jest czym sterować (hover:hover = mysz, nie dotyk, gdzie przewija się
   natywnym swipe'em); scroll-behavior:smooth (reguła wyżej) wyłączone na czas
   przeciągania, inaczej płynne dojeżdżanie "goni" kursor z opóźnieniem. */
@media (hover: hover) and (pointer: fine) {
  [data-jbh-drag] {
    cursor: grab;
  }
  [data-jbh-drag].is-dragging {
    cursor: grabbing;
    scroll-behavior: auto;
    user-select: none;
  }
}

/* karta produktu .ddc-card (dd-category.css) reużyta w poziomym railu zamiast siatki.
   display:contents na #ddc i na <ul> usuwa oba z drzewa layoutu — <li> stają się
   bezpośrednimi dziećmi flex .jbh-rail__track, więc ich % szerokości liczy się od
   stabilnej szerokości traku, a nie od auto-szerokości opakowań (co inaczej dawałoby
   obliczenie kołowe i błędne wymiary). #ddc samo w sobie nie ustawia żadnego
   layoutu (tylko tokeny/reset w dd-category.css), więc display:contents na nim
   jest bezpieczne. */
#jbh-bestsellers-track > #ddc {
  display: contents;
}
#jbh-bestsellers-track .ddc-grid.jbh-rail__list {
  display: contents;
}
/* 1.75 karty widoczne naraz na telefonie (zamiast 2.5 — przy 2.5 zdjęcia
   wychodziły za małe). 1 pełna karta + gap + 3/4 kolejnej jako podpowiedź do
   przewijania. calc() z JEDNYM gap-em (tylko między kartą 1 a 2 — reszta
   drugiej karty i tak wychodzi poza widoczny obszar), żeby 1.75 szerokości +
   1 gap dokładnie wypełniały 100%. */
#jbh-bestsellers-track .ddc-grid.jbh-rail__list > li {
  flex: 0 0 auto;
  width: calc((100% - 0.75rem) / 1.75);
}
/* Krótszy kadr zdjęcia na telefonie (4:3 zamiast 350:435 z karty kategorii) — ten
   sam powód: całościowo niższy blok karty, łatwiej przeciągać rail bez wchodzenia
   w galerię zdjęć. Od 640px wraca domyślny kadr .ddc-card (karty i tak szersze,
   więc proporcjonalnie nie są już tak wysokie). */
@media (max-width: 639px) {
  /* #jbh-bestsellers-track .ddc-card__track,
  #jbh-bestsellers-track .ddc-card__img {
    aspect-ratio: 4 / 3;
  } */
  /* Wymiary produktu (np. "Ø50 cm") pod ceną — na wąskiej karcie homepage'owego
     railu niepotrzebnie dokładają linię tekstu, której tu nikt nie oczekuje
     (w przeciwieństwie do strony kategorii, gdzie ma sens) — usunięte TYLKO
     w tym railu, nie na .ddc-card w ogóle. */
  #jbh-bestsellers-track .ddc-card__dims {
    display: none !important;
  }
  /* Swatche kolorów (.xsell-swatch, cv_xsell) na karcie kategorii mają margin:8px
     celowo — razem z 28x28 swatchem to 44x44 pole dotykowe (+ niewidoczny
     ::before{inset:-9px} jako dodatkowy, jeszcze większy bufor). Tu margines
     samych tylko zmniejszony (wizualny odstęp), ::before zostaje nietknięty —
     realne pole dotykowe się nie kurczy, tylko wizualnie ciaśniej, żeby rząd
     swatchy nie dominował nad zdjęciem na małej karcie 1.75-wide. */
  #jbh-bestsellers-track .ddc-card__variants {
    height: 40px;
  }
  #jbh-bestsellers-track .replaceonhover.xsell-swatch {
    width: 24px;
    height: 24px;
    margin: 3px;
  }
  /* Cena/stara cena/odznaka rabatu (.ddc-card__price, dd-category.css) ma tam
     flex-wrap: wrap — przy promocji (3 elementy naraz) na wąskiej karcie
     homepage'owego railu (1.75 karty na ekran) łamało się to na dwie linie.
     flex-wrap:nowrap samo nie wystarczyło: flex-item (np. stara cena) i tak mógł
     się skurczyć węziej niż jego tekst (domyślny flex-shrink:1), a sam tekst
     (white-space:normal) łamał się WEWNĄTRZ spana na dwie linie ("1 199,00" / "zł") —
     stąd white-space:nowrap na każdym z trzech elementów niżej. Dodatkowo
     zmniejszone fonty/padding, żeby cała trójka faktycznie zmieściła się w
     jednym wierszu na karcie szerokości ~1.75/ekran, zamiast tylko nie zawijać
     się kosztem widocznego poziomego obcięcia. */
  #jbh-bestsellers-track .ddc-card__price {
    flex-wrap: nowrap;
    gap: 4px;
  }
  #jbh-bestsellers-track .ddc-card__price > * {
    white-space: nowrap;
  }
  #jbh-bestsellers-track .ddc-card__price .ddc-price {
    font-size: 14px;
  }
  #jbh-bestsellers-track .ddc-card__price .ddc-price-old {
    font-size: 10px;
  }
  #jbh-bestsellers-track .ddc-card__price .ddc-price-saving {
    padding: 1px 4px;
    font-size: 10px;
  }
}
@media (min-width: 640px) {
  #jbh-bestsellers-track .ddc-grid.jbh-rail__list > li {
    width: 40%;
  }
}
@media (min-width: 768px) {
  #jbh-bestsellers-track .ddc-grid.jbh-rail__list > li {
    width: 31%;
  }
}
@media (min-width: 1024px) {
  #jbh-bestsellers-track .ddc-grid.jbh-rail__list > li {
    width: 23.5%;
  }
}

/* Drobne dopracowanie karty TYLKO na stronie głównej (scopowane przez #jbh-bestsellers-track,
   żeby w niczym nie ruszyć wyglądu .ddc-card na stronie kategorii, gdzie te same
   reguły z dd-category.css są współdzielone). */
#jbh-bestsellers-track .ddc-card {
  border-radius: 16px;
}
/* Nadpisanie TOKENU --ddc-product-bg (nie samego .ddc-card__media { background }) —
   #faf8f5 zamiast bazowego #f6f2ec z dd-category.css, dla spójności z resztą beży
   na stronie głównej (--jbh-beige itd.). Wcześniej token ten czytał też auto-crop
   w jb-home.js (fillRgb(), dopasowanie koloru wypalonego w przyciętym zdjęciu do
   tła kafla) — od wyłączenia cropu (patrz initProductCard w jb-home.js, ten sam
   wyłącznik co w dd-category.js) to już nieistotne, token zostaje wyłącznie dla
   tła .ddc-card__media. */
#jbh-bestsellers-track #ddc {
  --ddc-product-bg: #faf8f5;
}

/* ------------------------------------------------------------------ 5. LAMPY W PRAWDZIWYCH WNĘTRZACH */
.jbh-homes__track {
  align-items: flex-start;
  gap: 1.25rem;
}
/* Procenty w makiecie (CustomerHomes.tsx: w-[72%]/sm:46%/lg:31.5%) liczą się od
   jej węższego kontenera (container-shop, max-width 1240px) — u nas .jbh-container
   ma 1400px (celowo, dla spójności z resztą sklepu, patrz komentarz przy .jbh-container
   wyżej), więc te same procenty dawały zauważalnie większe kafle (zmierzone
   426.8×533.9px zamiast ok. 375×469px z makiety). Procenty tutaj zmniejszone
   ~11%, żeby wyrównać różnicę szerokości kontenera i wyjść na podobny rozmiar. */
.jbh-homes__slide {
  flex: 0 0 auto;
  width: 64%;
}
@media (min-width: 640px) {
  .jbh-homes__slide {
    width: 40%;
  }
}
@media (min-width: 1024px) {
  .jbh-homes__slide {
    width: 28%;
  }
}
.jbh-homes__media {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: 16px;
  border: 1px solid var(--jbh-border-soft);
  background: rgba(28, 25, 23, 0.05);
}
.jbh-homes__img,
.jbh-homes__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.jbh-homes__video {
  cursor: pointer;
}
.jbh-homes__video-controls {
  position: absolute;
  bottom: 0.625rem;
  left: 0.625rem;
  display: flex;
  gap: 0.375rem;
}
/* 1:1 z InteriorVideo w CustomerHomes.tsx: h-8 w-8 rounded-full bg-background/80
   shadow-sm backdrop-blur transition hover:bg-background (rgba(254,253,251,*) to
   --jbh-bg #fefdfb, patrz tokeny na górze pliku).
   .jbh .jbh-homes__video-btn (nie sama klasa) — przycisk to <button>, więc bez
   przedrostka ".jbh button { background: none; border: 0; }" (klasa+typ) bije
   samo tło/cień tej pojedynczej klasy specyficznością, tak jak wcześniej przy
   .jbh-rail__arrow / .jbh-btn--primary. */
.jbh .jbh-homes__video-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: rgba(254, 253, 251, 0.8);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  backdrop-filter: blur(8px);
  color: var(--jbh-fg);
  transition: background-color 0.15s ease;
}
.jbh-homes__video-btn:hover {
  background: var(--jbh-bg);
}
.jbh-homes__video-btn svg {
  width: 14px;
  height: 14px;
}
.jbh-homes__caption {
  margin-top: 0.5rem;
  padding-inline: 0.125rem;
}
.jbh-homes__product {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
  font-weight: 500;
}
.jbh .jbh-homes__link {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  margin-top: 0.1rem;
  font-size: 12px;
  font-weight: 600;
  color: var(--jbh-primary);
}
.jbh-homes__link:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.jbh-homes__link svg {
  width: 13px;
  height: 13px;
}

/* ------------------------------------------------------------------ 6. PORADNIKI O OŚWIETLENIU */
.jbh-guides {
  margin-top: 2.5rem;
}
/* touch-action:pan-y (usunięte) blokowało natywne przewijanie dotykiem w poziomie —
   przeglądarka zostawiała ten kierunek "do skryptu", a nasz drag-scroll (jb-home.js)
   obsługuje tylko mousedown/mousemove (desktop), nie zdarzenia dotyku — na telefonie
   nie dało się tym poziomo przesunąć żadnym sposobem. Bez tej deklaracji (domyślne
   touch-action: auto) przeglądarka sama obsługuje poziomy swipe po overflow-x:auto
   z .jbh-rail__track, dokładnie jak w Bestsellerach/Prawdziwych wnętrzach, które
   tego ograniczenia nigdy nie miały. */
.jbh-guides__track {
  scroll-snap-type: none;
  gap: 1.25rem;
  cursor: grab;
}
.jbh-guides__track.is-dragging {
  cursor: grabbing;
  scroll-snap-type: none;
  user-select: none;
}
.jbh-guides__track.is-dragging .jbh-guide__media {
  cursor: grabbing;
}
.jbh-guide {
  flex: 0 0 auto;
  width: 82%;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
}
@media (min-width: 640px) {
  .jbh-guide {
    width: 46%;
  }
}
@media (min-width: 1024px) {
  .jbh-guide {
    width: 31.5%;
  }
}
.jbh-guide__media {
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 16px;
  background: var(--jbh-product-bg);
  cursor: grab;
}
.jbh-guide__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
.jbh-guide__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  padding-top: 0.875rem;
}
.jbh-guide__meta {
  font-size: 11px;
  font-weight: 600;
}
.jbh-guide__category {
  color: var(--jbh-primary);
}
.jbh-guide__readtime {
  color: var(--jbh-muted);
  font-weight: 500;
}
/* 1:1 z GuidesGrid.tsx: "mt-1.5 text-[16px] font-semibold leading-snug ...
   sm:text-[17px]" — margin-top i line-height nie zgadzały się (0.2rem/1.3
   zamiast 0.375rem/1.375), brakowało też breakpointu 17px na sm. */
.jbh-guide__title {
  margin: 0.375rem 0 0;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.375;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.jbh-guide:hover .jbh-guide__title a {
  color: var(--jbh-primary);
}
/* "mt-1.5 ... text-[13px] leading-relaxed" — leading-relaxed to 1.625, nie 1.5. */
.jbh-guide__lead {
  margin: 0.375rem 0 0;
  font-size: 13px;
  line-height: 1.625;
  color: var(--jbh-muted);
}
/* "pt-3 text-[12.5px] font-semibold text-foreground" — kolor miał być neutralny
   (foreground), nie bordowy: ten CTA nie jest akcentem jak link sekcji, tylko
   zwykłym tekstem karty, więc var(--jbh-primary) tutaj było pomyłką. */
.jbh .jbh-guide__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: auto;
  padding-top: 0.75rem;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--jbh-fg);
}
.jbh-guide__cta:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.jbh-guide__cta svg {
  width: 14px;
  height: 14px;
}
@media (min-width: 640px) {
  .jbh-guide__title {
    font-size: 17px;
  }
}

/* Pasek postępu (port GuidesGrid.tsx: mt-3 h-0.5 rounded-full bg-border / bg-foreground/45,
   czyli --jbh-border / --jbh-fg z tokenów tego pliku). Szerokość i przesunięcie paska
   (data-jbh-progress-bar) liczone w jb-home.js (initProgressBars), na podstawie
   scrollLeft/scrollWidth/clientWidth traku poradników. */
.jbh-guides__progress {
  position: relative;
  margin-top: 0.75rem;
  height: 2px;
  overflow: hidden;
  border-radius: 999px;
  background: var(--jbh-border);
  display: none !important;
}
.jbh-guides__progress-bar {
  display: block;
  height: 100%;
  width: 18%;
  border-radius: 999px;
  background: rgba(28, 25, 23, 0.45);
  transition:
    width 0.15s ease,
    transform 0.15s ease;
}

/* ------------------------------------------------------------------ SEO (tekst pod Poradnikami) */
/* Moduł editorial — IndexController::getEditorialSeo()/tpl-parts/home/seo-text.tpl.
   Port 1:1 .ddc-seo__text ze strony kategorii (dd-category.css), tylko na --jbh-*
   tokenach zamiast --ddc-* (niewidocznych poza .ddc, patrz komentarz na górze pliku). */
.jbh-seo {
  margin-top: 2.5rem;
  padding-bottom: 2.5rem;
}
.jbh-seo__text {
  margin-top: 0.75rem;
  font-size: 13px;
  line-height: 1.75;
  color: var(--jbh-muted);
}
.jbh-seo__text p {
  margin: 0 0 1rem;
  font-size: inherit;
  line-height: inherit;
  color: inherit;
}
.jbh-seo__text p:last-child {
  margin-bottom: 0;
}
/* prawdziwa treść WYSIWYG (edytor modułu editorial) może nieść własne inline'owe
   kolory/rozmiary ze starej stopki — neutralizacja (ten sam trik co .ddc-seo__text),
   żeby wstawki z edytora nie rozjeżdżały spójnego, wyciszonego wyglądu tej sekcji. */
.jbh-seo__text p,
.jbh-seo__text span,
.jbh-seo__text div {
  font-size: inherit !important;
  line-height: inherit !important;
  color: inherit !important;
  font-family: inherit !important;
}
.jbh-seo__text a {
  color: var(--jbh-primary);
  text-underline-offset: 2px;
  text-decoration: underline;
}
.jbh-seo__text a:hover {
  color: var(--jbh-primary-hover);
}
/* treść z edytora WYSIWYG (modułu editorial) bywa WŁASNYM blokiem nagłówków
   (np. "Witaj w DAMI DOMO!..." jako <h1>/<h2> na początku tekstu, ze starej
   stopki) — bez tego dziedziczyły native, przeglądarkowe style nagłówków
   (dużo większe/grubsze niż reszta artykułu, wyraźnie odstające od
   .jbh-heading__title nad nimi). Ten sam trik co .ddc .ddc-seo__text h1 na
   stronie kategorii — śródtytuł w treści, nie strona-H1 (to jest title z
   section-heading.tpl wyżej). */
.jbh-seo__text h1,
.jbh-seo__text h2,
.jbh-seo__text h3 {
  margin: 1.5rem 0 0.5rem;
  font: 600 18px/1.3 var(--jbh-font);
  color: var(--jbh-fg);
  text-transform: none;
}
.jbh-seo__text h1:first-child,
.jbh-seo__text h2:first-child,
.jbh-seo__text h3:first-child {
  margin-top: 0;
}
@media (min-width: 1024px) {
  .jbh-seo__text {
    font-size: 14px;
  }
}
/* zwinięty widok (initClamp w jb-home.js) — WYŁĄCZNIE wizualne przycięcie
   (-webkit-line-clamp); pełny tekst zawsze zostaje w HTML, więc roboty widzą 100%
   treści niezależnie od stanu JS. */
.jbh-seo__text.is-clamped {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 6;
  line-clamp: 6;
  overflow: hidden;
}
.jbh-seo__text.is-clamped > * {
  display: inline;
  margin: 0;
}
.jbh-seo__text.is-clamped > *::after {
  content: " ";
}
.jbh .jbh-more {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 12px;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--jbh-primary);
  font-size: 13.5px;
  font-weight: 600;
}
.jbh-more:hover {
  text-decoration: underline;
}
.jbh-more svg {
  width: 14px;
  height: 14px;
  transition: transform 0.2s;
}
.jbh-more[aria-expanded="true"] svg {
  transform: rotate(180deg);
}

/* ------------------------------------------------------------------ 7. NEWSLETTER */
.jbh-newsletter {
  background: rgb(247, 241, 232);
  margin-top: 3rem;
  padding-block: 2.5rem;
}
.jbh-newsletter__grid {
  display: grid;
  gap: 1.5rem;
  align-items: center;
}
/* Kolory/line-height 1:1 z Newsletter.tsx (tracking-tight/leading-relaxed liczone
   z realnych rozmiarów, text-foreground/text-muted-foreground z oklch() makiety
   po przeliczeniu na sRGB — #15110d/#625d56, nie te same wartości co --jbh-fg/
   --jbh-muted [które są własnym, zaokrąglonym odczytem sprzed tego pomiaru] —
   nadpisane tu punktowo, żeby nie zmieniać koloru wszędzie indziej na stronie). */
.jbh-newsletter__title {
  margin: 0;
  font-size: 21px;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: -0.025em;
  color: #15110d;
}
.jbh-newsletter__lead {
  margin: 0.5rem 0 0;
  font-size: 13.5px;
  line-height: 1.625;
  color: #625d56;
}
/* align-items: stretch (nie center) na bazie/mobile — w układzie kolumnowym "center"
   centruje dzieci na ich WŁASNEJ, naturalnej szerokości zamiast rozciągać je na pełną
   szerokość wiersza (dokładnie jak w makiecie: flex flex-col gap-2 sm:flex-row, bez
   items-center na mobile) — stąd ściśnięty, nie-pełnowymiarowy wygląd zgłoszony na
   telefonie. "center" (wyśrodkowanie w pionie) ma sens tylko w układzie poziomym na
   desktopie, patrz @media (min-width:640px) niżej. */
.jbh-newsletter__row {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.5rem;
}
/* height:48px jawnie (nie tylko na inpucie w środku) — .jbh-newsletter__field jako
   flex item w wierszu (obok przycisku .jbh-btn, który ma własne jawne 48px) inaczej
   liczy wysokość z zawartości; jawna wartość na obu daje deterministyczne, równe
   48px zamiast polegać na tym, że się akurat zgodzą. */
.jbh-newsletter__field {
  position: relative;
  flex: 1;
  height: 48px !important;
  box-sizing: border-box !important;
  display: flex;
  align-items: center;
}
/* top:50%/translateY (jak w Newsletter.tsx: top-1/2 -translate-y-1/2) — bez tego
   position:absolute wyjmuje ikonę z flexa .jbh-newsletter__field (align-items:center
   go wtedy nie dotyczy) i pozycjonuje ją wg "static position" (efektywnie do góry
   pola, nie na środek). */
.jbh-newsletter__icon {
  position: absolute;
  left: 1rem;
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 16px;
  color: var(--jbh-muted);
  pointer-events: none;
}
/* border:#e5e7eb w spoczynku (neutralna szarość, nie zmieniane) — ":focus" dopisany
   jawnie, bo bez tego przeglądarka pokazuje własny, domyślny niebieski outline/ring
   zamiast bordowego akcentu marki. */
.jbh-newsletter__input {
  width: 100%;
  height: 48px;
  border-radius: 10px;
  border: 1px solid #e5e7eb;
  background: var(--jbh-card);
  padding-inline: 2.875rem 1rem;
  font-size: 14px;
  font-family: inherit;
  outline: none;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}
/* outline:none powtórzone tu (nie tylko w regule bazowej) — obrona przed dokładnie
   tym samym wzorcem błędu specyficzności co gdzie indziej w tym pliku: gdyby
   jakakolwiek reguła sklepu celowała w "input:focus" (klasa+typ+pseudoklasa =
   wyższa specyficzność niż sam .jbh-newsletter__input), zdublowany, niebieski
   natywny outline nakładałby się na nasz bordowy pierścień, dając wrażenie
   "podwójnej/rozmytej" ramki po kliknięciu.
   font-size:14px !important — modules/supercheckout/views/css/front/Bootstrap/bootstrap.css
   ładuje się globalnie na każdej stronie i ma "input:focus { font-size: 16px !important; }"
   (sztuczka przeciw auto-zoomowi Safari na iOS: pole z czcionką <16px focusowane
   na iPhone powoduje zoom całej strony — user-scalable=0 w meta viewport tego NIE
   blokuje). Specyficzność ".jbh-newsletter__input:focus" (klasa+pseudoklasa, 0-2-0)
   jest WYŻSZA niż "input:focus" sklepu (typ+pseudoklasa, 0-1-1) — przy obu !important
   o wyniku i tak rozstrzyga specyficzność, więc nasze 14px wygrywa. Ale to pole
   wraca do 16px na wąskich ekranach niżej (telefony — tam ten zoom realnie występuje,
   na desktopie/tablecie nie ma czego blokować). */
.jbh-newsletter__input:focus {
  outline: none;
  border-color: var(--jbh-primary);
  box-shadow: 0 0 0 3px rgba(148, 17, 20, 0.15);
  font-size: 14px !important;
}
@media (max-width: 639px) {
  .jbh-newsletter__input:focus {
    font-size: 16px !important;
  }
}
.jbh-newsletter__input::placeholder {
  color: var(--jbh-muted);
  opacity: 1;
}
.jbh-newsletter__submit {
  flex-shrink: 0;
  height: 48px !important;
  box-sizing: border-box !important;
  border-radius: 10px;
  padding-inline: 1.75rem;
}
.jbh-newsletter__consent {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.875rem;
  font-size: 11.5px;
  line-height: 1.625;
  color: #625d56;
  cursor: pointer;
  padding-left: 3px;
}
/* checkbox: uniform.js (autoload/uniform.default.css) podmienia natywny <input> na
   div.checker > span > input (sprite tła zamiast obrysu) — jego domyślny, bardzo
   jasny sprite ledwo widać na beżowym tle sekcji. Ten sam wzorzec nadpisania co
   #ddc .layered_filter_ul div.checker w dd-category.css: zwykła ramka + tło marki
   z białym ptaszkiem SVG po zaznaczeniu, zamiast sprite'u. */
.jbh-newsletter__consent .checker,
.jbh-newsletter__consent .checker span,
.jbh-newsletter__consent .checker input {
  width: 16px !important;
  height: 16px !important;
}
.jbh-newsletter__consent .checker {
  flex-shrink: 0;
  margin: -5px 1px 0 0 !important;
}
.jbh-newsletter__consent .checker span {
  display: block;
  border: 1px solid #9ca3af;
  border-radius: 4px;
  background: #fff;
  box-shadow: none;
}
/* background: (shorthand, jedna deklaracja) zamiast osobnych background-color/-image/
   -position/-size/-repeat — ten sam, sprawdzony zapis co #ddc .layered_filter_ul
   div.checker span.checked w dd-category.css (tam ptaszek renderuje się poprawnie);
   wersja na osobnych właściwościach longhand nie pokazywała ptaszku.
   background-position:center !important — uniform.default.css ma
   "div.checker.focus span.checked { background-position: -15px -257px; }"
   (klasa .focus dopisywana przez uniform.js, gdy checkbox MA fokus — czyli od razu
   po kliknięciu, zanim stracisz fokus klikając gdzieś indziej). Specyficzność tej
   reguły (div+.checker+.focus+span+.checked = 0-3-2) jest WYŻSZA niż nasza
   (0-3-1, bez dodatkowego typu "div"), więc wygrywała i spychała ptaszek SVG poza
   widoczny kwadrat — stąd pusty czerwony kafelek zaraz po kliknięciu, poprawny
   dopiero po utracie fokusu. !important na position (odczytywanej z shorthand
   background powyżej) to jedyny sposób, żeby pobić to bez dodawania "div" do
   naszego selektora na stałe. */
.jbh-newsletter__consent .checker span.checked {
  border-color: var(--jbh-primary);
  background: var(--jbh-primary)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E")
    center / 11px no-repeat;
  background-position: center !important;
}
.jbh-newsletter__consent a {
  font-weight: 500;
  color: #15110d;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.jbh-newsletter__msg {
  margin-top: 0.75rem;
  font-size: 13px;
  font-weight: 500;
}
.jbh-newsletter__msg.is-success {
  color: #1e7e34;
}
.jbh-newsletter__msg.is-error {
  color: var(--jbh-primary);
}
/* height:48px !important + overflow:hidden na samym wierszu (nie tylko na polu/
   przycisku w środku) — poprzednia wersja (height:48px bez !important/overflow)
   dalej dawała 58px w devtools, czyli coś jednak bije samo "height" mimo
   align-items:stretch i jawnych 48px na dzieciach. Zamiast dalej szukać czego,
   to ostateczny, nie do obejścia limit: box .jbh-newsletter__row fizycznie nie
   może przekroczyć 48px (overflow:hidden przycina, gdyby cokolwiek nadal chciało
   być wyższe), więc input/przycisk są wobec niego wyśrodkowane co do piksela.
   Tylko od 640px (poziomy układ) — w kolumnie na mobile wiersz musi się
   rozciągać na oba elementy pod sobą. */
@media (min-width: 640px) {
  .jbh-newsletter__row {
    flex-direction: row;
    align-items: center;
    height: 60px !important;
    overflow: hidden;
    padding-left: 3px;
  }
  .jbh-newsletter__title {
    font-size: 26px;
  }
}
@media (min-width: 1024px) {
  .jbh-newsletter {
    padding-block: 3.5rem;
  }
  .jbh-newsletter__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr);
  }
}

/* ------------------------------------------------------------------ 8. STOPKA */
.jbh-footer {
  margin-top: 3.5rem;
  border-top: 1px solid var(--jbh-border-soft);
  background: #fbf9f5;
  font-family: var(--jbh-font);
  color: var(--jbh-fg);
}
.jbh-footer__top {
  display: grid;
  gap: 2.25rem;
  padding-block: 2.5rem;
}
.jbh-footer__logo-link {
  display: inline-block;
}
.jbh-footer__logo-img {
  height: 40px;
  width: auto;
}
.jbh-footer__desc {
  max-width: 22rem;
  margin-top: 0.875rem;
  font-size: 13px;
  line-height: 1.6;
  color: var(--jbh-muted);
}
.jbh-footer__rating {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 1rem;
  font-size: 13px;
}
.jbh-footer__stars {
  display: flex;
  color: #c29440;
}
.jbh-footer__stars svg {
  width: 14px;
  height: 14px;
  fill: currentColor;
  stroke: none;
}
.jbh-footer__muted {
  color: var(--jbh-muted);
}
.jbh-footer__heading {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.jbh-footer__col ul {
  margin-top: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.jbh-footer__col a {
  font-size: 13px;
  color: var(--jbh-muted);
  transition: color 0.15s ease;
}
.jbh-footer__col a:hover {
  color: var(--jbh-fg);
}
.jbh-footer__contact {
  display: grid;
  gap: 0.75rem;
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
  border-top: 1px solid var(--jbh-border-soft);
}
.jbh-footer__contact a,
.jbh-footer__contact span {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 13px;
  color: var(--jbh-fg-75);
}
.jbh-footer__contact svg {
  width: 15px;
  height: 15px;
  color: var(--jbh-primary);
  flex-shrink: 0;
}
.jbh-footer__bottom {
  border-top: 1px solid var(--jbh-border-soft);
}
.jbh-footer__bottom-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding-block: 1rem;
  font-size: 12px;
  color: var(--jbh-muted);
}
@media (min-width: 768px) {
  .jbh-footer__top {
    grid-template-columns: 3fr 2fr 2fr 2fr;
  }
  .jbh-footer__contact {
    grid-template-columns: repeat(3, 1fr);
    border-top: 1px solid var(--jbh-border-soft);
  }
  .jbh-footer__bottom-row {
    flex-direction: row;
    justify-content: space-between;
  }
}
