/* ===== TOKENS ===== */
:root {
  --color-bg:           #F7F7F5;
  --color-text:         #1A1A1A;
  --color-heading:      #111111;
  --color-accent:       #1D3557;
  --color-accent-hover: #14263E;
  --color-border:       #DADAD6;
  --color-surface:      #FFFFFF;
  --color-muted:        #6B6B68;
  --color-sale:         #D4380D;

  --font-heading: 'Inter', system-ui, sans-serif;
  --font-body:    system-ui, sans-serif;
  --font-mono:    'DM Mono', 'Courier New', monospace;

  /* Repoint Bootstrap's primary at the DT navy. This covers text-primary, borders and
     anything building rgba() from the triple — but NOT buttons: Bootstrap 5.3 compiles
     .btn-primary with a literal `--bs-btn-bg`, so it never reads --bs-primary. Those
     are handled separately below. Verified by reading the computed --bs-btn-bg off a
     live button rather than assuming the variable cascaded. */
  --bs-primary:     #1D3557;
  --bs-primary-rgb: 29, 53, 87;
}

/* Buttons carry their own variable set. Overriding these rather than `background-color`
   keeps hover/active/disabled states consistent for free, and an unlayered rule beats
   Hummingbird's @layer-wrapped one regardless of specificity. */
.btn-primary {
  --bs-btn-bg:                  var(--color-accent);
  --bs-btn-border-color:        var(--color-accent);
  --bs-btn-hover-bg:            var(--color-accent-hover);
  --bs-btn-hover-border-color:  var(--color-accent-hover);
  --bs-btn-active-bg:           var(--color-accent-hover);
  --bs-btn-active-border-color: var(--color-accent-hover);
  --bs-btn-disabled-bg:         var(--color-accent);
  --bs-btn-disabled-border-color: var(--color-accent);
  --bs-btn-focus-shadow-rgb:    var(--bs-primary-rgb);
}

.btn-outline-primary {
  --bs-btn-color:             var(--color-accent);
  --bs-btn-border-color:      var(--color-accent);
  --bs-btn-hover-bg:          var(--color-accent);
  --bs-btn-hover-border-color: var(--color-accent);
  --bs-btn-active-bg:         var(--color-accent);
  --bs-btn-active-border-color: var(--color-accent);
}

/* ===== BASE ===== */
body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  color: var(--color-heading);
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* `:not(.btn)` is load-bearing. This rule is unlayered, so it outranks Bootstrap's
   layered `.btn { color: var(--bs-btn-color) }` no matter the specificity — without the
   guard every <a class="btn"> takes the accent as its TEXT colour. That went unnoticed
   while buttons were Bootstrap blue and only showed up once they became navy too: the
   cart's "Przejdź do realizacji zamówienia" rendered navy-on-navy, a solid unreadable
   block with the label still in the DOM. */
a:not(.btn) { color: var(--color-accent); }
a:not(.btn):hover { color: var(--color-accent-hover); }

/* ===== HEADER ===== */
#header {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}

#header .logo img { max-height: 48px; }

/* Single-bar header: override search bar's ms-auto so nav2 can sit to the right */
#_desktop_ps_searchbar { margin-left: 0 !important; }

nav .top-menu a {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--color-text);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

nav .top-menu a:hover { color: var(--color-accent); }

/* ===== MEGA MENU: THIRD LEVEL =====
   ps_mainmenu lays the third level out as a grid of fixed 225px columns, one per
   group, with each group's own link at 20px/600 — a format meant for groups that have
   a list of children underneath them. This catalogue is only three levels deep, so
   every one of those groups is a leaf (`--nochild`): the result was four oversized
   headings strung across a wide empty panel, each shouting louder than the 16px/400
   second-level parent it belongs to.

   Rendered instead as one narrow column that mirrors the second-level list beside it,
   at a weight below its parent so the hierarchy reads top-down. */
.header-nav-full-width .submenu__right-items {
  grid-template-columns: minmax(0, 300px);
  align-content: start;
  gap: 0;
}

.header-nav-full-width .submenu__right-items .menu-item__group-main-item {
  font-size: 0.95rem;
  font-weight: 400;
  padding: 0.45rem 0.75rem;
}

/* ===== HOMEPAGE CATEGORY GRID ===== */
.dt-category-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  margin: 2rem 0;
  border: 1px solid var(--color-border);
}

.dt-category-tile {
  background: var(--color-surface);
  padding: 2rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  border: 1px solid var(--color-border);
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}

.dt-category-tile:hover {
  background: var(--color-accent);
  border-color: var(--color-accent);
}

.dt-category-tile:hover .dt-cat-name,
.dt-category-tile:hover .dt-cat-count { color: #fff; }

.dt-cat-name {
  font-family: var(--font-heading);
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-heading);
}

.dt-cat-count {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--color-muted);
}

@media (max-width: 768px) {
  .dt-category-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 480px) {
  .dt-category-grid { grid-template-columns: 1fr; }
}

/* ===== PRODUCT GRID ===== */
.products {
  display: grid !important;
  grid-template-columns: repeat(4, 1fr) !important;
  gap: 1px !important;
}

@media (max-width: 1024px) { .products { grid-template-columns: repeat(2, 1fr) !important; } }
@media (max-width: 480px)  { .products { grid-template-columns: 1fr !important; } }

.product-miniature {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
}

/* Hummingbird v2 names its miniature parts product-miniature__*. The .thumbnail /
   .product-description / .product-title selectors a Classic-based theme would use do
   not exist in this markup, so rules written against them never applied. */
.product-miniature__image-container {
  aspect-ratio: 1;
  overflow: hidden;
}

.product-miniature__image {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 0.5rem;
}

.product-miniature__bottom { padding: 0.75rem 1rem 1rem; gap: 0.25rem; }

.product-miniature__title {
  font-family: var(--font-heading);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-text);
  text-decoration: none;
  line-height: 1.3;
}

.product-miniature__title:hover { color: var(--color-accent); }

.product-miniature__prices {
  font-weight: 700;
  color: var(--color-heading);
  padding-top: 0.5rem;
}

.product-miniature__prices .regular-price {
  font-size: 0.8rem;
  color: var(--color-muted);
  text-decoration: line-through;
}

/* The tile's add-to-cart is a 38px icon square. It only started rendering once
   available_for_order was set, so its alignment against the stepper had never been
   exercised — without this the two sit on different baselines. */
.product-miniature__actions .quantity-button__group,
.product-miniature__add { height: 38px; }

.product-miniature__form {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* ===== CATEGORY PAGE ===== */
.page-category .page-header h1 {
  font-size: 1.5rem;
  margin-bottom: 0.25rem;
}

.page-category .products-selection .total-products {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--color-muted);
}

/* ===== PRODUCT PAGE ===== */
.page-product .product-container {
  display: grid;
  grid-template-columns: 45% 55%;
  gap: 2rem;
  align-items: start;
}

@media (max-width: 768px) {
  .page-product .product-container { grid-template-columns: 1fr; }
}

/* These names are ours (catalog/product.tpl), not Hummingbird's — the theme's own
   product page markup is replaced wholesale, so none of the .page-title /
   .current-price selectors a Classic-based theme would use exist here. */
.dt-product__name {
  font-size: 1.6rem;
  line-height: 1.25;
  /* Titles are long and spec-heavy ("... walcowo-czołowy krótki HSS-E 11 mm").
     `balance` evens the lines instead of leaving one orphaned word. */
  text-wrap: balance;
  margin-bottom: 0.75rem;
}

@media (max-width: 480px) {
  .dt-product__name { font-size: 1.3rem; }
}

/* SKU left, brand logo right, on one baseline */
.dt-product__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 2.25rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: 1rem;
}

/* Two columns of max-content: the labels size themselves and the values line up with
   each other, which stacked <p>s cannot do when one label is "Numer katalogowy" and the
   next is "EAN". */
.dt-product__codes {
  display: grid;
  grid-template-columns: max-content max-content;
  column-gap: 0.85rem;
  row-gap: 0.2rem;
  align-items: baseline;
  margin: 0;
}

.dt-product__codes dt {
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-muted);
  font-weight: 400;
}

.dt-product__codes dd {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--color-text);
  margin: 0;
}

.dt-product__manufacturer { flex-shrink: 0; line-height: 0; }

/* Fed from the untouched original (product.tpl), so each logo keeps its own aspect
   ratio. Both axes are capped, and the ratio between the caps is the point.

   Pinning the HEIGHT alone made the brands wildly uneven, because their sources are
   different shapes: Fanar is a 449x112 banner (4:1), Norton a 250x250 square (1:1). At
   a fixed 80px height Fanar covered 280x80 and Norton 80x80 — three and a half times
   the ink for no reason other than the shape of the file.

   With max-width = 2 x max-height, a 4:1 logo is width-limited to 2H x H/2 and a 1:1
   logo is height-limited to H x H — both exactly H^2 of area. Anything in between peaks
   at 2x that (at aspect 2:1), so the whole catalogue lands in a 1x-2x band instead of
   the 1x-3.5x+ spread. Every original is larger than this box, so all of them scale
   down and none get upscaled. Change the two numbers together or the balance is lost. */
.dt-product__manufacturer-logo {
  width: auto;
  height: auto;
  max-height: 72px;
  max-width: 144px;
  object-fit: contain;
  mix-blend-mode: multiply; /* kills the white box against our off-white page */
}

/* The row is `align-items: center` for the SKU text; a taller logo would otherwise
   stretch the divider away from the heading. Keep this at least the logo's max-height. */
.dt-product__meta { min-height: 5rem; }

.dt-product__manufacturer-name {
  font-family: var(--font-heading);
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.2;
}

/* Price: gross large, net alongside in grey */
.dt-price-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.25rem;
}

.dt-price-gross {
  font-family: var(--font-heading);
  font-size: 1.75rem;
  font-weight: 700;
  color: var(--color-heading);
  line-height: 1.1;
}

.dt-price-net {
  font-family: var(--font-mono);
  font-size: 0.95rem;
  color: var(--color-muted);
}

.dt-price-unit {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-muted);
}

.dt-prices .product__tax-infos:empty,
.dt-product__desc-short:empty { display: none; }

.dt-prices .product__regular-price {
  font-size: 1rem;
  color: var(--color-muted);
  text-decoration: line-through;
}

.dt-prices .product__discount-percentage,
.dt-prices .product__discount-amount {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--color-sale);
}

/* ===== STOCK ===== */
.dt-stock {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  margin: 1rem 0;
}

.dt-stock__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  flex-shrink: 0;
  background: currentColor;
}

.dt-stock--in  { color: #1F7A46; }
.dt-stock--out { color: var(--color-sale); }

/* ===== SPECS TABLE ===== */
.product-features table,
.dt-specs-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
  margin: 1.5rem 0;
}

.product-features th,
.dt-specs-table th {
  font-family: var(--font-heading);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-muted);
  text-align: left;
  padding: 0.5rem 0.75rem;
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
  width: 45%;
}

.product-features td,
.dt-specs-table td {
  font-family: var(--font-mono);
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text);
}

.product-features tr:last-child th,
.product-features tr:last-child td,
.dt-specs-table tr:last-child th,
.dt-specs-table tr:last-child td { border-bottom: none; }

/* ===== ADD TO CART ===== */
/* One shared height for the stepper and the button — they sit side by side, and
   Hummingbird sizes them from different rules (form-control vs btn), so left alone
   they land a few pixels apart and the row reads as broken. */
:root { --dt-buy-height: 3rem; }

.page-product .product__actions-qty-add {
  display: flex;
  align-items: stretch;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

.page-product .product__quantity { flex: 0 0 auto; }
.page-product .product__add-to-cart { flex: 1 1 auto; display: flex; }

.page-product .quantity-button__group {
  height: var(--dt-buy-height);
  border: 1px solid var(--color-border);
  border-radius: 2px;
  background: var(--color-surface);
  overflow: hidden;
}

.page-product .quantity-button__group .btn,
.page-product .quantity-button__group .form-control {
  height: 100%;
  border: none;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.page-product .quantity-button__group .form-control {
  width: 3rem;
  text-align: center;
  font-family: var(--font-mono);
  padding: 0;
}

.page-product .product__add-to-cart-button {
  width: 100%;
  height: var(--dt-buy-height);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  background: var(--color-accent);
  border: 1px solid var(--color-accent);
  color: #fff;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 0.9rem;
  letter-spacing: 0.03em;
  padding: 0 1.5rem;
  border-radius: 2px;
  margin: 0;
}

.page-product .product__add-to-cart-button:hover:not(:disabled) {
  background: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
}

@media (max-width: 480px) {
  .page-product .product__actions-qty-add { flex-wrap: wrap; }
  .page-product .product__add-to-cart { flex-basis: 100%; }
}

/* ===== BREADCRUMB ===== */
.breadcrumb {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--color-muted);
  padding: 0.75rem 0;
}

.breadcrumb a { color: var(--color-muted); }
.breadcrumb .current { color: var(--color-text); }

/* ===== CMS PAGES ===== */
.dt-cms { max-width: 820px; margin: 0 auto; }

/* Banner strip */
.dt-cms-banner {
  background: var(--color-accent);
  color: #fff;
  padding: 1.25rem 1.5rem;
  display: flex;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 2rem;
}
.dt-cms-banner-label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  opacity: 0.65;
  flex-shrink: 0;
}
.dt-cms-banner-value {
  font-family: var(--font-heading);
  font-size: 1.4rem;
  font-weight: 700;
}

/* Section heading */
.dt-cms-heading {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-muted);
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--color-border);
  margin: 2rem 0 1rem;
}
.dt-cms-heading:first-child { margin-top: 0; }

/* Card grid (carriers, contact blocks) */
.dt-cms-grid {
  display: grid;
  gap: 1px;
  background: var(--color-border);
  border: 1px solid var(--color-border);
  margin: 1rem 0 1.5rem;
}
.dt-cms-grid--3 { grid-template-columns: repeat(3, 1fr); }
.dt-cms-grid--2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 768px) {
  .dt-cms-grid--3,
  .dt-cms-grid--2 { grid-template-columns: 1fr; }
}

.dt-cms-card {
  background: var(--color-surface);
  padding: 1.25rem 1.5rem;
}
.dt-cms-card-label {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-muted);
  margin-bottom: 0.4rem;
}
.dt-cms-card-title {
  font-family: var(--font-heading);
  font-size: 1rem;
  font-weight: 700;
  color: var(--color-heading);
  margin-bottom: 0.4rem;
}
.dt-cms-card-title a {
  color: var(--color-heading);
  text-decoration: none;
}
.dt-cms-card-title a:hover { color: var(--color-accent); }
.dt-cms-card-body {
  font-size: 0.875rem;
  color: var(--color-muted);
  line-height: 1.6;
}

/* Info box with left border */
.dt-cms-infobox {
  border-left: 3px solid var(--color-accent);
  background: var(--color-surface);
  padding: 0.9rem 1.25rem;
  margin: 1rem 0 1.5rem;
  font-size: 0.875rem;
  line-height: 1.6;
}
.dt-cms-infobox strong { color: var(--color-heading); }

/* Numbered steps */
.dt-cms-steps { margin: 1rem 0 1.5rem; display: flex; flex-direction: column; gap: 1px; }
.dt-cms-step {
  display: flex;
  gap: 1.25rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  padding: 1.1rem 1.25rem;
}
.dt-cms-step-num {
  flex-shrink: 0;
  width: 1.75rem;
  height: 1.75rem;
  background: var(--color-accent);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.dt-cms-step-body { flex: 1; font-size: 0.875rem; line-height: 1.6; color: var(--color-text); }
.dt-cms-step-body strong { color: var(--color-heading); font-family: var(--font-heading); }

/* Data table (key–value rows).
   Sits between .dt-cms-card and .dt-cms-infobox blocks, so it needs the same surface
   and the same inner padding as them. With cells padded `0.55rem 0` the labels ran
   flush to the container edge while every neighbouring block indented its text, which
   read as the copy being glued to the edge of the box. */
.dt-cms-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
  margin: 0.5rem 0 1.5rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
}
.dt-cms-table td {
  padding: 0.7rem 1.25rem;
  border-bottom: 1px solid var(--color-border);
  vertical-align: top;
  line-height: 1.5;
}
.dt-cms-table td:first-child {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-muted);
  width: 35%;
  padding-top: 0.85rem;
}
.dt-cms-table tr:last-child td { border-bottom: none; }

/* Cookies table */
.dt-cms-cookies {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
  margin: 0.75rem 0 1.5rem;
}
.dt-cms-cookies th {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-muted);
  text-align: left;
  padding: 0.5rem 0.75rem;
  background: var(--color-bg);
  border-bottom: 2px solid var(--color-border);
}
.dt-cms-cookies td {
  padding: 0.6rem 0.75rem;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text);
  vertical-align: top;
}
.dt-cms-cookies td:first-child { font-family: var(--font-mono); }
.dt-cms-cookies tr:last-child td { border-bottom: none; }

/* Legal (Regulamin) */
.dt-legal p, .dt-legal li { font-size: 0.9rem; line-height: 1.75; color: var(--color-text); }
.dt-legal ul, .dt-legal ol { padding-left: 1.5rem; margin-bottom: 0.75rem; }
.dt-legal h3 {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-muted);
  margin: 1.75rem 0 0.75rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--color-border);
}

/* Appendix box */
.dt-appendix {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  padding: 1.5rem;
  margin-top: 2rem;
}
.dt-appendix-label {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-muted);
  margin-bottom: 1rem;
}

/* ===== FOOTER ===== */
#footer {
  background: var(--color-heading);
  color: rgba(255,255,255,0.7);
  font-size: 0.85rem;
}

#footer a { color: rgba(255,255,255,0.7); }
#footer a:hover { color: #fff; }

#footer .footer-container h4,
#footer .footer-container .h4 {
  color: #fff;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* ===== PORADNIK ===== */
/* The 26 ported IdoSell blog posts. Their bodies carry no classes at all —
   strip_presentation() removed the old site's inline styling — so every rule
   below targets bare tags inside .dt-poradnik-body.

   The wrapper <section> keeps Hummingbird's `rich-text` class (see
   templates/cms/page.tpl for why), so these rules sit on top of rich-text's
   typography rather than replacing it. Anything already correct there is not
   repeated here. */

.dt-poradnik-article { max-width: 820px; margin: 0 auto; }

.dt-poradnik-body { line-height: 1.7; }

.dt-poradnik-body h2 {
  font-family: var(--font-heading);
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--color-heading);
  margin: 2.25rem 0 0.75rem;
}
.dt-poradnik-body h3 {
  font-family: var(--font-heading);
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--color-heading);
  margin: 1.75rem 0 0.5rem;
}
.dt-poradnik-body h4 {
  font-family: var(--font-heading);
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-heading);
  margin: 1.5rem 0 0.5rem;
}
/* The scraped bodies open with an image inside nested wrapper divs, so the
   first heading is rarely the first child — reset the top margin on whichever
   element actually starts the article. */
.dt-poradnik-body > :first-child { margin-top: 0; }

.dt-poradnik-body p { margin: 0 0 1rem; }
.dt-poradnik-body ul,
.dt-poradnik-body ol { margin: 0 0 1rem; padding-left: 1.25rem; }
.dt-poradnik-body li { margin-bottom: 0.35rem; }

/* Hummingbird's reset is `ol, ul { list-style: none; padding-left: 0 }` and its
   `.rich-text` rules only put the marker back on `ul` — `ol` is never restored.
   16 ordered lists across 13 of the 26 posts rendered as unnumbered, unindented
   text until this was added. Setting padding-left above was NOT enough; the
   reset's `list-style: none` still won.

   Scoped to .dt-poradnik-body on purpose. A `.rich-text ol` fix would also
   change the five legal CMS pages, which are deliberately left byte-identical. */
.dt-poradnik-body ol { list-style: decimal; }
.dt-poradnik-body ul { list-style: disc; }

/* Some prose sits in a bare <div> instead of a <p> and so inherits no paragraph
   spacing — it butts straight against whatever follows. Exactly one paragraph in
   the 26-post corpus does this today (akcesoria-i-narzedzia-przydatne-przy-
   gwintowaniu, where it collides with the table below it), but the rule is worth
   having because the shape comes from the source HTML, not from us.

   It has to match ONLY the leaf that holds the prose. The scraped bodies nest
   wrapper <div>s up to 8 deep, so a blanket `div { margin-bottom }` would stack
   eight margins on one paragraph. :has() is what makes "leaf" expressible.

   Two guards:
     :not(:empty)  — four <div></div> with no children at all would otherwise get
                     1rem of margin around nothing.
     img in the    — a <div> wrapping only an image already gets its spacing from
     :has() list     the img rule above; without this it would get both.

   Where :has() is unsupported the whole selector is invalid and dropped, which
   leaves that one paragraph rendering as it does today. It degrades to the status
   quo, not to something broken. */
.dt-poradnik-body div:not(:empty):not(:has(div, p, ul, ol, table, h1, h2, h3, h4, h5, h6, img)) {
  margin: 0 0 1rem;
}

/* Old-site images are up to 1200px wide and would otherwise blow past the
   820px text measure. */
.dt-poradnik-body img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 1.5rem 0;
  border: 1px solid var(--color-border);
}

.dt-poradnik-body table {
  width: 100%;
  border-collapse: collapse;
  margin: 1.25rem 0;
  font-size: 0.875rem;
}
.dt-poradnik-body th,
.dt-poradnik-body td {
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--color-border);
  text-align: left;
}
.dt-poradnik-body th { background: var(--color-surface); color: var(--color-heading); }

.dt-poradnik-body a { color: var(--color-accent); }

.dt-poradnik-intro { margin-bottom: 1.5rem; }

/* Index, homepage strip and category-page related block all reuse .dt-cms-grid,
   which ships no grid-template-columns of its own — each caller picks its own.

   .dt-cms-grid draws its hairlines by painting the whole grid with the border
   colour and letting a 1px `gap` show through. That works for the legal pages,
   where every cell is filled by hand. It does NOT work here: these grids are
   populated from a variable-length list, so a 4-item list in a 3-track grid
   leaves two cells unpainted and they render as a large grey slab. Screenshots
   of the Poradnik index caught it — the DOM looked perfectly correct.

   So this grid opts out of the trick: transparent background, real gap, and a
   border on each card instead. auto-fit (not auto-fill) collapses the empty
   tracks, so two cards become two half-width cards rather than two cards and a
   hole, and no breakpoint list is needed. */
.dt-poradnik-grid {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1rem;
  background: none;
  border: 0;
}

.dt-poradnik-card {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  border: 1px solid var(--color-border);
  text-decoration: none;
  color: inherit;
  transition: background 0.15s ease;
}
.dt-poradnik-card:hover { background: var(--color-bg); }
.dt-poradnik-card .dt-cms-card-title { margin-bottom: 0; }
.dt-poradnik-card:hover .dt-cms-card-title { color: var(--color-accent); }

/* Sub-category tiles on the Poradnik index read as navigation, not articles. */
.dt-poradnik-cat .dt-cms-card-title {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Bottom margin matters: neither the homepage `section.container` nor the
   category listing has bottom padding, so without it the strip sits flush
   against the dark footer. */
.dt-home-poradnik { margin: 3rem 0; }
.dt-poradnik-related { margin: 3rem 0; }

.dt-poradnik-more {
  display: inline-block;
  margin-top: 0.25rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-accent);
  text-decoration: none;
}
.dt-poradnik-more:hover { text-decoration: underline; }

/* ---- CMS text utilities ----
   HTMLPurifier (PS_USE_HTMLPURIFIER = 1) rejects any inline style whose value
   is a CSS custom property, so `style="font-family:var(--font-mono)"` inside
   CMS content is silently stripped on every CMS::update(). These classes give
   the same result and survive purification. Use them, never inline var(). */
.dt-cms-mono {
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
}

.dt-cms-muted {
  color: var(--color-muted);
}

/* ---- Free-shipping progress bar (cart) ---- */
/* Hummingbird's `.cart-summary__line` is `display:flex` with `justify-content:
   space-between` and the default `flex-wrap: nowrap`. The hint and the bar are
   extra children of that row, so without these two rules they would be squeezed
   onto the label/value line instead of stacking under it. */
.cart-summary__line--shipping { flex-wrap: wrap; }

.cart-summary__hint {
  display: block;
  flex: 0 0 100%;
  font-size: 0.8125rem;
  color: var(--color-muted);
  margin-top: 0.25rem;
}

.dt-freeship { flex: 0 0 100%; margin-top: 0.5rem; }

.dt-freeship__text {
  display: block;
  font-size: 0.8125rem;
  margin-bottom: 0.375rem;
}

.dt-freeship__scope { color: var(--color-muted); }

.dt-freeship__bar {
  display: block;
  height: 0.375rem;
  border-radius: 999px;
  background: var(--color-border);
  overflow: hidden;
}

.dt-freeship__fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--color-accent);
  transition: width 0.3s ease;
}

/* ---- Product page delivery list ---- */
.dt-delivery {
  list-style: none;
  padding: 0;
  margin: 1rem 0 0.5rem;
  font-size: 0.875rem;
}

.dt-delivery__item {
  padding: 0.25rem 0 0.25rem 1.25rem;
  position: relative;
}

.dt-delivery__item::before {
  content: "\00b7";
  position: absolute;
  left: 0.375rem;
  color: var(--color-accent);
  font-weight: 700;
}

.dt-delivery__note,
.dt-delivery__item--warn { color: var(--color-muted); }

.dt-delivery__item--warn { font-size: 0.8125rem; }

.dt-delivery__more { font-size: 0.8125rem; margin: 0; }

/* ===== COOKIE CONSENT BANNER ===== */
/* Injected into <body> by assets/js/consent.js, and only while no decision is
   stored — so these rules apply to at most one visit per visitor.

   Colours come from the tokens above rather than fresh hex values; the banner sits
   over arbitrary page content, so it needs the opaque --color-surface, not the page
   background. z-index is above Hummingbird's sticky header (1030) and its offcanvas
   backdrop (1040) — below either and the banner is unreachable on a page that has
   scrolled or opened the mobile menu. */
#dt-consent {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1080;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.25rem;
  background: var(--color-surface);
  color: var(--color-text);
  border-top: 1px solid var(--color-border);
  box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.12);
  font-size: 0.875rem;

  /* Unconditional, not inside the 480px query it started in: the constraint is
     "the bar must not eat the viewport", which is about HEIGHT, and a landscape
     phone (667x375) is wide enough to miss a width breakpoint while being the
     shortest viewport there is. Applying it always needs no second breakpoint and
     costs nothing on a desktop, where the bar is far under 60vh and never scrolls. */
  max-height: 60vh;
  overflow-y: auto;
}

/* consent.js focuses the bar on appearance so keyboard and screen-reader users land
   on it. That leaves a focus ring on the container itself, which is noise for a mouse
   user — :focus-visible keeps it for exactly the people it helps. */
#dt-consent:focus:not(:focus-visible) { outline: none; }

/* The withdraw-consent trigger consent.js injects into the footer link list, beside
   the privacy policy. It is a <button> because it performs an action rather than
   navigating, but it sits among <a>s and has to read as one of them — hence stripping
   the UA button chrome and inheriting the footer's own link colour rather than
   restating it. Keep in step with the `#footer a` rules above. */
.dt-consent-reopen {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  color: rgba(255,255,255,0.7);
  cursor: pointer;
}

.dt-consent-reopen:hover { color: #fff; }

/* `flex: 1 1 320px` rather than a percentage: the text keeps the buttons on the same
   row on a wide viewport and drops them to their own row once it cannot hold 320px,
   without a breakpoint having to guess where that is. */
#dt-consent .dt-consent__text {
  flex: 1 1 320px;
  margin: 0;
  line-height: 1.5;
}

#dt-consent .dt-consent__text a {
  color: var(--color-accent);
  text-decoration: underline;
}

#dt-consent .dt-consent__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  flex-shrink: 0;
}

/* Full-width buttons on a phone: at 480px the two sit side by side with barely a
   thumb's width each, and "Tylko niezbędne" wraps to two lines inside its own button. */
@media (max-width: 480px) {
  #dt-consent {
    padding: 0.875rem 1rem;
    gap: 0.75rem;
    font-size: 0.8125rem;
  }

  #dt-consent .dt-consent__actions {
    flex: 1 1 100%;
    flex-direction: column;
  }

  #dt-consent .dt-consent__actions .btn { width: 100%; }
}

/* ===== ORDER CONFIRMATION: BANK TRANSFER PANEL =====

   The "Informacje o płatności" panel on the order-confirmation page — the <dl class="dl-list">
   inside themes/hummingbird/modules/ps_wirepayment/views/templates/hook/payment_return.tpl.
   `.dl-list` is a Hummingbird component but it is used in exactly two templates, both
   payment_return (ps_wirepayment and the disabled ps_checkpayment), so styling it here is
   scoped to this panel in practice without a brittle :first-of-type selector — the card
   itself carries no class to hang one on.

   Hummingbird declares it as a fixed two-column grid at EVERY width:
     .dl-list { grid-template-columns: repeat(2, minmax(0, 1fr)) }
   with 1rem of padding on each dt and dd. On a 375px phone that leaves each value about
   127px of text, and the account number — the one string on this page a customer has to
   copy into a banking app — breaks across three lines mid-group:

       18 1240 4432
       1111 0011 2510
       9179

   A number split like that is exactly how a transfer goes to the wrong account. Stacking
   the list below the tablet breakpoint gives every value the full width of the card.

   The dt keeps its bottom border only when the pair is side by side; stacked, the border
   would cut between a term and its own value instead of between rows. */
@media (max-width: 768px) {
  .dl-list {
    grid-template-columns: 1fr;
  }

  .dl-list dt {
    border-block-end: none;
    padding-block-end: 0.25rem;
  }

  .dl-list dd {
    padding-block-start: 0;
  }
}

/* ---- Checkout order summary: inset the card contents ---- */
/* `.checkout__summary-accordion-item` is the white card in the checkout's right
   column, and it ships with `padding: 0`. Every row inside it — "Produkty",
   "Wysyłka", "Razem (brutto)" and the accordion header — therefore sits flush
   against both card edges: measured at 1280px, label `left` gap 0 and value
   `right` gap 0 from the card border. On narrower columns the trailing "zł"
   reads as clipped.
   Padding the card rather than the rows means the `.cart-summary__total`
   separator rules inset with it, which is the intended card look.
   Scoped to the accordion deliberately: `.cart-summary__line` is shared with
   /koszyk, where the summary is transparent and full-bleed is correct. */
.checkout__summary-accordion .checkout__summary-accordion-item {
  padding-left: 1rem;
  padding-right: 1rem;
}

/* The accordion header is a Bootstrap button whose own horizontal padding the
   theme zeroes; with the card padded it needs none of its own, or the label
   would sit 2rem in while the rows below sit at 1rem. */
.checkout__summary-accordion .accordion-button {
  padding-left: 0;
  padding-right: 0;
}

/* The same `padding: 0` left the card's first row flush against its top border
   too, which reads as clipped rather than as a deliberately tight card — the
   accordion header's text box starts at the border with nothing above it.
   1rem matches the horizontal inset so the content sits in a square margin
   rather than a letterbox; there is no reason for the top gap to differ from
   the one beside it, and an asymmetric inset is the kind of thing that reads as
   a bug even when nobody can name it.
   Written as `padding-block` rather than a second `padding-top`/`bottom` pair
   because the shorthand cannot be half-applied, so the two edges cannot drift
   apart in a later edit. */
.checkout__summary-accordion .checkout__summary-accordion-item {
  padding-block: 1rem;
}

/* The header button carries the theme's own vertical padding, which now stacks
   on top of the card's. Zeroing its top padding keeps the first line exactly
   1rem below the border, matching the 1rem beside it — otherwise the top gap
   is visibly the largest of the four. */
.checkout__summary-accordion .accordion-button {
  padding-top: 0;
}

/* ---- Checkout: why "Złóż zamówienie" is greyed out ---- */
/* The button is disabled until a payment method is chosen AND the terms are
   accepted, and until now it said so nowhere: a dead grey button with no cause
   on screen. The hint lives in
   templates/checkout/_partials/steps/payment.tpl and is shown purely by this
   selector, so its visibility is derived from the button's own state rather
   than recomputed. themes/_core/js/checkout-payment.js owns that state — it
   sets both the `disabled` attribute and the `.disabled` class in
   toggleOrderButton() — and matching on either means the hint is also correct
   for the server-rendered pre-JS state, where Smarty emits the class alone.
   The consequence of deriving it this way is that the hint cannot say which of
   the two conditions is missing, so the copy names both. */
.dt-order-blocked-hint {
  display: none;
}

#payment-confirmation button[disabled] + .dt-order-blocked-hint,
#payment-confirmation button.disabled + .dt-order-blocked-hint {
  display: block;
  color: var(--color-muted);
}

/* ---------------------------------------------------------------------------
   Checkout — payment option rows
   ---------------------------------------------------------------------------
   Upstream's payment.tpl puts the provider logo and the call-to-action text in
   one <label> with nothing between them:

     <label class="payment-option__label form-check-label">
       <img class="img-fluid" src="...">     BLIK
     </label>

   `img-fluid` sets only max-width, so a tall logo (the BLIK mark is the worst
   offender) keeps its intrinsic height, the label stays `display:inline`, and the
   text lands wherever the image's baseline leaves it — reading as "BLIKZostaniesz
   przekierowany..." against the artwork rather than beside it.

   Flex on the label fixes both at once: the gap separates logo from text, and
   align-items centres the text against the mark instead of sitting it on the
   baseline. The height cap is what actually tames the logos — without it the row
   is as tall as whatever each provider happened to upload.

   `.payment-option__additional-information` is a sibling of the form-check, not a
   child of the label, so it needs its own spacing; without it the explanatory
   line butts straight up under the logo it belongs to. It is indented to line up
   with the label text rather than the radio, so it reads as belonging to the
   option above it. */
.payment-option__label {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.payment-option__label img {
  max-height: 28px;
  width: auto;
  flex: 0 0 auto;
}

.payment-option__additional-information {
  margin: 0.35rem 0 0 1.9rem;
}

.payment-option + .payment-option {
  margin-top: 0.5rem;
}

/* ---------------------------------------------------------------------------
   Checkout — the country field is not a choice
   ---------------------------------------------------------------------------
   This shop ships to one country. The select renders with a single option, so it
   looks interactive while being unable to do anything, which is its own small
   confusion at the exact moment someone is checking their address.

   Styled inert rather than given the `disabled` attribute, deliberately: a
   disabled <select> is not submitted, so `id_country` would arrive empty and
   PrestaShop would reject the address. Carrying a parallel hidden input to make
   up for that is a second copy of the value, and the two drift. Keeping the real
   control in the form and only removing its affordances changes nothing about
   what POSTs.

   `pointer-events: none` stops the dropdown opening; the muted background and
   colour say why. The field stays in the tab order and still announces its value
   to a screen reader, which is correct — it is information, just not a decision.
   Scoped to the address form so no other select on the site is affected. */
.js-address-form select[name="id_country"],
#delivery-address select[name="id_country"],
#invoice-address select[name="id_country"] {
  pointer-events: none;
  background-color: var(--bs-secondary-bg, #f1f3f5);
  color: var(--color-muted, #6c757d);
  opacity: 1;
}
